Make sure that we diagnose attribute((overloadable)) functions without

prototypes. Fixes PR7738.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110443 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Douglas Gregor 2010-08-06 13:50:58 +00:00
Родитель 72283806e7
Коммит d945538a36
2 изменённых файлов: 25 добавлений и 20 удалений

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

@ -3548,6 +3548,20 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
NewFD->addAttr(::new (Context) OverloadableAttr());
}
if (NewFD->hasAttr<OverloadableAttr>() &&
!NewFD->getType()->getAs<FunctionProtoType>()) {
Diag(NewFD->getLocation(),
diag::err_attribute_overloadable_no_prototype)
<< NewFD;
// Turn this into a variadic function with no parameters.
const FunctionType *FT = NewFD->getType()->getAs<FunctionType>();
QualType R = Context.getFunctionType(FT->getResultType(),
0, 0, true, 0, false, false, 0, 0,
FT->getExtInfo());
NewFD->setType(R);
}
// If there's a #pragma GCC visibility in scope, and this isn't a class
// member, set the visibility of this function.
if (NewFD->getLinkage() == ExternalLinkage && !DC->isRecord())
@ -3639,27 +3653,9 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
Redeclaration = true;
OldDecl = Previous.getFoundDecl();
} else {
if (!getLangOptions().CPlusPlus) {
if (!getLangOptions().CPlusPlus)
OverloadableAttrRequired = true;
// Functions marked "overloadable" must have a prototype (that
// we can't get through declaration merging).
if (!NewFD->getType()->getAs<FunctionProtoType>()) {
Diag(NewFD->getLocation(),
diag::err_attribute_overloadable_no_prototype)
<< NewFD;
Redeclaration = true;
// Turn this into a variadic function with no parameters.
QualType R = Context.getFunctionType(
NewFD->getType()->getAs<FunctionType>()->getResultType(),
0, 0, true, 0, false, false, 0, 0,
FunctionType::ExtInfo());
NewFD->setType(R);
return NewFD->setInvalidDecl();
}
}
switch (CheckOverload(S, NewFD, Previous, OldDecl,
/*NewIsUsingDecl*/ false)) {
case Ovl_Match:

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

@ -41,7 +41,6 @@ double promote(float) __attribute__((__overloadable__)); // expected-note {{cand
double promote(double) __attribute__((__overloadable__)); // expected-note {{candidate}}
long double promote(long double) __attribute__((__overloadable__)); // expected-note {{candidate}}
void promote() __attribute__((__overloadable__)); // expected-error{{'overloadable' function 'promote' must have a prototype}}
void promote(...) __attribute__((__overloadable__, __unavailable__)); // \
// expected-note{{candidate function}}
@ -60,3 +59,13 @@ double magnitude(IntVec) __attribute__((__overloadable__));
double test_p6600(DoubleVec d) {
return magnitude(d) * magnitude(d);
}
// PR7738
extern int __attribute__((overloadable)) f0(); // expected-error{{'overloadable' function 'f0' must have a prototype}}
typedef int f1_type();
f1_type __attribute__((overloadable)) f1; // expected-error{{'overloadable' function 'f1' must have a prototype}}
void test() {
f0();
f1();
}