[clang] fcbc613 - Make "#pragma clang attribute" support uninitialized attribute.

Jian Cai via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 23 14:25:25 PDT 2020


Author: Jian Cai
Date: 2020-04-23T14:25:13-07:00
New Revision: fcbc613ad8b7785f710996f58726f26ad4ace50b

URL: https://github.com/llvm/llvm-project/commit/fcbc613ad8b7785f710996f58726f26ad4ace50b
DIFF: https://github.com/llvm/llvm-project/commit/fcbc613ad8b7785f710996f58726f26ad4ace50b.diff

LOG: Make "#pragma clang attribute" support uninitialized attribute.

Summary:
When using -ftrivial-auto-var-init=* options to initiate automatic
variables in a file, to disable initialization on some variables,
currently we have to manually annotate the variables with uninitialized
attribute, such as

int dont_initialize_me __attribute((uninitialized));

Making pragma clang attribute to support this attribute would make
annotating variables much easier, and could be particular useful for
bisection efforts, e.g.

void use(void*);

void buggy() {
    int arr[256];
    int boom;
    float bam;
    struct { int oops; } oops;
    union { int oof; float aaaaa; } oof;

    use(&arr);
    use(&boom);
    use(&bam);
    use(&oops);
    use(&oof);
}

Reviewers: jfb, rjmccall, aaron.ballman

Reviewed By: jfb, aaron.ballman

Subscribers: aaron.ballman, george.burgess.iv, dexonsmith, MaskRay, phosek, hubert.reinterpretcast, gbiv, manojgupta, llozano, srhines, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D78693

Added: 
    

Modified: 
    clang/docs/LanguageExtensions.rst
    clang/include/clang/Basic/Attr.td
    clang/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp
    clang/test/Misc/pragma-attribute-supported-attributes-list.test
    clang/test/Parser/pragma-attribute.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index 07062a191ce8..f1b7c79db6d6 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -3336,6 +3336,9 @@ Clang supports the following match rules:
 - ``variable(is_global)``: Can be used to apply attributes to global variables
   only.
 
+- ``variable(is_local)``: Can be used to apply attributes to local variables
+  only.
+
 - ``variable(is_parameter)``: Can be used to apply attributes to parameters
   only.
 

diff  --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index f9f14bfcc424..1f5ea4d83a4d 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -441,6 +441,7 @@ def SubjectMatcherForEnumConstant : AttrSubjectMatcherRule<"enum_constant",
 def SubjectMatcherForVar : AttrSubjectMatcherRule<"variable", [Var], [
   AttrSubjectMatcherSubRule<"is_thread_local", [TLSVar]>,
   AttrSubjectMatcherSubRule<"is_global", [GlobalVar]>,
+  AttrSubjectMatcherSubRule<"is_local", [LocalVar]>,
   AttrSubjectMatcherSubRule<"is_parameter", [ParmVar]>,
   // unless(is_parameter)
   AttrSubjectMatcherSubRule<"is_parameter", [NonParmVar], 1>
@@ -3381,6 +3382,7 @@ def NoSpeculativeLoadHardening : InheritableAttr {
 def Uninitialized : InheritableAttr {
   let Spellings = [Clang<"uninitialized", 0>];
   let Subjects = SubjectList<[LocalVar]>;
+  let PragmaAttributeSupport = 1;
   let Documentation = [UninitializedDocs];
 }
 

diff  --git a/clang/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp b/clang/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp
index e7c9e9ac2a5a..8b1bf2e57b21 100644
--- a/clang/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp
+++ b/clang/test/CodeGenCXX/trivial-auto-var-init-attribute.cpp
@@ -20,4 +20,20 @@ void test_attribute_uninitialized() {
   used(i);
 }
 
+#pragma clang attribute push([[clang::uninitialized]], apply_to = variable(is_local))
+// UNINIT-LABEL:  test_pragma_attribute_uninitialized(
+// UNINIT:      alloca
+// UNINIT-NEXT: call void
+// ZERO-LABEL:    test_pragma_attribute_uninitialized(
+// ZERO:      alloca
+// ZERO-NEXT: call void
+// PATTERN-LABEL: test_pragma_attribute_uninitialized(
+// PATTERN:      alloca
+// PATTERN-NEXT: call void
+void test_pragma_attribute_uninitialized() {
+  int i;
+  used(i);
+}
+#pragma clang attribute pop
+
 } // extern "C"

diff  --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index e4750705a249..c23a93218802 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -41,6 +41,7 @@
 // CHECK-NEXT: Callback (SubjectMatchRule_function)
 // CHECK-NEXT: Capability (SubjectMatchRule_record, SubjectMatchRule_type_alias)
 // CHECK-NEXT: CarriesDependency (SubjectMatchRule_variable_is_parameter, SubjectMatchRule_objc_method, SubjectMatchRule_function)
+// CHECK-NEXT: Cleanup (SubjectMatchRule_variable_is_local)
 // CHECK-NEXT: CmseNSEntry (SubjectMatchRule_function)
 // CHECK-NEXT: Cold (SubjectMatchRule_function)
 // CHECK-NEXT: Common (SubjectMatchRule_variable)
@@ -151,6 +152,7 @@
 // CHECK-NEXT: Target (SubjectMatchRule_function)
 // CHECK-NEXT: TestTypestate (SubjectMatchRule_function_is_member)
 // CHECK-NEXT: TrivialABI (SubjectMatchRule_record)
+// CHECK-NEXT: Uninitialized (SubjectMatchRule_variable_is_local)
 // CHECK-NEXT: UseHandle (SubjectMatchRule_variable_is_parameter)
 // CHECK-NEXT: VecReturn (SubjectMatchRule_record)
 // CHECK-NEXT: VecTypeHint (SubjectMatchRule_function)

diff  --git a/clang/test/Parser/pragma-attribute.cpp b/clang/test/Parser/pragma-attribute.cpp
index 4e860b6d5833..9d28832a902e 100644
--- a/clang/test/Parser/pragma-attribute.cpp
+++ b/clang/test/Parser/pragma-attribute.cpp
@@ -63,14 +63,14 @@ void function();
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = hasType(functionType)) // OK
 
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable( )) // expected-error {{expected ')'}}
-#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable( ) )) // expected-error {{expected an identifier that corresponds to an attribute subject matcher sub-rule; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_parameter', 'unless(is_parameter)'}}
-#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(is ) )) // expected-error {{unknown attribute subject matcher sub-rule 'is'; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_parameter', 'unless(is_parameter)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any(variable()))  // expected-error {{expected an identifier that corresponds to an attribute subject matcher sub-rule; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_local', 'is_parameter', 'unless(is_parameter)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any(variable(is)))                  // expected-error {{unknown attribute subject matcher sub-rule 'is'; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_local', 'is_parameter', 'unless(is_parameter)'}}
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(is_parameter, not) )) // expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable is_parameter )) // expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable ( ) // expected-error {{expected ')'}}
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = variable (  // expected-error {{expected ')'}}
-#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, variable (is ()) )) // expected-error {{unknown attribute subject matcher sub-rule 'is'; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_parameter', 'unless(is_parameter)'}}
-#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, variable (42) )) // expected-error {{expected an identifier that corresponds to an attribute subject matcher sub-rule; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_parameter', 'unless(is_parameter)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any(function, variable(is())))      // expected-error {{unknown attribute subject matcher sub-rule 'is'; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_local', 'is_parameter', 'unless(is_parameter)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any(function, variable(42)))        // expected-error {{expected an identifier that corresponds to an attribute subject matcher sub-rule; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_local', 'is_parameter', 'unless(is_parameter)'}}
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, namespace("test") )) // expected-error {{expected an identifier that corresponds to an attribute subject matcher sub-rule; 'namespace' matcher does not support sub-rules}}
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, variable ("test" )) // expected-error {{expected ')'}}
 
@@ -79,15 +79,15 @@ void function();
 
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any (function, variable (unless) )) // expected-error {{expected '('}}
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any (function, variable (unless() )) // expected-error {{expected ')'}}
-#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any ( function, variable (unless(is)) )) // expected-error {{unknown attribute subject matcher sub-rule 'unless(is)'; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_parameter', 'unless(is_parameter)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any(function, variable(unless(is)))) // expected-error {{unknown attribute subject matcher sub-rule 'unless(is)'; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_local', 'is_parameter', 'unless(is_parameter)'}}
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(unless(is_parameter, not)) )) // expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(unless(is_parameter), not) ) // expected-error {{expected ')'}}
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable unless is_parameter )) // expected-error {{expected ')'}} expected-note {{to match this '('}}
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(unless is_parameter) )) // expected-error {{expected '('}}
-#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, variable (unless(42)) )) // expected-error {{expected an identifier that corresponds to an attribute subject matcher sub-rule; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_parameter', 'unless(is_parameter)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any(function, variable(unless(42))))  // expected-error {{expected an identifier that corresponds to an attribute subject matcher sub-rule; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_local', 'is_parameter', 'unless(is_parameter)'}}
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, enum(unless("test")) )) // expected-error {{expected an identifier that corresponds to an attribute subject matcher sub-rule; 'enum' matcher does not support sub-rules}}
 
-#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, variable (unless(is_global)) )) // expected-error {{unknown attribute subject matcher sub-rule 'unless(is_global)'; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_parameter', 'unless(is_parameter)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any(function, variable(unless(is_global)))) // expected-error {{unknown attribute subject matcher sub-rule 'unless(is_global)'; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_local', 'is_parameter', 'unless(is_parameter)'}}
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( enum(unless(is_parameter)) )) // expected-error {{invalid use of attribute subject matcher sub-rule 'unless(is_parameter)'; 'enum' matcher does not support sub-rules}}
 
 #pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, function )) // expected-error {{duplicate attribute subject matcher 'function'}}
@@ -182,3 +182,16 @@ _Pragma("clang attribute pop");
 // expected-note at -1 {{use the GNU '__attribute__' syntax}}
 #pragma clang attribute push (annotate("test")) // expected-error {{expected an attribute that is specified using the GNU, C++11 or '__declspec' syntax}}
 // expected-note at -1 {{use the GNU '__attribute__' syntax}}
+
+#pragma clang attribute push([[clang::uninitialized]], apply_to = variable(is_local))
+#pragma clang attribute pop
+#pragma clang attribute push([[clang::uninitialized]], apply_to = function) // expected-error {{attribute 'uninitialized' can't be applied to 'function'}}
+#pragma clang attribute pop
+#pragma clang attribute push([[clang::uninitialized]], apply_to = variable) // expected-error {{attribute 'uninitialized' can't be applied to 'variable'}}
+#pragma clang attribute pop
+#pragma clang attribute push([[clang::uninitialized]], apply_to = variable(is_thread_local)) // expected-error {{attribute 'uninitialized' can't be applied to 'variable(is_thread_local)'}}
+#pragma clang attribute pop
+#pragma clang attribute push([[clang::uninitialized]], apply_to = variable(is_global)) // expected-error {{attribute 'uninitialized' can't be applied to 'variable(is_global)'}}
+#pragma clang attribute pop
+#pragma clang attribute push([[clang::uninitialized]], apply_to = any(variable(is_parameter), variable(unless(is_parameter)))) // expected-error {{attribute 'uninitialized' can't be applied to 'variable(is_parameter)', and 'variable(unless(is_parameter))'}}
+#pragma clang attribute pop


        


More information about the cfe-commits mailing list