From b30cd4a09bbf0adfa644b957a2b28fe31c5d45e4 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 15 Jun 2011 05:45:11 +0000 Subject: [PATCH] Don't add redundant FormatAttr, ConstAttr, or NoThrowAttr attributes, either imlicitly (for builtins) or explicitly (due to multiple specification of the same attributes). Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133045 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 7 +++++-- lib/Sema/SemaDeclAttr.cpp | 33 ++++++++++++++++++++++++++++++--- test/Sema/format-strings.c | 5 +++++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 49e59c76aa..c7545cf532 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6471,6 +6471,9 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, /// These attributes can apply both to implicitly-declared builtins /// (like __builtin___printf_chk) or to library-declared functions /// like NSLog or printf. +/// +/// We need to check for duplicate attributes both here and where user-written +/// attributes are applied to declarations. void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { if (FD->isInvalidDecl()) return; @@ -6504,9 +6507,9 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context)); } - if (Context.BuiltinInfo.isNoThrow(BuiltinID)) + if (Context.BuiltinInfo.isNoThrow(BuiltinID) && !FD->getAttr()) FD->addAttr(::new (Context) NoThrowAttr(FD->getLocation(), Context)); - if (Context.BuiltinInfo.isConst(BuiltinID)) + if (Context.BuiltinInfo.isConst(BuiltinID) && !FD->getAttr()) FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context)); } diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 7f93ab72d6..1ec7199562 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -1525,8 +1525,13 @@ static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; return; } - - d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context)); + + if (NoThrowAttr *Existing = d->getAttr()) { + if (Existing->getLocation().isInvalid()) + Existing->setLocation(Attr.getLoc()); + } else { + d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context)); + } } static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -1536,7 +1541,12 @@ static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context)); + if (ConstAttr *Existing = d->getAttr()) { + if (Existing->getLocation().isInvalid()) + Existing->setLocation(Attr.getLoc()); + } else { + d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context)); + } } static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -1904,6 +1914,23 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } + // Check whether we already have an equivalent format attribute. + for (specific_attr_iterator + i = d->specific_attr_begin(), + e = d->specific_attr_end(); + i != e ; ++i) { + FormatAttr *f = *i; + if (f->getType() == Format && + f->getFormatIdx() == (int)Idx.getZExtValue() && + f->getFirstArg() == (int)FirstArg.getZExtValue()) { + // If we don't have a valid location for this attribute, adopt the + // location. + if (f->getLocation().isInvalid()) + f->setLocation(Attr.getLoc()); + return; + } + } + d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format, Idx.getZExtValue(), FirstArg.getZExtValue())); diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c index c78095a04d..35210c341a 100644 --- a/test/Sema/format-strings.c +++ b/test/Sema/format-strings.c @@ -358,3 +358,8 @@ void pr9314() { printf(__func__); // no-warning } +int printf(const char * restrict, ...) __attribute__((__format__ (__printf__, 1, 2))); + +void rdar9612060(void) { + printf("%s", 2); // expected-warning{{conversion specifies type 'char *' but the argument has type 'int'}} +} -- 2.40.0