зеркало из https://github.com/microsoft/clang-1.git
When we substitute into the type of a function based on the
TypeSourceInfo, we may have lost some adjustments made to the type of that function due to declaration merging. Adjust the resulting type correspondingly. Fixes PR12948 / <rdar://problem/11552434>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163845 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
7b4362ec11
Коммит
71074fdf40
|
@ -1008,6 +1008,21 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
|
|||
return Record;
|
||||
}
|
||||
|
||||
/// \brief Adjust the given function type for an instantiation of the
|
||||
/// given declaration, to cope with modifications to the function's type that
|
||||
/// aren't reflected in the type-source information.
|
||||
///
|
||||
/// \param D The declaration we're instantiating.
|
||||
/// \param TInfo The already-instantiated type.
|
||||
static QualType adjustFunctionTypeForInstantiation(ASTContext &Context,
|
||||
FunctionDecl *D,
|
||||
TypeSourceInfo *TInfo) {
|
||||
const FunctionType *OrigFunc = D->getType()->castAs<FunctionType>();
|
||||
const FunctionType *NewFunc = TInfo->getType()->castAs<FunctionType>();
|
||||
return QualType(Context.adjustFunctionType(NewFunc, OrigFunc->getExtInfo()),
|
||||
0);
|
||||
}
|
||||
|
||||
/// Normal class members are of more specific types and therefore
|
||||
/// don't make it here. This function serves two purposes:
|
||||
/// 1) instantiating function templates
|
||||
|
@ -1048,7 +1063,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
|
|||
TypeSourceInfo *TInfo = SubstFunctionType(D, Params);
|
||||
if (!TInfo)
|
||||
return 0;
|
||||
QualType T = TInfo->getType();
|
||||
QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo);
|
||||
|
||||
NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc();
|
||||
if (QualifierLoc) {
|
||||
|
@ -1366,7 +1381,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
|
|||
TypeSourceInfo *TInfo = SubstFunctionType(D, Params);
|
||||
if (!TInfo)
|
||||
return 0;
|
||||
QualType T = TInfo->getType();
|
||||
QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo);
|
||||
|
||||
// \brief If the type of this function, after ignoring parentheses,
|
||||
// is not *directly* a function type, then we're instantiating a function
|
||||
|
|
|
@ -54,3 +54,29 @@ class xpto {
|
|||
int xpto::blah() {
|
||||
return 3; // expected-warning {{function 'blah' declared 'noreturn' should not return}}
|
||||
}
|
||||
|
||||
// PR12948
|
||||
|
||||
namespace PR12948 {
|
||||
template<int>
|
||||
void foo() __attribute__((__noreturn__));
|
||||
|
||||
template<int>
|
||||
void foo() {
|
||||
while (1) continue;
|
||||
}
|
||||
|
||||
void bar() __attribute__((__noreturn__));
|
||||
|
||||
void bar() {
|
||||
foo<0>();
|
||||
}
|
||||
|
||||
|
||||
void baz() __attribute__((__noreturn__));
|
||||
typedef void voidfn();
|
||||
voidfn baz;
|
||||
|
||||
template<typename> void wibble() __attribute__((__noreturn__));
|
||||
template<typename> voidfn wibble;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче