eandrews created this revision. eandrews added reviewers: rnk, gribozavr, gribozavr2, Szelethus, erichkeane, riccibruno.
This patch reapplies D61027 <https://reviews.llvm.org/D61027>. When D61027 <https://reviews.llvm.org/D61027> was previously committed (76945821b9cad3), buildbots failed due to clang-tidy test fails. The test fails are because some errors in templates are now diagnosed earlier (does not wait till instantiation). I have modified the tests to add checks for these diagnostics/prevent these diagnostics. Since I have not worked on clang-tidy in the past, I am hoping someone with more familiarity in this area can take a look and review my changes. There are no code changes in this second attempt (compared to D61027 <https://reviews.llvm.org/D61027>). I have only modified failing tests. Summary of code changes (pasted from D61027 <https://reviews.llvm.org/D61027>) is below - Clang currently crashes for switch statements inside a template when the condition is a non-integer field member because contextual implicit conversion is skipped when parsing the condition. This conversion is however later checked in an assert when the case statement is handled. The conversion is skipped when parsing the condition because the field member is set as type-dependent based on its containing class. This patch sets the type dependency based on the field's type instead. This patch fixes Bug 40982. https://reviews.llvm.org/D69950 Files: clang-tools-extra/test/clang-tidy/checkers/bugprone-string-integer-assignment.cpp clang-tools-extra/test/clang-tidy/checkers/misc-unused-parameters.cpp clang/lib/AST/Expr.cpp clang/lib/Sema/SemaChecking.cpp clang/test/SemaCXX/constant-expression-cxx2a.cpp clang/test/SemaTemplate/dependent-names.cpp clang/test/SemaTemplate/enum-argument.cpp clang/test/SemaTemplate/member-access-expr.cpp clang/test/SemaTemplate/non-integral-switch-cond.cpp
Index: clang/test/SemaTemplate/non-integral-switch-cond.cpp =================================================================== --- /dev/null +++ clang/test/SemaTemplate/non-integral-switch-cond.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct NOT_AN_INTEGRAL_TYPE {}; + +template <typename T> +struct foo { + NOT_AN_INTEGRAL_TYPE Bad; + void run() { + switch (Bad) { // expected-error {{statement requires expression of integer type ('NOT_AN_INTEGRAL_TYPE' invalid)}} + case 0: + break; + } + } +}; Index: clang/test/SemaTemplate/member-access-expr.cpp =================================================================== --- clang/test/SemaTemplate/member-access-expr.cpp +++ clang/test/SemaTemplate/member-access-expr.cpp @@ -156,7 +156,7 @@ void get(B **ptr) { // It's okay if at some point we figure out how to diagnose this // at instantiation time. - *ptr = field; + *ptr = field; // expected-error {{assigning to 'test6::B *' from incompatible type 'test6::A *}} } }; } Index: clang/test/SemaTemplate/enum-argument.cpp =================================================================== --- clang/test/SemaTemplate/enum-argument.cpp +++ clang/test/SemaTemplate/enum-argument.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -// expected-no-diagnostics enum Enum { val = 1 }; template <Enum v> struct C { @@ -31,7 +30,7 @@ unsigned long long bitfield : e0; void f(int j) { - bitfield + j; + bitfield + j; // expected-warning {{expression result unused}} } }; } Index: clang/test/SemaTemplate/dependent-names.cpp =================================================================== --- clang/test/SemaTemplate/dependent-names.cpp +++ clang/test/SemaTemplate/dependent-names.cpp @@ -273,9 +273,6 @@ } int e[10]; }; - void g() { - S<int>().f(); // expected-note {{here}} - } } namespace A2 { Index: clang/test/SemaCXX/constant-expression-cxx2a.cpp =================================================================== --- clang/test/SemaCXX/constant-expression-cxx2a.cpp +++ clang/test/SemaCXX/constant-expression-cxx2a.cpp @@ -18,6 +18,7 @@ [[nodiscard]] void *operator new(std::size_t, std::align_val_t, const std::nothrow_t&) noexcept; [[nodiscard]] void *operator new[](std::size_t, const std::nothrow_t&) noexcept; [[nodiscard]] void *operator new[](std::size_t, std::align_val_t, const std::nothrow_t&) noexcept; +[[nodiscard]] void *operator new[](std::size_t, std::align_val_t); void operator delete(void*, const std::nothrow_t&) noexcept; void operator delete(void*, std::align_val_t, const std::nothrow_t&) noexcept; void operator delete[](void*, const std::nothrow_t&) noexcept; @@ -1050,7 +1051,7 @@ // Ensure that we don't try to evaluate these for overflow and crash. These // are all value-dependent expressions. p = new char[n]; - p = new (n) char[n]; + p = new ((std::align_val_t)n) char[n]; p = new char(n); } } Index: clang/lib/Sema/SemaChecking.cpp =================================================================== --- clang/lib/Sema/SemaChecking.cpp +++ clang/lib/Sema/SemaChecking.cpp @@ -14682,6 +14682,8 @@ bool AnyIsPacked = false; do { QualType BaseType = ME->getBase()->getType(); + if (BaseType->isDependentType()) + return; if (ME->isArrow()) BaseType = BaseType->getPointeeType(); RecordDecl *RD = BaseType->castAs<RecordType>()->getDecl(); Index: clang/lib/AST/Expr.cpp =================================================================== --- clang/lib/AST/Expr.cpp +++ clang/lib/AST/Expr.cpp @@ -1675,6 +1675,15 @@ MemberExpr *E = new (Mem) MemberExpr(Base, IsArrow, OperatorLoc, MemberDecl, NameInfo, T, VK, OK, NOUR); + if (FieldDecl *Field = dyn_cast<FieldDecl>(MemberDecl)) { + DeclContext *DC = MemberDecl->getDeclContext(); + // dyn_cast_or_null is used to handle objC variables which do not + // have a declaration context. + CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(DC); + if (RD && RD->isDependentContext() && RD->isCurrentInstantiation(DC)) + E->setTypeDependent(T->isDependentType()); + } + if (HasQualOrFound) { // FIXME: Wrong. We should be looking at the member declaration we found. if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isDependent()) { Index: clang-tools-extra/test/clang-tidy/checkers/misc-unused-parameters.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/misc-unused-parameters.cpp +++ clang-tools-extra/test/clang-tidy/checkers/misc-unused-parameters.cpp @@ -233,7 +233,7 @@ template <class> class d { a e; - void f() { e.b(); } + void f() { e.b(0); } }; } // namespace } // namespace PR38055 Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-string-integer-assignment.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/bugprone-string-integer-assignment.cpp +++ clang-tools-extra/test/clang-tidy/checkers/bugprone-string-integer-assignment.cpp @@ -103,6 +103,8 @@ static constexpr T t = 0x8000; std::string s; void f(char c) { s += c | static_cast<int>(t); } + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: an integer is interpreted as a chara + // CHECK-FIXES: {{^}} void f(char c) { s += std::to_string(c | static_cast<int>(t)); } }; template S<int>;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits