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:
Douglas Gregor 2012-09-13 21:56:43 +00:00
Родитель 7b4362ec11
Коммит 71074fdf40
2 изменённых файлов: 43 добавлений и 2 удалений

Просмотреть файл

@ -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;
}