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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits