Skip to content

Conversation

@aleclearmind
Copy link
Contributor

We need this change in order to do this.
Comments?

@aleclearmind aleclearmind requested review from drblallo and pfez January 26, 2021 15:15
@drblallo
Copy link
Contributor

if i understand correctly the issue is that there are some custom classes that do not implements the serializable traits but are serializable in some other way and the removed overloads prevents selecting the correct one?

@aleclearmind
Copy link
Contributor Author

if i understand correctly the issue is that there are some custom classes that do not implements the serializable traits but are serializable in some other way and the removed overloads prevents selecting the correct one?

The problem is that LLVM has an implementation of yamlize that is enable_ifd if all the other known implementation do not fit.
The point is that the enable_if condition does not consider implementation that other users might want to introduce (such as ours).

Long story short, the fallback implementation (which is used to provide "useful" error information to the developer in case he's using a class for which GraphTraits are not implemented) prevents using our custom yamlize function.

Dropping the fallback implementation solves the problem, but we no longer have nice errors if we're trying to use YAMLTraits with a class for which they are actually not implemented.

Makes sense?

@drblallo
Copy link
Contributor

then wouldn't be better to add

enabled_if<missing_traits and not is_KeyedObjectContainer_t<T>>

?

since we must operate changes on llvm we may as well improve it rather than just removing a feature.
I guess that would require to move is_keyedObject to llvm?

@aleclearmind
Copy link
Contributor Author

I guess that would require to move is_keyedObject to llvm?

Yeah, we don't want to do that...

@pfez
Copy link
Contributor

pfez commented Jan 26, 2021

In LLVM's code (llvm/include/llvm/Support/YAMLTraits.h:720 I see the following,

  template <typename T, typename Context>
  struct missingTraits
      : public std::integral_constant<bool,
                                      !has_ScalarEnumerationTraits<T>::value &&
                                          !has_ScalarBitSetTraits<T>::value &&
                                          !has_ScalarTraits<T>::value &&
                                          !has_BlockScalarTraits<T>::value &&
                                          !has_TaggedScalarTraits<T>::value &&
                                          !has_MappingTraits<T, Context>::value &&
                                          !has_SequenceTraits<T>::value &&
                                          !has_CustomMappingTraits<T>::value &&
                                          !has_DocumentListTraits<T>::value &&
                                          !has_PolymorphicTraits<T>::value> {};

Can't we massage our own data structures that need to be serialized so that they make has_MappingTraits or has_CustomMappingTraits or any of the other relevant cases true?

I'm not that much into the Model data structures yet, but it looks like we should be able to make them fit into one of the foreseen cases. Is that not the case?

@aleclearmind
Copy link
Contributor Author

Can't we massage our own data structures that need to be serialized so that they make has_MappingTraits or has_CustomMappingTraits or any of the other relevant cases true?

Nope, those you mentioned create YAML "mappings" (a "map"), in this situation we want a YAML "sequence" (a "vector").

We might create a new trait in LLVM, CustomSequenceTraits, and move the bulk of our logic in a yamlize specialization using that trait. Then, in revng, we can specialize that trait for our data structures.

This is probably the cleanest way to go. Users are not supposed to specialize yamlize after all.

Problem is: it might take a bit of time and this issue is annoying @drblallo and Alain.
I'll see if it's doable.

Copy link
Contributor

@pfez pfez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! The best thing would be if we manage to customize it using has_SequenceTraits. But yeah, try to understand how long it may take. If it's blocking @drblallo we can go ahead with how it is right now.

If we go ahead like it is right now, please add a comment for future reference on the right way to do it. Or at least mention it in the commit message.

@aleclearmind
Copy link
Contributor Author

Yes! The best thing would be if we manage to customize it using has_SequenceTraits.

Wait, we need CustomSequenceTraits. Regular SequenceTraits assume you have a pre-.resized vector(-like), which is not the situation we're in.
Nevertheless, it can be done with a custom trait, or maybe changing the existign one in a backward compatible way.

@pfez
Copy link
Contributor

pfez commented Jan 26, 2021

Yes! The best thing would be if we manage to customize it using has_SequenceTraits.

Wait, we need CustomSequenceTraits. Regular SequenceTraits assume you have a pre-.resized vector(-like), which is not the situation we're in.

Yeah, sorry, my bad. CustomSequenceTraits. Sloppy copy-pasting.

@aleclearmind aleclearmind force-pushed the feature/drop-missing-yamltraits branch 2 times, most recently from b1170a6 to 2620fd3 Compare January 27, 2021 11:46
@aleclearmind
Copy link
Contributor Author

New usage:

template<typename T>
struct llvm::yaml::SequenceTraits<T, enable_if_is_KeyedObjectContainer_t<T>> {
  static size_t size(IO &io, T &Seq) { return Seq.size(); }

  class Inserter {
  private:
    using value_type = typename T::value_type;
    using KOT = KeyedObjectTraits<value_type>;
    using key_type = decltype(KOT::key(std::declval<value_type>()));

  private:
    typename T::BatchInserter BatchInserter;
    value_type Instance;

  public:
    Inserter(IO &io, T &Seq) :
      BatchInserter(Seq.batch_insert()), Instance(KOT::fromKey(key_type())) {}

    auto &preflightElement(unsigned) { return Instance; }

    void postflightElement(unsigned) {
      BatchInserter.insert(Instance);
      Instance = KOT::fromKey(key_type());
    };
  };
};

@aleclearmind aleclearmind force-pushed the feature/drop-missing-yamltraits branch from 2620fd3 to befde3c Compare January 27, 2021 11:49
@aleclearmind aleclearmind changed the title Drop fallback for yamlize Extend llvm::yaml::SequenceTraits for batch insertion Jan 27, 2021
@aleclearmind
Copy link
Contributor Author

Merged in befde3c.
Thanks everyone for the feedback.

aleclearmind pushed a commit that referenced this pull request Apr 5, 2023
Change https://reviews.llvm.org/D140059 exposed the following crash in
Z3Solver, where bit widths were not checked consistently with that
change. This change makes the check consistent, and fixes the crash.

```
clang: <root>/llvm/include/llvm/ADT/APSInt.h:99:
  int64_t llvm::APSInt::getExtValue() const: Assertion
  `isRepresentableByInt64() && "Too many bits for int64_t"' failed.
...
Stack dump:
0. Program arguments: clang -cc1 -internal-isystem <root>/lib/clang/16/include
  -nostdsysteminc -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection
  -analyzer-config crosscheck-with-z3=true -verify reproducer.c

 #0 0x00000000045b3476 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int)
  <root>/llvm/lib/Support/Unix/Signals.inc:567:22
 #1 0x00000000045b3862 PrintStackTraceSignalHandler(void*)
  <root>/llvm/lib/Support/Unix/Signals.inc:641:1
 #2 0x00000000045b14a5 llvm::sys::RunSignalHandlers()
  <root>/llvm/lib/Support/Signals.cpp:104:20
 #3 0x00000000045b2eb4 SignalHandler(int)
  <root>/llvm/lib/Support/Unix/Signals.inc:412:1
 ...
 #9 0x0000000004be2eb3 llvm::APSInt::getExtValue() const
  <root>/llvm/include/llvm/ADT/APSInt.h:99:5
  <root>/llvm/lib/Support/Z3Solver.cpp:740:53
  clang::ASTContext&, clang::ento::SymExpr const*, llvm::APSInt const&, llvm::APSInt const&, bool)
  <root>/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h:552:61
```

Reviewed By: steakhal

Differential Revision: https://reviews.llvm.org/D142627

(cherry picked from commit f027dd55f32a3c1803fc3cbd53029acee849465c)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants