diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-05-14 05:18:44 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-05-14 05:18:44 +0000 |
commit | f039e3eb0ffa87aae0e38cec48f367ee179b4de6 (patch) | |
tree | a8dd1ae8bc567222723711e7faea00bdc3b75ca4 | |
parent | 69db555a7a4d0aa11d65001ffc25669c354a5de0 (diff) | |
download | clang-f039e3eb0ffa87aae0e38cec48f367ee179b4de6.tar.gz clang-f039e3eb0ffa87aae0e38cec48f367ee179b4de6.tar.bz2 clang-f039e3eb0ffa87aae0e38cec48f367ee179b4de6.tar.xz |
Suppress bogus "use of undefined constexpr function" error if the function body
was erroneous and got discarded.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181758 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/AST/ExprConstant.cpp | 5 | ||||
-rw-r--r-- | test/SemaCXX/constant-expression-cxx11.cpp | 8 | ||||
-rw-r--r-- | test/SemaCXX/enum-unscoped-nonexistent.cpp | 4 |
3 files changed, 15 insertions, 2 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 0f44985471..2a3efb225b 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -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; diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp index 09a9cb5dd8..97b0b91b99 100644 --- a/test/SemaCXX/constant-expression-cxx11.cpp +++ b/test/SemaCXX/constant-expression-cxx11.cpp @@ -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}} +} diff --git a/test/SemaCXX/enum-unscoped-nonexistent.cpp b/test/SemaCXX/enum-unscoped-nonexistent.cpp index e9da38f558..7da9a96d60 100644 --- a/test/SemaCXX/enum-unscoped-nonexistent.cpp +++ b/test/SemaCXX/enum-unscoped-nonexistent.cpp @@ -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, ""); |