]> granicus.if.org Git - clang/commitdiff
Add a big test case for I-C-Es in C++, and a fix to make it work. The fix might not...
authorSebastian Redl <sebastian.redl@getdesigned.at>
Wed, 27 May 2009 19:34:06 +0000 (19:34 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Wed, 27 May 2009 19:34:06 +0000 (19:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72490 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/RecordLayout.h
lib/AST/ASTContext.cpp
test/SemaCXX/constant-expression.cpp [new file with mode: 0644]

index 11001ce52a9445adc4a2146ecadaf79aacf312ce..ab184563da23dd954500a3f6b6f36e0af0a48eee 100644 (file)
@@ -46,9 +46,12 @@ class ASTRecordLayout {
     FieldCount = N;
     FieldOffsets = new uint64_t[N];
   }
-  
+
   /// Finalize record layout. Adjust record size based on the alignment.
-  void FinalizeLayout() {
+  void FinalizeLayout(bool ForceNonEmpty = false) {
+    // In C++, records cannot be of size 0.
+    if (ForceNonEmpty && Size == 0)
+      Size = 8;
     // Finally, round the size of the record up to the alignment of the
     // record itself.
     Size = (Size + (Alignment-1)) & ~(Alignment-1);
index c168e98ea44f8d6348120b91cbe4c808ca66c55f..0db5f9b2bf6f76de9644dd1a93aee1b793c1b4c1 100644 (file)
@@ -360,6 +360,7 @@ ASTContext::getTypeInfo(const Type *T) {
     case BuiltinType::NullPtr:
       Width = Target.getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t)
       Align = Target.getPointerAlign(0); //   == sizeof(void*)
+      break;
     }
     break;
   case Type::FixedWidthInt:
@@ -768,7 +769,7 @@ const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) {
 
   // Finally, round the size of the total struct up to the alignment of the
   // struct itself.
-  NewEntry->FinalizeLayout();
+  NewEntry->FinalizeLayout(getLangOptions().CPlusPlus);
   return *NewEntry;
 }
 
diff --git a/test/SemaCXX/constant-expression.cpp b/test/SemaCXX/constant-expression.cpp
new file mode 100644 (file)
index 0000000..02ea802
--- /dev/null
@@ -0,0 +1,83 @@
+// RUN: clang-cc -fsyntax-only -verify -std=c++98 %s
+
+// C++ [expr.const]p1:
+//   In several places, C++ requires expressions that evaluate to an integral
+//   or enumeration constant: as array bounds, as case expressions, as
+//   bit-field lengths, as enumerator initializers, as static member
+//   initializers, and as integral or enumeration non-type template arguments.
+//   An integral constant-expression can involve only literals, enumerators,
+//   const variables or static data members of integral or enumeration types
+//   initialized with constant expressions, and sizeof expressions. Floating
+//   literals can appear only if they are cast to integral or enumeration types.
+
+enum Enum { eval = 1 };
+const int cval = 2;
+const Enum ceval = eval;
+struct Struct {
+  static const int sval = 3;
+  static const Enum seval = eval;
+};
+
+template <int itval, Enum etval> struct C {
+  enum E {
+    v1 = 1,
+    v2 = eval,
+    v3 = cval,
+    v4 = ceval,
+    v5 = Struct::sval,
+    v6 = Struct::seval,
+    v7 = itval,
+    v8 = etval,
+    v9 = (int)1.5,
+    v10 = sizeof(Struct),
+    v11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
+  };
+  unsigned
+    b1 : 1,
+    b2 : eval,
+    b3 : cval,
+    b4 : ceval,
+    b5 : Struct::sval,
+    b6 : Struct::seval,
+    b7 : itval,
+    b8 : etval,
+    b9 : (int)1.5,
+    b10 : sizeof(Struct),
+    b11 : true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
+    ;
+  static const int
+    i1 = 1,
+    i2 = eval,
+    i3 = cval,
+    i4 = ceval,
+    i5 = Struct::sval,
+    i6 = Struct::seval,
+    i7 = itval,
+    i8 = etval,
+    i9 = (int)1.5,
+    i10 = sizeof(Struct),
+    i11 = true? 1 + cval * Struct::sval ^ itval / (int)1.5 - sizeof(Struct) : 0
+    ;
+  void f() {
+    switch(0) {
+    case    0 + 1:
+    case  100 + eval:
+    case  200 + cval:
+    case  300 + ceval:
+    case  400 + Struct::sval:
+    case  500 + Struct::seval:
+    case  600 + itval:
+    case  700 + etval:
+    case  800 + (int)1.5:
+    case  900 + sizeof(Struct):
+    case 1000 + (true? 1 + cval * Struct::sval ^
+                 itval / (int)1.5 - sizeof(Struct) : 0):
+      ;
+    }
+  }
+  typedef C<itval, etval> T0;
+};
+
+template struct C<1, eval>;
+//template struct C<cval, ceval>;
+//template struct C<Struct::sval, Struct::seval>;