108 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s2 3struct S0 {4 int x;5 static const int test0 = __alignof__(x); // expected-error {{invalid application of 'alignof' to a field of a class still being defined}}6 static const int test1 = __alignof__(S0::x); // expected-error {{invalid application of 'alignof' to a field of a class still being defined}}7 auto test2() -> char(&)[__alignof__(x)]; // expected-error {{invalid application of 'alignof' to a field of a class still being defined}}8};9 10struct S1; // expected-note 6 {{forward declaration}}11extern S1 s1;12const int test3 = __alignof__(s1); // expected-error {{invalid application of '__alignof' to an incomplete type 'S1'}}13 14struct S2 {15 S2();16 S1 &s;17 int x;18 19 int test4 = __alignof__(x); // ok20 int test5 = __alignof__(s); // expected-error {{invalid application of '__alignof' to an incomplete type 'S1'}}21};22 23const int test6 = __alignof__(S2::x);24const int test7 = __alignof__(S2::s); // expected-error {{invalid application of '__alignof' to an incomplete type 'S1'}}25 26// Arguably, these should fail like the S1 cases do: the alignment of27// 's2.x' should depend on the alignment of both x-within-S2 and28// s2-within-S3 and thus require 'S3' to be complete. If we start29// doing the appropriate recursive walk to do that, we should make30// sure that these cases don't explode.31struct S3 {32 S2 s2;33 34 static const int test8 = __alignof__(s2.x);35 static const int test9 = __alignof__(s2.s); // expected-error {{invalid application of '__alignof' to an incomplete type 'S1'}}36 auto test10() -> char(&)[__alignof__(s2.x)];37 static const int test11 = __alignof__(S3::s2.x);38 static const int test12 = __alignof__(S3::s2.s); // expected-error {{invalid application of '__alignof' to an incomplete type 'S1'}}39 auto test13() -> char(&)[__alignof__(s2.x)];40};41 42// Same reasoning as S3.43struct S4 {44 union {45 int x;46 };47 static const int test0 = __alignof__(x);48 static const int test1 = __alignof__(S0::x);49 auto test2() -> char(&)[__alignof__(x)];50};51 52// Regression test for asking for the alignment of a field within an invalid53// record.54struct S5 {55 S1 s; // expected-error {{incomplete type}}56 int x;57};58const int test8 = __alignof__(S5::x);59 60int test14[2];61 62static_assert(alignof(test14) == 4, "foo"); // expected-warning {{'alignof' applied to an expression is a GNU extension}}63 64// PR1999265static_assert(alignof(int[]) == alignof(int), ""); // ok66 67namespace alignof_array_expr {68 alignas(32) extern int n[];69 static_assert(alignof(n) == 32, ""); // expected-warning {{GNU extension}}70 71 template<int> struct S {72 static int a[];73 };74 template<int N> int S<N>::a[N];75 // ok, does not complete type of S<-1>::a76 static_assert(alignof(S<-1>::a) == alignof(int), ""); // expected-warning {{GNU extension}}77}78 79template <typename T> void n(T) {80 alignas(T) int T1;81 char k[__alignof__(T1)];82 static_assert(sizeof(k) == alignof(long long), "");83}84template void n(long long);85 86namespace PR22042 {87template <typename T>88void Fun(T A) {89 typedef int __attribute__((__aligned__(A))) T1; // expected-error {{requested alignment is dependent but declaration is not dependent}}90 int k1[__alignof__(T1)];91}92 93template <int N>94struct S {95 typedef __attribute__((aligned(N))) int Field[sizeof(N)]; // expected-error {{requested alignment is dependent but declaration is not dependent}}96};97}98 99typedef int __attribute__((aligned(16))) aligned_int;100template <typename>101using template_alias = aligned_int;102static_assert(alignof(template_alias<void>) == 16, "Expected alignment of 16" );103 104struct PR47138 {105 invalid_type a; // expected-error {{unknown type}}106};107static_assert(__alignof__(PR47138) == 1, ""); // Don't crash.108