steakhal updated this revision to Diff 284126. steakhal marked 3 inline comments as done. steakhal edited the summary of this revision. steakhal added a comment.
- Using `dump`s instead of `reaching` in tests. - Not requiring complete enums anymore //(unlike we did before the patch)//. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D85528/new/ https://reviews.llvm.org/D85528 Files: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h clang/test/Analysis/z3-refute-enum-crash.cpp Index: clang/test/Analysis/z3-refute-enum-crash.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/z3-refute-enum-crash.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection \ +// RUN: -analyzer-config crosscheck-with-z3=true -verify %s +// REQUIRES: z3 +// +// Requires z3 only for refutation. Works with both constraint managers. + +void clang_analyzer_dump(int); + +using sugar_t = unsigned char; + +// Enum types +enum class ScopedSugared : sugar_t {}; +enum class ScopedPrimitive : unsigned char {}; +enum UnscopedSugared : sugar_t {}; +enum UnscopedPrimitive : unsigned char {}; + +template <typename T> +T conjure(); + +void test_enum_types() { + int sym1 = static_cast<unsigned char>(conjure<ScopedSugared>()) & 0x0F; + int sym2 = static_cast<unsigned char>(conjure<ScopedPrimitive>()) & 0x0F; + int sym3 = static_cast<unsigned char>(conjure<UnscopedSugared>()) & 0x0F; + int sym4 = static_cast<unsigned char>(conjure<UnscopedPrimitive>()) & 0x0F; + + if (sym1 && sym2 && sym3 && sym4) { + // no-crash on these dumps + clang_analyzer_dump(sym1); // expected-warning{{((unsigned char) (conj_}} + clang_analyzer_dump(sym2); // expected-warning{{((unsigned char) (conj_}} + clang_analyzer_dump(sym3); // expected-warning{{(conj_}} + clang_analyzer_dump(sym4); // expected-warning{{(conj_}} + } +} Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h =================================================================== --- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -95,11 +95,15 @@ } bool haveSameType(QualType Ty1, QualType Ty2) { + const bool BothHaveSameCanonicalTypes = + Context.getCanonicalType(Ty1) == Context.getCanonicalType(Ty2); + const bool BothHaveIntegralOrUnscopedEnumerationType = + Ty1->isIntegralOrUnscopedEnumerationType() && + Ty2->isIntegralOrUnscopedEnumerationType(); // FIXME: Remove the second disjunct when we support symbolic // truncation/extension. - return (Context.getCanonicalType(Ty1) == Context.getCanonicalType(Ty2) || - (Ty1->isIntegralOrEnumerationType() && - Ty2->isIntegralOrEnumerationType())); + return BothHaveSameCanonicalTypes || + BothHaveIntegralOrUnscopedEnumerationType; } SVal evalCast(SVal val, QualType castTy, QualType originalType);
Index: clang/test/Analysis/z3-refute-enum-crash.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/z3-refute-enum-crash.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection \ +// RUN: -analyzer-config crosscheck-with-z3=true -verify %s +// REQUIRES: z3 +// +// Requires z3 only for refutation. Works with both constraint managers. + +void clang_analyzer_dump(int); + +using sugar_t = unsigned char; + +// Enum types +enum class ScopedSugared : sugar_t {}; +enum class ScopedPrimitive : unsigned char {}; +enum UnscopedSugared : sugar_t {}; +enum UnscopedPrimitive : unsigned char {}; + +template <typename T> +T conjure(); + +void test_enum_types() { + int sym1 = static_cast<unsigned char>(conjure<ScopedSugared>()) & 0x0F; + int sym2 = static_cast<unsigned char>(conjure<ScopedPrimitive>()) & 0x0F; + int sym3 = static_cast<unsigned char>(conjure<UnscopedSugared>()) & 0x0F; + int sym4 = static_cast<unsigned char>(conjure<UnscopedPrimitive>()) & 0x0F; + + if (sym1 && sym2 && sym3 && sym4) { + // no-crash on these dumps + clang_analyzer_dump(sym1); // expected-warning{{((unsigned char) (conj_}} + clang_analyzer_dump(sym2); // expected-warning{{((unsigned char) (conj_}} + clang_analyzer_dump(sym3); // expected-warning{{(conj_}} + clang_analyzer_dump(sym4); // expected-warning{{(conj_}} + } +} Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h =================================================================== --- clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -95,11 +95,15 @@ } bool haveSameType(QualType Ty1, QualType Ty2) { + const bool BothHaveSameCanonicalTypes = + Context.getCanonicalType(Ty1) == Context.getCanonicalType(Ty2); + const bool BothHaveIntegralOrUnscopedEnumerationType = + Ty1->isIntegralOrUnscopedEnumerationType() && + Ty2->isIntegralOrUnscopedEnumerationType(); // FIXME: Remove the second disjunct when we support symbolic // truncation/extension. - return (Context.getCanonicalType(Ty1) == Context.getCanonicalType(Ty2) || - (Ty1->isIntegralOrEnumerationType() && - Ty2->isIntegralOrEnumerationType())); + return BothHaveSameCanonicalTypes || + BothHaveIntegralOrUnscopedEnumerationType; } SVal evalCast(SVal val, QualType castTy, QualType originalType);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits