1 // RUN: %clang_cc1 %s -std=c++17 -fsyntax-only -fcxx-exceptions -verify 2 3 struct S1 { 4 void f() [[clang::annotate_type("foo")]]; 5 // FIXME: We would want to prohibit the attribute in the following location. 6 // However, Clang currently generally doesn't prohibit type-only C++11 7 // attributes on declarations. This should be fixed more generally. 8 [[clang::annotate_type("foo")]] void g(); 9 }; 10 11 template <typename T1, typename T2> struct is_same { 12 static constexpr bool value = false; 13 }; 14 15 template <typename T1> struct is_same<T1, T1> { 16 static constexpr bool value = true; 17 }; 18 19 static_assert(is_same<int, int [[clang::annotate_type("foo")]]>::value); 20 static_assert(is_same<int [[clang::annotate_type("foo")]], 21 int [[clang::annotate_type("bar")]]>::value); 22 static_assert(is_same<int *, int *[[clang::annotate_type("foo")]]>::value); 23 24 // Cannot overload on types that only differ by `annotate_type` attribute. 25 void f(int) {} // expected-note {{previous definition is here}} 26 void f(int [[clang::annotate_type("foo")]]) {} // expected-error {{redefinition of 'f'}} 27 28 // Cannot specialize on types that only differ by `annotate_type` attribute. 29 template <class T> struct S2 {}; 30 31 template <> struct S2<int> {}; // expected-note {{previous definition is here}} 32 33 template <> 34 struct S2<int [[clang::annotate_type("foo")]]> {}; // expected-error {{redefinition of 'S2<int>'}} 35 36 // Test that the attribute supports parameter pack expansion. 37 template <int... Is> void variadic_func_template() { 38 int [[clang::annotate_type("foo", Is...)]] val; 39 } 40 int f2() { variadic_func_template<1, 2, 3>(); } 41 42 // Make sure we correctly diagnose wrong number of arguments for 43 // [[clang::annotate_type]] inside a template argument. 44 template <typename Ty> void func_template(); 45 void f3() { 46 func_template<int [[clang::annotate_type()]]>(); // expected-error {{'annotate_type' attribute takes at least 1 argument}} 47 } 48 49 // More error cases: Prohibit adding the attribute to declarations. 50 // Different declarations hit different code paths, so they need separate tests. 51 // FIXME: Clang currently generally doesn't prohibit type-only C++11 52 // attributes on declarations. 53 namespace [[clang::annotate_type("foo")]] my_namespace {} 54 struct [[clang::annotate_type("foo")]] S3; 55 struct [[clang::annotate_type("foo")]] S3{ 56 [[clang::annotate_type("foo")]] int member; 57 }; 58 void f4() { 59 for ([[clang::annotate_type("foo")]] int i = 0; i < 42; ++i) {} 60 for (; [[clang::annotate_type("foo")]] bool b = false;) {} 61 while ([[clang::annotate_type("foo")]] bool b = false) {} 62 if ([[clang::annotate_type("foo")]] bool b = false) {} 63 try { 64 } catch ([[clang::annotate_type("foo")]] int i) { 65 } 66 } 67 template <class T> 68 [[clang::annotate_type("foo")]] T var_template; 69 [[clang::annotate_type("foo")]] extern "C" int extern_c_func(); 70 extern "C" [[clang::annotate_type("foo")]] int extern_c_func(); 71