You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Support guarded_by attribute and related attributes inside C structs and support late parsing them
This fixes#20777. This replaces #94216 which was reverted after being merged.
Previously the `guarded_by`, `pt_guarded_by`, `acquired_after`, and `acquired_before` attributes were only supported inside C++ classes or top level C/C++ declaration.
This patch allows these attributes to be added to struct members in C. These attributes have also now support experimental late parsing. This is off by default but can be enabled by passing `-fexperimental-late-parse-attributes`. This is useful for referring to a struct member after the annotated member. E.g.
```
struct Example {
int a_value_defined_before __attribute__ ((guarded_by(a_mutex)));
struct Mutex *a_mutex;
};
```
structMutex*other_muACQUIRED_AFTER(mu_); // Note: referencing the parent structure is convenient here, but this should probably be disallowed if the child structure is re-used outside of the parent.
37
+
structMutex*third_muACQUIRED_BEFORE(other_mu);
38
+
} bar;
39
+
40
+
int*a_ptrPT_GUARDED_BY(bar.other_mu);
41
+
};
42
+
43
+
structLOCKABLELock {};
44
+
structA {
45
+
structLocklock;
46
+
union {
47
+
intb __attribute__((guarded_by(lock))); // Note: referencing the parent structure is convenient here, but this should probably be disallowed if the child is re-used outside of the parent.
48
+
};
32
49
};
33
50
34
51
// Declare mutex lock/unlock functions.
@@ -74,6 +91,19 @@ int get_value(int *p) SHARED_LOCKS_REQUIRED(foo_.mu_){
mutex_exclusive_lock(late_parsing.a_mutex_defined_early); // expected-warning{{mutex 'a_mutex_defined_early' must be acquired before 'a_mutex_defined_late'}}
mutex_exclusive_lock(late_parsing.a_mutex_defined_very_late); // expected-warning{{mutex 'a_mutex_defined_very_late' must be acquired before 'a_mutex_defined_late'}}
// We had a problem where we'd skip all attributes that follow a late-parsed
143
197
// attribute in a single __attribute__.
144
198
voidrun(void) __attribute__((guarded_by(mu1), guarded_by(mu1))); // expected-warning 2{{only applies to non-static data members and global variables}}
199
+
200
+
intvalue_with_wrong_number_of_argsGUARDED_BY(mu1, mu2); // expected-error{{'guarded_by' attribute takes one argument}}
201
+
202
+
int*ptr_with_wrong_number_of_argsPT_GUARDED_BY(mu1, mu2); // expected-error{{'pt_guarded_by' attribute takes one argument}}
203
+
204
+
intvalue_with_no_open_brace __attribute__((guarded_by)); // expected-error{{'guarded_by' attribute takes one argument}}
205
+
int*ptr_with_no_open_brace __attribute__((pt_guarded_by)); // expected-error{{'pt_guarded_by' attribute takes one argument}}
206
+
207
+
intvalue_with_no_open_brace_on_acquire_after __attribute__((acquired_after)); // expected-error{{'acquired_after' attribute takes at least 1 argument}}
208
+
intvalue_with_no_open_brace_on_acquire_before __attribute__((acquired_before)); // expected-error{{'acquired_before' attribute takes at least 1 argument}}
209
+
210
+
intvalue_with_bad_exprGUARDED_BY(bad_expr); // expected-error{{use of undeclared identifier 'bad_expr'}}
211
+
int*ptr_with_bad_exprPT_GUARDED_BY(bad_expr); // expected-error{{use of undeclared identifier 'bad_expr'}}
212
+
213
+
intvalue_with_bad_expr_on_acquire_after __attribute__((acquired_after(other_bad_expr))); // expected-error{{use of undeclared identifier 'other_bad_expr'}}
214
+
intvalue_with_bad_expr_on_acquire_before __attribute__((acquired_before(other_bad_expr))); // expected-error{{use of undeclared identifier 'other_bad_expr'}}
0 commit comments