From: Nico Weber Date: Sat, 17 Jan 2015 02:33:17 +0000 (+0000) Subject: If a function decl cannot be merged, mark it as invalid. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c04fe08bbe6d736c709b8336efcdc9a5fea7ba96;p=clang If a function decl cannot be merged, mark it as invalid. Clang currently crashes on class C { C() = default; C() = delete; }; My cunning plan for fixing this was to change the `if (!FnD)` in Parser::ParseCXXInlineMethodDef() to `if (!FnD || FnD->isInvalidDecl)` – but alas, the second constructor decl wasn't marked as invalid. This lets Sema::MergeFunctionDecl() return true on function redeclarations, which leads to them being marked invalid. This also improves error messages when functions are redeclared. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@226365 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 9b9a6afbfd..9aa1d9ca83 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2761,6 +2761,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, << New << New->getType(); } Diag(OldLocation, PrevDiag) << Old << Old->getType(); + return true; // Complain if this is an explicit declaration of a special // member that was initially declared implicitly. diff --git a/test/Parser/DelayedTemplateParsing.cpp b/test/Parser/DelayedTemplateParsing.cpp index eff31208c8..6ea245c2d4 100644 --- a/test/Parser/DelayedTemplateParsing.cpp +++ b/test/Parser/DelayedTemplateParsing.cpp @@ -10,8 +10,8 @@ class A { template class B { - void foo4() { } // expected-note {{previous definition is here}} expected-note {{previous definition is here}} - void foo4() { } // expected-error {{class member cannot be redeclared}} expected-error {{redefinition of 'foo4'}} + void foo4() { } // expected-note {{previous definition is here}} + void foo4() { } // expected-error {{class member cannot be redeclared}} void foo5() { } // expected-note {{previous definition is here}} friend void foo3() { diff --git a/test/Parser/cxx0x-ambig.cpp b/test/Parser/cxx0x-ambig.cpp index b06f432c43..a47585f8b6 100644 --- a/test/Parser/cxx0x-ambig.cpp +++ b/test/Parser/cxx0x-ambig.cpp @@ -110,8 +110,8 @@ namespace ellipsis { template struct S { void e(S::S()); - void f(S(...args[sizeof(T)])); // expected-note {{here}} - void f(S(...args)[sizeof(T)]); // expected-error {{redeclared}} expected-note {{here}} + void f(S(...args[sizeof(T)])); // expected-note {{here}} expected-note {{here}} + void f(S(...args)[sizeof(T)]); // expected-error {{redeclared}} void f(S ...args[sizeof(T)]); // expected-error {{redeclared}} void g(S(...[sizeof(T)])); // expected-note {{here}} expected-warning {{ISO C++11 requires a parenthesized pack declaration to have a name}} void g(S(...)[sizeof(T)]); // expected-error {{function cannot return array type}} diff --git a/test/SemaCXX/class.cpp b/test/SemaCXX/class.cpp index 636f584cf6..a6694403a6 100644 --- a/test/SemaCXX/class.cpp +++ b/test/SemaCXX/class.cpp @@ -119,9 +119,9 @@ struct C4 { // PR5415 - don't hang! struct S { - void f(); // expected-note 1 {{previous declaration}} - void S::f() {} // expected-error {{extra qualification on member}} expected-error {{class member cannot be redeclared}} expected-note {{previous declaration}} expected-note {{previous definition}} - void f() {} // expected-error {{class member cannot be redeclared}} expected-error {{redefinition}} + void f(); // expected-note 1 {{previous declaration}} expected-note {{previous declaration}} + void S::f() {} // expected-error {{extra qualification on member}} expected-error {{class member cannot be redeclared}} + void f() {} // expected-error {{class member cannot be redeclared}} }; // Don't crash on this bogus code. diff --git a/test/SemaCXX/cxx1y-constexpr-not-const.cpp b/test/SemaCXX/cxx1y-constexpr-not-const.cpp index 071b39c7fb..2352bb7d9b 100644 --- a/test/SemaCXX/cxx1y-constexpr-not-const.cpp +++ b/test/SemaCXX/cxx1y-constexpr-not-const.cpp @@ -11,8 +11,6 @@ struct X { // expected-error@6 {{class member cannot be redeclared}} // expected-note@5 {{previous}} -// expected-error@6 {{non-constexpr declaration of 'f' follows constexpr declaration}} -// expected-note@5 {{previous}} #else // expected-warning@5 {{'constexpr' non-static member function will not be implicitly 'const' in C++14; add 'const' to avoid a change in behavior}} #endif diff --git a/test/SemaCXX/cxx1y-deduced-return-type.cpp b/test/SemaCXX/cxx1y-deduced-return-type.cpp index 50e0cf79c5..225d2348cc 100644 --- a/test/SemaCXX/cxx1y-deduced-return-type.cpp +++ b/test/SemaCXX/cxx1y-deduced-return-type.cpp @@ -21,8 +21,8 @@ int conv1c = conv1.operator auto(); int conv1d = conv1.operator int(); // expected-error {{no member named 'operator int'}} struct Conv2 { - operator auto() { return 0; } // expected-note 2{{previous}} - operator auto() { return 0.; } // expected-error {{cannot be redeclared}} expected-error {{redefinition of 'operator auto'}} + operator auto() { return 0; } // expected-note {{previous}} + operator auto() { return 0.; } // expected-error {{cannot be redeclared}} expected-error {{cannot initialize return object of type 'auto' with an rvalue of type 'double'}} }; struct Conv3 { diff --git a/test/SemaCXX/overload-decl.cpp b/test/SemaCXX/overload-decl.cpp index fdb14cb173..1201396996 100644 --- a/test/SemaCXX/overload-decl.cpp +++ b/test/SemaCXX/overload-decl.cpp @@ -30,10 +30,8 @@ class X { static void g(int); // expected-error {{static and non-static member functions with the same parameter types cannot be overloaded}} static void g(float); // expected-error {{class member cannot be redeclared}} - void h(); // expected-note {{previous declaration is here}} \ - expected-note {{previous declaration is here}} - void h() __restrict; // expected-error {{class member cannot be redeclared}} \ - expected-error {{conflicting types for 'h'}} + void h(); // expected-note {{previous declaration is here}} + void h() __restrict; // expected-error {{class member cannot be redeclared}} }; int main() {} // expected-note {{previous definition is here}}