Merge the "regparm" attribute from a previous declaration of a

function to redeclarations of that function. Fixes PR7025.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106317 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2010-06-18 21:30:25 +00:00
Родитель 4ab92891a5
Коммит d2c6490385
5 изменённых файлов: 48 добавлений и 7 удалений

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

@ -914,6 +914,10 @@ def err_cconv_knr : Error<
"function with no prototype cannot use %0 calling convention">;
def err_cconv_varargs : Error<
"variadic function cannot use %0 calling convention">;
def err_regparm_mismatch : Error<"function declared with with regparm(%0) "
"attribute was previously declared %plural{0:without the regparm|1:"
"with the regparm(1)|2:with the regparm(2)|3:with the regparm(3)|:with the"
"regparm}1 attribute">;
def warn_impcast_vector_scalar : Warning<
"implicit cast turns vector to scalar: %0 to %1">,

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

@ -1057,13 +1057,27 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
}
// FIXME: diagnose the other way around?
if (OldType->getNoReturnAttr() &&
!NewType->getNoReturnAttr()) {
if (OldType->getNoReturnAttr() && !NewType->getNoReturnAttr()) {
NewQType = Context.getNoReturnType(NewQType);
New->setType(NewQType);
assert(NewQType.isCanonical());
}
// Merge regparm attribute.
if (OldType->getRegParmType() != NewType->getRegParmType()) {
if (NewType->getRegParmType()) {
Diag(New->getLocation(), diag::err_regparm_mismatch)
<< NewType->getRegParmType()
<< OldType->getRegParmType();
Diag(Old->getLocation(), diag::note_previous_declaration);
return true;
}
NewQType = Context.getRegParmType(NewQType, OldType->getRegParmType());
New->setType(NewQType);
assert(NewQType.isCanonical());
}
if (getLangOptions().CPlusPlus) {
// (C++98 13.1p2):
// Certain function declarations cannot be overloaded:

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

@ -14,6 +14,11 @@ FType bar;
static void FASTCALL
reduced(char b, double c, foo* d, double e, int f);
// PR7025
void FASTCALL f1(int i, int j, int k);
// CHECK: define void @f1(i32 inreg %i, i32 inreg %j, i32 %k)
void f1(int i, int j, int k) { }
int
main(void) {
// CHECK: call void @reduced(i8 signext inreg 0, {{.*}} %struct.anon* inreg null

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

@ -1,7 +1,11 @@
// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
__attribute((regparm(2))) int x(void);
__attribute((regparm(1.0))) int x(void); // expected-error{{'regparm' attribute requires integer constant}}
__attribute((regparm(-1))) int x(void); // expected-error{{'regparm' parameter must be between 0 and 3 inclusive}}
__attribute((regparm(5))) int x(void); // expected-error{{'regparm' parameter must be between 0 and 3 inclusive}}
__attribute((regparm(5,3))) int x(void); // expected-error{{attribute requires 1 argument(s)}}
__attribute((regparm(2))) int x0(void);
__attribute((regparm(1.0))) int x1(void); // expected-error{{'regparm' attribute requires integer constant}}
__attribute((regparm(-1))) int x2(void); // expected-error{{'regparm' parameter must be between 0 and 3 inclusive}}
__attribute((regparm(5))) int x3(void); // expected-error{{'regparm' parameter must be between 0 and 3 inclusive}}
__attribute((regparm(5,3))) int x4(void); // expected-error{{attribute requires 1 argument(s)}}
void __attribute__((regparm(3))) x5(int);
void x5(int); // expected-note{{previous declaration is here}}
void __attribute__((regparm(2))) x5(int); // expected-error{{function declared with with regparm(2) attribute was previously declared with the regparm(3) attribute}}

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

@ -0,0 +1,14 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// PR7025
struct X0 {
void __attribute__((regparm(3))) f0();
void __attribute__((regparm(3))) f1();
void __attribute__((regparm(3))) f2(); // expected-note{{previous declaration is here}}
void f3(); // expected-note{{previous declaration is here}}
};
void X0::f0() { }
void __attribute__((regparm(3))) X0::f1() { }
void __attribute__((regparm(2))) X0::f2() { } // expected-error{{function declared with with regparm(2) attribute was previously declared with the regparm(3) attribute}}
void __attribute__((regparm(2))) X0::f3() { } // expected-error{{function declared with with regparm(2) attribute was previously declared without the regparm attribute}}