mattd created this revision. In the case of ill-formed templates, a value dependent name can reach the integral constant expression (ICE) check. After an error occurs following an ill-formed template, an ICE check can be performed on a template definition. That definition might contain an expression, such as "const a = sizeof(T);" where T is a template type argument. In this case, the latter expression is ValueDependent, T is type dependent, and the sizeof expression is therefore considered Value Dependent.
The assertions will trigger, if the implementation of a templated member function occurs in a separate namespace from its definition (bad code). If such a case occurs, an ODR marking of a variable decl is performed, which happens to check that a particular variable is constant. Additionally, ValueDependent items can be ICEs, but we never check that case, and the assertions assume we never see them in the first place. In general, I don't like removing assertions, for obvious reasons. But in this case, I am not sure they are necessary, and can be problematic as seen by the included test case. https://reviews.llvm.org/D40398 Files: lib/AST/Decl.cpp lib/AST/ExprConstant.cpp test/SemaTemplate/illformed-template-ice.cpp Index: test/SemaTemplate/illformed-template-ice.cpp =================================================================== --- test/SemaTemplate/illformed-template-ice.cpp +++ test/SemaTemplate/illformed-template-ice.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +class A { +public: + template <typename T> void B(); +}; + +namespace { + template <typename T> void A::B() { // expected-error {{cannot define or redeclare 'B' here because namespace '' does not enclose namespace 'A'}} + const int a = sizeof(T); + int b = a; + } +} Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -10250,7 +10250,6 @@ } static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { - assert(!E->isValueDependent() && "Should not see value dependent exprs!"); if (!E->getType()->isIntegralOrEnumerationType()) return ICEDiag(IK_NotICE, E->getLocStart()); Index: lib/AST/Decl.cpp =================================================================== --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -2216,7 +2216,6 @@ return Eval->Evaluated.isUninit() ? nullptr : &Eval->Evaluated; const auto *Init = cast<Expr>(Eval->Value); - assert(!Init->isValueDependent()); if (Eval->IsEvaluating) { // FIXME: Produce a diagnostic for self-initialization. @@ -2284,7 +2283,6 @@ return Eval->IsICE; const auto *Init = cast<Expr>(Eval->Value); - assert(!Init->isValueDependent()); // In C++11, evaluate the initializer to check whether it's a constant // expression.
Index: test/SemaTemplate/illformed-template-ice.cpp =================================================================== --- test/SemaTemplate/illformed-template-ice.cpp +++ test/SemaTemplate/illformed-template-ice.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +class A { +public: + template <typename T> void B(); +}; + +namespace { + template <typename T> void A::B() { // expected-error {{cannot define or redeclare 'B' here because namespace '' does not enclose namespace 'A'}} + const int a = sizeof(T); + int b = a; + } +} Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -10250,7 +10250,6 @@ } static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { - assert(!E->isValueDependent() && "Should not see value dependent exprs!"); if (!E->getType()->isIntegralOrEnumerationType()) return ICEDiag(IK_NotICE, E->getLocStart()); Index: lib/AST/Decl.cpp =================================================================== --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -2216,7 +2216,6 @@ return Eval->Evaluated.isUninit() ? nullptr : &Eval->Evaluated; const auto *Init = cast<Expr>(Eval->Value); - assert(!Init->isValueDependent()); if (Eval->IsEvaluating) { // FIXME: Produce a diagnostic for self-initialization. @@ -2284,7 +2283,6 @@ return Eval->IsICE; const auto *Init = cast<Expr>(Eval->Value); - assert(!Init->isValueDependent()); // In C++11, evaluate the initializer to check whether it's a constant // expression.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits