forked from OSchip/llvm-project
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
This commit is contained in:
parent
90b1d152b5
commit
4486d61c03
|
@ -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() ||
|
||||
|
|
|
@ -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);};
|
||||
|
||||
|
|
|
@ -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);}
|
||||
};
|
||||
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue