Implement a rigorous type checking when we call getX and setX.

These interfaces assume we know the type and we should compare if the underlying
type is the one we expect when using the setters and getters. Unfortunately,
this is not the case and we need to further investigate.
This commit is contained in:
Vassil Vassilev 2022-09-16 11:11:49 +00:00 committed by jenkins
parent 5add0d7732
commit 632aba9c56
2 changed files with 31 additions and 9 deletions

View File

@ -158,6 +158,7 @@ namespace cling {
/// \brief Get a reference to the value with type checking.
template <typename T> T getAs() const;
void AssertTypeMismatch(const char* Type) const;
public:
/// \brief Default constructor, creates a value that IsInvalid().
Value():
@ -223,23 +224,35 @@ namespace cling {
/// \brief Determine whether the Value is set and not void.
//
/// Determine whether the Value is set and not void.
/// Only in this case can getAs() or simplisticCastAs() be called.
/// Only in this case can we can get the represented value.
bool hasValue() const { return isValid() && !isVoid(); }
/// \brief Get a reference to the value without type checking.
/// T *must* correspond to type. Else use simplisticCastAs()!
template <typename T> T getAs() const;
// FIXME: If the cling::Value is destroyed and it handed out an address that
// might be accessing invalid memory.
void** getPtrAddress() { return &m_Storage.m_Ptr; }
void* getPtr() const { return m_Storage.m_Ptr; }
void setPtr(void* Val) { m_Storage.m_Ptr = Val; }
// FIXME: Add AssertInvalid("##name")
#ifndef NDEBUG
#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)
// FIXME: Uncomment and debug the various type mismatches.
//#define ASSERT_TYPE_MISMATCH(name) AssertTypeMismatch(STRINGIFY(name))
#define ASSERT_TYPE_MISMATCH(name)
#undef STRINGIFY
#undef _STRINGIFY
#else
#define ASSERT_TYPE_MISMATCH(name)
#endif // NDEBUG
#define X(type, name) \
type get##name() const {return m_Storage.m_##name;} \
void set##name(type Val) {m_Storage.m_##name = Val;} \
type get##name() const { \
ASSERT_TYPE_MISMATCH(name); \
return m_Storage.m_##name; \
} \
void set##name(type Val) { \
ASSERT_TYPE_MISMATCH(name); \
m_Storage.m_##name = Val; \
} \
BUILTIN_TYPES

View File

@ -251,6 +251,15 @@ namespace cling {
return QT.getCanonicalType();
}
void Value::AssertTypeMismatch(const char* Type) const {
#ifndef NDEBUG
assert(hasBuiltinType() && "Must be a builtin!");
const clang::BuiltinType *BT = getType()->castAs<clang::BuiltinType>();
clang::PrintingPolicy Policy = getASTContext().getPrintingPolicy();
#endif // NDEBUG
assert(BT->getName(Policy).equals(Type));
}
template <typename T> T convert(clang::QualType QT, Value::Storage& S) {
QT = getBuiltinCanonicalType(QT);
assert(QT->isBuiltinType());
@ -310,7 +319,7 @@ namespace cling {
}
void Value::AssertOnUnsupportedTypeCast() const {
assert("unsupported type in Value, cannot cast simplistically!" && 0);
assert("unsupported type in Value, cannot cast!" && 0);
}
namespace valuePrinterInternal {