diff options
author | John McCall <rjmccall@apple.com> | 2013-05-06 07:40:34 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2013-05-06 07:40:34 +0000 |
commit | 10f6f065456a2cfb6c2ab5dfedefb930e5e52e9d (patch) | |
tree | 6576c188ece19da725ee49abf51aa026366a80dd /test | |
parent | 692eafd2052fb6ca581530d6f3569eea9520a508 (diff) |
Require the containing type to be complete when we see
__alignof__ of a field.
This problem can only happen in C++11.
Also do some petty optimizations.
rdar://13784901
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181185 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/SemaCXX/alignof.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/test/SemaCXX/alignof.cpp b/test/SemaCXX/alignof.cpp new file mode 100644 index 0000000000..a9de1ad07c --- /dev/null +++ b/test/SemaCXX/alignof.cpp @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +// rdar://13784901 + +struct S0 { + int x; + static const int test0 = __alignof__(x); // expected-error {{invalid application of 'alignof' to a field of a class still being defined}} + static const int test1 = __alignof__(S0::x); // expected-error {{invalid application of 'alignof' to a field of a class still being defined}} + auto test2() -> char(&)[__alignof__(x)]; // expected-error {{invalid application of 'alignof' to a field of a class still being defined}} +}; + +struct S1; // expected-note 5 {{forward declaration}} +extern S1 s1; +const int test3 = __alignof__(s1); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}} + +struct S2 { + S2(); + S1 &s; + int x; + + int test4 = __alignof__(x); // ok + int test5 = __alignof__(s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}} +}; + +const int test6 = __alignof__(S2::x); +const int test7 = __alignof__(S2::s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}} + +// Arguably, these should fail like the S1 cases do: the alignment of +// 's2.x' should depend on the alignment of both x-within-S2 and +// s2-within-S3 and thus require 'S3' to be complete. If we start +// doing the appropriate recursive walk to do that, we should make +// sure that these cases don't explode. +struct S3 { + S2 s2; + + static const int test8 = __alignof__(s2.x); + static const int test9 = __alignof__(s2.s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}} + auto test10() -> char(&)[__alignof__(s2.x)]; + static const int test11 = __alignof__(S3::s2.x); + static const int test12 = __alignof__(S3::s2.s); // expected-error {{invalid application of 'alignof' to an incomplete type 'S1'}} + auto test13() -> char(&)[__alignof__(s2.x)]; +}; + +// Same reasoning as S3. +struct S4 { + union { + int x; + }; + static const int test0 = __alignof__(x); + static const int test1 = __alignof__(S0::x); + auto test2() -> char(&)[__alignof__(x)]; +}; |