tbaeder updated this revision to Diff 460758.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133934/new/

https://reviews.llvm.org/D133934

Files:
  clang/lib/AST/Interp/Boolean.h
  clang/lib/AST/Interp/ByteCodeExprGen.cpp
  clang/lib/AST/Interp/ByteCodeExprGen.h
  clang/lib/AST/Interp/Opcodes.td
  clang/test/AST/Interp/literals.cpp

Index: clang/test/AST/Interp/literals.cpp
===================================================================
--- clang/test/AST/Interp/literals.cpp
+++ clang/test/AST/Interp/literals.cpp
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++11 -verify %s
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++20 -verify %s
 // RUN: %clang_cc1 -std=c++11 -verify=ref %s
+// RUN: %clang_cc1 -std=c++20 -verify=ref %s
 
 static_assert(true, "");
 static_assert(false, ""); // expected-error{{failed}} ref-error{{failed}}
@@ -72,10 +74,74 @@
 constexpr const int* getIntPointer() {
   return &m;
 }
-//static_assert(getIntPointer() == &m, ""); TODO
-//static_assert(*getIntPointer() == 10, ""); TODO
+static_assert(getIntPointer() == &m, "");
+static_assert(*getIntPointer() == 10, "");
 
 constexpr int gimme(int k) {
   return k;
 }
-// static_assert(gimme(5) == 5, ""); TODO
+static_assert(gimme(5) == 5, "");
+
+namespace SizeOf {
+  constexpr int soint = sizeof(int);
+  constexpr int souint = sizeof(unsigned int);
+  static_assert(soint == souint, "");
+
+  static_assert(sizeof(&soint) == sizeof(void*), "");
+  static_assert(sizeof(&soint) == sizeof(nullptr), "");
+
+  static_assert(sizeof(long) == sizeof(unsigned long), "");
+  static_assert(sizeof(char) == sizeof(unsigned char), "");
+
+  constexpr int N = 4;
+  constexpr int arr[N] = {1,2,3,4};
+  static_assert(sizeof(arr) == N * sizeof(int), "");
+  static_assert(sizeof(arr) == N * sizeof(arr[0]), "");
+
+  constexpr bool arrB[N] = {true, true, true, true};
+  static_assert(sizeof(arrB) == N * sizeof(bool), "");
+
+  static_assert(sizeof(bool) == 1, "");
+  static_assert(sizeof(char) == 1, "");
+
+  constexpr int F = sizeof(void); // expected-error{{incomplete type 'void'}} \
+                                  // ref-error{{incomplete type 'void'}}
+
+  constexpr int F2 = sizeof(gimme); // expected-error{{to a function type}} \
+                                    // ref-error{{to a function type}}
+
+
+
+  /// FIXME: The following code should be accepted.
+  struct S {
+    void func();
+  };
+  constexpr void (S::*Func)() = &S::func; // expected-error {{must be initialized by a constant expression}} \
+                                          // expected-error {{interpreter failed to evaluate an expression}}
+  static_assert(sizeof(Func) == sizeof(&S::func), "");
+
+
+  void func() {
+    int n = 12;
+    constexpr int oofda = sizeof(int[n++]); // expected-error {{must be initialized by a constant expression}} \
+                                            // ref-error {{must be initialized by a constant expression}}
+  }
+
+
+#if __cplusplus >= 202002L
+  /// FIXME: The following code should be accepted.
+  consteval int foo(int n) { // ref-error {{consteval function never produces a constant expression}}
+    return sizeof(int[n]); // ref-note 3{{not valid in a constant expression}} \
+                           // expected-note {{not valid in a constant expression}}
+  }
+  constinit int var = foo(5); // ref-error {{not a constant expression}} \
+                              // ref-note 2{{in call to}} \
+                              // ref-error {{does not have a constant initializer}} \
+                              // ref-note {{required by 'constinit' specifier}} \
+                              // expected-error  {{is not a constant expression}} \
+                              // expected-note {{in call to}} \
+                              // expected-error {{does not have a constant initializer}} \
+                              // expected-note {{required by 'constinit' specifier}} \
+
+#endif
+};
Index: clang/lib/AST/Interp/Opcodes.td
===================================================================
--- clang/lib/AST/Interp/Opcodes.td
+++ clang/lib/AST/Interp/Opcodes.td
@@ -427,11 +427,11 @@
 // TODO: Expand this to handle casts between more types.
 
 def FromCastTypeClass : TypeClass {
-  let Types = [Uint32, Sint32, Bool];
+  let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool];
 }
 
 def ToCastTypeClass : TypeClass {
-  let Types = [Uint32, Sint32, Bool];
+  let Types = [Uint8, Sint8, Uint16, Sint16, Uint32, Sint32, Uint64, Sint64, Bool];
 }
 
 def Cast: Opcode {
Index: clang/lib/AST/Interp/ByteCodeExprGen.h
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.h
+++ clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -80,6 +80,7 @@
   bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E);
   bool VisitInitListExpr(const InitListExpr *E);
   bool VisitConstantExpr(const ConstantExpr *E);
+  bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
 
 protected:
   bool visitExpr(const Expr *E) override;
Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -281,7 +281,28 @@
 }
 
 template <class Emitter>
-bool ByteCodeExprGen<Emitter>::discard(const Expr *E) {
+bool ByteCodeExprGen<Emitter>::VisitUnaryExprOrTypeTraitExpr(
+    const UnaryExprOrTypeTraitExpr *E) {
+
+  if (E->getKind() == UETT_SizeOf) {
+    QualType ArgType = E->getTypeOfArgument();
+
+    if (ArgType->isDependentType() || !ArgType->isConstantSizeType())
+      return false;
+
+    CharUnits Size;
+    if (ArgType->isVoidType() || ArgType->isFunctionType())
+      Size = CharUnits::One();
+    else
+      Size = Ctx.getASTContext().getTypeSizeInChars(ArgType);
+
+    return this->emitConst(E, Size.getQuantity());
+  }
+
+  return false;
+}
+
+template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) {
   OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true);
   return this->Visit(E);
 }
Index: clang/lib/AST/Interp/Boolean.h
===================================================================
--- clang/lib/AST/Interp/Boolean.h
+++ clang/lib/AST/Interp/Boolean.h
@@ -48,6 +48,10 @@
   Boolean operator~() const { return Boolean(true); }
 
   explicit operator unsigned() const { return V; }
+  explicit operator int8_t() const { return V; }
+  explicit operator uint8_t() const { return V; }
+  explicit operator int16_t() const { return V; }
+  explicit operator uint16_t() const { return V; }
   explicit operator int64_t() const { return V; }
   explicit operator uint64_t() const { return V; }
   explicit operator int() const { return V; }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to