summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-02-13 00:26:38 +0000
committerDouglas Gregor <dgregor@apple.com>2009-02-13 00:26:38 +0000
commit633b73783f90879d79c05d982a5bf588dc75ee89 (patch)
tree63acc07455faf75d7c19309b21f1e50edbdd9b02 /clang/lib/Sema/SemaDecl.cpp
parent5fec5b0495a5dee334b6d1eb19a0af8a90f2ac3b (diff)
downloadbcm5719-llvm-633b73783f90879d79c05d982a5bf588dc75ee89.tar.gz
bcm5719-llvm-633b73783f90879d79c05d982a5bf588dc75ee89.zip
Tighten checking of the "overloadable" attribute. If any function by a
given name in a given scope is marked as "overloadable", every function declaration and definition with that same name and in that same scope needs to have the "overloadable" attribute. Essentially, the "overloadable" attribute is not part of attribute merging, so it must be specified even for redeclarations. This keeps users from trying to be too sneaky for their own good: double sin(double) __attribute__((overloadable)); // too sneaky #include <math.h> Previously, this would have made "sin" overloadable, and therefore given it a mangled name. Now, we get an error inside math.h when we see a (re)declaration of "sin" that doesn't have the "overloadable" attribute. llvm-svn: 64414
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp27
1 files changed, 13 insertions, 14 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index de06ca610cf..0dbd6d3804e 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -446,15 +446,15 @@ static void MergeAttributes(Decl *New, Decl *Old) {
Attr *attr = const_cast<Attr*>(Old->getAttrs()), *tmp;
while (attr) {
- tmp = attr;
- attr = attr->getNext();
+ tmp = attr;
+ attr = attr->getNext();
- if (!DeclHasAttr(New, tmp)) {
- tmp->setInherited(true);
- New->addAttr(tmp);
+ if (!DeclHasAttr(New, tmp) && tmp->isMerged()) {
+ tmp->setInherited(true);
+ New->addAttr(tmp);
} else {
- tmp->setNext(0);
- delete(tmp);
+ tmp->setNext(0);
+ delete(tmp);
}
}
@@ -1666,6 +1666,11 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// there's no more work to do here; we'll just add the new
// function to the scope.
OverloadedFunctionDecl::function_iterator MatchedDecl;
+
+ if (!getLangOptions().CPlusPlus &&
+ AllowOverloadingOfFunction(PrevDecl, Context))
+ OverloadableAttrRequired = true;
+
if (!AllowOverloadingOfFunction(PrevDecl, Context) ||
!IsOverload(NewFD, PrevDecl, MatchedDecl)) {
Decl *OldDecl = PrevDecl;
@@ -1693,12 +1698,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
}
}
}
-
- // If we're in C, this new declaration better have the
- // "overloadable" attribute on it.
- if (!getLangOptions().CPlusPlus &&
- PrevDecl->getAttr<OverloadableAttr>())
- OverloadableAttrRequired = true;
}
if (D.getCXXScopeSpec().isSet() &&
@@ -1743,7 +1742,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// If a function name is overloadable in C, then every function
// with that name must be marked "overloadable".
Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
- << NewFD;
+ << Redeclaration << NewFD;
if (PrevDecl)
Diag(PrevDecl->getLocation(),
diag::note_attribute_overloadable_prev_overload);
OpenPOWER on IntegriCloud