]> granicus.if.org Git - clang/commitdiff
Suppress bogus "use of undefined constexpr function" error if the function body
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 14 May 2013 05:18:44 +0000 (05:18 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 14 May 2013 05:18:44 +0000 (05:18 +0000)
was erroneous and got discarded.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181758 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ExprConstant.cpp
test/SemaCXX/constant-expression-cxx11.cpp
test/SemaCXX/enum-unscoped-nonexistent.cpp

index 0f449854716752681c3b2fc65a603a7871178204..2a3efb225bd647c0ed28352da372510c098cb4f0 100644 (file)
@@ -3161,6 +3161,11 @@ static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc,
       Declaration->isConstexpr())
     return false;
 
+  // Bail out with no diagnostic if the function declaration itself is invalid.
+  // We will have produced a relevant diagnostic while parsing it.
+  if (Declaration->isInvalidDecl())
+    return false;
+
   // Can we evaluate this function call?
   if (Definition && Definition->isConstexpr() && !Definition->isInvalidDecl())
     return true;
index 09a9cb5dd8dbe6333076009f444abfc02f6fbd57..97b0b91b99f338310c8613a578dd85a4bea5f9b0 100644 (file)
@@ -1503,3 +1503,11 @@ namespace PR15884 {
   // expected-note@-3 {{pointer to temporary is not a constant expression}}
   // expected-note@-4 {{temporary created here}}
 }
+
+namespace AfterError {
+  // FIXME: Suppress the 'no return statements' diagnostic if the body is invalid.
+  constexpr int error() { // expected-error {{no return statement}}
+    return foobar; // expected-error {{undeclared identifier}}
+  }
+  constexpr int k = error(); // expected-error {{must be initialized by a constant expression}}
+}
index e9da38f558d3bf327fedaf014454bc187e5135fc..7da9a96d6054361012c0af963ae942d33039db1f 100644 (file)
@@ -6,7 +6,7 @@ struct Base {
 template<typename T> struct S : Base {
   enum E : int;
   constexpr int f() const;
-  constexpr int g() const; // expected-note {{declared here}}
+  constexpr int g() const;
   void h();
 };
 template<> enum S<char>::E : int {}; // expected-note {{enum 'S<char>::E' was explicitly specialized here}}
@@ -23,7 +23,7 @@ static_assert(S<int>().f() == 1, "");
 // The unqualified-id here names a member of the current instantiation, which
 // bizarrely might not exist in some instantiations.
 template<typename T> constexpr int S<T>::g() const { return b; } // expected-error {{enumerator 'b' does not exist in instantiation of 'S<char>'}}
-static_assert(S<char>().g() == 1, ""); // expected-note {{here}} expected-error {{not an integral constant expression}} expected-note {{undefined}}
+static_assert(S<char>().g() == 1, ""); // expected-note {{here}} expected-error {{not an integral constant expression}}
 static_assert(S<short>().g() == 2, "");
 static_assert(S<long>().g() == 8, "");