From: Aaron Ballman Date: Fri, 13 Sep 2013 19:35:18 +0000 (+0000) Subject: Switching the WeakRef attribute to using the new checkStringLiteralArgument helper... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=422ac9ee19c177fe65e613ff49998bd5a6e55408;p=clang Switching the WeakRef attribute to using the new checkStringLiteralArgument helper function. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190719 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index ceb4a3649b..9d2b269d30 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -282,6 +282,43 @@ static bool checkFunctionOrMethodArgumentIndex(Sema &S, const Decl *D, return true; } +/// \brief Check if the argument \p ArgNum of \p Attr is a ASCII string literal. +/// If not emit an error and return false. If the argument is an identifier it +/// will emit an error with a fixit hint and treat it as if it was a string +/// literal. +static bool checkStringLiteralArgument(Sema &S, StringRef &Str, + const AttributeList &Attr, + unsigned ArgNum, + SourceLocation *ArgLocation = 0) { + // Look for identifiers. If we have one emit a hint to fix it to a literal. + if (Attr.isArgIdent(ArgNum)) { + IdentifierLoc *Loc = Attr.getArgAsIdent(ArgNum); + S.Diag(Loc->Loc, diag::err_attribute_argument_type) + << Attr.getName() << AANT_ArgumentString + << FixItHint::CreateInsertion(Loc->Loc, "\"") + << FixItHint::CreateInsertion(S.PP.getLocForEndOfToken(Loc->Loc), "\""); + Str = Loc->Ident->getName(); + if (ArgLocation) + *ArgLocation = Loc->Loc; + return true; + } + + // Now check for an actual string literal. + Expr *ArgExpr = Attr.getArgAsExpr(ArgNum); + StringLiteral *Literal = dyn_cast(ArgExpr->IgnoreParenCasts()); + if (ArgLocation) + *ArgLocation = ArgExpr->getLocStart(); + + if (!Literal || !Literal->isAscii()) { + S.Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type) + << Attr.getName() << AANT_ArgumentString; + return false; + } + + Str = Literal->getString(); + return true; +} + /// /// \brief Check if passed in Decl is a field or potentially shared global var /// \return true if the Decl is a field or potentially shared global variable @@ -1541,64 +1578,18 @@ static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) { // FIXME: it would be good for us to keep the WeakRefAttr as-written instead // of transforming it into an AliasAttr. The WeakRefAttr never uses the // StringRef parameter it was given anyway. - if (Attr.isArgExpr(0)) { - Expr *Arg = Attr.getArgAsExpr(0); - Arg = Arg->IgnoreParenCasts(); - StringLiteral *Str = dyn_cast(Arg); - - if (!Str || !Str->isAscii()) { - S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type) - << Attr.getName() << 1 << AANT_ArgumentString; - return; - } + StringRef Str; + if (Attr.getNumArgs() && checkStringLiteralArgument(S, Str, Attr, 0)) // GCC will accept anything as the argument of weakref. Should we // check for an existing decl? - D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, - Str->getString())); - } + D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context, Str, + Attr.getAttributeSpellingListIndex())); D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); } -/// \brief Check if the argument \p ArgNum of \p Attr is a ASCII string literal. -/// If not emit an error and return false. If the argument is an identifier it -/// will emit an error with a fixit hint and treat it as if it was a string -/// literal. -static bool checkStringLiteralArgument(Sema &S, StringRef &Str, - const AttributeList &Attr, - unsigned ArgNum, - SourceLocation *ArgLocation = 0) { - // Look for identifiers. If we have one emit a hint to fix it to a literal. - if (Attr.isArgIdent(ArgNum)) { - IdentifierLoc *Loc = Attr.getArgAsIdent(ArgNum); - S.Diag(Loc->Loc, diag::err_attribute_argument_type) - << Attr.getName() << AANT_ArgumentString - << FixItHint::CreateInsertion(Loc->Loc, "\"") - << FixItHint::CreateInsertion(S.PP.getLocForEndOfToken(Loc->Loc), "\""); - Str = Loc->Ident->getName(); - if (ArgLocation) - *ArgLocation = Loc->Loc; - return true; - } - - // Now check for an actual string literal. - Expr *ArgExpr = Attr.getArgAsExpr(ArgNum); - StringLiteral *Literal = dyn_cast(ArgExpr->IgnoreParenCasts()); - if (ArgLocation) - *ArgLocation = ArgExpr->getLocStart(); - - if (!Literal || !Literal->isAscii()) { - S.Diag(ArgExpr->getLocStart(), diag::err_attribute_argument_type) - << Attr.getName() << AANT_ArgumentString; - return false; - } - - Str = Literal->getString(); - return true; -} - static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { StringRef Str; if (!checkStringLiteralArgument(S, Str, Attr, 0)) diff --git a/test/SemaCXX/attr-weakref.cpp b/test/SemaCXX/attr-weakref.cpp index f3d7a6241c..0c3f1d20e7 100644 --- a/test/SemaCXX/attr-weakref.cpp +++ b/test/SemaCXX/attr-weakref.cpp @@ -32,3 +32,5 @@ int a9 __attribute__((weakref)); // expected-error {{weakref declaration of 'a9 static int a10(); int a10() __attribute__((weakref ("foo"))); + +static int v __attribute__((weakref(a1), alias("foo"))); // expected-error {{'weakref' attribute requires a string}}