Fix assertion "Chunk.Kind == DeclaratorChunk::Function" with attributed type.

This patch is to upgrade FunctionTypeUnwrapper for correct processing of
AttributedType. Fixes PR25786.
Patch by Alexander Makarov.

Differential Revision: http://reviews.llvm.org/D15373

llvm-svn: 260373
This commit is contained in:
Denis Zobnin 2016-02-10 11:23:48 +00:00
parent ea0636b554
commit f49c0f83aa
3 changed files with 30 additions and 0 deletions

View File

@ -5370,6 +5370,7 @@ namespace {
struct FunctionTypeUnwrapper {
enum WrapKind {
Desugar,
Attributed,
Parens,
Pointer,
BlockPointer,
@ -5402,6 +5403,9 @@ namespace {
} else if (isa<ReferenceType>(Ty)) {
T = cast<ReferenceType>(Ty)->getPointeeType();
Stack.push_back(Reference);
} else if (isa<AttributedType>(Ty)) {
T = cast<AttributedType>(Ty)->getEquivalentType();
Stack.push_back(Attributed);
} else {
const Type *DTy = Ty->getUnqualifiedDesugaredType();
if (Ty == DTy) {
@ -5450,6 +5454,9 @@ namespace {
// information.
return wrap(C, Old->getUnqualifiedDesugaredType(), I);
case Attributed:
return wrap(C, cast<AttributedType>(Old)->getEquivalentType(), I);
case Parens: {
QualType New = wrap(C, cast<ParenType>(Old)->getInnerType(), I);
return C.getParenType(New);

View File

@ -0,0 +1,11 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple i686-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-OK
void (__attribute__((regparm(3), stdcall)) *pf) ();
void (__attribute__((regparm(2), stdcall)) foo)(int a) {
}
// CHECK: @pf = common global void (...)* null
// CHECK: define void @foo(i32 %a)
// CHECK-OK: @pf = common global void (...)* null
// CHECK-OK: define x86_stdcallcc void @foo(i32 inreg %a)

12
clang/test/Sema/pr25786.c Normal file
View File

@ -0,0 +1,12 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -DTEST -fsyntax-only -verify %s
// RUN: %clang_cc1 -triple i686-unknown-linux-gnu -fsyntax-only -verify %s
#if TEST
void (__attribute__((regparm(3), stdcall)) *pf) (); //expected-warning {{calling convention 'stdcall' ignored for this target}}
void (__attribute__((regparm(2), stdcall)) foo)(int a) { //expected-warning {{calling convention 'stdcall' ignored for this target}}
}
#else
//expected-no-diagnostics
void (__attribute__((regparm(3), stdcall)) *pf) ();
void (__attribute__((regparm(2), stdcall)) foo)(int a) {}
#endif