r303712 - Enhance the 'diagnose_if' attribute so that we can apply it for ObjC methods and properties as well
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Wed May 24 08:59:05 PDT 2017
On Tue, May 23, 2017 at 8:46 PM, Argyrios Kyrtzidis via cfe-commits
<cfe-commits at lists.llvm.org> wrote:
> Author: akirtzidis
> Date: Tue May 23 19:46:27 2017
> New Revision: 303712
>
> URL: http://llvm.org/viewvc/llvm-project?rev=303712&view=rev
> Log:
> Enhance the 'diagnose_if' attribute so that we can apply it for ObjC methods and properties as well
>
> This is an initial commit to allow using it with constant expressions, a follow-up commit will enable full support for it in ObjC methods.
>
> Added:
> cfe/trunk/test/SemaObjC/diagnose_if.m
> Modified:
> cfe/trunk/include/clang/Basic/Attr.td
> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> cfe/trunk/include/clang/Sema/AttributeList.h
> cfe/trunk/include/clang/Sema/Sema.h
> cfe/trunk/lib/Lex/PPMacroExpansion.cpp
> cfe/trunk/lib/Sema/SemaDeclAttr.cpp
> cfe/trunk/lib/Sema/SemaExpr.cpp
> cfe/trunk/lib/Sema/SemaOverload.cpp
> cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
>
> Modified: cfe/trunk/include/clang/Basic/Attr.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=303712&r1=303711&r2=303712&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/Attr.td (original)
> +++ cfe/trunk/include/clang/Basic/Attr.td Tue May 23 19:46:27 2017
> @@ -149,6 +149,9 @@ class ExprArgument<string name, bit opt
> class FunctionArgument<string name, bit opt = 0, bit fake = 0> : Argument<name,
> opt,
> fake>;
> +class NamedArgument<string name, bit opt = 0, bit fake = 0> : Argument<name,
> + opt,
> + fake>;
> class TypeArgument<string name, bit opt = 0> : Argument<name, opt>;
> class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>;
> class VariadicUnsignedArgument<string name> : Argument<name, 1>;
> @@ -1819,14 +1822,14 @@ def Unavailable : InheritableAttr {
>
> def DiagnoseIf : InheritableAttr {
> let Spellings = [GNU<"diagnose_if">];
> - let Subjects = SubjectList<[Function]>;
> + let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>;
> let Args = [ExprArgument<"Cond">, StringArgument<"Message">,
> EnumArgument<"DiagnosticType",
> "DiagnosticType",
> ["error", "warning"],
> ["DT_Error", "DT_Warning"]>,
> BoolArgument<"ArgDependent", 0, /*fake*/ 1>,
> - FunctionArgument<"Parent", 0, /*fake*/ 1>];
> + NamedArgument<"Parent", 0, /*fake*/ 1>];
> let DuplicatesAllowedWhileMerging = 1;
> let LateParsed = 1;
> let AdditionalMembers = [{
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=303712&r1=303711&r2=303712&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue May 23 19:46:27 2017
> @@ -2771,6 +2771,7 @@ def warn_attribute_wrong_decl_type : War
> "|types and namespaces"
> "|Objective-C interfaces"
> "|methods and properties"
> + "|functions, methods and properties"
functions, methods, and properties (inserting the Oxford comma).
> "|struct or union"
> "|struct, union or class"
> "|types"
>
> Modified: cfe/trunk/include/clang/Sema/AttributeList.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=303712&r1=303711&r2=303712&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/AttributeList.h (original)
> +++ cfe/trunk/include/clang/Sema/AttributeList.h Tue May 23 19:46:27 2017
> @@ -915,6 +915,7 @@ enum AttributeDeclKind {
> ExpectedTypeOrNamespace,
> ExpectedObjectiveCInterface,
> ExpectedMethodOrProperty,
> + ExpectedFunctionOrMethodOrProperty,
> ExpectedStructOrUnion,
> ExpectedStructOrUnionOrClass,
> ExpectedType,
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=303712&r1=303711&r2=303712&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Tue May 23 19:46:27 2017
> @@ -2727,7 +2727,7 @@ public:
> /// of a function.
> ///
> /// Returns true if any errors were emitted.
> - bool diagnoseArgIndependentDiagnoseIfAttrs(const FunctionDecl *Function,
> + bool diagnoseArgIndependentDiagnoseIfAttrs(const NamedDecl *ND,
> SourceLocation Loc);
>
> /// Returns whether the given function's address can be taken or not,
>
> Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=303712&r1=303711&r2=303712&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
> +++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Tue May 23 19:46:27 2017
> @@ -1166,6 +1166,7 @@ static bool HasFeature(const Preprocesso
> .Case("objc_generics", LangOpts.ObjC2)
> .Case("objc_generics_variance", LangOpts.ObjC2)
> .Case("objc_class_property", LangOpts.ObjC2)
> + .Case("objc_diagnose_if_attr", LangOpts.ObjC2)
> // C11 features
> .Case("c_alignas", LangOpts.C11)
> .Case("c_alignof", LangOpts.C11)
>
> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=303712&r1=303711&r2=303712&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue May 23 19:46:27 2017
> @@ -949,7 +949,7 @@ static bool checkFunctionConditionAttr(S
> Msg = "<no message provided>";
>
> SmallVector<PartialDiagnosticAt, 8> Diags;
> - if (!Cond->isValueDependent() &&
> + if (isa<FunctionDecl>(D) && !Cond->isValueDependent() &&
> !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(D),
> Diags)) {
> S.Diag(Attr.getLoc(), diag::err_attr_cond_never_constant_expr)
> @@ -1037,10 +1037,11 @@ static void handleDiagnoseIfAttr(Sema &S
> return;
> }
>
> - auto *FD = cast<FunctionDecl>(D);
> - bool ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond);
> + bool ArgDependent = false;
> + if (auto *FD = dyn_cast<FunctionDecl>(D))
Please use const auto *.
> + ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond);
> D->addAttr(::new (S.Context) DiagnoseIfAttr(
> - Attr.getRange(), S.Context, Cond, Msg, DiagType, ArgDependent, FD,
> + Attr.getRange(), S.Context, Cond, Msg, DiagType, ArgDependent, cast<NamedDecl>(D),
> Attr.getAttributeSpellingListIndex()));
> }
>
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=303712&r1=303711&r2=303712&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue May 23 19:46:27 2017
> @@ -366,8 +366,19 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *
>
> if (getLangOpts().CUDA && !CheckCUDACall(Loc, FD))
> return true;
> + }
>
> - if (diagnoseArgIndependentDiagnoseIfAttrs(FD, Loc))
> + auto getReferencedObjCProp = [](const NamedDecl *D) ->
> + const ObjCPropertyDecl * {
> + if (auto *MD = dyn_cast<ObjCMethodDecl>(D))
Please use const auto *.
> + return MD->findPropertyDecl();
> + return nullptr;
> + };
> + if (auto *ObjCPDecl = getReferencedObjCProp(D)) {
Please do not use auto here (the type is not spelled out in the
initialization). Also, please mark it explicitly as being a const
pointer.
> + if (diagnoseArgIndependentDiagnoseIfAttrs(ObjCPDecl, Loc))
> + return true;
> + } else {
> + if (diagnoseArgIndependentDiagnoseIfAttrs(D, Loc))
Please bump the if up to be part of the else clause.
~Aaron
> return true;
> }
>
>
> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=303712&r1=303711&r2=303712&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue May 23 19:46:27 2017
> @@ -6242,11 +6242,11 @@ EnableIfAttr *Sema::CheckEnableIf(Functi
> }
>
> template <typename CheckFn>
> -static bool diagnoseDiagnoseIfAttrsWith(Sema &S, const FunctionDecl *FD,
> +static bool diagnoseDiagnoseIfAttrsWith(Sema &S, const NamedDecl *ND,
> bool ArgDependent, SourceLocation Loc,
> CheckFn &&IsSuccessful) {
> SmallVector<const DiagnoseIfAttr *, 8> Attrs;
> - for (const auto *DIA : FD->specific_attrs<DiagnoseIfAttr>()) {
> + for (const auto *DIA : ND->specific_attrs<DiagnoseIfAttr>()) {
> if (ArgDependent == DIA->getArgDependent())
> Attrs.push_back(DIA);
> }
> @@ -6293,16 +6293,16 @@ bool Sema::diagnoseArgDependentDiagnoseI
> // EvaluateWithSubstitution only cares about the position of each
> // argument in the arg list, not the ParmVarDecl* it maps to.
> if (!DIA->getCond()->EvaluateWithSubstitution(
> - Result, Context, DIA->getParent(), Args, ThisArg))
> + Result, Context, cast<FunctionDecl>(DIA->getParent()), Args, ThisArg))
> return false;
> return Result.isInt() && Result.getInt().getBoolValue();
> });
> }
>
> -bool Sema::diagnoseArgIndependentDiagnoseIfAttrs(const FunctionDecl *Function,
> +bool Sema::diagnoseArgIndependentDiagnoseIfAttrs(const NamedDecl *ND,
> SourceLocation Loc) {
> return diagnoseDiagnoseIfAttrsWith(
> - *this, Function, /*ArgDependent=*/false, Loc,
> + *this, ND, /*ArgDependent=*/false, Loc,
> [&](const DiagnoseIfAttr *DIA) {
> bool Result;
> return DIA->getCond()->EvaluateAsBooleanCondition(Result, Context) &&
>
> Added: cfe/trunk/test/SemaObjC/diagnose_if.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/diagnose_if.m?rev=303712&view=auto
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/diagnose_if.m (added)
> +++ cfe/trunk/test/SemaObjC/diagnose_if.m Tue May 23 19:46:27 2017
> @@ -0,0 +1,16 @@
> +// RUN: %clang_cc1 %s -verify -fno-builtin
> +
> +_Static_assert(__has_feature(objc_diagnose_if_attr), "feature check failed?");
> +
> +#define _diagnose_if(...) __attribute__((diagnose_if(__VA_ARGS__)))
> +
> + at interface I
> +-(void)meth _diagnose_if(1, "don't use this", "warning"); // expected-note 1{{from 'diagnose_if'}}
> + at property (assign) id prop _diagnose_if(1, "don't use this", "warning"); // expected-note 2{{from 'diagnose_if'}}
> + at end
> +
> +void test(I *i) {
> + [i meth]; // expected-warning {{don't use this}}
> + id o1 = i.prop; // expected-warning {{don't use this}}
> + id o2 = [i prop]; // expected-warning {{don't use this}}
> +}
>
> Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=303712&r1=303711&r2=303712&view=diff
> ==============================================================================
> --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
> +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Tue May 23 19:46:27 2017
> @@ -312,7 +312,7 @@ namespace {
> }
>
> void writeDump(raw_ostream &OS) const override {
> - if (type == "FunctionDecl *") {
> + if (type == "FunctionDecl *" || type == "NamedDecl *") {
> OS << " OS << \" \";\n";
> OS << " dumpBareDeclRef(SA->get" << getUpperName() << "());\n";
> } else if (type == "IdentifierInfo *") {
> @@ -1181,6 +1181,8 @@ createArgument(const Record &Arg, String
> Ptr = llvm::make_unique<ExprArgument>(Arg, Attr);
> else if (ArgName == "FunctionArgument")
> Ptr = llvm::make_unique<SimpleArgument>(Arg, Attr, "FunctionDecl *");
> + else if (ArgName == "NamedArgument")
> + Ptr = llvm::make_unique<SimpleArgument>(Arg, Attr, "NamedDecl *");
> else if (ArgName == "IdentifierArgument")
> Ptr = llvm::make_unique<SimpleArgument>(Arg, Attr, "IdentifierInfo *");
> else if (ArgName == "DefaultBoolArgument")
> @@ -3103,6 +3105,8 @@ static std::string CalculateDiagnostic(c
> " : ExpectedVariableOrFunction))";
>
> case ObjCMethod | ObjCProp: return "ExpectedMethodOrProperty";
> + case Func | ObjCMethod | ObjCProp:
> + return "ExpectedFunctionOrMethodOrProperty";
> case ObjCProtocol | ObjCInterface:
> return "ExpectedObjectiveCInterfaceOrProtocol";
> case Field | Var: return "ExpectedFieldOrGlobalVar";
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list