diff options
| author | Nico Weber <nicolasweber@gmx.de> | 2015-02-18 05:19:40 +0000 |
|---|---|---|
| committer | Nico Weber <nicolasweber@gmx.de> | 2015-02-18 05:19:40 +0000 |
| commit | 4486d61c03c1fe9c84af63727bbed269d957e720 (patch) | |
| tree | d3eca2d5a191a47f654b3cca26365f62ca38f69e /clang | |
| parent | 90b1d152b5161ca87b6545da0a7134173cf7336f (diff) | |
| download | bcm5719-llvm-4486d61c03c1fe9c84af63727bbed269d957e720.tar.gz bcm5719-llvm-4486d61c03c1fe9c84af63727bbed269d957e720.zip | |
Port r163224 to C++.
The motivation is to fix a crash on
struct S {} s;
Foo S::~S() { s.~S(); }
What was happening here was that S::~S() was marked as invalid since its
return type is invalid, and as a consequence CheckFunctionDeclaration() wasn't
called and S::~S() didn't get merged into S's implicit destructor. This way,
the class ended up with two destructors, which confused the overload printer
when it suddenly had to print two possible destructors for `s.~S()`.
In addition to fixing the crash, this change also seems to improve diagnostics
in a few other places, see test changes.
Crash found by SLi's bot.
llvm-svn: 229639
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 5 | ||||
| -rw-r--r-- | clang/test/SemaCXX/PR9461.cpp | 4 | ||||
| -rw-r--r-- | clang/test/SemaCXX/crashes.cpp | 13 | ||||
| -rw-r--r-- | clang/test/SemaCXX/destructor.cpp | 6 |
4 files changed, 18 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index ae18d9cbdb4..d351b4841f8 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -7418,7 +7418,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous, isExplicitSpecialization)); else if (!Previous.empty()) - // Make graceful recovery from an invalid redeclaration. + // Recover gracefully from an invalid redeclaration. D.setRedeclaration(true); assert((NewFD->isInvalidDecl() || !D.isRedeclaration() || Previous.getResultKind() != LookupResult::FoundOverloaded) && @@ -7559,6 +7559,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (!NewFD->isInvalidDecl()) D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous, isExplicitSpecialization)); + else if (!Previous.empty()) + // Recover gracefully from an invalid redeclaration. + D.setRedeclaration(true); } assert((NewFD->isInvalidDecl() || !D.isRedeclaration() || diff --git a/clang/test/SemaCXX/PR9461.cpp b/clang/test/SemaCXX/PR9461.cpp index beed348abb7..f97a208192b 100644 --- a/clang/test/SemaCXX/PR9461.cpp +++ b/clang/test/SemaCXX/PR9461.cpp @@ -22,9 +22,9 @@ _S_construct(); // expected-error {{requires}} }; template<typename _CharT,typename _Traits,typename _Alloc> -basic_string<_CharT,_Traits,_Alloc>::basic_string(const _CharT*,const _Alloc&) +basic_string<_CharT,_Traits,_Alloc>::basic_string(const _CharT* c,const _Alloc&) :us(_S_construct) -{string a;} +{string a(c);} struct runtime_error{runtime_error(string);}; diff --git a/clang/test/SemaCXX/crashes.cpp b/clang/test/SemaCXX/crashes.cpp index 6ae476f7080..12251bba95a 100644 --- a/clang/test/SemaCXX/crashes.cpp +++ b/clang/test/SemaCXX/crashes.cpp @@ -175,16 +175,16 @@ namespace test3 { namespace pr16964 { template<typename> struct bs { bs(); - static int* member(); + static int* member(); // expected-note{{possible target}} member(); // expected-error{{C++ requires a type specifier for all declarations}} static member(); // expected-error{{C++ requires a type specifier for all declarations}} - static int* member(int); + static int* member(int); // expected-note{{possible target}} }; - template<typename T> bs<T>::bs() { member; } + template<typename T> bs<T>::bs() { member; } // expected-error{{did you mean to call it}} bs<int> test() { - return bs<int>(); + return bs<int>(); // expected-note{{in instantiation}} } } @@ -195,7 +195,7 @@ namespace pr12791 { struct forward_iterator_tag : public input_iterator_tag {}; template<typename _CharT, typename _Traits, typename _Alloc> struct basic_string { - struct _Alloc_hider : _Alloc {}; + struct _Alloc_hider : _Alloc { _Alloc_hider(_CharT*, const _Alloc&); }; mutable _Alloc_hider _M_dataplus; template<class _InputIterator> basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a = _Alloc()); template<class _InIterator> static _CharT* _S_construct(_InIterator __beg, _InIterator __end, const _Alloc& __a, input_iterator_tag); @@ -206,12 +206,11 @@ namespace pr12791 { template<typename _CharT, typename _Traits, typename _Alloc> template<typename _InputIterator> basic_string<_CharT, _Traits, _Alloc>:: basic_string(_InputIterator __beg, _InputIterator __end, const _Alloc& __a) - : _M_dataplus(_S_construct(__beg, __end, __a), __a) {} + : _M_dataplus(_S_construct(__beg, __end, __a, input_iterator_tag()), __a) {} template<typename _CharT, typename _Traits = char_traits<_CharT>, typename _Alloc = allocator<_CharT> > struct basic_stringbuf { typedef _CharT char_type; typedef basic_string<char_type, _Traits, _Alloc> __string_type; - typedef typename __string_type::size_type __size_type; __string_type str() const {__string_type((char_type*)0,(char_type*)0);} }; diff --git a/clang/test/SemaCXX/destructor.cpp b/clang/test/SemaCXX/destructor.cpp index 5305ff5f7ca..c66ec9f2c75 100644 --- a/clang/test/SemaCXX/destructor.cpp +++ b/clang/test/SemaCXX/destructor.cpp @@ -173,6 +173,12 @@ protected: ~S7(); }; +struct S8 {} s8; + +UnknownType S8::~S8() { // expected-error {{unknown type name 'UnknownType'}} + s8.~S8(); +} + template<class T> class TS : public B { virtual void m(); }; |

