[clang] ef1bb11 - [clang][Parse] Fix crash when emitting template diagnostic

2022-08-30 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-08-30T15:11:38+02:00
New Revision: ef1bb11a34de2822514878b99b442575a022a658

URL: 
https://github.com/llvm/llvm-project/commit/ef1bb11a34de2822514878b99b442575a022a658
DIFF: 
https://github.com/llvm/llvm-project/commit/ef1bb11a34de2822514878b99b442575a022a658.diff

LOG: [clang][Parse] Fix crash when emitting template diagnostic

This was passing a 6 to the diagnostic engine, which the diagnostic
message didn't handle.

Add the new value to the diagnosic message, remove an unused value and
add a test.

This fixes https://github.com/llvm/llvm-project/issues/57415

Differential Revision: https://reviews.llvm.org/D132821

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/test/Parser/cxx-concept-declaration.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 92b52b8998b4f..54060deca5c30 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -84,6 +84,8 @@ Bug Fixes
 - Fix assert that triggers a crash during template name lookup when a type was
   incomplete but was not also a TagType. This fixes
   `Issue 57387 `_.
+- Fix a crash when emitting a concept-related diagnostic. This fixes
+  `Issue 57415 `_.
 
 
 Improvements to Clang's diagnostics

diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 18adb21e2be08..84504b15764b1 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -775,7 +775,8 @@ def warn_cxx14_compat_template_template_param_typename : 
Warning<
 def err_template_spec_syntax_non_template : Error<
   "identifier followed by '<' indicates a class template specialization but "
   "%0 %select{does not refer to a template|refers to a function template|"
-  "|refers to a variable template||refers to a concept}1">;
+  "|refers to a variable template|||"
+  "refers to a concept}1">;
 def err_id_after_template_in_nested_name_spec : Error<
   "expected template name after 'template' keyword in nested name specifier">;
 def err_unexpected_template_in_unqualified_id : Error<

diff  --git a/clang/test/Parser/cxx-concept-declaration.cpp 
b/clang/test/Parser/cxx-concept-declaration.cpp
index 41bf53aed36e5..9248e26b9cbeb 100644
--- a/clang/test/Parser/cxx-concept-declaration.cpp
+++ b/clang/test/Parser/cxx-concept-declaration.cpp
@@ -1,7 +1,12 @@
 
 // Support parsing of concepts
 // Disabled for now.
-// expected-no-diagnostics
 
-// RUN:  %clang_cc1 -std=c++14 -x c++ -verify %s
-// template concept C1 = true;
+// RUN:  %clang_cc1 -std=c++20 -x c++ -verify %s
+template concept C1 = true;
+
+template
+concept C = true;
+
+template
+class C {}; //expected-error{{identifier followed by '<' indicates a 
class template specialization but 'C' refers to a concept}}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 5777c05 - [clang] Perform implicit lvalue-to-rvalue cast with new interpreter

2022-09-07 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-08T07:31:07+02:00
New Revision: 5777c05d16098cb690decef95ad6c20c695a5fa9

URL: 
https://github.com/llvm/llvm-project/commit/5777c05d16098cb690decef95ad6c20c695a5fa9
DIFF: 
https://github.com/llvm/llvm-project/commit/5777c05d16098cb690decef95ad6c20c695a5fa9.diff

LOG: [clang] Perform implicit lvalue-to-rvalue cast with new interpreter

The EvaluateAsRValue() documentation mentions that an implicit
lvalue-to-rvalue cast is being performed if the result is an lvalue.
However, that was not being done if the new constant interpreter was in
use.

Just always do it.

Differential Revision: https://reviews.llvm.org/D132136

Added: 


Modified: 
clang/lib/AST/ExprConstant.cpp
clang/test/AST/Interp/literals.cpp
clang/unittests/AST/EvaluateAsRValueTest.cpp

Removed: 




diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 3df0e4292b6c..ba5690cd3c5a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -14934,25 +14934,27 @@ static bool EvaluateInPlace(APValue &Result, EvalInfo 
&Info, const LValue &This,
 /// lvalue-to-rvalue cast if it is an lvalue.
 static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result) {
   assert(!E->isValueDependent());
+
+  if (E->getType().isNull())
+return false;
+
+  if (!CheckLiteralType(Info, E))
+return false;
+
   if (Info.EnableNewConstInterp) {
 if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E, Result))
   return false;
   } else {
-if (E->getType().isNull())
-  return false;
-
-if (!CheckLiteralType(Info, E))
-  return false;
-
 if (!::Evaluate(Result, Info, E))
   return false;
+  }
 
-if (E->isGLValue()) {
-  LValue LV;
-  LV.setFrom(Info.Ctx, Result);
-  if (!handleLValueToRValueConversion(Info, E, E->getType(), LV, Result))
-return false;
-}
+  // Implicit lvalue-to-rvalue cast.
+  if (E->isGLValue()) {
+LValue LV;
+LV.setFrom(Info.Ctx, Result);
+if (!handleLValueToRValueConversion(Info, E, E->getType(), LV, Result))
+  return false;
   }
 
   // Check this core constant expression is a constant expression.

diff  --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index f32f813a4986..6831091d596b 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -11,6 +11,7 @@ constexpr int number = 10;
 static_assert(number == 10, "");
 static_assert(number != 10, ""); // expected-error{{failed}} \
  // ref-error{{failed}} \
+ // expected-note{{evaluates to}} \
  // ref-note{{evaluates to}}
 
 constexpr bool getTrue() { return true; }

diff  --git a/clang/unittests/AST/EvaluateAsRValueTest.cpp 
b/clang/unittests/AST/EvaluateAsRValueTest.cpp
index bf44136835f2..f6261b827671 100644
--- a/clang/unittests/AST/EvaluateAsRValueTest.cpp
+++ b/clang/unittests/AST/EvaluateAsRValueTest.cpp
@@ -107,3 +107,50 @@ TEST(EvaluateAsRValue, FailsGracefullyForUnknownTypes) {
 Args));
   }
 }
+
+class CheckLValueToRValueConversionVisitor
+: public clang::RecursiveASTVisitor {
+public:
+  bool VisitDeclRefExpr(const clang::DeclRefExpr *E) {
+clang::Expr::EvalResult Result;
+E->EvaluateAsRValue(Result, E->getDecl()->getASTContext(), true);
+
+EXPECT_TRUE(Result.Val.hasValue());
+// Since EvaluateAsRValue does an implicit lvalue-to-rvalue conversion,
+// the result cannot be a LValue.
+EXPECT_FALSE(Result.Val.isLValue());
+
+return true;
+  }
+};
+
+class CheckConversionAction : public clang::ASTFrontendAction {
+public:
+  std::unique_ptr
+  CreateASTConsumer(clang::CompilerInstance &Compiler,
+llvm::StringRef FilePath) override {
+return std::make_unique();
+  }
+
+private:
+  class Consumer : public clang::ASTConsumer {
+  public:
+~Consumer() override {}
+
+void HandleTranslationUnit(clang::ASTContext &Ctx) override {
+  CheckLValueToRValueConversionVisitor Evaluator;
+  Evaluator.TraverseDecl(Ctx.getTranslationUnitDecl());
+}
+  };
+};
+
+TEST(EvaluateAsRValue, LValueToRValueConversionWorks) {
+  std::string ModesToTest[] = {"", "-fexperimental-new-constant-interpreter"};
+  for (std::string const &Mode : ModesToTest) {
+std::vector Args(1, Mode);
+
ASSERT_TRUE(runToolOnCodeWithArgs(std::make_unique(),
+  "constexpr int a = 20;\n"
+  "static_assert(a == 20, \"\");\n",
+  Args));
+  }
+}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 8e41e6a - [clang][Interp] Implement function calls

2022-09-07 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-08T07:31:07+02:00
New Revision: 8e41e6a4eafa2b667ec37ece33a85493fe0156c2

URL: 
https://github.com/llvm/llvm-project/commit/8e41e6a4eafa2b667ec37ece33a85493fe0156c2
DIFF: 
https://github.com/llvm/llvm-project/commit/8e41e6a4eafa2b667ec37ece33a85493fe0156c2.diff

LOG: [clang][Interp] Implement function calls

Add Call() and CallVoid() ops and use them to call functions. Only
FunctionDecls are supported for now.

Differential Revision: https://reviews.llvm.org/D132286

Added: 
clang/test/AST/Interp/functions.cpp

Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/lib/AST/Interp/EvalEmitter.cpp
clang/lib/AST/Interp/Function.h
clang/lib/AST/Interp/Interp.cpp
clang/lib/AST/Interp/InterpFrame.h
clang/lib/AST/Interp/Opcodes.td
clang/test/AST/Interp/cxx20.cpp
clang/utils/TableGen/ClangOpcodesEmitter.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 03f877197d16..18f3341439ee 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -9,6 +9,7 @@
 #include "ByteCodeExprGen.h"
 #include "ByteCodeEmitter.h"
 #include "ByteCodeGenError.h"
+#include "ByteCodeStmtGen.h"
 #include "Context.h"
 #include "Function.h"
 #include "PrimType.h"
@@ -593,6 +594,52 @@ bool ByteCodeExprGen::visitDecl(const VarDecl 
*VD) {
   return this->bail(VD);
 }
 
+template 
+bool ByteCodeExprGen::VisitCallExpr(const CallExpr *E) {
+  assert(!E->getBuiltinCallee() && "Builtin functions aren't supported yet");
+
+  const Decl *Callee = E->getCalleeDecl();
+  if (const auto *FuncDecl = dyn_cast_or_null(Callee)) {
+const Function *Func = P.getFunction(FuncDecl);
+
+// Templated functions might not have been compiled yet, so do it now.
+if (!Func) {
+  if (auto R =
+  ByteCodeStmtGen(Ctx, P).compileFunc(FuncDecl))
+Func = *R;
+}
+assert(Func);
+
+QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
+Optional T = classify(ReturnType);
+
+if (T || ReturnType->isVoidType()) {
+  // Put arguments on the stack.
+  for (const auto *Arg : E->arguments()) {
+if (!this->visit(Arg))
+  return false;
+  }
+
+  if (T)
+return this->emitCall(*T, Func, E);
+  return this->emitCallVoid(Func, E);
+} else {
+  assert(false && "Can't classify function return type");
+}
+
+  } else {
+assert(false && "We don't support non-FunctionDecl callees right now.");
+  }
+
+  return false;
+}
+
+template 
+bool ByteCodeExprGen::VisitCXXDefaultArgExpr(
+const CXXDefaultArgExpr *E) {
+  return this->visit(E->getExpr());
+}
+
 template 
 bool ByteCodeExprGen::VisitCXXBoolLiteralExpr(
 const CXXBoolLiteralExpr *E) {

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index f0459b55c8ef..f603f436f3c7 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -69,6 +69,8 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   bool VisitIntegerLiteral(const IntegerLiteral *E);
   bool VisitParenExpr(const ParenExpr *E);
   bool VisitBinaryOperator(const BinaryOperator *E);
+  bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E);
+  bool VisitCallExpr(const CallExpr *E);
   bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E);
   bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E);
   bool VisitUnaryOperator(const UnaryOperator *E);

diff  --git a/clang/lib/AST/Interp/EvalEmitter.cpp 
b/clang/lib/AST/Interp/EvalEmitter.cpp
index 22e8695b9211..3cc7ab0257d6 100644
--- a/clang/lib/AST/Interp/EvalEmitter.cpp
+++ b/clang/lib/AST/Interp/EvalEmitter.cpp
@@ -102,6 +102,24 @@ template  bool EvalEmitter::emitRet(const 
SourceInfo &Info) {
   return ReturnValue(S.Stk.pop(), Result);
 }
 
+template 
+bool EvalEmitter::emitCall(const Function *Func, const SourceInfo &Info) {
+
+  S.Current =
+  new InterpFrame(S, const_cast(Func), S.Current, {}, {});
+  // Result of call will be on the stack and needs to be handled by the caller.
+  return Interpret(S, Result);
+}
+
+bool EvalEmitter::emitCallVoid(const Function *Func, const SourceInfo &Info) {
+  APValue VoidResult;
+  S.Current =
+  new InterpFrame(S, const_cast(Func), S.Current, {}, {});
+  bool Success = Interpret(S, VoidResult);
+  assert(VoidResult.isAbsent());
+  return Success;
+}
+
 bool EvalEmitter::emitRetVoid(const SourceInfo &Info) { return true; }
 
 bool EvalEmitter::emitRetValue(const SourceInfo &Info) {

diff  --git a/clang/lib/AST/Interp/Function.h b/clang/lib/AST/Interp/Function.h
index fa850f76c026..b009167c1bd6 100644
--- a/clang/lib/AST/Interp/Function.h
+++ b/clang/lib/AST/Interp/Function.h
@@ -62,7 +62,7 @@ class Function {
 
   /// Returns the size of th

[clang] 95e6a40 - [clang][Interp] Implement IntegralToBoolean casts

2022-09-07 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-08T07:31:07+02:00
New Revision: 95e6a407d92bbb1d977351cc6ee39aa990ed50c5

URL: 
https://github.com/llvm/llvm-project/commit/95e6a407d92bbb1d977351cc6ee39aa990ed50c5
DIFF: 
https://github.com/llvm/llvm-project/commit/95e6a407d92bbb1d977351cc6ee39aa990ed50c5.diff

LOG: [clang][Interp] Implement IntegralToBoolean casts

Redo how we do IntegralCasts and implement IntegralToBoolean casts using
the already existing cast op.

Differential Revision: https://reviews.llvm.org/D132739

Added: 


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

Removed: 




diff  --git a/clang/lib/AST/Interp/Boolean.h b/clang/lib/AST/Interp/Boolean.h
index cc3d4686f8f7..e739ce28e92c 100644
--- a/clang/lib/AST/Interp/Boolean.h
+++ b/clang/lib/AST/Interp/Boolean.h
@@ -50,6 +50,7 @@ class Boolean {
   explicit operator int64_t() const { return V; }
   explicit operator uint64_t() const { return V; }
   explicit operator int() const { return V; }
+  explicit operator bool() const { return V; }
 
   APSInt toAPSInt() const {
 return APSInt(APInt(1, static_cast(V), false), true);
@@ -85,9 +86,10 @@ class Boolean {
   static Boolean min(unsigned NumBits) { return Boolean(false); }
   static Boolean max(unsigned NumBits) { return Boolean(true); }
 
-  template 
-  static std::enable_if_t::value, Boolean> from(T Value) {
-return Boolean(Value != 0);
+  template  static Boolean from(T Value) {
+if constexpr (std::is_integral::value)
+  return Boolean(Value != 0);
+return Boolean(static_cast(Value) != 0);
   }
 
   template 

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 18f3341439ee..d2efad4e082c 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -117,6 +117,7 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr 
*CE) {
   case CK_NullToPointer:
 return this->Visit(SubExpr);
 
+  case CK_IntegralToBoolean:
   case CK_IntegralCast: {
 Optional FromT = classify(SubExpr->getType());
 Optional ToT = classify(CE->getType());
@@ -132,19 +133,6 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
   case CK_ToVoid:
 return discard(SubExpr);
 
-  case CK_IntegralToBoolean:
-// Compare integral from Subexpr with 0
-if (Optional T = classify(SubExpr->getType())) {
-  if (!this->Visit(SubExpr))
-return false;
-
-  if (!this->emitConst(SubExpr, 0))
-return false;
-
-  return this->emitNE(*T, SubExpr);
-}
-return false;
-
   default:
 assert(false && "Cast not implemented");
   }

diff  --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index 8bc072c53d6b..dcb995266c2c 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -425,12 +425,16 @@ def Neg: Opcode {
 
//===--===//
 // TODO: Expand this to handle casts between more types.
 
-def Sint32TypeClass : TypeClass {
-  let Types = [Sint32];
+def FromCastTypeClass : TypeClass {
+  let Types = [Uint32, Sint32, Bool];
+}
+
+def ToCastTypeClass : TypeClass {
+  let Types = [Uint32, Sint32, Bool];
 }
 
 def Cast: Opcode {
-  let Types = [BoolTypeClass, Sint32TypeClass];
+  let Types = [FromCastTypeClass, ToCastTypeClass];
   let HasGroup = 1;
 }
 

diff  --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index 6831091d596b..5c1df00a25e7 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -14,6 +14,37 @@ static_assert(number != 10, ""); // expected-error{{failed}} 
\
  // expected-note{{evaluates to}} \
  // ref-note{{evaluates to}}
 
+constexpr bool b = number;
+static_assert(b, "");
+constexpr int one = true;
+static_assert(one == 1, "");
+
+namespace IntegralCasts {
+  constexpr int i = 12;
+  constexpr unsigned int ui = i;
+  static_assert(ui == 12, "");
+  constexpr unsigned int ub = !false;
+  static_assert(ub == 1, "");
+
+  constexpr int si = ui;
+  static_assert(si == 12, "");
+  constexpr int sb = true;
+  static_assert(sb == 1, "");
+
+  constexpr int zero = 0;
+  constexpr unsigned int uzero = 0;
+  constexpr bool bs = i;
+  static_assert(bs, "");
+  constexpr bool bu = ui;
+  static_assert(bu, "");
+  constexpr bool ns = zero;
+  static_assert(!ns, "");
+  constexpr bool nu = uzero;
+  static_assert(!nu, "");
+};
+
+
+
 constexpr bool getTrue() { return true; }
 constexpr bool getFalse() { return false; }
 constexpr void* getNull() { return nullptr; }



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cf

[clang] 4d700ff - [clang][Interp] Implement ImplicitValueInitExprs

2022-09-07 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-08T07:31:07+02:00
New Revision: 4d700ffe67be03220487604785ee2049570ba6db

URL: 
https://github.com/llvm/llvm-project/commit/4d700ffe67be03220487604785ee2049570ba6db
DIFF: 
https://github.com/llvm/llvm-project/commit/4d700ffe67be03220487604785ee2049570ba6db.diff

LOG: [clang][Interp] Implement ImplicitValueInitExprs

Take the existing Zero opcode and emit it.

Differential Revision: https://reviews.llvm.org/D132829

Added: 
clang/test/AST/Interp/arrays.cpp

Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/lib/AST/Interp/Opcodes.td

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index d2efad4e082c..a6fea951f759 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -223,6 +223,14 @@ bool ByteCodeExprGen::VisitBinaryOperator(const 
BinaryOperator *BO) {
   return this->bail(BO);
 }
 
+template 
+bool ByteCodeExprGen::VisitImplicitValueInitExpr(const 
ImplicitValueInitExpr *E) {
+  if (Optional T = classify(E))
+return this->emitZero(*T, E);
+
+  return false;
+}
+
 template 
 bool ByteCodeExprGen::discard(const Expr *E) {
   OptionScope Scope(this, /*NewDiscardResult=*/true);

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index f603f436f3c7..6793cdffecee 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -75,6 +75,7 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E);
   bool VisitUnaryOperator(const UnaryOperator *E);
   bool VisitDeclRefExpr(const DeclRefExpr *E);
+  bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E);
 
 protected:
   bool visitExpr(const Expr *E) override;

diff  --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index dcb995266c2c..49cc0e0253de 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -203,6 +203,7 @@ def ConstBool : ConstOpcode;
 // [] -> [Integer]
 def Zero : Opcode {
   let Types = [AluTypeClass];
+  let HasGroup = 1;
 }
 
 // [] -> [Pointer]

diff  --git a/clang/test/AST/Interp/arrays.cpp 
b/clang/test/AST/Interp/arrays.cpp
new file mode 100644
index ..74fd1f0fbb3f
--- /dev/null
+++ b/clang/test/AST/Interp/arrays.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s
+// RUN: %clang_cc1 -verify=ref %s
+
+
+/// expected-no-diagnostics
+/// ref-no-diagnostics
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc99-extensions"
+#pragma clang diagnostic ignored "-Winitializer-overrides"
+/// FIXME: The example below tests ImplicitValueInitExprs, but we can't
+///   currently evaluate other parts of it.
+#if 0
+struct fred {
+  char s [6];
+  int n;
+};
+
+struct fred y [] = { [0] = { .s[0] = 'q' } };
+#endif
+#pragma clang diagnostic pop



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 5c4dbff - [clang][Interp] Handle SubstNonTypeTemplateParmExprs

2022-09-07 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-08T07:31:07+02:00
New Revision: 5c4dbff0b6c3943dfbcba930986e23e015df97c5

URL: 
https://github.com/llvm/llvm-project/commit/5c4dbff0b6c3943dfbcba930986e23e015df97c5
DIFF: 
https://github.com/llvm/llvm-project/commit/5c4dbff0b6c3943dfbcba930986e23e015df97c5.diff

LOG: [clang][Interp] Handle SubstNonTypeTemplateParmExprs

Differential Revision: https://reviews.llvm.org/D132831

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/test/AST/Interp/functions.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index a6fea951f759..f9dac9a21978 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -231,6 +231,12 @@ bool 
ByteCodeExprGen::VisitImplicitValueInitExpr(const ImplicitValueIni
   return false;
 }
 
+template 
+bool ByteCodeExprGen::VisitSubstNonTypeTemplateParmExpr(
+const SubstNonTypeTemplateParmExpr *E) {
+  return this->visit(E->getReplacement());
+}
+
 template 
 bool ByteCodeExprGen::discard(const Expr *E) {
   OptionScope Scope(this, /*NewDiscardResult=*/true);

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 6793cdffecee..6132e2b67435 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -76,6 +76,7 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   bool VisitUnaryOperator(const UnaryOperator *E);
   bool VisitDeclRefExpr(const DeclRefExpr *E);
   bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E);
+  bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr 
*E);
 
 protected:
   bool visitExpr(const Expr *E) override;

diff  --git a/clang/test/AST/Interp/functions.cpp 
b/clang/test/AST/Interp/functions.cpp
index a0e0a14a03c9..494133c10cb1 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -65,3 +65,11 @@ constexpr int recursion(int i) {
   return recursion(i);
 }
 static_assert(recursion(10) == 0, "");
+
+template
+constexpr decltype(N) getNum() {
+  return N;
+}
+static_assert(getNum<-2>() == -2, "");
+static_assert(getNum<10>() == 10, "");
+static_assert(getNum() == 5, "");



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] aa7c5c9 - [clang][Interp] Handle missing local initializers better

2022-09-07 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-08T07:31:07+02:00
New Revision: aa7c5c9c4e5e56fc668b055ce40c1a65fae1e38e

URL: 
https://github.com/llvm/llvm-project/commit/aa7c5c9c4e5e56fc668b055ce40c1a65fae1e38e
DIFF: 
https://github.com/llvm/llvm-project/commit/aa7c5c9c4e5e56fc668b055ce40c1a65fae1e38e.diff

LOG: [clang][Interp] Handle missing local initializers better

This is illegal in a constexpr context. We can already figure that out,
but we'd still run into an assertion later on when trying to visit the
missing initializer or run the invalid function.

Differential Revision: https://reviews.llvm.org/D132832

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeEmitter.cpp
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeStmtGen.cpp
clang/lib/AST/Interp/Function.h
clang/test/AST/Interp/cxx20.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp 
b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
index a69b23fd613c..42a3ab7837f9 100644
--- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp
+++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp
@@ -62,8 +62,10 @@ Expected ByteCodeEmitter::compileFunc(const 
FunctionDecl *F) {
 // Return a dummy function if compilation failed.
 if (BailLocation)
   return llvm::make_error(*BailLocation);
-else
+else {
+  Func->setIsFullyCompiled(true);
   return Func;
+}
   } else {
 // Create scopes from descriptors.
 llvm::SmallVector Scopes;
@@ -74,6 +76,7 @@ Expected ByteCodeEmitter::compileFunc(const 
FunctionDecl *F) {
 // Set the function's code.
 Func->setCode(NextLocalOffset, std::move(Code), std::move(SrcMap),
   std::move(Scopes));
+Func->setIsFullyCompiled(true);
 return Func;
   }
 }

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index f9dac9a21978..cf4cbde37975 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -612,6 +612,14 @@ bool ByteCodeExprGen::VisitCallExpr(const 
CallExpr *E) {
 }
 assert(Func);
 
+// If the function is being compiled right now, this is a recursive call.
+// In that case, the function can't be valid yet, even though it will be
+// later.
+// If the function is already fully compiled but not constexpr, it was
+// found to be faulty earlier on, so bail out.
+if (Func->isFullyCompiled() && !Func->isConstexpr())
+  return false;
+
 QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
 Optional T = classify(ReturnType);
 

diff  --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp 
b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
index 90e84149b055..f279267bbe1f 100644
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -241,11 +241,16 @@ bool ByteCodeStmtGen::visitVarDecl(const VarDecl 
*VD) {
 
   // Integers, pointers, primitives.
   if (Optional T = this->classify(DT)) {
+const Expr *Init = VD->getInit();
+
+if (!Init)
+  return false;
+
 auto Off = this->allocateLocalPrimitive(VD, *T, DT.isConstQualified());
-// Compile the initialiser in its own scope.
+// Compile the initializer in its own scope.
 {
   ExprScope Scope(this);
-  if (!this->visit(VD->getInit()))
+  if (!this->visit(Init))
 return false;
 }
 // Set the value.

diff  --git a/clang/lib/AST/Interp/Function.h b/clang/lib/AST/Interp/Function.h
index b009167c1bd6..d52560eaceb2 100644
--- a/clang/lib/AST/Interp/Function.h
+++ b/clang/lib/AST/Interp/Function.h
@@ -112,6 +112,9 @@ class Function {
   /// Checks if the function is a constructor.
   bool isConstructor() const { return isa(F); }
 
+  /// Checks if the function is fully done compiling.
+  bool isFullyCompiled() const { return IsFullyCompiled; }
+
 private:
   /// Construct a function representing an actual function.
   Function(Program &P, const FunctionDecl *F, unsigned ArgSize,
@@ -128,6 +131,8 @@ class Function {
 IsValid = true;
   }
 
+  void setIsFullyCompiled(bool FC) { IsFullyCompiled = FC; }
+
 private:
   friend class Program;
   friend class ByteCodeEmitter;
@@ -154,6 +159,9 @@ class Function {
   llvm::DenseMap Params;
   /// Flag to indicate if the function is valid.
   bool IsValid = false;
+  /// Flag to indicate if the function is done being
+  /// compiled to bytecode.
+  bool IsFullyCompiled = false;
 
 public:
   /// Dumps the disassembled bytecode to \c llvm::errs().

diff  --git a/clang/test/AST/Interp/cxx20.cpp b/clang/test/AST/Interp/cxx20.cpp
index 1e43b472793a..e088f6bafb7e 100644
--- a/clang/test/AST/Interp/cxx20.cpp
+++ b/clang/test/AST/Interp/cxx20.cpp
@@ -2,8 +2,6 @@
 // RUN: %clang_cc1 -std=c++20 -verify=ref %s
 
 
-// expected-no-diagnostics
-// ref-no-diagnostics
 constexpr int getMinus5() {
   int a = 10;
   a = -5;
@@ -53,3 +51,12 @@ constexpr int p

[clang] 3a7d476 - [clang][Interp] Implement array initializers and subscript expressions

2022-09-07 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-08T07:31:07+02:00
New Revision: 3a7d476087df175b6fe056e7c20ac9707019e92b

URL: 
https://github.com/llvm/llvm-project/commit/3a7d476087df175b6fe056e7c20ac9707019e92b
DIFF: 
https://github.com/llvm/llvm-project/commit/3a7d476087df175b6fe056e7c20ac9707019e92b.diff

LOG: [clang][Interp] Implement array initializers and subscript expressions

Differential Revision: https://reviews.llvm.org/D132727

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/lib/AST/Interp/ByteCodeStmtGen.cpp
clang/lib/AST/Interp/Interp.h
clang/lib/AST/Interp/Pointer.cpp
clang/lib/AST/Interp/Program.cpp
clang/test/AST/Interp/arrays.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index cf4cbde37975..790f58f67e68 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -231,12 +231,55 @@ bool 
ByteCodeExprGen::VisitImplicitValueInitExpr(const ImplicitValueIni
   return false;
 }
 
+template 
+bool ByteCodeExprGen::VisitArraySubscriptExpr(
+const ArraySubscriptExpr *E) {
+  const Expr *Base = E->getBase();
+  const Expr *Index = E->getIdx();
+
+  // Take pointer of LHS, add offset from RHS, narrow result.
+  // What's left on the stack after this is a pointer.
+  if (Optional IndexT = classify(Index->getType())) {
+if (!this->Visit(Base))
+  return false;
+
+if (!this->Visit(Index))
+  return false;
+
+if (!this->emitAddOffset(*IndexT, E))
+  return false;
+
+if (!this->emitNarrowPtr(E))
+  return false;
+
+return true;
+  }
+
+  return false;
+}
+
+template 
+bool ByteCodeExprGen::VisitInitListExpr(const InitListExpr *E) {
+  for (const Expr *Init : E->inits()) {
+if (!this->visit(Init))
+  return false;
+  }
+  return true;
+}
+
 template 
 bool ByteCodeExprGen::VisitSubstNonTypeTemplateParmExpr(
 const SubstNonTypeTemplateParmExpr *E) {
   return this->visit(E->getReplacement());
 }
 
+template 
+bool ByteCodeExprGen::VisitConstantExpr(const ConstantExpr *E) {
+  // TODO: Check if the ConstantExpr already has a value set and if so,
+  //   use that instead of evaluating it again.
+  return this->visit(E->getSubExpr());
+}
+
 template 
 bool ByteCodeExprGen::discard(const Expr *E) {
   OptionScope Scope(this, /*NewDiscardResult=*/true);
@@ -492,11 +535,62 @@ ByteCodeExprGen::allocateLocal(DeclTy &&Src, 
bool IsExtended) {
   return Local.Offset;
 }
 
+// NB: When calling this function, we have a pointer to the
+//   array-to-initialize on the stack.
 template 
-bool ByteCodeExprGen::visitInitializer(
-const Expr *Init, InitFnRef InitFn) {
-  OptionScope Scope(this, InitFn);
-  return this->Visit(Init);
+bool ByteCodeExprGen::visitArrayInitializer(const Expr *Initializer) {
+  assert(Initializer->getType()->isArrayType());
+
+  // TODO: Fillers?
+  if (const auto *InitList = dyn_cast(Initializer)) {
+unsigned ElementIndex = 0;
+for (const Expr *Init : InitList->inits()) {
+  QualType InitType = Init->getType();
+
+  if (InitType->isArrayType()) {
+// Advance the pointer currently on the stack to the given
+// dimension and narrow().
+if (!this->emitDupPtr(Init))
+  return false;
+if (!this->emitConstUint32(ElementIndex, Init))
+  return false;
+if (!this->emitAddOffsetUint32(Init))
+  return false;
+if (!this->emitNarrowPtr(Init))
+  return false;
+if (!visitArrayInitializer(Init))
+  return false;
+if (!this->emitPopPtr(Init))
+  return false;
+  } else if (Optional T = classify(InitType)) {
+// Visit the primitive element like normal.
+if (!this->visit(Init))
+  return false;
+if (!this->emitInitElem(*T, ElementIndex, Init))
+  return false;
+  } else {
+assert(false && "Unhandled type in array initializer initlist");
+  }
+
+  ++ElementIndex;
+}
+
+  } else {
+assert(false && "Unknown expression for array initialization");
+  }
+
+  return true;
+}
+
+template 
+bool ByteCodeExprGen::visitInitializer(const Expr *Initializer) {
+  QualType InitializerType = Initializer->getType();
+
+  if (InitializerType->isArrayType())
+return visitArrayInitializer(Initializer);
+
+  // Otherwise, visit the expression like normal.
+  return this->Visit(Initializer);
 }
 
 template 

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 6132e2b67435..6a74bc371855 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -64,7 +64,7 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   ByteCodeExprGen(Context &Ctx, Program &P, Tys &&... Args)
   : Emitter(Ctx, P, Args...), Ctx(Ctx),

[clang] 0da7e40 - [clang][Interp][NFC] Context::classify() can be const

2022-09-07 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-08T07:31:08+02:00
New Revision: 0da7e409e0cb09ea955d9751d2601449244cc53f

URL: 
https://github.com/llvm/llvm-project/commit/0da7e409e0cb09ea955d9751d2601449244cc53f
DIFF: 
https://github.com/llvm/llvm-project/commit/0da7e409e0cb09ea955d9751d2601449244cc53f.diff

LOG: [clang][Interp][NFC] Context::classify() can be const

Added: 


Modified: 
clang/lib/AST/Interp/Context.cpp
clang/lib/AST/Interp/Context.h

Removed: 




diff  --git a/clang/lib/AST/Interp/Context.cpp 
b/clang/lib/AST/Interp/Context.cpp
index 3bfcdfcd4c58..9f3f5542fe83 100644
--- a/clang/lib/AST/Interp/Context.cpp
+++ b/clang/lib/AST/Interp/Context.cpp
@@ -59,7 +59,7 @@ bool Context::evaluateAsInitializer(State &Parent, const 
VarDecl *VD,
 
 const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); }
 
-llvm::Optional Context::classify(QualType T) {
+llvm::Optional Context::classify(QualType T) const {
   if (T->isReferenceType() || T->isPointerType()) {
 return PT_Ptr;
   }

diff  --git a/clang/lib/AST/Interp/Context.h b/clang/lib/AST/Interp/Context.h
index 0627d9fb14f5..fbd781026850 100644
--- a/clang/lib/AST/Interp/Context.h
+++ b/clang/lib/AST/Interp/Context.h
@@ -60,7 +60,7 @@ class Context {
   unsigned getCharBit() const;
 
   /// Classifies an expression.
-  llvm::Optional classify(QualType T);
+  llvm::Optional classify(QualType T) const;
 
 private:
   /// Runs a function.



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 651f4ce - [clang][Interp][NFC] Use constexpr if when possible in Integral.h

2022-09-07 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-08T07:31:08+02:00
New Revision: 651f4ce7b186079e78de20d7de903112ea78d846

URL: 
https://github.com/llvm/llvm-project/commit/651f4ce7b186079e78de20d7de903112ea78d846
DIFF: 
https://github.com/llvm/llvm-project/commit/651f4ce7b186079e78de20d7de903112ea78d846.diff

LOG: [clang][Interp][NFC] Use constexpr if when possible in Integral.h

Added: 


Modified: 
clang/lib/AST/Interp/Integral.h

Removed: 




diff  --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h
index dc17df44282a..d2498fda6181 100644
--- a/clang/lib/AST/Interp/Integral.h
+++ b/clang/lib/AST/Interp/Integral.h
@@ -107,7 +107,7 @@ template  class Integral {
 return APSInt(APInt(Bits, static_cast(V), Signed), !Signed);
   }
   APSInt toAPSInt(unsigned NumBits) const {
-if (Signed)
+if constexpr (Signed)
   return APSInt(toAPSInt().sextOrTrunc(NumBits), !Signed);
 else
   return APSInt(toAPSInt().zextOrTrunc(NumBits), !Signed);
@@ -171,7 +171,7 @@ template  class Integral {
   }
 
   template  static Integral from(Integral<0, SrcSign> Value) {
-if (SrcSign)
+if constexpr (SrcSign)
   return Integral(Value.V.getSExtValue());
 else
   return Integral(Value.V.getZExtValue());



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 8627179 - [clang][Interp] Only initialize initmaps for primitive arrays

2022-09-08 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-08T10:03:06+02:00
New Revision: 86271798e51a7866dd2af44e0ee183d1331089e6

URL: 
https://github.com/llvm/llvm-project/commit/86271798e51a7866dd2af44e0ee183d1331089e6
DIFF: 
https://github.com/llvm/llvm-project/commit/86271798e51a7866dd2af44e0ee183d1331089e6.diff

LOG: [clang][Interp] Only initialize initmaps for primitive arrays

As the comment states, this code should only run for primitive arrays.

This should fix the memory sanitize builds.

Added: 


Modified: 
clang/lib/AST/Interp/Pointer.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/Pointer.cpp 
b/clang/lib/AST/Interp/Pointer.cpp
index cb687377e97b..1dfb8f4b18eb 100644
--- a/clang/lib/AST/Interp/Pointer.cpp
+++ b/clang/lib/AST/Interp/Pointer.cpp
@@ -156,7 +156,7 @@ void Pointer::initialize() const {
   Descriptor *Desc = getFieldDesc();
 
   if (Desc->isArray()) {
-if (!Pointee->IsStatic) {
+if (Desc->isPrimitiveArray() && !Pointee->IsStatic) {
   // Primitive array initializer.
   InitMap *&Map = getInitMap();
   if (Map == (InitMap *)-1)



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] bf3efa8 - [clang][Interp] Handle DeclRefExpr of reference types

2022-09-13 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-13T10:40:51+02:00
New Revision: bf3efa8b1622080b29b2dc4ba57bdccd0ca1e889

URL: 
https://github.com/llvm/llvm-project/commit/bf3efa8b1622080b29b2dc4ba57bdccd0ca1e889
DIFF: 
https://github.com/llvm/llvm-project/commit/bf3efa8b1622080b29b2dc4ba57bdccd0ca1e889.diff

LOG: [clang][Interp] Handle DeclRefExpr of reference types

References are implemented through pointers, so we need a second deref
when encountering a DeclRefExpr of a reference type.

Differential Revision: https://reviews.llvm.org/D132997

Added: 
clang/test/AST/Interp/references.cpp

Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/AST/Interp/arrays.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 790f58f67e68..0abd3ff73674 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -814,15 +814,38 @@ bool ByteCodeExprGen::VisitUnaryOperator(const 
UnaryOperator *E) {
 template 
 bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) {
   const auto *Decl = E->getDecl();
+  bool IsReference = Decl->getType()->isReferenceType();
+  bool FoundDecl = false;
 
   if (auto It = Locals.find(Decl); It != Locals.end()) {
 const unsigned Offset = It->second.Offset;
-return this->emitGetPtrLocal(Offset, E);
+if (!this->emitGetPtrLocal(Offset, E))
+  return false;
+
+FoundDecl = true;
   } else if (auto GlobalIndex = P.getGlobal(Decl)) {
-return this->emitGetPtrGlobal(*GlobalIndex, E);
+if (!this->emitGetPtrGlobal(*GlobalIndex, E))
+  return false;
+
+FoundDecl = true;
   } else if (const auto *PVD = dyn_cast(Decl)) {
-if (auto It = this->Params.find(PVD); It != this->Params.end())
-  return this->emitGetPtrParam(It->second, E);
+if (auto It = this->Params.find(PVD); It != this->Params.end()) {
+  if (!this->emitGetPtrParam(It->second, E))
+return false;
+
+  FoundDecl = true;
+}
+  }
+
+  // References are implemented using pointers, so when we get here,
+  // we have a pointer to a pointer, which we need to de-reference once.
+  if (FoundDecl) {
+if (IsReference) {
+  if (!this->emitLoadPopPtr(E))
+return false;
+}
+
+return true;
   }
 
   return false;

diff  --git a/clang/test/AST/Interp/arrays.cpp 
b/clang/test/AST/Interp/arrays.cpp
index 88bb0a8eadb5..302c8b2a86cc 100644
--- a/clang/test/AST/Interp/arrays.cpp
+++ b/clang/test/AST/Interp/arrays.cpp
@@ -45,6 +45,13 @@ constexpr T getElementOf(T* array, int i) {
 static_assert(getElementOf(foo[0], 1) == &m, "");
 
 
+template 
+constexpr T& getElementOfArray(T (&array)[N], int I) {
+  return array[I];
+}
+static_assert(getElementOfArray(foo[2], 3) == &m, "");
+
+
 constexpr int data[] = {5, 4, 3, 2, 1};
 static_assert(data[0] == 4, ""); // expected-error{{failed}} \
  // expected-note{{5 == 4}} \

diff  --git a/clang/test/AST/Interp/references.cpp 
b/clang/test/AST/Interp/references.cpp
new file mode 100644
index ..61d4d91e4224
--- /dev/null
+++ b/clang/test/AST/Interp/references.cpp
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s
+// RUN: %clang_cc1 -verify=ref %s
+
+
+// ref-no-diagnostics
+
+constexpr int a = 10;
+constexpr const int &b = a;
+static_assert(a == b, "");
+
+constexpr int assignToReference() {
+  int a = 20;
+  int &b = a;
+
+  b = 100;
+  return a;
+}
+static_assert(assignToReference() == 100, "");
+
+
+constexpr void setValue(int &dest, int val) {
+  dest = val;
+}
+
+constexpr int checkSetValue() {
+  int l = 100;
+  setValue(l, 200);
+  return l;
+}
+static_assert(checkSetValue() == 200, "");
+
+constexpr int readLocalRef() {
+  int a = 20;
+  int &b = a;
+  return b;
+}
+static_assert(readLocalRef() == 20, "");
+
+constexpr int incRef() {
+  int a = 0;
+  int &b = a;
+
+  b = b + 1;
+
+  return a;
+}
+static_assert(incRef() == 1, "");
+
+
+template
+constexpr void Plus3(int &A) {
+  A = V + 3;
+}
+constexpr int foo = 4;
+
+constexpr int callTemplate() {
+  int a = 3;
+  Plus3(a);
+  return a;
+}
+static_assert(callTemplate() == 7, "");
+
+
+constexpr int& getValue(int *array, int index) {
+  return array[index];
+}
+constexpr int testGetValue() {
+  int values[] = {1, 2, 3, 4};
+  getValue(values, 2) = 30;
+  return values[2];
+}
+static_assert(testGetValue() == 30, "");
+
+// FIXME: ExprWithCleanups + MaterializeTemporaryExpr not implemented
+constexpr const int &MCE = 1; // expected-error{{must be initialized by a 
constant expression}}
+
+
+struct S {
+  int i, j;
+};
+
+constexpr int RefToMemberExpr() {
+  S s{1, 2};
+
+  int &j = s.i;
+  j += 10;
+
+  return j;
+}
+// FIXME: Should be accepted.
+static_assert(RefToMemberExpr() == 11, ""); // expected-error{{not an integral 
constant expression}}



_

[clang] 9b087a7 - [clang][Interp][NFC] Forward-declare Pointer in PrimType header

2022-09-13 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-13T10:40:52+02:00
New Revision: 9b087a70e66c785f64279634c536a848e78261ea

URL: 
https://github.com/llvm/llvm-project/commit/9b087a70e66c785f64279634c536a848e78261ea
DIFF: 
https://github.com/llvm/llvm-project/commit/9b087a70e66c785f64279634c536a848e78261ea.diff

LOG: [clang][Interp][NFC] Forward-declare Pointer in PrimType header

No need to include the full Pointer.h here.

Added: 


Modified: 
clang/lib/AST/Interp/PrimType.cpp
clang/lib/AST/Interp/PrimType.h

Removed: 




diff  --git a/clang/lib/AST/Interp/PrimType.cpp 
b/clang/lib/AST/Interp/PrimType.cpp
index 082bfaf3c207..bd0f73df2ead 100644
--- a/clang/lib/AST/Interp/PrimType.cpp
+++ b/clang/lib/AST/Interp/PrimType.cpp
@@ -7,6 +7,7 @@
 
//===--===//
 
 #include "PrimType.h"
+#include "Pointer.h"
 
 using namespace clang;
 using namespace clang::interp;

diff  --git a/clang/lib/AST/Interp/PrimType.h b/clang/lib/AST/Interp/PrimType.h
index de4bf9bf802e..8490c1f6548a 100644
--- a/clang/lib/AST/Interp/PrimType.h
+++ b/clang/lib/AST/Interp/PrimType.h
@@ -18,11 +18,12 @@
 #include 
 #include "Boolean.h"
 #include "Integral.h"
-#include "Pointer.h"
 
 namespace clang {
 namespace interp {
 
+class Pointer;
+
 /// Enumeration of the primitive types of the VM.
 enum PrimType : unsigned {
   PT_Sint8,



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] f756ddb - [clang][Interp][NFC] InterpFrame: localBlock() can be const

2022-09-13 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-13T10:41:18+02:00
New Revision: f756ddba17c9f0f0ee49b45dd4b15b487aff9b67

URL: 
https://github.com/llvm/llvm-project/commit/f756ddba17c9f0f0ee49b45dd4b15b487aff9b67
DIFF: 
https://github.com/llvm/llvm-project/commit/f756ddba17c9f0f0ee49b45dd4b15b487aff9b67.diff

LOG: [clang][Interp][NFC] InterpFrame: localBlock() can be const

Added: 


Modified: 
clang/lib/AST/Interp/InterpFrame.h

Removed: 




diff  --git a/clang/lib/AST/Interp/InterpFrame.h 
b/clang/lib/AST/Interp/InterpFrame.h
index 3769c9a5f5f1..ca9803d48dd1 100644
--- a/clang/lib/AST/Interp/InterpFrame.h
+++ b/clang/lib/AST/Interp/InterpFrame.h
@@ -123,7 +123,7 @@ class InterpFrame final : public Frame {
   }
 
   /// Returns a pointer to a local's block.
-  void *localBlock(unsigned Offset) {
+  void *localBlock(unsigned Offset) const {
 return Locals.get() + Offset - sizeof(Block);
   }
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 5d24514 - [clang][Interp][NFC] InterpFrame::getLocal() can be const

2022-09-13 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-13T10:41:24+02:00
New Revision: 5d2451468c5f105bd7837f57c5e385fbbbdb65a4

URL: 
https://github.com/llvm/llvm-project/commit/5d2451468c5f105bd7837f57c5e385fbbbdb65a4
DIFF: 
https://github.com/llvm/llvm-project/commit/5d2451468c5f105bd7837f57c5e385fbbbdb65a4.diff

LOG: [clang][Interp][NFC] InterpFrame::getLocal() can be const

Make localRef() const and use that.

Added: 


Modified: 
clang/lib/AST/Interp/InterpFrame.h

Removed: 




diff  --git a/clang/lib/AST/Interp/InterpFrame.h 
b/clang/lib/AST/Interp/InterpFrame.h
index ca9803d48dd1..88b4a5af8e5a 100644
--- a/clang/lib/AST/Interp/InterpFrame.h
+++ b/clang/lib/AST/Interp/InterpFrame.h
@@ -63,7 +63,7 @@ class InterpFrame final : public Frame {
   size_t getFrameOffset() const { return FrameOffset; }
 
   /// Returns the value of a local variable.
-  template  const T &getLocal(unsigned Offset) {
+  template  const T &getLocal(unsigned Offset) const {
 return localRef(Offset);
   }
 
@@ -118,7 +118,7 @@ class InterpFrame final : public Frame {
   }
 
   /// Returns an offset to a local.
-  template  T &localRef(unsigned Offset) {
+  template  T &localRef(unsigned Offset) const {
 return *reinterpret_cast(Locals.get() + Offset);
   }
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 53d8687 - [clang][Interp][NFC] Use constexpr if in OffsetHelper

2022-09-13 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-13T10:41:34+02:00
New Revision: 53d8687a13e76b5a387e8df59ae231ab53ab9279

URL: 
https://github.com/llvm/llvm-project/commit/53d8687a13e76b5a387e8df59ae231ab53ab9279
DIFF: 
https://github.com/llvm/llvm-project/commit/53d8687a13e76b5a387e8df59ae231ab53ab9279.diff

LOG: [clang][Interp][NFC] Use constexpr if in OffsetHelper

Add is a template parameter, so we can use constexpr if here.

Added: 


Modified: 
clang/lib/AST/Interp/Interp.h

Removed: 




diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 0a5c8dc847c3..5c96cd8d2340 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -788,18 +788,24 @@ template  bool 
OffsetHelper(InterpState &S, CodePtr OpPC) {
 return false;
   };
 
-  // If the new offset would be negative, bail out.
-  if (Add && Offset.isNegative() && (Offset.isMin() || -Offset > Index))
-return InvalidOffset();
-  if (!Add && Offset.isPositive() && Index < Offset)
-return InvalidOffset();
-
-  // If the new offset would be out of bounds, bail out.
   unsigned MaxOffset = MaxIndex - Ptr.getIndex();
-  if (Add && Offset.isPositive() && Offset > MaxOffset)
-return InvalidOffset();
-  if (!Add && Offset.isNegative() && (Offset.isMin() || -Offset > MaxOffset))
-return InvalidOffset();
+  if constexpr (Add) {
+// If the new offset would be negative, bail out.
+if (Offset.isNegative() && (Offset.isMin() || -Offset > Index))
+  return InvalidOffset();
+
+// If the new offset would be out of bounds, bail out.
+if (Offset.isPositive() && Offset > MaxOffset)
+  return InvalidOffset();
+  } else {
+// If the new offset would be negative, bail out.
+if (Offset.isPositive() && Index < Offset)
+  return InvalidOffset();
+
+// If the new offset would be out of bounds, bail out.
+if (Offset.isNegative() && (Offset.isMin() || -Offset > MaxOffset))
+  return InvalidOffset();
+  }
 
   // Offset is valid - compute it on unsigned.
   int64_t WideIndex = static_cast(Index);



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] b02f689 - [clang][Interp][NFC] InterpFrame::getParam can be const

2022-09-13 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-13T10:41:28+02:00
New Revision: b02f6890f52a48de6fc3a1d977a6ae50bc8fa984

URL: 
https://github.com/llvm/llvm-project/commit/b02f6890f52a48de6fc3a1d977a6ae50bc8fa984
DIFF: 
https://github.com/llvm/llvm-project/commit/b02f6890f52a48de6fc3a1d977a6ae50bc8fa984.diff

LOG: [clang][Interp][NFC] InterpFrame::getParam can be const

Make stackRef() const as well and use that.

Added: 


Modified: 
clang/lib/AST/Interp/InterpFrame.h

Removed: 




diff  --git a/clang/lib/AST/Interp/InterpFrame.h 
b/clang/lib/AST/Interp/InterpFrame.h
index 88b4a5af8e5a..16d073c8c3a0 100644
--- a/clang/lib/AST/Interp/InterpFrame.h
+++ b/clang/lib/AST/Interp/InterpFrame.h
@@ -76,7 +76,7 @@ class InterpFrame final : public Frame {
   Pointer getLocalPointer(unsigned Offset);
 
   /// Returns the value of an argument.
-  template  const T &getParam(unsigned Offset) {
+  template  const T &getParam(unsigned Offset) const {
 auto Pt = Params.find(Offset);
 if (Pt == Params.end()) {
   return stackRef(Offset);
@@ -112,7 +112,7 @@ class InterpFrame final : public Frame {
 
 private:
   /// Returns an original argument from the stack.
-  template  const T &stackRef(unsigned Offset) {
+  template  const T &stackRef(unsigned Offset) const {
 assert(Args);
 return *reinterpret_cast(Args - ArgSize + Offset);
   }



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] a884364 - [clang][Interp] Remove struct from a testcase

2022-09-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-09-14T09:44:01+02:00
New Revision: a8843643cd75d0e93ebcf3f30b470d2b8e59868d

URL: 
https://github.com/llvm/llvm-project/commit/a8843643cd75d0e93ebcf3f30b470d2b8e59868d
DIFF: 
https://github.com/llvm/llvm-project/commit/a8843643cd75d0e93ebcf3f30b470d2b8e59868d.diff

LOG: [clang][Interp] Remove struct from a testcase

This should fix the leak sanitizer breakage introduced by
https://reviews.llvm.org/D132997, e.g.
https://lab.llvm.org/buildbot/#/builders/5/builds/27410

Added: 


Modified: 
clang/test/AST/Interp/references.cpp

Removed: 




diff  --git a/clang/test/AST/Interp/references.cpp 
b/clang/test/AST/Interp/references.cpp
index 61d4d91e42245..2b5187ca29dd9 100644
--- a/clang/test/AST/Interp/references.cpp
+++ b/clang/test/AST/Interp/references.cpp
@@ -75,6 +75,7 @@ static_assert(testGetValue() == 30, "");
 constexpr const int &MCE = 1; // expected-error{{must be initialized by a 
constant expression}}
 
 
+#if 0
 struct S {
   int i, j;
 };
@@ -88,4 +89,5 @@ constexpr int RefToMemberExpr() {
   return j;
 }
 // FIXME: Should be accepted.
-static_assert(RefToMemberExpr() == 11, ""); // expected-error{{not an integral 
constant expression}}
+static_assert(RefToMemberExpr() == 11, "");
+#endif



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] c468e89 - [clang][Interp][NFC] Fix right shifting signed IntegralAP values

2023-11-08 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-11-08T09:33:37+01:00
New Revision: c468e8923cadfa4c181eaa8bdbcf8d95feb70132

URL: 
https://github.com/llvm/llvm-project/commit/c468e8923cadfa4c181eaa8bdbcf8d95feb70132
DIFF: 
https://github.com/llvm/llvm-project/commit/c468e8923cadfa4c181eaa8bdbcf8d95feb70132.diff

LOG: [clang][Interp][NFC] Fix right shifting signed IntegralAP values

Added: 


Modified: 
clang/lib/AST/Interp/IntegralAP.h

Removed: 




diff  --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index 1f535d420bcd54b..6d301bad784af47 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -248,7 +248,11 @@ template  class IntegralAP final {
 
   static void shiftRight(const IntegralAP A, const IntegralAP B,
  unsigned OpBits, IntegralAP *R) {
-*R = IntegralAP(A.V.ashr(B.V.getZExtValue()));
+unsigned ShiftAmount = B.V.getZExtValue();
+if constexpr (Signed)
+  *R = IntegralAP(A.V.ashr(ShiftAmount));
+else
+  *R = IntegralAP(A.V.lshr(ShiftAmount));
   }
 
 private:



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 7b1a058 - [clang][Interp][NFC] Use direct Get{Local,Global} when possible

2023-11-10 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-11-10T11:30:38+01:00
New Revision: 7b1a0580216796045b880251e031a1e5e0ecad74

URL: 
https://github.com/llvm/llvm-project/commit/7b1a0580216796045b880251e031a1e5e0ecad74
DIFF: 
https://github.com/llvm/llvm-project/commit/7b1a0580216796045b880251e031a1e5e0ecad74.diff

LOG: [clang][Interp][NFC] Use direct Get{Local,Global} when possible

When returning variable declaration values, try to get the value
directly instead of always going through a Pointer.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index a2cf682b2532bde..15a717089660337 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2119,27 +2119,33 @@ bool ByteCodeExprGen::visitDecl(const VarDecl 
*VD) {
   if (!this->visitVarDecl(VD))
 return false;
 
+  std::optional VarT = classify(VD->getType());
   // Get a pointer to the variable
   if (Context::shouldBeGloballyIndexed(VD)) {
 auto GlobalIndex = P.getGlobal(VD);
 assert(GlobalIndex); // visitVarDecl() didn't return false.
-if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
-  return false;
+if (VarT) {
+  if (!this->emitGetGlobal(*VarT, *GlobalIndex, VD))
+return false;
+} else {
+  if (!this->emitGetPtrGlobal(*GlobalIndex, VD))
+return false;
+}
   } else {
 auto Local = Locals.find(VD);
 assert(Local != Locals.end()); // Same here.
-if (!this->emitGetPtrLocal(Local->second.Offset, VD))
-  return false;
+if (VarT) {
+  if (!this->emitGetLocal(*VarT, Local->second.Offset, VD))
+return false;
+} else {
+  if (!this->emitGetPtrLocal(Local->second.Offset, VD))
+return false;
+}
   }
 
   // Return the value
-  if (std::optional VarT = classify(VD->getType())) {
-if (!this->emitLoadPop(*VarT, VD))
-  return false;
-
+  if (VarT)
 return this->emitRet(*VarT, VD);
-  }
-
   return this->emitRetValue(VD);
 }
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 8ff81de - [clang][Interp][NFC] Remove some redundant code

2023-11-11 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-11-12T06:37:51+01:00
New Revision: 8ff81deeaa71ec5792c480c9b962f7c48753e0a6

URL: 
https://github.com/llvm/llvm-project/commit/8ff81deeaa71ec5792c480c9b962f7c48753e0a6
DIFF: 
https://github.com/llvm/llvm-project/commit/8ff81deeaa71ec5792c480c9b962f7c48753e0a6.diff

LOG: [clang][Interp][NFC] Remove some redundant code

The needsRuntimeArgPop() stuff is now handled by the
cleanupAfterFunctionCall() function.

Added: 


Modified: 
clang/lib/AST/Interp/Function.cpp
clang/lib/AST/Interp/Function.h
clang/lib/AST/Interp/Interp.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/Function.cpp 
b/clang/lib/AST/Interp/Function.cpp
index 357aff7fe6229b9..69ab1e57b633018 100644
--- a/clang/lib/AST/Interp/Function.cpp
+++ b/clang/lib/AST/Interp/Function.cpp
@@ -48,9 +48,3 @@ bool Function::isVirtual() const {
 return M->isVirtual();
   return false;
 }
-
-bool Function::needsRuntimeArgPop(const ASTContext &Ctx) const {
-  if (!isBuiltin())
-return false;
-  return Ctx.BuiltinInfo.hasCustomTypechecking(getBuiltinID());
-}

diff  --git a/clang/lib/AST/Interp/Function.h b/clang/lib/AST/Interp/Function.h
index be9b1733635f725..94eb2a611771b0c 100644
--- a/clang/lib/AST/Interp/Function.h
+++ b/clang/lib/AST/Interp/Function.h
@@ -179,10 +179,6 @@ class Function final {
 
   bool isBuiltin() const { return F->getBuiltinID() != 0; }
 
-  /// Does this function need its arguments to be classified at runtime
-  /// rather than at bytecode-compile-time?
-  bool needsRuntimeArgPop(const ASTContext &Ctx) const;
-
   unsigned getNumParams() const { return ParamTypes.size(); }
 
   unsigned getParamOffset(unsigned ParamIndex) const {

diff  --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index 144b674451e353c..5fe9cf80fc94709 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -131,20 +131,6 @@ void cleanupAfterFunctionCall(InterpState &S, CodePtr 
OpPC) {
   const Function *CurFunc = S.Current->getFunction();
   assert(CurFunc);
 
-  // Certain builtin functions are declared as func-name(...), so the
-  // parameters are checked in Sema and only available through the CallExpr.
-  // The interp::Function we create for them has 0 parameters, so we need to
-  // remove them from the stack by checking the CallExpr.
-  // FIXME: This is potentially just a special case and could be handled more
-  // generally with the code just below?
-  if (CurFunc->needsRuntimeArgPop(S.getCtx())) {
-const auto *CE = cast(S.Current->getExpr(OpPC));
-for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
-  popArg(S, CE->getArg(I));
-}
-return;
-  }
-
   if (S.Current->Caller && CurFunc->isVariadic()) {
 // CallExpr we're look for is at the return PC of the current function, 
i.e.
 // in the caller.



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 9406d2a - [clang][Interp][NFC] Remove unused include

2023-12-07 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-07T15:20:22+01:00
New Revision: 9406d2a345e827146b7bf369542d8778982bfc6c

URL: 
https://github.com/llvm/llvm-project/commit/9406d2a345e827146b7bf369542d8778982bfc6c
DIFF: 
https://github.com/llvm/llvm-project/commit/9406d2a345e827146b7bf369542d8778982bfc6c.diff

LOG: [clang][Interp][NFC] Remove unused include

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index f45e8624a7741..f7f8e6c73d84e 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -15,7 +15,6 @@
 #include "Function.h"
 #include "PrimType.h"
 #include "Program.h"
-#include "State.h"
 
 using namespace clang;
 using namespace clang::interp;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 32ec462 - [clang][Interp][NFC] Handle body-less functions like implicit ones

2023-12-11 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-11T16:48:21+01:00
New Revision: 32ec462519accb92176fe87b1fc7566b02187e4b

URL: 
https://github.com/llvm/llvm-project/commit/32ec462519accb92176fe87b1fc7566b02187e4b
DIFF: 
https://github.com/llvm/llvm-project/commit/32ec462519accb92176fe87b1fc7566b02187e4b.diff

LOG: [clang][Interp][NFC] Handle body-less functions like implicit ones

They don't have any source to look up locations in.

Added: 


Modified: 
clang/lib/AST/Interp/InterpFrame.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/InterpFrame.cpp 
b/clang/lib/AST/Interp/InterpFrame.cpp
index b06923114c7a24..d460d7ea3710a8 100644
--- a/clang/lib/AST/Interp/InterpFrame.cpp
+++ b/clang/lib/AST/Interp/InterpFrame.cpp
@@ -228,7 +228,7 @@ Pointer InterpFrame::getParamPointer(unsigned Off) {
 SourceInfo InterpFrame::getSource(CodePtr PC) const {
   // Implicitly created functions don't have any code we could point at,
   // so return the call site.
-  if (Func && Func->getDecl()->isImplicit() && Caller)
+  if (Func && (!Func->hasBody() || Func->getDecl()->isImplicit()) && Caller)
 return Caller->getSource(RetPC);
 
   return S.getSource(Func, PC);
@@ -243,7 +243,7 @@ SourceLocation InterpFrame::getLocation(CodePtr PC) const {
 }
 
 SourceRange InterpFrame::getRange(CodePtr PC) const {
-  if (Func && Func->getDecl()->isImplicit() && Caller)
+  if (Func && (!Func->hasBody() || Func->getDecl()->isImplicit()) && Caller)
 return Caller->getRange(RetPC);
 
   return S.getRange(Func, PC);



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 5480be1 - [clang][NFC] Refactor Sema::DiagnoseSentinelCalls

2023-11-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-11-15T08:37:01+01:00
New Revision: 5480be13d5bff9df8d306cd948ff975ed577c054

URL: 
https://github.com/llvm/llvm-project/commit/5480be13d5bff9df8d306cd948ff975ed577c054
DIFF: 
https://github.com/llvm/llvm-project/commit/5480be13d5bff9df8d306cd948ff975ed577c054.diff

LOG: [clang][NFC] Refactor Sema::DiagnoseSentinelCalls

Fix indentation, naming and capitalization to match current style
guides.

Added: 


Modified: 
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaExpr.cpp

Removed: 




diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 38377f01a10086f..a35a3c2c26c22ad 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5452,7 +5452,7 @@ class Sema final {
   bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
 ObjCMethodDecl *Getter,
 SourceLocation Loc);
-  void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
+  void DiagnoseSentinelCalls(const NamedDecl *D, SourceLocation Loc,
  ArrayRef Args);
 
   void PushExpressionEvaluationContext(

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5b0c4439fd1710c..fc39d6149c1cc65 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -414,80 +414,83 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, 
ArrayRef Locs,
 /// message-send is to a declaration with the sentinel attribute, and
 /// if so, it checks that the requirements of the sentinel are
 /// satisfied.
-void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
+void Sema::DiagnoseSentinelCalls(const NamedDecl *D, SourceLocation Loc,
  ArrayRef Args) {
-  const SentinelAttr *attr = D->getAttr();
-  if (!attr)
+  const SentinelAttr *Attr = D->getAttr();
+  if (!Attr)
 return;
 
   // The number of formal parameters of the declaration.
-  unsigned numFormalParams;
+  unsigned NumFormalParams;
 
   // The kind of declaration.  This is also an index into a %select in
   // the diagnostic.
-  enum CalleeType { CT_Function, CT_Method, CT_Block } calleeType;
-
-  if (ObjCMethodDecl *MD = dyn_cast(D)) {
-numFormalParams = MD->param_size();
-calleeType = CT_Method;
-  } else if (FunctionDecl *FD = dyn_cast(D)) {
-numFormalParams = FD->param_size();
-calleeType = CT_Function;
-  } else if (isa(D)) {
-QualType type = cast(D)->getType();
-const FunctionType *fn = nullptr;
-if (const PointerType *ptr = type->getAs()) {
-  fn = ptr->getPointeeType()->getAs();
-  if (!fn) return;
-  calleeType = CT_Function;
-} else if (const BlockPointerType *ptr = type->getAs()) {
-  fn = ptr->getPointeeType()->castAs();
-  calleeType = CT_Block;
+  enum { CK_Function, CK_Method, CK_Block } CalleeKind;
+
+  if (const auto *MD = dyn_cast(D)) {
+NumFormalParams = MD->param_size();
+CalleeKind = CK_Method;
+  } else if (const auto *FD = dyn_cast(D)) {
+NumFormalParams = FD->param_size();
+CalleeKind = CK_Function;
+  } else if (const auto *VD = dyn_cast(D)) {
+QualType Ty = VD->getType();
+const FunctionType *Fn = nullptr;
+if (const auto *PtrTy = Ty->getAs()) {
+  Fn = PtrTy->getPointeeType()->getAs();
+  if (!Fn)
+return;
+  CalleeKind = CK_Function;
+} else if (const auto *PtrTy = Ty->getAs()) {
+  Fn = PtrTy->getPointeeType()->castAs();
+  CalleeKind = CK_Block;
 } else {
   return;
 }
 
-if (const FunctionProtoType *proto = dyn_cast(fn)) {
-  numFormalParams = proto->getNumParams();
-} else {
-  numFormalParams = 0;
-}
+if (const auto *proto = dyn_cast(Fn))
+  NumFormalParams = proto->getNumParams();
+else
+  NumFormalParams = 0;
   } else {
 return;
   }
 
-  // "nullPos" is the number of formal parameters at the end which
+  // "NullPos" is the number of formal parameters at the end which
   // effectively count as part of the variadic arguments.  This is
   // useful if you would prefer to not have *any* formal parameters,
   // but the language forces you to have at least one.
-  unsigned nullPos = attr->getNullPos();
-  assert((nullPos == 0 || nullPos == 1) && "invalid null position on 
sentinel");
-  numFormalParams = (nullPos > numFormalParams ? 0 : numFormalParams - 
nullPos);
+  unsigned NullPos = Attr->getNullPos();
+  assert((NullPos == 0 || NullPos == 1) && "invalid null position on 
sentinel");
+  NumFormalParams = (NullPos > NumFormalParams ? 0 : NumFormalParams - 
NullPos);
 
   // The number of arguments which should follow the sentinel.
-  unsigned numArgsAfterSentinel = attr->getSentinel();
+  unsigned NumArgsAfterSentinel = Attr->getSentinel();
 
   // If there aren't enough arguments for all the formal parameters,
   // the sentinel, and the args

[clang] c3329b1 - [clang][Interp][NFC] Limit Pointer::isArrayElement() to actual arrays

2023-11-15 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-11-15T13:40:16+01:00
New Revision: c3329b1cac3158bba62aab14d648b9dc615f8c67

URL: 
https://github.com/llvm/llvm-project/commit/c3329b1cac3158bba62aab14d648b9dc615f8c67
DIFF: 
https://github.com/llvm/llvm-project/commit/c3329b1cac3158bba62aab14d648b9dc615f8c67.diff

LOG: [clang][Interp][NFC] Limit Pointer::isArrayElement() to actual arrays

Similar to what we do in isArrayRoot() - only return true here if the
Pointee is actually of array type.

Added: 


Modified: 
clang/lib/AST/Interp/Pointer.h

Removed: 




diff  --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h
index 843bcad16b5d1e3..a8f6e62fa76d356 100644
--- a/clang/lib/AST/Interp/Pointer.h
+++ b/clang/lib/AST/Interp/Pointer.h
@@ -279,7 +279,7 @@ class Pointer {
 return getFieldDesc()->isUnknownSizeArray();
   }
   /// Checks if the pointer points to an array.
-  bool isArrayElement() const { return Base != Offset; }
+  bool isArrayElement() const { return inArray() && Base != Offset; }
   /// Pointer points directly to a block.
   bool isRoot() const {
 return (Base == 0 || Base == RootPtrMark) && Offset == 0;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 894a387 - [clang][Interp][NFC] Properly implement IntegralAP::from(IntegralAP)

2023-11-16 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-11-17T08:04:30+01:00
New Revision: 894a38753e8c4cfef7a1dae17a76b405208b2708

URL: 
https://github.com/llvm/llvm-project/commit/894a38753e8c4cfef7a1dae17a76b405208b2708
DIFF: 
https://github.com/llvm/llvm-project/commit/894a38753e8c4cfef7a1dae17a76b405208b2708.diff

LOG: [clang][Interp][NFC] Properly implement IntegralAP::from(IntegralAP)

This used to just pass on the given parameter, but we need to respect
the given bit width.

Added: 


Modified: 
clang/lib/AST/Interp/IntegralAP.h

Removed: 




diff  --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index bd665959cf3dcc4..9019f32e6cef2a3 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -102,7 +102,12 @@ template  class IntegralAP final {
 
   template 
   static IntegralAP from(IntegralAP V, unsigned NumBits = 0) {
-return IntegralAP(V.V);
+if (NumBits == 0)
+  NumBits = V.bitWidth();
+
+if constexpr (InputSigned)
+  return IntegralAP(V.V.sextOrTrunc(NumBits));
+return IntegralAP(V.V.zextOrTrunc(NumBits));
   }
 
   template 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 4a8b43b - [clang][Interp][NFC] Factor array element init into its own function

2023-11-20 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-11-20T13:00:57+01:00
New Revision: 4a8b43ba3bd5427dd98a7a93d1b1ed25051c31e8

URL: 
https://github.com/llvm/llvm-project/commit/4a8b43ba3bd5427dd98a7a93d1b1ed25051c31e8
DIFF: 
https://github.com/llvm/llvm-project/commit/4a8b43ba3bd5427dd98a7a93d1b1ed25051c31e8.diff

LOG: [clang][Interp][NFC] Factor array element init into its own function

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index a1f45f5e3658d26..5dc1f9dfb10ff32 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -614,6 +614,29 @@ bool 
ByteCodeExprGen::visitInitList(ArrayRef Inits,
   return true;
 }
 
+/// Pointer to the array(not the element!) must be on the stack when calling
+/// this.
+template 
+bool ByteCodeExprGen::visitArrayElemInit(unsigned ElemIndex,
+  const Expr *Init) {
+  if (std::optional T = classify(Init->getType())) {
+// Visit the primitive element like normal.
+if (!this->visit(Init))
+  return false;
+return this->emitInitElem(*T, ElemIndex, Init);
+  }
+
+  // Advance the pointer currently on the stack to the given
+  // dimension.
+  if (!this->emitConstUint32(ElemIndex, Init))
+return false;
+  if (!this->emitArrayElemPtrUint32(Init))
+return false;
+  if (!this->visitInitializer(Init))
+return false;
+  return this->emitPopPtr(Init);
+}
+
 template 
 bool ByteCodeExprGen::VisitInitListExpr(const InitListExpr *E) {
   // Handle discarding first.
@@ -642,25 +665,8 @@ bool ByteCodeExprGen::VisitInitListExpr(const 
InitListExpr *E) {
 // FIXME: Array fillers.
 unsigned ElementIndex = 0;
 for (const Expr *Init : E->inits()) {
-  if (std::optional T = classify(Init->getType())) {
-// Visit the primitive element like normal.
-if (!this->visit(Init))
-  return false;
-if (!this->emitInitElem(*T, ElementIndex, Init))
-  return false;
-  } else {
-// Advance the pointer currently on the stack to the given
-// dimension.
-if (!this->emitConstUint32(ElementIndex, Init))
-  return false;
-if (!this->emitArrayElemPtrUint32(Init))
-  return false;
-if (!this->visitInitializer(Init))
-  return false;
-if (!this->emitPopPtr(Init))
-  return false;
-  }
-
+  if (!this->visitArrayElemInit(ElementIndex, Init))
+return false;
   ++ElementIndex;
 }
 return true;
@@ -831,7 +837,6 @@ bool ByteCodeExprGen::VisitArrayInitLoopExpr(
   const Expr *SubExpr = E->getSubExpr();
   const Expr *CommonExpr = E->getCommonExpr();
   size_t Size = E->getArraySize().getZExtValue();
-  std::optional ElemT = classify(SubExpr->getType());
 
   // If the common expression is an opaque expression, we visit it
   // here once so we have its value cached.
@@ -848,22 +853,8 @@ bool ByteCodeExprGen::VisitArrayInitLoopExpr(
 ArrayIndexScope IndexScope(this, I);
 BlockScope BS(this);
 
-if (ElemT) {
-  if (!this->visit(SubExpr))
-return false;
-  if (!this->emitInitElem(*ElemT, I, E))
-return false;
-} else {
-  // Get to our array element and recurse into visitInitializer()
-  if (!this->emitConstUint64(I, SubExpr))
-return false;
-  if (!this->emitArrayElemPtrUint64(SubExpr))
-return false;
-  if (!visitInitializer(SubExpr))
-return false;
-  if (!this->emitPopPtr(E))
-return false;
-}
+if (!this->visitArrayElemInit(I, SubExpr))
+  return false;
   }
   return true;
 }

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 602cee45f381df5..bc1d5d11a115135 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -209,6 +209,7 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   }
 
   bool visitInitList(ArrayRef Inits, const Expr *E);
+  bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init);
 
   /// Creates a local primitive value.
   unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst,



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 9bdbb82 - [clang][Interp][NFC] Use isArrayRoot() when comparing pointers

2023-11-20 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-11-20T13:17:47+01:00
New Revision: 9bdbb8226e70fb248b40a4b5002699ee9eeeda93

URL: 
https://github.com/llvm/llvm-project/commit/9bdbb8226e70fb248b40a4b5002699ee9eeeda93
DIFF: 
https://github.com/llvm/llvm-project/commit/9bdbb8226e70fb248b40a4b5002699ee9eeeda93.diff

LOG: [clang][Interp][NFC] Use isArrayRoot() when comparing pointers

The previous code was just an open-coded version of isArrayRoot().

Added: 


Modified: 
clang/lib/AST/Interp/Interp.h

Removed: 




diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 026a95d65488da9..64b376e101c8720 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -770,9 +770,9 @@ inline bool CmpHelperEQ(InterpState &S, CodePtr 
OpPC, CompareFn Fn) {
 // element in the same array are NOT equal. They have the same Base value,
 // but a 
diff erent Offset. This is a pretty rare case, so we fix this here
 // by comparing pointers to the first elements.
-if (LHS.inArray() && LHS.isRoot())
+if (LHS.isArrayRoot())
   VL = LHS.atIndex(0).getByteOffset();
-if (RHS.inArray() && RHS.isRoot())
+if (RHS.isArrayRoot())
   VR = RHS.atIndex(0).getByteOffset();
 
 S.Stk.push(BoolT::from(Fn(Compare(VL, VR;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 6e547ce - [clang][Interp][NFC] Add const InterpBlock::deref() overload

2023-11-20 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-11-20T17:53:30+01:00
New Revision: 6e547ce1c072f6f086a4f44fb8168df23413f597

URL: 
https://github.com/llvm/llvm-project/commit/6e547ce1c072f6f086a4f44fb8168df23413f597
DIFF: 
https://github.com/llvm/llvm-project/commit/6e547ce1c072f6f086a4f44fb8168df23413f597.diff

LOG: [clang][Interp][NFC] Add const InterpBlock::deref() overload

Added: 


Modified: 
clang/lib/AST/Interp/Interp.h
clang/lib/AST/Interp/InterpBlock.h

Removed: 




diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 64b376e101c8720..4f7778bdd2ff333 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1004,7 +1004,7 @@ bool SetThisField(InterpState &S, CodePtr OpPC, uint32_t 
I) {
 
 template ::T>
 bool GetGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
-  auto *B = S.P.getGlobal(I);
+  const Block *B = S.P.getGlobal(I);
   if (B->isExtern())
 return false;
   S.Stk.push(B->deref());

diff  --git a/clang/lib/AST/Interp/InterpBlock.h 
b/clang/lib/AST/Interp/InterpBlock.h
index 9d0c4859fd06c15..9db82567d2d5d63 100644
--- a/clang/lib/AST/Interp/InterpBlock.h
+++ b/clang/lib/AST/Interp/InterpBlock.h
@@ -98,6 +98,9 @@ class Block final {
   /// Returns a view over the data.
   template 
   T &deref() { return *reinterpret_cast(data()); }
+  template  const T &deref() const {
+return *reinterpret_cast(data());
+  }
 
   /// Invokes the constructor.
   void invokeCtor() {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] f8fe400 - [clang][Interp][NFC] Make IntegralAP::isSigned() constexpr

2023-10-29 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-10-29T14:15:44+01:00
New Revision: f8fe40090ab302921bc4b83969bfec8b31c902aa

URL: 
https://github.com/llvm/llvm-project/commit/f8fe40090ab302921bc4b83969bfec8b31c902aa
DIFF: 
https://github.com/llvm/llvm-project/commit/f8fe40090ab302921bc4b83969bfec8b31c902aa.diff

LOG: [clang][Interp][NFC] Make IntegralAP::isSigned() constexpr

Added: 


Modified: 
clang/lib/AST/Interp/IntegralAP.h

Removed: 




diff  --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index 45e5b49546270aa..cfed9ca29336d2e 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -124,7 +124,7 @@ template  class IntegralAP final {
   bool isNegative() const { return !V.isNonNegative(); }
   bool isMin() const { return V.isMinValue(); }
   bool isMax() const { return V.isMaxValue(); }
-  static bool isSigned() { return Signed; }
+  static constexpr bool isSigned() { return Signed; }
   bool isMinusOne() const { return Signed && V == -1; }
 
   unsigned countLeadingZeros() const { return V.countl_zero(); }



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 8a1719d - [clang][Interp][NFC] Use delegate() in VisitCXXBindTemporaryExpr

2023-10-30 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-10-30T17:20:27+01:00
New Revision: 8a1719d3edbb04ac6a20062911d59d38aec3b2ca

URL: 
https://github.com/llvm/llvm-project/commit/8a1719d3edbb04ac6a20062911d59d38aec3b2ca
DIFF: 
https://github.com/llvm/llvm-project/commit/8a1719d3edbb04ac6a20062911d59d38aec3b2ca.diff

LOG: [clang][Interp][NFC] Use delegate() in VisitCXXBindTemporaryExpr

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 195af664c13dafc..485893d58f487ae 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1314,9 +1314,7 @@ bool 
ByteCodeExprGen::VisitMaterializeTemporaryExpr(
 template 
 bool ByteCodeExprGen::VisitCXXBindTemporaryExpr(
 const CXXBindTemporaryExpr *E) {
-  if (Initializing)
-return this->visitInitializer(E->getSubExpr());
-  return this->visit(E->getSubExpr());
+  return this->delegate(E->getSubExpr());
 }
 
 template 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 00d809c - [clang][Interp][NFC] Fix a comment typo

2023-12-12 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-12T15:47:49+01:00
New Revision: 00d809c37409470f4777ecc977c4e9473e6839d3

URL: 
https://github.com/llvm/llvm-project/commit/00d809c37409470f4777ecc977c4e9473e6839d3
DIFF: 
https://github.com/llvm/llvm-project/commit/00d809c37409470f4777ecc977c4e9473e6839d3.diff

LOG: [clang][Interp][NFC] Fix a comment typo

Added: 


Modified: 
clang/lib/AST/Interp/Context.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/Context.cpp 
b/clang/lib/AST/Interp/Context.cpp
index cb96e56fb5e1a..4fe6d1173f427 100644
--- a/clang/lib/AST/Interp/Context.cpp
+++ b/clang/lib/AST/Interp/Context.cpp
@@ -168,7 +168,7 @@ bool Context::Run(State &Parent, const Function *Func, 
APValue &Result) {
 }
 
 // State gets destroyed here, so the Stk.clear() below doesn't accidentally
-// remove values the State's destructor might accedd.
+// remove values the State's destructor might access.
   }
 
   Stk.clear();



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 70c84f8 - [clang][NFC] Remove unused parameter

2023-12-12 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-12T15:47:49+01:00
New Revision: 70c84f80906d389455ffc331b9b9ed7e511df204

URL: 
https://github.com/llvm/llvm-project/commit/70c84f80906d389455ffc331b9b9ed7e511df204
DIFF: 
https://github.com/llvm/llvm-project/commit/70c84f80906d389455ffc331b9b9ed7e511df204.diff

LOG: [clang][NFC] Remove unused parameter

Added: 


Modified: 
clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParseExprCXX.cpp
clang/lib/Sema/SemaLambda.cpp

Removed: 




diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 1902d098f3c25e..1d7b4c729ce84e 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -7311,8 +7311,7 @@ class Sema final {
 
   /// ActOnLambdaExpr - This is called when the body of a lambda expression
   /// was successfully completed.
-  ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
- Scope *CurScope);
+  ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body);
 
   /// Does copying/destroying the captured variable have side effects?
   bool CaptureHasSideEffects(const sema::Capture &From);

diff  --git a/clang/lib/Parse/ParseExprCXX.cpp 
b/clang/lib/Parse/ParseExprCXX.cpp
index 8b86db1bb8fc5d..2fc364fc811b32 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -1548,7 +1548,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
 
   if (!Stmt.isInvalid() && !TrailingReturnType.isInvalid() &&
   !D.isInvalidType())
-return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.get(), getCurScope());
+return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.get());
 
   Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());
   return ExprError();

diff  --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 4cc87c9fa765c4..e7b6443c984c91 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1885,8 +1885,7 @@ ExprResult Sema::BuildCaptureInit(const Capture &Cap,
   return InitSeq.Perform(*this, Entity, InitKind, InitExpr);
 }
 
-ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
- Scope *CurScope) {
+ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body) {
   LambdaScopeInfo LSI = *cast(FunctionScopes.back());
   ActOnFinishFunctionBody(LSI.CallOperator, Body);
   return BuildLambdaExpr(StartLoc, Body->getEndLoc(), &LSI);



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] d36f72b - [clang][Sema][NFC] Add a boolean parameter comment

2023-12-13 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-13T11:11:39+01:00
New Revision: d36f72b4187c3d934fd0558d174ad0c5ecafe140

URL: 
https://github.com/llvm/llvm-project/commit/d36f72b4187c3d934fd0558d174ad0c5ecafe140
DIFF: 
https://github.com/llvm/llvm-project/commit/d36f72b4187c3d934fd0558d174ad0c5ecafe140.diff

LOG: [clang][Sema][NFC] Add a boolean parameter comment

Added: 


Modified: 
clang/lib/Sema/SemaDecl.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 19d972ed8ab2d..63854846f3d8c 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15800,7 +15800,7 @@ Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) {
 }
 
 Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) {
-  return ActOnFinishFunctionBody(D, BodyArg, false);
+  return ActOnFinishFunctionBody(D, BodyArg, /*IsInstantiation=*/false);
 }
 
 /// RAII object that pops an ExpressionEvaluationContext when exiting a 
function



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 2eb1e75 - [clang][NFC] Inline some lambdas to their only call site

2023-12-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-14T10:47:32+01:00
New Revision: 2eb1e75f42d7e09e97907f535bfa749722722dbd

URL: 
https://github.com/llvm/llvm-project/commit/2eb1e75f42d7e09e97907f535bfa749722722dbd
DIFF: 
https://github.com/llvm/llvm-project/commit/2eb1e75f42d7e09e97907f535bfa749722722dbd.diff

LOG: [clang][NFC] Inline some lambdas to their only call site

Added: 


Modified: 
clang/lib/Parse/ParseExprCXX.cpp

Removed: 




diff  --git a/clang/lib/Parse/ParseExprCXX.cpp 
b/clang/lib/Parse/ParseExprCXX.cpp
index 2fc364fc811b32..ef9ea6575205cd 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -1311,18 +1311,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
 D.takeAttributes(Attributes);
   }
 
-  // Helper to emit a warning if we see a CUDA host/device/global attribute
-  // after '(...)'. nvcc doesn't accept this.
-  auto WarnIfHasCUDATargetAttr = [&] {
-if (getLangOpts().CUDA)
-  for (const ParsedAttr &A : Attributes)
-if (A.getKind() == ParsedAttr::AT_CUDADevice ||
-A.getKind() == ParsedAttr::AT_CUDAHost ||
-A.getKind() == ParsedAttr::AT_CUDAGlobal)
-  Diag(A.getLoc(), diag::warn_cuda_attr_lambda_position)
-  << A.getAttrName()->getName();
-  };
-
   MultiParseScope TemplateParamScope(*this);
   if (Tok.is(tok::less)) {
 Diag(Tok, getLangOpts().CPlusPlus20
@@ -1377,91 +1365,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
   bool HasSpecifiers = false;
   SourceLocation MutableLoc;
 
-  auto ParseConstexprAndMutableSpecifiers = [&] {
-// GNU-style attributes must be parsed before the mutable specifier to
-// be compatible with GCC. MSVC-style attributes must be parsed before
-// the mutable specifier to be compatible with MSVC.
-MaybeParseAttributes(PAKM_GNU | PAKM_Declspec, Attributes);
-// Parse mutable-opt and/or constexpr-opt or consteval-opt, and update
-// the DeclEndLoc.
-SourceLocation ConstexprLoc;
-SourceLocation ConstevalLoc;
-SourceLocation StaticLoc;
-
-tryConsumeLambdaSpecifierToken(*this, MutableLoc, StaticLoc, ConstexprLoc,
-   ConstevalLoc, DeclEndLoc);
-
-DiagnoseStaticSpecifierRestrictions(*this, StaticLoc, MutableLoc, Intro);
-
-addStaticToLambdaDeclSpecifier(*this, StaticLoc, DS);
-addConstexprToLambdaDeclSpecifier(*this, ConstexprLoc, DS);
-addConstevalToLambdaDeclSpecifier(*this, ConstevalLoc, DS);
-  };
-
-  auto ParseLambdaSpecifiers =
-  [&](MutableArrayRef ParamInfo,
-  SourceLocation EllipsisLoc) {
-// Parse exception-specification[opt].
-ExceptionSpecificationType ESpecType = EST_None;
-SourceRange ESpecRange;
-SmallVector DynamicExceptions;
-SmallVector DynamicExceptionRanges;
-ExprResult NoexceptExpr;
-CachedTokens *ExceptionSpecTokens;
-
-ESpecType = tryParseExceptionSpecification(
-/*Delayed=*/false, ESpecRange, DynamicExceptions,
-DynamicExceptionRanges, NoexceptExpr, ExceptionSpecTokens);
-
-if (ESpecType != EST_None)
-  DeclEndLoc = ESpecRange.getEnd();
-
-// Parse attribute-specifier[opt].
-if (MaybeParseCXX11Attributes(Attributes))
-  DeclEndLoc = Attributes.Range.getEnd();
-
-// Parse OpenCL addr space attribute.
-if (Tok.isOneOf(tok::kw___private, tok::kw___global, tok::kw___local,
-tok::kw___constant, tok::kw___generic)) {
-  ParseOpenCLQualifiers(DS.getAttributes());
-  ConsumeToken();
-}
-
-SourceLocation FunLocalRangeEnd = DeclEndLoc;
-
-// Parse trailing-return-type[opt].
-if (Tok.is(tok::arrow)) {
-  FunLocalRangeEnd = Tok.getLocation();
-  SourceRange Range;
-  TrailingReturnType = ParseTrailingReturnType(
-  Range, /*MayBeFollowedByDirectInit*/ false);
-  TrailingReturnTypeLoc = Range.getBegin();
-  if (Range.getEnd().isValid())
-DeclEndLoc = Range.getEnd();
-}
-
-SourceLocation NoLoc;
-D.AddTypeInfo(
-DeclaratorChunk::getFunction(
-/*HasProto=*/true,
-/*IsAmbiguous=*/false, LParenLoc, ParamInfo.data(),
-ParamInfo.size(), EllipsisLoc, RParenLoc,
-/*RefQualifierIsLvalueRef=*/true,
-/*RefQualifierLoc=*/NoLoc, MutableLoc, ESpecType, ESpecRange,
-DynamicExceptions.data(), DynamicExceptionRanges.data(),
-DynamicExceptions.size(),
-NoexceptExpr.isUsable() ? NoexceptExpr.get() : nullptr,
-/*ExceptionSpecTokens*/ nullptr,
-/*DeclsInPrototype=*/std::nullopt, LParenLoc, FunLocalRangeEnd,
-D, TrailingReturnType, TrailingReturnTypeLoc, &DS),
-std::move(Attri

[clang] 797fee6 - [clang][Interp] Start supporting complex types

2023-12-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-14T11:57:38+01:00
New Revision: 797fee68d1cb6a4122d89880d44f8c99559c5cac

URL: 
https://github.com/llvm/llvm-project/commit/797fee68d1cb6a4122d89880d44f8c99559c5cac
DIFF: 
https://github.com/llvm/llvm-project/commit/797fee68d1cb6a4122d89880d44f8c99559c5cac.diff

LOG: [clang][Interp] Start supporting complex types

Differential Revision: https://reviews.llvm.org/D146408

Added: 
clang/test/AST/Interp/complex.cpp

Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/Context.cpp
clang/lib/AST/Interp/EvalEmitter.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index f7f8e6c73d84e2..efa98c6517a2ef 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -671,6 +671,22 @@ bool ByteCodeExprGen::VisitInitListExpr(const 
InitListExpr *E) {
 return true;
   }
 
+  if (T->isAnyComplexType()) {
+unsigned InitIndex = 0;
+for (const Expr *Init : E->inits()) {
+  PrimType InitT = classifyPrim(Init->getType());
+
+  if (!this->visit(Init))
+return false;
+
+  if (!this->emitInitElem(InitT, InitIndex, E))
+return false;
+  ++InitIndex;
+}
+assert(InitIndex == 2);
+return true;
+  }
+
   return false;
 }
 
@@ -2550,8 +2566,22 @@ bool ByteCodeExprGen::VisitUnaryOperator(const 
UnaryOperator *E) {
 if (!this->visit(SubExpr))
   return false;
 return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);
-  case UO_Real:   // __real x
-  case UO_Imag:   // __imag x
+  case UO_Real: { // __real x
+assert(!T);
+if (!this->visit(SubExpr))
+  return false;
+if (!this->emitConstUint8(0, E))
+  return false;
+return this->emitArrayElemPtrPopUint8(E);
+  }
+  case UO_Imag: { // __imag x
+assert(!T);
+if (!this->visit(SubExpr))
+  return false;
+if (!this->emitConstUint8(1, E))
+  return false;
+return this->emitArrayElemPtrPopUint8(E);
+  }
   case UO_Extension:
 return this->delegate(SubExpr);
   case UO_Coawait:

diff  --git a/clang/lib/AST/Interp/Context.cpp 
b/clang/lib/AST/Interp/Context.cpp
index 4fe6d1173f427e..17abb71635839c 100644
--- a/clang/lib/AST/Interp/Context.cpp
+++ b/clang/lib/AST/Interp/Context.cpp
@@ -92,6 +92,9 @@ std::optional Context::classify(QualType T) const {
   if (T->isBooleanType())
 return PT_Bool;
 
+  if (T->isAnyComplexType())
+return std::nullopt;
+
   if (T->isSignedIntegerOrEnumerationType()) {
 switch (Ctx.getIntWidth(T)) {
 case 64:

diff  --git a/clang/lib/AST/Interp/EvalEmitter.cpp 
b/clang/lib/AST/Interp/EvalEmitter.cpp
index 9bc42057c5f578..0ff0bde8fd17e8 100644
--- a/clang/lib/AST/Interp/EvalEmitter.cpp
+++ b/clang/lib/AST/Interp/EvalEmitter.cpp
@@ -208,6 +208,27 @@ bool EvalEmitter::emitRetValue(const SourceInfo &Info) {
   }
   return Ok;
 }
+
+// Complex types.
+if (const auto *CT = Ty->getAs()) {
+  QualType ElemTy = CT->getElementType();
+  std::optional ElemT = Ctx.classify(ElemTy);
+  assert(ElemT);
+
+  if (ElemTy->isIntegerType()) {
+INT_TYPE_SWITCH(*ElemT, {
+  auto V1 = Ptr.atIndex(0).deref();
+  auto V2 = Ptr.atIndex(1).deref();
+  Result = APValue(V1.toAPSInt(), V2.toAPSInt());
+  return true;
+});
+  } else if (ElemTy->isFloatingType()) {
+Result = APValue(Ptr.atIndex(0).deref().getAPFloat(),
+ Ptr.atIndex(1).deref().getAPFloat());
+return true;
+  }
+  return false;
+}
 llvm_unreachable("invalid value to return");
   };
 

diff  --git a/clang/test/AST/Interp/complex.cpp 
b/clang/test/AST/Interp/complex.cpp
new file mode 100644
index 00..4fd2b5cfd73640
--- /dev/null
+++ b/clang/test/AST/Interp/complex.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s
+// RUN: %clang_cc1 -verify=ref %s
+
+// expected-no-diagnostics
+// ref-no-diagnostics
+
+constexpr _Complex double z1 = {1.0, 2.0};
+static_assert(__real(z1) == 1.0, "");
+static_assert(__imag(z1) == 2.0, "");
+
+constexpr double setter() {
+  _Complex float d = {1.0, 2.0};
+
+  __imag(d) = 4.0;
+  return __imag(d);
+}
+static_assert(setter() == 4, "");
+
+constexpr _Complex double getter() {
+  return {1.0, 3.0};
+}
+constexpr _Complex double D = getter();
+static_assert(__real(D) == 1.0, "");
+static_assert(__imag(D) == 3.0, "");
+
+
+constexpr _Complex int I1 = {1, 2};
+static_assert(__real(I1) == 1, "");
+static_assert(__imag(I1) == 2, "");
+
+
+/// FIXME: This should work in the new interpreter as well.
+// constexpr _Complex _BitInt(8) A = 0;// = {4};



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 07e3c24 - [clang][Interp] Support empty initlist initializers for complex types

2023-12-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-14T12:53:40+01:00
New Revision: 07e3c245ba2c8560123cf4559678e0ac2542

URL: 
https://github.com/llvm/llvm-project/commit/07e3c245ba2c8560123cf4559678e0ac2542
DIFF: 
https://github.com/llvm/llvm-project/commit/07e3c245ba2c8560123cf4559678e0ac2542.diff

LOG: [clang][Interp] Support empty initlist initializers for complex types

Differential Revision: https://reviews.llvm.org/D147369

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/AST/Interp/complex.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index efa98c6517a2ef..a4a00ddab65036 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -672,18 +672,28 @@ bool ByteCodeExprGen::VisitInitListExpr(const 
InitListExpr *E) {
   }
 
   if (T->isAnyComplexType()) {
-unsigned InitIndex = 0;
-for (const Expr *Init : E->inits()) {
-  PrimType InitT = classifyPrim(Init->getType());
-
-  if (!this->visit(Init))
-return false;
+unsigned NumInits = E->getNumInits();
+QualType ElemQT = E->getType()->getAs()->getElementType();
+PrimType ElemT = classifyPrim(ElemQT);
+if (NumInits == 0) {
+  // Zero-initialize both elements.
+  for (unsigned I = 0; I < 2; ++I) {
+if (!this->visitZeroInitializer(ElemT, ElemQT, E))
+  return false;
+if (!this->emitInitElem(ElemT, I, E))
+  return false;
+  }
+} else if (NumInits == 2) {
+  unsigned InitIndex = 0;
+  for (const Expr *Init : E->inits()) {
+if (!this->visit(Init))
+  return false;
 
-  if (!this->emitInitElem(InitT, InitIndex, E))
-return false;
-  ++InitIndex;
+if (!this->emitInitElem(ElemT, InitIndex, E))
+  return false;
+++InitIndex;
+  }
 }
-assert(InitIndex == 2);
 return true;
   }
 

diff  --git a/clang/test/AST/Interp/complex.cpp 
b/clang/test/AST/Interp/complex.cpp
index 4fd2b5cfd73640..ba9fcd39fdd777 100644
--- a/clang/test/AST/Interp/complex.cpp
+++ b/clang/test/AST/Interp/complex.cpp
@@ -29,5 +29,28 @@ static_assert(__real(I1) == 1, "");
 static_assert(__imag(I1) == 2, "");
 
 
+constexpr _Complex double D1 = {};
+static_assert(__real(D1) == 0, "");
+static_assert(__imag(D1) == 0, "");
+
+constexpr _Complex int I2 = {};
+static_assert(__real(I2) == 0, "");
+static_assert(__imag(I2) == 0, "");
+
+
+#if 0
+/// FIXME: This should work in the new interpreter.
+constexpr _Complex double D2 = {12};
+static_assert(__real(D2) == 12, "");
+static_assert(__imag(D2) == 12, "");
+
+constexpr _Complex int I3 = {15};
+static_assert(__real(I3) == 15, "");
+static_assert(__imag(I3) == 15, "");
+#endif
+
+
+
+
 /// FIXME: This should work in the new interpreter as well.
 // constexpr _Complex _BitInt(8) A = 0;// = {4};



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 497480b - [clang][Interp] IntegralComplexToBoolean casts

2023-12-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-14T13:11:00+01:00
New Revision: 497480b38a49977b67c33651b3f29d5f1d151793

URL: 
https://github.com/llvm/llvm-project/commit/497480b38a49977b67c33651b3f29d5f1d151793
DIFF: 
https://github.com/llvm/llvm-project/commit/497480b38a49977b67c33651b3f29d5f1d151793.diff

LOG: [clang][Interp] IntegralComplexToBoolean casts

Differential Revision: https://reviews.llvm.org/D148426

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/test/AST/Interp/complex.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index a4a00ddab65036..c428446386c04b 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -222,6 +222,52 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
 return this->emitNE(PtrT, CE);
   }
 
+  case CK_IntegralComplexToBoolean: {
+std::optional ElemT =
+classifyComplexElementType(SubExpr->getType());
+if (!ElemT)
+  return false;
+// We emit the expression (__real(E) != 0 || __imag(E) != 0)
+// for us, that means (bool)E[0] || (bool)E[1]
+if (!this->visit(SubExpr))
+  return false;
+if (!this->emitConstUint8(0, CE))
+  return false;
+if (!this->emitArrayElemPtrUint8(CE))
+  return false;
+if (!this->emitLoadPop(*ElemT, CE))
+  return false;
+if (!this->emitCast(*ElemT, PT_Bool, CE))
+  return false;
+// We now have the bool value of E[0] on the stack.
+LabelTy LabelTrue = this->getLabel();
+if (!this->jumpTrue(LabelTrue))
+  return false;
+
+if (!this->emitConstUint8(1, CE))
+  return false;
+if (!this->emitArrayElemPtrPopUint8(CE))
+  return false;
+if (!this->emitLoadPop(*ElemT, CE))
+  return false;
+if (!this->emitCast(*ElemT, PT_Bool, CE))
+  return false;
+// Leave the boolean value of E[1] on the stack.
+LabelTy EndLabel = this->getLabel();
+this->jump(EndLabel);
+
+this->emitLabel(LabelTrue);
+if (!this->emitPopPtr(CE))
+  return false;
+if (!this->emitConstBool(true, CE))
+  return false;
+
+this->fallthrough(EndLabel);
+this->emitLabel(EndLabel);
+
+return true;
+  }
+
   case CK_ToVoid:
 return discard(SubExpr);
 
@@ -1673,7 +1719,8 @@ template  bool 
ByteCodeExprGen::visit(const Expr *E) {
 return this->discard(E);
 
   // Create local variable to hold the return value.
-  if (!E->isGLValue() && !classify(E->getType())) {
+  if (!E->isGLValue() && !E->getType()->isAnyComplexType() &&
+  !classify(E->getType())) {
 std::optional LocalIndex = allocateLocal(E, /*IsExtended=*/true);
 if (!LocalIndex)
   return false;
@@ -1859,6 +1906,9 @@ bool ByteCodeExprGen::dereference(
 return Indirect(*T);
   }
 
+  if (LV->getType()->isAnyComplexType())
+return visit(LV);
+
   return false;
 }
 

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index bc1d5d11a11513..1c4739544454af 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -285,6 +285,14 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   }
 
   bool emitPrimCast(PrimType FromT, PrimType ToT, QualType ToQT, const Expr 
*E);
+  std::optional classifyComplexElementType(QualType T) const {
+assert(T->isAnyComplexType());
+
+QualType ElemType = T->getAs()->getElementType();
+
+return this->classify(ElemType);
+  }
+
   bool emitRecordDestruction(const Descriptor *Desc);
   unsigned collectBaseOffset(const RecordType *BaseType,
  const RecordType *DerivedType);

diff  --git a/clang/test/AST/Interp/complex.cpp 
b/clang/test/AST/Interp/complex.cpp
index ba9fcd39fdd777..dbdbc2f7356e6b 100644
--- a/clang/test/AST/Interp/complex.cpp
+++ b/clang/test/AST/Interp/complex.cpp
@@ -49,8 +49,21 @@ static_assert(__real(I3) == 15, "");
 static_assert(__imag(I3) == 15, "");
 #endif
 
-
-
-
 /// FIXME: This should work in the new interpreter as well.
 // constexpr _Complex _BitInt(8) A = 0;// = {4};
+
+namespace CastToBool {
+  constexpr _Complex int F = {0, 1};
+  static_assert(F, "");
+  constexpr _Complex int F2 = {1, 0};
+  static_assert(F2, "");
+  constexpr _Complex int F3 = {0, 0};
+  static_assert(!F3, "");
+
+  constexpr _Complex unsigned char F4 = {0, 1};
+  static_assert(F4, "");
+  constexpr _Complex unsigned char F5 = {1, 0};
+  static_assert(F5, "");
+  constexpr _Complex unsigned char F6 = {0, 0};
+  static_assert(!F6, "");
+}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 935f5ee - [clang][Interp] ComplexFloatingToBoolean casts

2023-12-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-14T13:17:40+01:00
New Revision: 935f5ee9c9fd6ff358b07fb4ff8e21b77c1a5ce8

URL: 
https://github.com/llvm/llvm-project/commit/935f5ee9c9fd6ff358b07fb4ff8e21b77c1a5ce8
DIFF: 
https://github.com/llvm/llvm-project/commit/935f5ee9c9fd6ff358b07fb4ff8e21b77c1a5ce8.diff

LOG: [clang][Interp] ComplexFloatingToBoolean casts

Differential Revision: https://reviews.llvm.org/D150654

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/AST/Interp/complex.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index c428446386c04b..fdc84d0a0da005 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -222,7 +222,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr 
*CE) {
 return this->emitNE(PtrT, CE);
   }
 
-  case CK_IntegralComplexToBoolean: {
+  case CK_IntegralComplexToBoolean:
+  case CK_FloatingComplexToBoolean: {
 std::optional ElemT =
 classifyComplexElementType(SubExpr->getType());
 if (!ElemT)
@@ -237,8 +238,14 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
   return false;
 if (!this->emitLoadPop(*ElemT, CE))
   return false;
-if (!this->emitCast(*ElemT, PT_Bool, CE))
-  return false;
+if (*ElemT == PT_Float) {
+  if (!this->emitCastFloatingIntegral(PT_Bool, CE))
+return false;
+} else {
+  if (!this->emitCast(*ElemT, PT_Bool, CE))
+return false;
+}
+
 // We now have the bool value of E[0] on the stack.
 LabelTy LabelTrue = this->getLabel();
 if (!this->jumpTrue(LabelTrue))
@@ -250,8 +257,13 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
   return false;
 if (!this->emitLoadPop(*ElemT, CE))
   return false;
-if (!this->emitCast(*ElemT, PT_Bool, CE))
-  return false;
+if (*ElemT == PT_Float) {
+  if (!this->emitCastFloatingIntegral(PT_Bool, CE))
+return false;
+} else {
+  if (!this->emitCast(*ElemT, PT_Bool, CE))
+return false;
+}
 // Leave the boolean value of E[1] on the stack.
 LabelTy EndLabel = this->getLabel();
 this->jump(EndLabel);

diff  --git a/clang/test/AST/Interp/complex.cpp 
b/clang/test/AST/Interp/complex.cpp
index dbdbc2f7356e6b..084a63d4701c23 100644
--- a/clang/test/AST/Interp/complex.cpp
+++ b/clang/test/AST/Interp/complex.cpp
@@ -66,4 +66,11 @@ namespace CastToBool {
   static_assert(F5, "");
   constexpr _Complex unsigned char F6 = {0, 0};
   static_assert(!F6, "");
+
+  constexpr _Complex float F7 = {0, 1};
+  static_assert(F7, "");
+  constexpr _Complex float F8 = {1, 0};
+  static_assert(F8, "");
+  constexpr _Complex double F9 = {0, 0};
+  static_assert(!F9, "");
 }



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 88abd53 - [clang][Interp] Allow evaluating standalone complex expressions

2023-12-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-14T15:07:42+01:00
New Revision: 88abd530ef8e66ba4275146ffba028aa8923bf7f

URL: 
https://github.com/llvm/llvm-project/commit/88abd530ef8e66ba4275146ffba028aa8923bf7f
DIFF: 
https://github.com/llvm/llvm-project/commit/88abd530ef8e66ba4275146ffba028aa8923bf7f.diff

LOG: [clang][Interp] Allow evaluating standalone complex expressions

We reach visitExpr() when evaluating standalone expressions. However,
the RetValue() code path was unused before, because we never reach it,
even with structs or arrays.

RetValue expects a pointer on the stack it can take apart to return an
APValue, so provide it with one.

Differential Revision: https://reviews.llvm.org/D150661

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/AST/Interp/complex.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index fdc84d0a0da005..080b7e896a8201 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2180,15 +2180,33 @@ const Function 
*ByteCodeExprGen::getFunction(const FunctionDecl *FD) {
 template 
 bool ByteCodeExprGen::visitExpr(const Expr *E) {
   ExprScope RootScope(this);
-  if (!visit(E))
-return false;
-
-  if (E->getType()->isVoidType())
+  // Void expressions.
+  if (E->getType()->isVoidType()) {
+if (!visit(E))
+  return false;
 return this->emitRetVoid(E);
+  }
 
-  if (std::optional T = classify(E))
+  // Expressions with a primitive return type.
+  if (std::optional T = classify(E)) {
+if (!visit(E))
+  return false;
 return this->emitRet(*T, E);
-  return this->emitRetValue(E);
+  }
+
+  // Expressions with a composite return type.
+  // For us, that means everything we don't
+  // have a PrimType for.
+  if (std::optional LocalOffset = this->allocateLocal(E)) {
+if (!this->visitLocalInitializer(E, *LocalOffset))
+  return false;
+
+if (!this->emitGetPtrLocal(*LocalOffset, E))
+  return false;
+return this->emitRetValue(E);
+  }
+
+  return false;
 }
 
 /// Toplevel visitDecl().
@@ -2644,7 +2662,14 @@ bool ByteCodeExprGen::VisitUnaryOperator(const 
UnaryOperator *E) {
   return false;
 if (!this->emitConstUint8(0, E))
   return false;
-return this->emitArrayElemPtrPopUint8(E);
+if (!this->emitArrayElemPtrPopUint8(E))
+  return false;
+
+// Since our _Complex implementation does not map to a primitive type,
+// we sometimes have to do the lvalue-to-rvalue conversion here manually.
+if (!SubExpr->isLValue())
+  return this->emitLoadPop(classifyPrim(E->getType()), E);
+return true;
   }
   case UO_Imag: { // __imag x
 assert(!T);
@@ -2652,7 +2677,14 @@ bool ByteCodeExprGen::VisitUnaryOperator(const 
UnaryOperator *E) {
   return false;
 if (!this->emitConstUint8(1, E))
   return false;
-return this->emitArrayElemPtrPopUint8(E);
+if (!this->emitArrayElemPtrPopUint8(E))
+  return false;
+
+// Since our _Complex implementation does not map to a primitive type,
+// we sometimes have to do the lvalue-to-rvalue conversion here manually.
+if (!SubExpr->isLValue())
+  return this->emitLoadPop(classifyPrim(E->getType()), E);
+return true;
   }
   case UO_Extension:
 return this->delegate(SubExpr);

diff  --git a/clang/test/AST/Interp/complex.cpp 
b/clang/test/AST/Interp/complex.cpp
index 084a63d4701c23..1eb70a1b9ce3b4 100644
--- a/clang/test/AST/Interp/complex.cpp
+++ b/clang/test/AST/Interp/complex.cpp
@@ -38,6 +38,10 @@ static_assert(__real(I2) == 0, "");
 static_assert(__imag(I2) == 0, "");
 
 
+/// Standalone complex expressions.
+static_assert(__real((_Complex float){1.0, 3.0}) == 1.0, "");
+
+
 #if 0
 /// FIXME: This should work in the new interpreter.
 constexpr _Complex double D2 = {12};



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] d16cf47 - [clang][Interp] Start implementing binary operators for complex types

2023-12-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-14T15:33:52+01:00
New Revision: d16cf470ac4600bb1a6b462ed843078ad65a3d93

URL: 
https://github.com/llvm/llvm-project/commit/d16cf470ac4600bb1a6b462ed843078ad65a3d93
DIFF: 
https://github.com/llvm/llvm-project/commit/d16cf470ac4600bb1a6b462ed843078ad65a3d93.diff

LOG: [clang][Interp] Start implementing binary operators for complex types

Differential Revision: https://reviews.llvm.org/D155572

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/test/AST/Interp/complex.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 080b7e896a8201..d0980882f402b9 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -316,6 +316,9 @@ bool ByteCodeExprGen::VisitBinaryOperator(const 
BinaryOperator *BO) {
   if (BO->isLogicalOp())
 return this->VisitLogicalBinOp(BO);
 
+  if (BO->getType()->isAnyComplexType())
+return this->VisitComplexBinOp(BO);
+
   const Expr *LHS = BO->getLHS();
   const Expr *RHS = BO->getRHS();
 
@@ -558,6 +561,107 @@ bool ByteCodeExprGen::VisitLogicalBinOp(const 
BinaryOperator *E) {
   return true;
 }
 
+template 
+bool ByteCodeExprGen::VisitComplexBinOp(const BinaryOperator *E) {
+  // FIXME: We expect a pointer on the stack here.
+  //   we should not do that, but that's part of a bigger rework.
+  const Expr *LHS = E->getLHS();
+  const Expr *RHS = E->getRHS();
+  PrimType LHSElemT = *this->classifyComplexElementType(LHS->getType());
+  PrimType RHSElemT = *this->classifyComplexElementType(RHS->getType());
+
+  unsigned LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false);
+  unsigned RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false);
+  unsigned ResultOffset = ~0u;
+  if (!this->DiscardResult)
+ResultOffset = this->allocateLocalPrimitive(E, PT_Ptr, true, false);
+
+  assert(LHSElemT == RHSElemT);
+
+  // Save result pointer in ResultOffset
+  if (!this->DiscardResult) {
+if (!this->emitDupPtr(E))
+  return false;
+if (!this->emitSetLocal(PT_Ptr, ResultOffset, E))
+  return false;
+  }
+
+  // Evaluate LHS and save value to LHSOffset.
+  if (!this->visit(LHS))
+return false;
+  if (!this->emitSetLocal(PT_Ptr, LHSOffset, E))
+return false;
+
+  // Same with RHS.
+  if (!this->visit(RHS))
+return false;
+  if (!this->emitSetLocal(PT_Ptr, RHSOffset, E))
+return false;
+
+  // Now we can get pointers to the LHS and RHS from the offsets above.
+  BinaryOperatorKind Op = E->getOpcode();
+  for (unsigned ElemIndex = 0; ElemIndex != 2; ++ElemIndex) {
+// Result pointer for the store later.
+if (!this->DiscardResult) {
+  if (!this->emitGetLocal(PT_Ptr, ResultOffset, E))
+return false;
+}
+
+if (!this->emitGetLocal(PT_Ptr, LHSOffset, E))
+  return false;
+if (!this->emitConstUint8(ElemIndex, E))
+  return false;
+if (!this->emitArrayElemPtrPopUint8(E))
+  return false;
+if (!this->emitLoadPop(LHSElemT, E))
+  return false;
+
+if (!this->emitGetLocal(PT_Ptr, RHSOffset, E))
+  return false;
+if (!this->emitConstUint8(ElemIndex, E))
+  return false;
+if (!this->emitArrayElemPtrPopUint8(E))
+  return false;
+if (!this->emitLoadPop(RHSElemT, E))
+  return false;
+
+// The actual operation.
+switch (Op) {
+case BO_Add:
+  if (LHSElemT == PT_Float) {
+if (!this->emitAddf(getRoundingMode(E), E))
+  return false;
+  } else {
+if (!this->emitAdd(LHSElemT, E))
+  return false;
+  }
+  break;
+case BO_Sub:
+  if (LHSElemT == PT_Float) {
+if (!this->emitSubf(getRoundingMode(E), E))
+  return false;
+  } else {
+if (!this->emitSub(LHSElemT, E))
+  return false;
+  }
+  break;
+
+default:
+  return false;
+}
+
+if (!this->DiscardResult) {
+  // Initialize array element with the value we just computed.
+  if (!this->emitInitElemPop(LHSElemT, ElemIndex, E))
+return false;
+} else {
+  if (!this->emitPop(LHSElemT, E))
+return false;
+}
+  }
+  return true;
+}
+
 template 
 bool ByteCodeExprGen::VisitImplicitValueInitExpr(const 
ImplicitValueInitExpr *E) {
   QualType QT = E->getType();

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 1c4739544454af..bbb13e97e72569 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -65,6 +65,7 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   bool VisitBinaryOperator(const BinaryOperator *E);
   bool VisitLogicalBinOp(const BinaryOperator *E);
   bool VisitPointerArithBinOp(const BinaryOperator *E);
+  bool VisitComplexBinOp(const BinaryOperator *E);
 

[clang] f32662a - [clang][Interp][NFC] Remove outdated FIXME comment

2023-12-15 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-15T14:30:44+01:00
New Revision: f32662a40b0cc25f779ed10ea6515ba798922df8

URL: 
https://github.com/llvm/llvm-project/commit/f32662a40b0cc25f779ed10ea6515ba798922df8
DIFF: 
https://github.com/llvm/llvm-project/commit/f32662a40b0cc25f779ed10ea6515ba798922df8.diff

LOG: [clang][Interp][NFC] Remove outdated FIXME comment

This rework has already happened.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index d0980882f402b9..e6b3097a80d8f7 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -563,8 +563,8 @@ bool ByteCodeExprGen::VisitLogicalBinOp(const 
BinaryOperator *E) {
 
 template 
 bool ByteCodeExprGen::VisitComplexBinOp(const BinaryOperator *E) {
-  // FIXME: We expect a pointer on the stack here.
-  //   we should not do that, but that's part of a bigger rework.
+  assert(Initializing);
+
   const Expr *LHS = E->getLHS();
   const Expr *RHS = E->getRHS();
   PrimType LHSElemT = *this->classifyComplexElementType(LHS->getType());



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 258c2ae - [clang][Sema][NFC] Merge two if statements

2023-12-19 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-19T09:46:06+01:00
New Revision: 258c2ae9dfc8a16c837975efdaad7aeaa1e647be

URL: 
https://github.com/llvm/llvm-project/commit/258c2ae9dfc8a16c837975efdaad7aeaa1e647be
DIFF: 
https://github.com/llvm/llvm-project/commit/258c2ae9dfc8a16c837975efdaad7aeaa1e647be.diff

LOG: [clang][Sema][NFC] Merge two if statements

Added: 


Modified: 
clang/lib/Sema/SemaDecl.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index edf44bbc52119b..7dde037baccfe7 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2211,10 +2211,9 @@ void Sema::DiagnoseUnusedButSetDecl(const VarDecl *VD,
   return;
 // In C++, don't warn for record types that don't have WarnUnusedAttr, to
 // mimic gcc's behavior.
-if (const CXXRecordDecl *RD = dyn_cast(Tag)) {
-  if (!RD->hasAttr())
-return;
-}
+if (const auto *RD = dyn_cast(Tag);
+RD && !RD->hasAttr())
+  return;
   }
 
   // Don't warn about __block Objective-C pointer variables, as they might



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 42e5214 - [clang][Sema][NFC] Clean up ShouldDiagnoseUnusedDecl

2023-12-19 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-19T09:46:06+01:00
New Revision: 42e5214a9b6f1bc2fbed283f7adb30f733b5a351

URL: 
https://github.com/llvm/llvm-project/commit/42e5214a9b6f1bc2fbed283f7adb30f733b5a351
DIFF: 
https://github.com/llvm/llvm-project/commit/42e5214a9b6f1bc2fbed283f7adb30f733b5a351.diff

LOG: [clang][Sema][NFC] Clean up ShouldDiagnoseUnusedDecl

Const qualify a few locals, merge two if statements and use
dyn_cast_if_present instead of _or_null.

Added: 


Modified: 
clang/lib/Sema/SemaDecl.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 7dde037baccfe7..d1a26fe1218432 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2005,12 +2005,12 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions 
&LangOpts,
   if (D->isInvalidDecl())
 return false;
 
-  if (auto *DD = dyn_cast(D)) {
+  if (const auto *DD = dyn_cast(D)) {
 // For a decomposition declaration, warn if none of the bindings are
 // referenced, instead of if the variable itself is referenced (which
 // it is, by the bindings' expressions).
 bool IsAllPlaceholders = true;
-for (auto *BD : DD->bindings()) {
+for (const auto *BD : DD->bindings()) {
   if (BD->isReferenced())
 return false;
   IsAllPlaceholders = IsAllPlaceholders && BD->isPlaceholderVar(LangOpts);
@@ -2054,7 +2054,7 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions 
&LangOpts,
   if (const VarDecl *VD = dyn_cast(D)) {
 
 const Expr *Init = VD->getInit();
-if (const auto *Cleanups = dyn_cast_or_null(Init))
+if (const auto *Cleanups = dyn_cast_if_present(Init))
   Init = Cleanups->getSubExpr();
 
 const auto *Ty = VD->getType().getTypePtr();
@@ -2068,11 +2068,10 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions 
&LangOpts,
 
 // Warn for reference variables whose initializtion performs lifetime
 // extension.
-if (const auto *MTE = dyn_cast_or_null(Init)) {
-  if (MTE->getExtendingDecl()) {
-Ty = VD->getType().getNonReferenceType().getTypePtr();
-Init = MTE->getSubExpr()->IgnoreImplicitAsWritten();
-  }
+if (const auto *MTE = dyn_cast_if_present(Init);
+MTE && MTE->getExtendingDecl()) {
+  Ty = VD->getType().getNonReferenceType().getTypePtr();
+  Init = MTE->getSubExpr()->IgnoreImplicitAsWritten();
 }
 
 // If we failed to complete the type for some reason, or if the type is
@@ -2089,15 +2088,14 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions 
&LangOpts,
   if (Tag->hasAttr())
 return false;
 
-  if (const CXXRecordDecl *RD = dyn_cast(Tag)) {
+  if (const auto *RD = dyn_cast(Tag)) {
 if (!RD->hasTrivialDestructor() && !RD->hasAttr())
   return false;
 
 if (Init) {
-  const CXXConstructExpr *Construct =
-dyn_cast(Init);
+  const auto *Construct = dyn_cast(Init);
   if (Construct && !Construct->isElidable()) {
-CXXConstructorDecl *CD = Construct->getConstructor();
+const CXXConstructorDecl *CD = Construct->getConstructor();
 if (!CD->isTrivial() && !RD->hasAttr() &&
 (VD->getInit()->isValueDependent() || !VD->evaluateValue()))
   return false;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] b0ac829 - [clang][AST][NFC] const-qualify a few locals in isPlaceholderVar

2023-12-19 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-19T09:46:06+01:00
New Revision: b0ac829d7180e1d669ae218fef8d3f4da70394ed

URL: 
https://github.com/llvm/llvm-project/commit/b0ac829d7180e1d669ae218fef8d3f4da70394ed
DIFF: 
https://github.com/llvm/llvm-project/commit/b0ac829d7180e1d669ae218fef8d3f4da70394ed.diff

LOG: [clang][AST][NFC] const-qualify a few locals in isPlaceholderVar

Added: 


Modified: 
clang/lib/AST/Decl.cpp

Removed: 




diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 527ea6042daa03..fbd5ff9a2ecf22 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -1088,11 +1088,11 @@ bool NamedDecl::isPlaceholderVar(const LangOptions 
&LangOpts) const {
 return false;
   if (isa(this))
 return true;
-  if (auto *IFD = dyn_cast(this)) {
+  if (const auto *IFD = dyn_cast(this)) {
 if (!getDeclContext()->isFunctionOrMethod() &&
 !getDeclContext()->isRecord())
   return false;
-VarDecl *VD = IFD->getVarDecl();
+const VarDecl *VD = IFD->getVarDecl();
 return !VD || VD->getStorageDuration() == SD_Automatic;
   }
   // and it declares a variable with automatic storage duration
@@ -1105,7 +1105,7 @@ bool NamedDecl::isPlaceholderVar(const LangOptions 
&LangOpts) const {
   }
   if (const auto *BD = dyn_cast(this);
   BD && getDeclContext()->isFunctionOrMethod()) {
-VarDecl *VD = BD->getHoldingVar();
+const VarDecl *VD = BD->getHoldingVar();
 return !VD || VD->getStorageDuration() == StorageDuration::SD_Automatic;
   }
   return false;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 17fa04e - [clang][AST][NFC] Make declarationReplaces()'s first parameter const

2023-12-19 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-19T10:19:52+01:00
New Revision: 17fa04e32f8f7e7b65363dad0bc64d058030ef7c

URL: 
https://github.com/llvm/llvm-project/commit/17fa04e32f8f7e7b65363dad0bc64d058030ef7c
DIFF: 
https://github.com/llvm/llvm-project/commit/17fa04e32f8f7e7b65363dad0bc64d058030ef7c.diff

LOG: [clang][AST][NFC] Make declarationReplaces()'s first parameter const

And const qualify some local variables

Added: 


Modified: 
clang/include/clang/AST/Decl.h
clang/lib/AST/Decl.cpp

Removed: 




diff  --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index f9bf9cc5de7cb4..a807bcdd76b30d 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -358,7 +358,8 @@ class NamedDecl : public Decl {
   ///
   /// \param IsKnownNewer \c true if this declaration is known to be newer
   /// than \p OldD (for instance, if this declaration is newly-created).
-  bool declarationReplaces(NamedDecl *OldD, bool IsKnownNewer = true) const;
+  bool declarationReplaces(const NamedDecl *OldD,
+   bool IsKnownNewer = true) const;
 
   /// Determine whether this declaration has linkage.
   bool hasLinkage() const;

diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index fbd5ff9a2ecf22..f8e6f4efff4ebb 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -1843,7 +1843,8 @@ static bool isRedeclarable(Decl::Kind K) {
   llvm_unreachable("unknown decl kind");
 }
 
-bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const {
+bool NamedDecl::declarationReplaces(const NamedDecl *OldD,
+bool IsKnownNewer) const {
   assert(getDeclName() == OldD->getDeclName() && "Declaration name mismatch");
 
   // Never replace one imported declaration with another; we need both results
@@ -1873,13 +1874,13 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, 
bool IsKnownNewer) const {
 
   // Using declarations can be replaced if they import the same name from the
   // same context.
-  if (auto *UD = dyn_cast(this)) {
+  if (const auto *UD = dyn_cast(this)) {
 ASTContext &Context = getASTContext();
 return Context.getCanonicalNestedNameSpecifier(UD->getQualifier()) ==
Context.getCanonicalNestedNameSpecifier(
cast(OldD)->getQualifier());
   }
-  if (auto *UUVD = dyn_cast(this)) {
+  if (const auto *UUVD = dyn_cast(this)) {
 ASTContext &Context = getASTContext();
 return Context.getCanonicalNestedNameSpecifier(UUVD->getQualifier()) ==
Context.getCanonicalNestedNameSpecifier(
@@ -1896,7 +1897,7 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool 
IsKnownNewer) const {
 // Check whether this is actually newer than OldD. We want to keep the
 // newer declaration. This loop will usually only iterate once, because
 // OldD is usually the previous declaration.
-for (auto *D : redecls()) {
+for (const auto *D : redecls()) {
   if (D == OldD)
 break;
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] c52a46a - [clang][AST][NFC] Remove a local variable

2023-12-19 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-19T10:54:58+01:00
New Revision: c52a46a53b4845c92d60b21e3cf1d979273eb20f

URL: 
https://github.com/llvm/llvm-project/commit/c52a46a53b4845c92d60b21e3cf1d979273eb20f
DIFF: 
https://github.com/llvm/llvm-project/commit/c52a46a53b4845c92d60b21e3cf1d979273eb20f.diff

LOG: [clang][AST][NFC] Remove a local variable

The reference could be const, but this is even better.

Added: 


Modified: 
clang/lib/AST/Decl.cpp

Removed: 




diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index f8e6f4efff4ebb..c2ea155679193d 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2200,8 +2200,7 @@ static LanguageLinkage getDeclLanguageLinkage(const T &D) 
{
 
   // Language linkage is a C++ concept, but saying that everything else in C 
has
   // C language linkage fits the implementation nicely.
-  ASTContext &Context = D.getASTContext();
-  if (!Context.getLangOpts().CPlusPlus)
+  if (!D.getASTContext().getLangOpts().CPlusPlus)
 return CLanguageLinkage;
 
   // C++ [dcl.link]p4: A C language linkage is ignored in determining the



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 6905438 - [clang][Sema][NFC] Simplify ActOnCXXThrow

2023-12-19 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-19T14:47:48+01:00
New Revision: 6905438204b194973b6d6e56ddfe787ee4ce1e2d

URL: 
https://github.com/llvm/llvm-project/commit/6905438204b194973b6d6e56ddfe787ee4ce1e2d
DIFF: 
https://github.com/llvm/llvm-project/commit/6905438204b194973b6d6e56ddfe787ee4ce1e2d.diff

LOG: [clang][Sema][NFC] Simplify ActOnCXXThrow

Added: 


Modified: 
clang/lib/Sema/SemaExprCXX.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 081b568762ae22..4ae04358d5df7c 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -843,21 +843,21 @@ Sema::ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr 
*Ex) {
 //   operation from the operand to the exception object (15.1) can be
 //   omitted by constructing the automatic object directly into the
 //   exception object
-if (DeclRefExpr *DRE = dyn_cast(Ex->IgnoreParens()))
-  if (VarDecl *Var = dyn_cast(DRE->getDecl())) {
-if (Var->hasLocalStorage() && !Var->getType().isVolatileQualified()) {
-  for( ; S; S = S->getParent()) {
-if (S->isDeclScope(Var)) {
-  IsThrownVarInScope = true;
-  break;
-}
-
-// FIXME: Many of the scope checks here seem incorrect.
-if (S->getFlags() &
-(Scope::FnScope | Scope::ClassScope | Scope::BlockScope |
- Scope::ObjCMethodScope | Scope::TryScope))
-  break;
+if (const auto *DRE = dyn_cast(Ex->IgnoreParens()))
+  if (const auto *Var = dyn_cast(DRE->getDecl());
+  Var && Var->hasLocalStorage() &&
+  !Var->getType().isVolatileQualified()) {
+for (; S; S = S->getParent()) {
+  if (S->isDeclScope(Var)) {
+IsThrownVarInScope = true;
+break;
   }
+
+  // FIXME: Many of the scope checks here seem incorrect.
+  if (S->getFlags() &
+  (Scope::FnScope | Scope::ClassScope | Scope::BlockScope |
+   Scope::ObjCMethodScope | Scope::TryScope))
+break;
 }
   }
   }



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 489df61 - [clang][Interp][NFC] const qualify a local variable

2023-11-27 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-11-27T11:17:49+01:00
New Revision: 489df61a2960cbd154fe0a2c23918c2609ef4357

URL: 
https://github.com/llvm/llvm-project/commit/489df61a2960cbd154fe0a2c23918c2609ef4357
DIFF: 
https://github.com/llvm/llvm-project/commit/489df61a2960cbd154fe0a2c23918c2609ef4357.diff

LOG: [clang][Interp][NFC] const qualify a local variable

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 5dc1f9dfb10ff32..f45e8624a7741a5 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -75,7 +75,7 @@ template  class OptionScope final {
 
 template 
 bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) {
-  auto *SubExpr = CE->getSubExpr();
+  const Expr *SubExpr = CE->getSubExpr();
   switch (CE->getCastKind()) {
 
   case CK_LValueToRValue: {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] d5c98e7 - [clang][AST][NFC] const-qualify some local references

2023-12-20 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2023-12-21T06:32:32+01:00
New Revision: d5c98e783779c4e6b26b2010b20cd0ab7210ead3

URL: 
https://github.com/llvm/llvm-project/commit/d5c98e783779c4e6b26b2010b20cd0ab7210ead3
DIFF: 
https://github.com/llvm/llvm-project/commit/d5c98e783779c4e6b26b2010b20cd0ab7210ead3.diff

LOG: [clang][AST][NFC] const-qualify some local references

Added: 


Modified: 
clang/lib/AST/Decl.cpp

Removed: 




diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index c2ea155679193d..12e0a6faa4c33d 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -2943,7 +2943,7 @@ bool ParmVarDecl::isDestroyedInCallee() const {
 
   // FIXME: isParamDestroyedInCallee() should probably imply
   // isDestructedType()
-  auto *RT = getType()->getAs();
+  const auto *RT = getType()->getAs();
   if (RT && RT->getDecl()->isParamDestroyedInCallee() &&
   getType().isDestructedType())
 return true;
@@ -3105,7 +3105,7 @@ FunctionDecl::getDefaultedFunctionInfo() const {
 }
 
 bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const {
-  for (auto *I : redecls()) {
+  for (const auto *I : redecls()) {
 if (I->doesThisDeclarationHaveABody()) {
   Definition = I;
   return true;
@@ -3116,7 +3116,7 @@ bool FunctionDecl::hasBody(const FunctionDecl 
*&Definition) const {
 }
 
 bool FunctionDecl::hasTrivialBody() const {
-  Stmt *S = getBody();
+  const Stmt *S = getBody();
   if (!S) {
 // Since we don't have a body for this function, we don't know if it's
 // trivial or not.
@@ -3212,7 +3212,7 @@ void FunctionDecl::setPure(bool P) {
 
 template
 static bool isNamed(const NamedDecl *ND, const char (&Str)[Len]) {
-  IdentifierInfo *II = ND->getIdentifier();
+  const IdentifierInfo *II = ND->getIdentifier();
   return II && II->isStr(Str);
 }
 
@@ -3305,9 +3305,9 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() 
const {
   if (proto->getNumParams() != 2 || proto->isVariadic())
 return false;
 
-  ASTContext &Context =
-cast(getDeclContext()->getRedeclContext())
-  ->getASTContext();
+  const ASTContext &Context =
+  cast(getDeclContext()->getRedeclContext())
+  ->getASTContext();
 
   // The result type and first argument type are constant across all
   // these operators.  The second argument must be exactly void*.
@@ -3342,7 +3342,7 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction(
 
   unsigned Params = 1;
   QualType Ty = FPT->getParamType(Params);
-  ASTContext &Ctx = getASTContext();
+  const ASTContext &Ctx = getASTContext();
 
   auto Consume = [&] {
 ++Params;
@@ -3388,7 +3388,8 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction(
 QualType T = Ty;
 while (const auto *TD = T->getAs())
   T = TD->getDecl()->getUnderlyingType();
-IdentifierInfo *II = T->castAs()->getDecl()->getIdentifier();
+const IdentifierInfo *II =
+T->castAs()->getDecl()->getIdentifier();
 if (II && II->isStr("__hot_cold_t"))
   Consume();
   }
@@ -3586,7 +3587,7 @@ unsigned FunctionDecl::getBuiltinID(bool 
ConsiderWrapperFunctions) const {
   (!hasAttr() && !hasAttr()))
 return 0;
 
-  ASTContext &Context = getASTContext();
+  const ASTContext &Context = getASTContext();
   if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
 return BuiltinID;
 
@@ -3745,7 +3746,7 @@ bool 
FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const {
   assert(!doesThisDeclarationHaveABody() &&
  "Must have a declaration without a body.");
 
-  ASTContext &Context = getASTContext();
+  const ASTContext &Context = getASTContext();
 
   if (Context.getLangOpts().MSVCCompat) {
 const FunctionDecl *Definition;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 687c51a - [clang][Interp][NFC] Remove unused using alias

2024-01-02 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-01-02T14:18:29+01:00
New Revision: 687c51a3972af17b3f225e692e79fd898a1b6f95

URL: 
https://github.com/llvm/llvm-project/commit/687c51a3972af17b3f225e692e79fd898a1b6f95
DIFF: 
https://github.com/llvm/llvm-project/commit/687c51a3972af17b3f225e692e79fd898a1b6f95.diff

LOG: [clang][Interp][NFC] Remove unused using alias

Added: 


Modified: 
clang/lib/AST/Interp/Interp.h

Removed: 




diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index a240d74d63425e..828d4ea35526d6 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -37,7 +37,6 @@
 namespace clang {
 namespace interp {
 
-using APInt = llvm::APInt;
 using APSInt = llvm::APSInt;
 
 /// Convert a value to an APValue.



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] f0f16be - [clang][Sema][NFC] Clean up BuildOverloadedCallExpr

2024-01-08 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-01-08T15:04:52+01:00
New Revision: f0f16be77e1977d04535556ef69eaccd5bfef36f

URL: 
https://github.com/llvm/llvm-project/commit/f0f16be77e1977d04535556ef69eaccd5bfef36f
DIFF: 
https://github.com/llvm/llvm-project/commit/f0f16be77e1977d04535556ef69eaccd5bfef36f.diff

LOG: [clang][Sema][NFC] Clean up BuildOverloadedCallExpr

Added: 


Modified: 
clang/lib/Sema/SemaOverload.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 8e3a2d1288079b..07da5cb150b467 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -13999,17 +13999,14 @@ ExprResult Sema::BuildOverloadedCallExpr(Scope *S, 
Expr *Fn,
   // encloses the call and whose return type contains a placeholder type as if
   // the UnresolvedLookupExpr was type-dependent.
   if (OverloadResult == OR_Success) {
-FunctionDecl *FDecl = Best->Function;
+const FunctionDecl *FDecl = Best->Function;
 if (FDecl && FDecl->isTemplateInstantiation() &&
 FDecl->getReturnType()->isUndeducedType()) {
-  if (auto TP = FDecl->getTemplateInstantiationPattern(false)) {
-if (TP->willHaveBody()) {
-  CallExpr *CE =
-  CallExpr::Create(Context, Fn, Args, Context.DependentTy,
-   VK_PRValue, RParenLoc, CurFPFeatureOverrides());
-  result = CE;
-  return result;
-}
+  if (const auto *TP =
+  FDecl->getTemplateInstantiationPattern(/*ForDefinition=*/false);
+  TP && TP->willHaveBody()) {
+return CallExpr::Create(Context, Fn, Args, Context.DependentTy,
+VK_PRValue, RParenLoc, 
CurFPFeatureOverrides());
   }
 }
   }



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 20c144e - [clang][Sema][NFC] Make a few parameters const

2024-01-09 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-01-09T14:46:37+01:00
New Revision: 20c144ea10be1e4b2620a4a1c949cbad315cff72

URL: 
https://github.com/llvm/llvm-project/commit/20c144ea10be1e4b2620a4a1c949cbad315cff72
DIFF: 
https://github.com/llvm/llvm-project/commit/20c144ea10be1e4b2620a4a1c949cbad315cff72.diff

LOG: [clang][Sema][NFC] Make a few parameters const

Added: 


Modified: 
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaExpr.cpp

Removed: 




diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 4c464a1ae4c67f..edaee4c4b66d55 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -12972,7 +12972,7 @@ class Sema final {
   QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS,
 SourceLocation QuestionLoc);
 
-  bool DiagnoseConditionalForNull(Expr *LHSExpr, Expr *RHSExpr,
+  bool DiagnoseConditionalForNull(const Expr *LHSExpr, const Expr *RHSExpr,
   SourceLocation QuestionLoc);
 
   void DiagnoseAlwaysNonNullPointer(Expr *E,

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 960f513db2..60ad035570c830 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -8691,10 +8691,10 @@ ExprResult Sema::ActOnParenListExpr(SourceLocation L,
 /// Emit a specialized diagnostic when one expression is a null pointer
 /// constant and the other is not a pointer.  Returns true if a diagnostic is
 /// emitted.
-bool Sema::DiagnoseConditionalForNull(Expr *LHSExpr, Expr *RHSExpr,
+bool Sema::DiagnoseConditionalForNull(const Expr *LHSExpr, const Expr *RHSExpr,
   SourceLocation QuestionLoc) {
-  Expr *NullExpr = LHSExpr;
-  Expr *NonPointerExpr = RHSExpr;
+  const Expr *NullExpr = LHSExpr;
+  const Expr *NonPointerExpr = RHSExpr;
   Expr::NullPointerConstantKind NullKind =
   NullExpr->isNullPointerConstant(Context,
   Expr::NPC_ValueDependentIsNotNull);
@@ -8730,7 +8730,8 @@ bool Sema::DiagnoseConditionalForNull(Expr *LHSExpr, Expr 
*RHSExpr,
 }
 
 /// Return false if the condition expression is valid, true otherwise.
-static bool checkCondition(Sema &S, Expr *Cond, SourceLocation QuestionLoc) {
+static bool checkCondition(Sema &S, const Expr *Cond,
+   SourceLocation QuestionLoc) {
   QualType CondTy = Cond->getType();
 
   // OpenCL v1.1 s6.3.i says the condition cannot be a floating point type.
@@ -9542,28 +9543,27 @@ static bool IsArithmeticOp(BinaryOperatorKind Opc) {
 /// expression, either using a built-in or overloaded operator,
 /// and sets *OpCode to the opcode and *RHSExprs to the right-hand side
 /// expression.
-static bool IsArithmeticBinaryExpr(Expr *E, BinaryOperatorKind *Opcode,
-   Expr **RHSExprs) {
+static bool IsArithmeticBinaryExpr(const Expr *E, BinaryOperatorKind *Opcode,
+   const Expr **RHSExprs) {
   // Don't strip parenthesis: we should not warn if E is in parenthesis.
   E = E->IgnoreImpCasts();
   E = E->IgnoreConversionOperatorSingleStep();
   E = E->IgnoreImpCasts();
-  if (auto *MTE = dyn_cast(E)) {
+  if (const auto *MTE = dyn_cast(E)) {
 E = MTE->getSubExpr();
 E = E->IgnoreImpCasts();
   }
 
   // Built-in binary operator.
-  if (BinaryOperator *OP = dyn_cast(E)) {
-if (IsArithmeticOp(OP->getOpcode())) {
-  *Opcode = OP->getOpcode();
-  *RHSExprs = OP->getRHS();
-  return true;
-}
+  if (const auto *OP = dyn_cast(E);
+  OP && IsArithmeticOp(OP->getOpcode())) {
+*Opcode = OP->getOpcode();
+*RHSExprs = OP->getRHS();
+return true;
   }
 
   // Overloaded operator.
-  if (CXXOperatorCallExpr *Call = dyn_cast(E)) {
+  if (const auto *Call = dyn_cast(E)) {
 if (Call->getNumArgs() != 2)
   return false;
 
@@ -9588,14 +9588,14 @@ static bool IsArithmeticBinaryExpr(Expr *E, 
BinaryOperatorKind *Opcode,
 /// ExprLooksBoolean - Returns true if E looks boolean, i.e. it has boolean 
type
 /// or is a logical expression such as (x==y) which has int type, but is
 /// commonly interpreted as boolean.
-static bool ExprLooksBoolean(Expr *E) {
+static bool ExprLooksBoolean(const Expr *E) {
   E = E->IgnoreParenImpCasts();
 
   if (E->getType()->isBooleanType())
 return true;
-  if (BinaryOperator *OP = dyn_cast(E))
+  if (const auto *OP = dyn_cast(E))
 return OP->isComparisonOp() || OP->isLogicalOp();
-  if (UnaryOperator *OP = dyn_cast(E))
+  if (const auto *OP = dyn_cast(E))
 return OP->getOpcode() == UO_LNot;
   if (E->getType()->isPointerType())
 return true;
@@ -9609,13 +9609,11 @@ static bool ExprLooksBoolean(Expr *E) {
 /// and binary operator are mixed in a way that suggests the programmer assumed
 /// the conditional operator has higher precedence, for example:
 /// "int x = a

[clang] c2b57a0 - [clang][Interp][NFC] Make a few pointers const

2024-01-09 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-01-10T06:38:28+01:00
New Revision: c2b57a052daee22cb6401bc7bc514d858ea11eb6

URL: 
https://github.com/llvm/llvm-project/commit/c2b57a052daee22cb6401bc7bc514d858ea11eb6
DIFF: 
https://github.com/llvm/llvm-project/commit/c2b57a052daee22cb6401bc7bc514d858ea11eb6.diff

LOG: [clang][Interp][NFC] Make a few pointers const

Added: 


Modified: 
clang/lib/AST/Interp/Descriptor.cpp
clang/lib/AST/Interp/Descriptor.h
clang/lib/AST/Interp/Program.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/Descriptor.cpp 
b/clang/lib/AST/Interp/Descriptor.cpp
index 59a952135a2d80..b330e54baf335a 100644
--- a/clang/lib/AST/Interp/Descriptor.cpp
+++ b/clang/lib/AST/Interp/Descriptor.cpp
@@ -275,8 +275,8 @@ Descriptor::Descriptor(const DeclTy &D, const Descriptor 
*Elem, MetadataSize MD,
 }
 
 /// Unknown-size arrays of composite elements.
-Descriptor::Descriptor(const DeclTy &D, Descriptor *Elem, bool IsTemporary,
-   UnknownSize)
+Descriptor::Descriptor(const DeclTy &D, const Descriptor *Elem,
+   bool IsTemporary, UnknownSize)
 : Source(D), ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)),
   Size(UnknownSizeMark), MDSize(0),
   AllocSize(alignof(void *) + sizeof(InitMapPtr)), ElemDesc(Elem),
@@ -286,7 +286,7 @@ Descriptor::Descriptor(const DeclTy &D, Descriptor *Elem, 
bool IsTemporary,
 }
 
 /// Composite records.
-Descriptor::Descriptor(const DeclTy &D, Record *R, MetadataSize MD,
+Descriptor::Descriptor(const DeclTy &D, const Record *R, MetadataSize MD,
bool IsConst, bool IsTemporary, bool IsMutable)
 : Source(D), ElemSize(std::max(alignof(void *), R->getFullSize())),
   Size(ElemSize), MDSize(MD.value_or(0)), AllocSize(Size + MDSize),

diff  --git a/clang/lib/AST/Interp/Descriptor.h 
b/clang/lib/AST/Interp/Descriptor.h
index 8135f3d12f7035..580c200f909529 100644
--- a/clang/lib/AST/Interp/Descriptor.h
+++ b/clang/lib/AST/Interp/Descriptor.h
@@ -100,7 +100,7 @@ struct Descriptor final {
   static constexpr MetadataSize InlineDescMD = sizeof(InlineDescriptor);
 
   /// Pointer to the record, if block contains records.
-  Record *const ElemRecord = nullptr;
+  const Record *const ElemRecord = nullptr;
   /// Descriptor of the array element.
   const Descriptor *const ElemDesc = nullptr;
   /// Flag indicating if the block is mutable.
@@ -135,10 +135,11 @@ struct Descriptor final {
  unsigned NumElems, bool IsConst, bool IsTemporary, bool 
IsMutable);
 
   /// Allocates a descriptor for an array of composites of unknown size.
-  Descriptor(const DeclTy &D, Descriptor *Elem, bool IsTemporary, UnknownSize);
+  Descriptor(const DeclTy &D, const Descriptor *Elem, bool IsTemporary,
+ UnknownSize);
 
   /// Allocates a descriptor for a record.
-  Descriptor(const DeclTy &D, Record *R, MetadataSize MD, bool IsConst,
+  Descriptor(const DeclTy &D, const Record *R, MetadataSize MD, bool IsConst,
  bool IsTemporary, bool IsMutable);
 
   Descriptor(const DeclTy &D, MetadataSize MD);

diff  --git a/clang/lib/AST/Interp/Program.cpp 
b/clang/lib/AST/Interp/Program.cpp
index 52e13398163ecf..1daefab4dcdac1 100644
--- a/clang/lib/AST/Interp/Program.cpp
+++ b/clang/lib/AST/Interp/Program.cpp
@@ -315,14 +315,14 @@ Descriptor *Program::createDescriptor(const DeclTy &D, 
const Type *Ty,
   bool IsConst, bool IsTemporary,
   bool IsMutable, const Expr *Init) {
   // Classes and structures.
-  if (auto *RT = Ty->getAs()) {
-if (auto *Record = getOrCreateRecord(RT->getDecl()))
+  if (const auto *RT = Ty->getAs()) {
+if (const auto *Record = getOrCreateRecord(RT->getDecl()))
   return allocateDescriptor(D, Record, MDSize, IsConst, IsTemporary,
 IsMutable);
   }
 
   // Arrays.
-  if (auto ArrayType = Ty->getAsArrayTypeUnsafe()) {
+  if (const auto ArrayType = Ty->getAsArrayTypeUnsafe()) {
 QualType ElemTy = ArrayType->getElementType();
 // Array of well-known bounds.
 if (auto CAT = dyn_cast(ArrayType)) {
@@ -338,7 +338,7 @@ Descriptor *Program::createDescriptor(const DeclTy &D, 
const Type *Ty,
   } else {
 // Arrays of composites. In this case, the array is a list of pointers,
 // followed by the actual elements.
-Descriptor *ElemDesc = createDescriptor(
+const Descriptor *ElemDesc = createDescriptor(
 D, ElemTy.getTypePtr(), std::nullopt, IsConst, IsTemporary);
 if (!ElemDesc)
   return nullptr;
@@ -358,8 +358,8 @@ Descriptor *Program::createDescriptor(const DeclTy &D, 
const Type *Ty,
 return allocateDescriptor(D, *T, IsTemporary,
   Descriptor::UnknownSize{});
   } else {
-Descriptor *Desc = createDescriptor(D, ElemTy.getTypePtr(), MDSize,
-   

[clang] 711e3a5 - [clang][parse] Move source range into ParsedAttibutesView

2022-03-24 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-03-24T08:11:57+01:00
New Revision: 711e3a569167ee6f3fbccf983933d92cd03a469b

URL: 
https://github.com/llvm/llvm-project/commit/711e3a569167ee6f3fbccf983933d92cd03a469b
DIFF: 
https://github.com/llvm/llvm-project/commit/711e3a569167ee6f3fbccf983933d92cd03a469b.diff

LOG: [clang][parse] Move source range into ParsedAttibutesView

Move the SourceRange from the old ParsedAttributesWithRange into
ParsedAttributesView, so we have source range information available
everywhere we use attributes.

This also removes ParsedAttributesWithRange (replaced by simply using
ParsedAttributes) and ParsedAttributesVieWithRange (replaced by using
ParsedAttributesView).

Differential Revision: https://reviews.llvm.org/D121201

Added: 


Modified: 
clang/include/clang/Parse/Parser.h
clang/include/clang/Sema/DeclSpec.h
clang/include/clang/Sema/ParsedAttr.h
clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParseCXXInlineMethods.cpp
clang/lib/Parse/ParseDecl.cpp
clang/lib/Parse/ParseDeclCXX.cpp
clang/lib/Parse/ParseExprCXX.cpp
clang/lib/Parse/ParseObjc.cpp
clang/lib/Parse/ParseOpenMP.cpp
clang/lib/Parse/ParsePragma.cpp
clang/lib/Parse/ParseStmt.cpp
clang/lib/Parse/ParseTemplate.cpp
clang/lib/Parse/ParseTentative.cpp
clang/lib/Parse/Parser.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaStmt.cpp
clang/lib/Sema/SemaStmtAttr.cpp
clang/lib/Sema/SemaType.cpp
clang/test/SemaOpenCL/address-spaces.cl

Removed: 




diff  --git a/clang/include/clang/Parse/Parser.h 
b/clang/include/clang/Parse/Parser.h
index a3c1a15d333ce..1af53a151f8c9 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -1544,7 +1544,7 @@ class Parser : public CodeCompletionHandler {
   };
 
   NamedDecl *ParseCXXInlineMethodDef(AccessSpecifier AS,
- ParsedAttributes &AccessAttrs,
+ const ParsedAttributesView &AccessAttrs,
  ParsingDeclarator &D,
  const ParsedTemplateInfo &TemplateInfo,
  const VirtSpecifiers &VS,
@@ -1580,15 +1580,15 @@ class Parser : public CodeCompletionHandler {
 
   
//======//
   // C99 6.9: External Definitions.
-  DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
+  DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributes &Attrs,
   ParsingDeclSpec *DS = nullptr);
   bool isDeclarationAfterDeclarator();
   bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
-  DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(
-  ParsedAttributesWithRange 
&attrs,
-  ParsingDeclSpec *DS = 
nullptr,
-  AccessSpecifier AS = 
AS_none);
-  DeclGroupPtrTy ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange 
&attrs,
+  DeclGroupPtrTy
+  ParseDeclarationOrFunctionDefinition(ParsedAttributes &Attrs,
+   ParsingDeclSpec *DS = nullptr,
+   AccessSpecifier AS = AS_none);
+  DeclGroupPtrTy ParseDeclOrFunctionDefInternal(ParsedAttributes &Attrs,
 ParsingDeclSpec &DS,
 AccessSpecifier AS);
 
@@ -1603,7 +1603,7 @@ class Parser : public CodeCompletionHandler {
 
   // Objective-C External Declarations
   void MaybeSkipAttributes(tok::ObjCKeywordKind Kind);
-  DeclGroupPtrTy ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs);
+  DeclGroupPtrTy ParseObjCAtDirectives(ParsedAttributes &Attrs);
   DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc);
   Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
 ParsedAttributes &prefixAttrs);
@@ -1984,9 +1984,8 @@ class Parser : public CodeCompletionHandler {
   bool MissingOK,
   ForRangeInfo *FRI = nullptr,
   bool EnterForConditionScope = false);
-  DeclGroupPtrTy
-  ParseAliasDeclarationInInitStatement(DeclaratorContext Context,
-   ParsedAttributesWithRange &Attrs);
+  DeclGroupPtrTy ParseAliasDeclarationInInitStatement(DeclaratorContext 
Context,
+  ParsedAttributes &Attrs);
 
   
//======//
   // C++ Coroutines
@@ -2066,12 +2065,10 @@ class Parser : public CodeCompletionHandler {
   StmtVe

[clang] 11e52ec - [clang] Short-circuit trivial constructors when evaluating arrays

2022-08-03 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-08-03T10:38:15+02:00
New Revision: 11e52ecf74e942b738fa8496960bbb2f0a7373de

URL: 
https://github.com/llvm/llvm-project/commit/11e52ecf74e942b738fa8496960bbb2f0a7373de
DIFF: 
https://github.com/llvm/llvm-project/commit/11e52ecf74e942b738fa8496960bbb2f0a7373de.diff

LOG: [clang] Short-circuit trivial constructors when evaluating arrays

VisitCXXConstructExpr() will later do something similar, but for large
arrays, we should try to do it once an not for every element.

Fixes #56774

Differential Revision: https://reviews.llvm.org/D130791

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/AST/ExprConstant.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9dc08639dafb4..2c439a01d7216 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -54,6 +54,9 @@ Bug Fixes
   `Issue 56800 `_.
 - Fix `#56772 `_ - invalid
   destructor names were incorrectly accepted on template classes.
+- Improve compile-times with large dynamic array allocations with trivial
+  constructors. This fixes
+  `Issue 56774`_.
 
 Improvements to Clang's diagnostics
 ^^^

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 32a04ca9e3de3..efaccf52132b3 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10833,6 +10833,9 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const 
CXXConstructExpr *E,
 if (FinalSize == 0)
   return true;
 
+bool HasTrivialConstructor = CheckTrivialDefaultConstructor(
+Info, E->getExprLoc(), E->getConstructor(),
+E->requiresZeroInitialization());
 LValue ArrayElt = Subobject;
 ArrayElt.addArray(Info, E, CAT);
 // We do the whole initialization in two passes, first for just one 
element,
@@ -10856,19 +10859,26 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const 
CXXConstructExpr *E,
 for (unsigned I = OldElts; I < N; ++I)
   Value->getArrayInitializedElt(I) = Filler;
 
-  // Initialize the elements.
-  for (unsigned I = OldElts; I < N; ++I) {
-if (!VisitCXXConstructExpr(E, ArrayElt,
-   &Value->getArrayInitializedElt(I),
-   CAT->getElementType()) ||
-!HandleLValueArrayAdjustment(Info, E, ArrayElt,
- CAT->getElementType(), 1))
-  return false;
-// When checking for const initilization any diagnostic is considered
-// an error.
-if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
-!Info.keepEvaluatingAfterFailure())
-  return false;
+  if (HasTrivialConstructor && N == FinalSize) {
+// If we have a trivial constructor, only evaluate it once and copy
+// the result into all the array elements.
+APValue &FirstResult = Value->getArrayInitializedElt(0);
+for (unsigned I = OldElts; I < FinalSize; ++I)
+  Value->getArrayInitializedElt(I) = FirstResult;
+  } else {
+for (unsigned I = OldElts; I < N; ++I) {
+  if (!VisitCXXConstructExpr(E, ArrayElt,
+ &Value->getArrayInitializedElt(I),
+ CAT->getElementType()) ||
+  !HandleLValueArrayAdjustment(Info, E, ArrayElt,
+   CAT->getElementType(), 1))
+return false;
+  // When checking for const initilization any diagnostic is considered
+  // an error.
+  if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
+  !Info.keepEvaluatingAfterFailure())
+return false;
+}
   }
 }
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] f4b9c07 - [clang][NFC] Try to fix the docs build

2022-08-03 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-08-03T10:52:02+02:00
New Revision: f4b9c0735e339b177d98fe69cf210eea00c0af62

URL: 
https://github.com/llvm/llvm-project/commit/f4b9c0735e339b177d98fe69cf210eea00c0af62
DIFF: 
https://github.com/llvm/llvm-project/commit/f4b9c0735e339b177d98fe69cf210eea00c0af62.diff

LOG: [clang][NFC] Try to fix the docs build

Added: 


Modified: 
clang/docs/ReleaseNotes.rst

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2c439a01d721..8e35bd567b65 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -56,7 +56,7 @@ Bug Fixes
   destructor names were incorrectly accepted on template classes.
 - Improve compile-times with large dynamic array allocations with trivial
   constructors. This fixes
-  `Issue 56774`_.
+  `Issue 56774 `_.
 
 Improvements to Clang's diagnostics
 ^^^



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 8b74074 - [clang][sema] Fix collectConjunctionTerms()

2022-08-04 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-08-05T06:45:32+02:00
New Revision: 8b74074731eeb3ff673bd7da4cd963efe78f8db6

URL: 
https://github.com/llvm/llvm-project/commit/8b74074731eeb3ff673bd7da4cd963efe78f8db6
DIFF: 
https://github.com/llvm/llvm-project/commit/8b74074731eeb3ff673bd7da4cd963efe78f8db6.diff

LOG: [clang][sema] Fix collectConjunctionTerms()

Consider:

A == 5 && A != 5

IfA is 5, the old collectConjunctionTerms() would call itself again for
the LHS (which it ignores), then the RHS (which it also ignores) and
then just return without ever adding anything to the Terms array.

Differential Revision: https://reviews.llvm.org/D131070

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaTemplate.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b9729a6a047f..c9f65b271413 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -60,6 +60,8 @@ Bug Fixes
 - No longer assert/miscompile when trying to make a vectorized ``_BitInt`` type
   using the ``ext_vector_type`` attribute (the ``vector_size`` attribute was
   already properly diagnosing this case).
+- Fix clang not properly diagnosing the failing subexpression when chained
+  binary operators are used in a ``static_assert`` expression.
 
 Improvements to Clang's diagnostics
 ^^^

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index ec1d5421ff51..a9ed3ef6400c 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3585,9 +3585,8 @@ static void collectConjunctionTerms(Expr *Clause,
 if (BinOp->getOpcode() == BO_LAnd) {
   collectConjunctionTerms(BinOp->getLHS(), Terms);
   collectConjunctionTerms(BinOp->getRHS(), Terms);
+  return;
 }
-
-return;
   }
 
   Terms.push_back(Clause);



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] d194285 - [clang] Consider array filler in MaybeElementDependentArrayfiller()

2022-08-04 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-08-05T06:47:49+02:00
New Revision: d1942855c4317c61f9fae173afa2cbe1076c3c4c

URL: 
https://github.com/llvm/llvm-project/commit/d1942855c4317c61f9fae173afa2cbe1076c3c4c
DIFF: 
https://github.com/llvm/llvm-project/commit/d1942855c4317c61f9fae173afa2cbe1076c3c4c.diff

LOG: [clang] Consider array filler in MaybeElementDependentArrayfiller()

Any InitListExpr may have an array filler and since we may be evaluating
the array filler as well, we need to take into account that the array
filler expression might make the InitListExpr element dependent.

Fixes https://github.com/llvm/llvm-project/issues/56016

Differential Revision: https://reviews.llvm.org/D131155

Added: 
clang/test/SemaCXX/constexpr-array-init.cpp

Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/AST/ExprConstant.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c9f65b271413..a2d7526bb770 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -62,6 +62,10 @@ Bug Fixes
   already properly diagnosing this case).
 - Fix clang not properly diagnosing the failing subexpression when chained
   binary operators are used in a ``static_assert`` expression.
+- Fix a crash when evaluating a multi-dimensional array's array filler
+  expression is element-dependent. This fixes
+  `Issue 50601 `_.
+
 
 Improvements to Clang's diagnostics
 ^^^

diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 6f3539a4b2c1..36f957711316 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10695,6 +10695,11 @@ static bool MaybeElementDependentArrayFiller(const 
Expr *FillerExpr) {
   if (MaybeElementDependentArrayFiller(ILE->getInit(I)))
 return true;
 }
+
+if (ILE->hasArrayFiller() &&
+MaybeElementDependentArrayFiller(ILE->getArrayFiller()))
+  return true;
+
 return false;
   }
   return true;

diff  --git a/clang/test/SemaCXX/constexpr-array-init.cpp 
b/clang/test/SemaCXX/constexpr-array-init.cpp
new file mode 100644
index ..cb11f47fb3cb
--- /dev/null
+++ b/clang/test/SemaCXX/constexpr-array-init.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++20 -verify %s
+
+/// This test case used to crash in constant evaluation
+/// because of the two-dimensional array with an array
+/// filler expression.
+
+/// expected-no-diagnostics
+struct Foo {
+  int a;
+  constexpr Foo()
+  : a(get_int()) {
+  }
+
+  constexpr int get_int() const {
+return 5;
+  }
+};
+
+static constexpr Foo bar[2][1] = {
+{{}},
+};
+static_assert(bar[0][0].a == 5);
+static_assert(bar[1][0].a == 5);
+



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] e5ccd66 - [clang][sema] Enable first-class bool support for C2x

2022-03-09 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-03-09T15:04:24+01:00
New Revision: e5ccd668019888de2704ae670da88a7be8cf7e0f

URL: 
https://github.com/llvm/llvm-project/commit/e5ccd668019888de2704ae670da88a7be8cf7e0f
DIFF: 
https://github.com/llvm/llvm-project/commit/e5ccd668019888de2704ae670da88a7be8cf7e0f.diff

LOG: [clang][sema] Enable first-class bool support for C2x

Implement N2395 for C2x.

This also covers adding "bool", which is part of N2394.

Differential Revision: https://reviews.llvm.org/D120244

Added: 
clang/test/Headers/stdbool.c
clang/test/Sema/c2x-bool.c

Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Frontend/CompilerInvocation.cpp
clang/lib/Headers/stdbool.h

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 662d4b1b2443e..53d07c03af0f9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -110,6 +110,7 @@ C2x Feature Support
 ---
 
 - Implemented `WG14 N2674 The noreturn attribute 
`_.
+- Implemented `WG14 N2935 Make false and true first-class language features 
`_.
 
 C++ Language Changes in Clang
 -

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index 5d7c999b0143a..cac443de75dae 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3249,8 +3249,8 @@ void CompilerInvocation::setLangDefaults(LangOptions 
&Opts, InputKind IK,
 
   Opts.RenderScript = IK.getLanguage() == Language::RenderScript;
 
-  // OpenCL and C++ both have bool, true, false keywords.
-  Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
+  // OpenCL, C++ and C2x have bool, true, false keywords.
+  Opts.Bool = Opts.OpenCL || Opts.CPlusPlus || Opts.C2x;
 
   // OpenCL has half keyword
   Opts.Half = Opts.OpenCL;

diff  --git a/clang/lib/Headers/stdbool.h b/clang/lib/Headers/stdbool.h
index 2525363dd02a5..ecf560218c3b5 100644
--- a/clang/lib/Headers/stdbool.h
+++ b/clang/lib/Headers/stdbool.h
@@ -10,8 +10,13 @@
 #ifndef __STDBOOL_H
 #define __STDBOOL_H
 
-/* Don't define bool, true, and false in C++, except as a GNU extension. */
-#ifndef __cplusplus
+#define __bool_true_false_are_defined 1
+
+#if __STDC_VERSION__ > 201710L
+#if !defined(_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS)
+#warning "the  header is deprecated in C2x"
+#endif /* !defined(_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS) */
+#elif !defined(__cplusplus)
 #define bool _Bool
 #define true 1
 #define false 0
@@ -20,12 +25,10 @@
 #define _Bool bool
 #if __cplusplus < 201103L
 /* For C++98, define bool, false, true as a GNU extension. */
-#define bool  bool
+#define bool bool
 #define false false
-#define true  true
+#define true true
 #endif
 #endif
 
-#define __bool_true_false_are_defined 1
-
 #endif /* __STDBOOL_H */

diff  --git a/clang/test/Headers/stdbool.c b/clang/test/Headers/stdbool.c
new file mode 100644
index 0..1ac94dc67a28f
--- /dev/null
+++ b/clang/test/Headers/stdbool.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fgnuc-version=4.2.1 -std=c11 -E -dM %s 2>&1 | FileCheck 
--check-prefix=CHECK-C11 %s
+// RUN: %clang_cc1 -fgnuc-version=4.2.1 -std=c2x -E -dM %s 2>&1 | FileCheck 
--check-prefix=CHECK-C2X %s
+// RUN: %clang_cc1 -fgnuc-version=4.2.1 -std=c2x -E -dM 
-D_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS %s 2>&1 | FileCheck 
--check-prefix=CHECK-C2X-CRT %s
+
+#include 
+
+// CHECK-C11: #define bool _Bool
+// CHECK-C11: #define false 0
+// CHECK-C11: #define true 1
+
+// CHECK-C2X: warning "the  header is deprecated
+// CHECK-C2X-NOT: #define bool
+// CHECK-C2X-NOT: #define true
+// CHECK-C2X-NOT: #define falsea
+
+// CHECK-C2X-CRT-NOT: warning "the  header is deprecated
+// CHECK-C2X-CRT-NOT: #define bool
+// CHECK-C2X-CRT-NOT: #define true
+// CHECK-C2X-CRT-NOT: #define false

diff  --git a/clang/test/Sema/c2x-bool.c b/clang/test/Sema/c2x-bool.c
new file mode 100644
index 0..0bc147228fda4
--- /dev/null
+++ b/clang/test/Sema/c2x-bool.c
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -std=c2x -fsyntax-only -verify %s
+
+_Static_assert(_Generic(true, _Bool : 1, default: 0));
+_Static_assert(_Generic(false, _Bool : 1, default: 0));
+
+_Static_assert(_Generic(true, bool : 1, default: 0));
+_Static_assert(_Generic(false, bool : 1, default: 0));
+
+_Static_assert(_Generic(true, bool : true, default: false));
+_Static_assert(_Generic(false, bool : true, default: false));
+
+_Static_assert(true == (bool)+1);
+_Static_assert(false == (bool)+0);
+
+_Static_assert(_Generic(+true, bool : 0, unsigned int : 0, signed int : 1, 
default : 0));
+
+struct S {
+  bool b : 1;
+} s;
+_Static_assert(_Generic(+s.b, bool : 0, unsigned int : 0, signed int : 1, 
default : 0));
+
+static void *f = false; // expected-warning {{to null from a constant boolean 
expressi

[clang] 0eb5891 - [clang][preprocessor] Allow calling DumpToken() on annotation tokens

2022-04-12 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-04-13T07:06:00+02:00
New Revision: 0eb5891adcb84ccf665e88a62f573a1e22696782

URL: 
https://github.com/llvm/llvm-project/commit/0eb5891adcb84ccf665e88a62f573a1e22696782
DIFF: 
https://github.com/llvm/llvm-project/commit/0eb5891adcb84ccf665e88a62f573a1e22696782.diff

LOG: [clang][preprocessor] Allow calling DumpToken() on annotation tokens

Differential Revision: https://reviews.llvm.org/D122659

Added: 


Modified: 
clang/lib/Lex/Preprocessor.cpp

Removed: 




diff  --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
index 43b9930db1d6d..abbd1e9d3 100644
--- a/clang/lib/Lex/Preprocessor.cpp
+++ b/clang/lib/Lex/Preprocessor.cpp
@@ -232,8 +232,10 @@ void Preprocessor::FinalizeForModelFile() {
 }
 
 void Preprocessor::DumpToken(const Token &Tok, bool DumpFlags) const {
-  llvm::errs() << tok::getTokenName(Tok.getKind()) << " '"
-   << getSpelling(Tok) << "'";
+  llvm::errs() << tok::getTokenName(Tok.getKind());
+
+  if (!Tok.isAnnotation())
+llvm::errs() << " '" << getSpelling(Tok) << "'";
 
   if (!DumpFlags) return;
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 33ec653 - [clang][lexer] Allow u8 character literal prefixes in C2x

2022-04-19 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-04-19T09:57:51+02:00
New Revision: 33ec65305525626d5d93bd794c1c9cfa55d0ca8f

URL: 
https://github.com/llvm/llvm-project/commit/33ec65305525626d5d93bd794c1c9cfa55d0ca8f
DIFF: 
https://github.com/llvm/llvm-project/commit/33ec65305525626d5d93bd794c1c9cfa55d0ca8f.diff

LOG: [clang][lexer] Allow u8 character literal prefixes in C2x

Implement N2418 for C2x.

Differential Revision: https://reviews.llvm.org/D119221

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Lex/Lexer.cpp
clang/lib/Sema/SemaExpr.cpp
clang/test/Lexer/utf8-char-literal.cpp
clang/www/c_status.html

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index fd4eac5458c0a..c396322f2de57 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -226,6 +226,7 @@ C2x Feature Support
 - Implemented `WG14 N2775 Literal suffixes for bit-precise integers 
`_.
 - Implemented the `*_WIDTH` macros to complete support for
   `WG14 N2412 Two's complement sign representation for C2x 
`_.
+- Implemented `WG14 N2418 Adding the u8 character prefix 
`_.
 
 C++ Language Changes in Clang
 -

diff  --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 6e8072fb1b2d9..6fc78cfa8ad95 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -3459,7 +3459,10 @@ bool Lexer::LexTokenInternal(Token &Result, bool 
TokAtPhysicalStartOfLine) {
 MIOpt.ReadToken();
 return LexNumericConstant(Result, CurPtr);
 
-  case 'u':   // Identifier (uber) or C11/C++11 UTF-8 or UTF-16 string literal
+  // Identifier (e.g., uber), or
+  // UTF-8 (C2x/C++17) or UTF-16 (C11/C++11) character literal, or
+  // UTF-8 or UTF-16 string literal (C11/C++11).
+  case 'u':
 // Notify MIOpt that we read a non-whitespace/non-comment token.
 MIOpt.ReadToken();
 
@@ -3493,7 +3496,7 @@ bool Lexer::LexTokenInternal(Token &Result, bool 
TokAtPhysicalStartOfLine) {
ConsumeChar(ConsumeChar(CurPtr, SizeTmp, 
Result),
SizeTmp2, Result),
tok::utf8_string_literal);
-if (Char2 == '\'' && LangOpts.CPlusPlus17)
+if (Char2 == '\'' && (LangOpts.CPlusPlus17 || LangOpts.C2x))
   return LexCharConstant(
   Result, ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
   SizeTmp2, Result),
@@ -3517,7 +3520,7 @@ bool Lexer::LexTokenInternal(Token &Result, bool 
TokAtPhysicalStartOfLine) {
 // treat u like the start of an identifier.
 return LexIdentifierContinue(Result, CurPtr);
 
-  case 'U':   // Identifier (Uber) or C11/C++11 UTF-32 string literal
+  case 'U': // Identifier (e.g. Uber) or C11/C++11 UTF-32 string literal
 // Notify MIOpt that we read a non-whitespace/non-comment token.
 MIOpt.ReadToken();
 

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3e84961a5079f..bb0bde6a31b50 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3609,6 +3609,8 @@ ExprResult Sema::ActOnCharacterConstant(const Token &Tok, 
Scope *UDLScope) {
   QualType Ty;
   if (Literal.isWide())
 Ty = Context.WideCharTy; // L'x' -> wchar_t in C and C++.
+  else if (Literal.isUTF8() && getLangOpts().C2x)
+Ty = Context.UnsignedCharTy; // u8'x' -> unsigned char in C2x
   else if (Literal.isUTF8() && getLangOpts().Char8)
 Ty = Context.Char8Ty; // u8'x' -> char8_t when it exists.
   else if (Literal.isUTF16())
@@ -3618,7 +3620,8 @@ ExprResult Sema::ActOnCharacterConstant(const Token &Tok, 
Scope *UDLScope) {
   else if (!getLangOpts().CPlusPlus || Literal.isMultiChar())
 Ty = Context.IntTy;   // 'x' -> int in C, 'wxyz' -> int in C++.
   else
-Ty = Context.CharTy;  // 'x' -> char in C++
+Ty = Context.CharTy; // 'x' -> char in C++;
+ // u8'x' -> char in C11-C17 and in C++ without 
char8_t.
 
   CharacterLiteral::CharacterKind Kind = CharacterLiteral::Ascii;
   if (Literal.isWide())

diff  --git a/clang/test/Lexer/utf8-char-literal.cpp 
b/clang/test/Lexer/utf8-char-literal.cpp
index 0ddaabc842257..ababc8b9c21bc 100644
--- a/clang/test/Lexer/utf8-char-literal.cpp
+++ b/clang/test/Lexer/utf8-char-literal.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -fsyntax-only 
-verify %s
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c11 -x c -fsyntax-only 
-verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c2x -x c -fsyntax-only 
-verify %s
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++1z -fsyntax-only 
-verify %s
 
 int array0[u'ñ' == u'\xf1'? 1 : -1];
@@ -12,4 +13,16 @@ char c = u

[clang] b5787a0 - [clang][driver][wasm] Support -stdlib=libstdc++ for WebAssembly

2022-02-03 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-02-03T16:37:52+01:00
New Revision: b5787a0c6cc4da47b7d7b218e23f780076ad2f5f

URL: 
https://github.com/llvm/llvm-project/commit/b5787a0c6cc4da47b7d7b218e23f780076ad2f5f
DIFF: 
https://github.com/llvm/llvm-project/commit/b5787a0c6cc4da47b7d7b218e23f780076ad2f5f.diff

LOG: [clang][driver][wasm] Support -stdlib=libstdc++ for WebAssembly

The WebAssembly toolchain currently supports only -stdlib=libc++
and implicitly assumes the c++ stdlib to be libc++. Change this to also
support libstdc++.

Differential Revision: https://reviews.llvm.org/D117888#3290628

Added: 


Modified: 
clang/lib/Driver/ToolChains/WebAssembly.cpp
clang/lib/Driver/ToolChains/WebAssembly.h
clang/test/Driver/wasm-toolchain.cpp

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 3614272a5f747..5f64792b45014 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -8,15 +8,17 @@
 
 #include "WebAssembly.h"
 #include "CommonArgs.h"
+#include "Gnu.h"
 #include "clang/Basic/Version.h"
 #include "clang/Config/config.h"
 #include "clang/Driver/Compilation.h"
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
+#include "llvm/Option/ArgList.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
-#include "llvm/Option/ArgList.h"
+#include "llvm/Support/VirtualFileSystem.h"
 
 using namespace clang::driver;
 using namespace clang::driver::tools;
@@ -371,7 +373,11 @@ ToolChain::CXXStdlibType
 WebAssembly::GetCXXStdlibType(const ArgList &Args) const {
   if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
 StringRef Value = A->getValue();
-if (Value != "libc++")
+if (Value == "libc++")
+  return ToolChain::CST_Libcxx;
+else if (Value == "libstdc++")
+  return ToolChain::CST_Libstdcxx;
+else
   getDriver().Diag(diag::err_drv_invalid_stdlib_name)
   << A->getAsString(Args);
   }
@@ -417,17 +423,20 @@ void WebAssembly::AddClangSystemIncludeArgs(const ArgList 
&DriverArgs,
 
 void WebAssembly::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
-  if (!DriverArgs.hasArg(options::OPT_nostdlibinc) &&
-  !DriverArgs.hasArg(options::OPT_nostdincxx)) {
-if (getTriple().getOS() != llvm::Triple::UnknownOS) {
-  const std::string MultiarchTriple =
-  getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot);
-  addSystemInclude(DriverArgs, CC1Args,
-   getDriver().SysRoot + "/include/" + MultiarchTriple +
-   "/c++/v1");
-}
-addSystemInclude(DriverArgs, CC1Args,
- getDriver().SysRoot + "/include/c++/v1");
+
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+  DriverArgs.hasArg(options::OPT_nostdincxx))
+return;
+
+  switch (GetCXXStdlibType(DriverArgs)) {
+  case ToolChain::CST_Libcxx:
+addLibCxxIncludePaths(DriverArgs, CC1Args);
+break;
+  case ToolChain::CST_Libstdcxx:
+addLibStdCXXIncludePaths(DriverArgs, CC1Args);
+break;
+  default:
+llvm_unreachable("Unknown stdlib type");
   }
 }
 
@@ -440,6 +449,9 @@ void WebAssembly::AddCXXStdlibLibArgs(const 
llvm::opt::ArgList &Args,
 CmdArgs.push_back("-lc++abi");
 break;
   case ToolChain::CST_Libstdcxx:
+CmdArgs.push_back("-lstdc++");
+break;
+  default:
 llvm_unreachable("invalid stdlib name");
   }
 }
@@ -455,3 +467,75 @@ SanitizerMask WebAssembly::getSupportedSanitizers() const {
 Tool *WebAssembly::buildLinker() const {
   return new tools::wasm::Linker(*this);
 }
+
+void WebAssembly::addLibCxxIncludePaths(
+const llvm::opt::ArgList &DriverArgs,
+llvm::opt::ArgStringList &CC1Args) const {
+  const Driver &D = getDriver();
+  std::string SysRoot = computeSysRoot();
+  std::string LibPath = SysRoot + "/include";
+  const std::string MultiarchTriple =
+  getMultiarchTriple(D, getTriple(), SysRoot);
+  bool IsKnownOs = (getTriple().getOS() != llvm::Triple::UnknownOS);
+
+  std::string Version = detectLibcxxVersion(LibPath);
+  if (Version.empty())
+return;
+
+  // First add the per-target include path if the OS is known.
+  if (IsKnownOs) {
+std::string TargetDir = LibPath + "/" + MultiarchTriple + "/c++/" + 
Version;
+addSystemInclude(DriverArgs, CC1Args, TargetDir);
+  }
+
+  // Second add the generic one.
+  addSystemInclude(DriverArgs, CC1Args, LibPath + "/c++/" + Version);
+}
+
+void WebAssembly::addLibStdCXXIncludePaths(
+const llvm::opt::ArgList &DriverArgs,
+llvm::opt::ArgStringList &CC1Args) const {
+  // We cannot use GCCInstallationDetector here as the sysroot usually does
+  // not contain a full GCC installation.
+  // Instead, we search the given sysroot for /usr

[clang] 2dd35e9 - [clang][driver][wasm] Remove unneeded default labels

2022-02-03 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-02-03T16:52:41+01:00
New Revision: 2dd35e98d3ffa1327df8261077958b47b2bdbb15

URL: 
https://github.com/llvm/llvm-project/commit/2dd35e98d3ffa1327df8261077958b47b2bdbb15
DIFF: 
https://github.com/llvm/llvm-project/commit/2dd35e98d3ffa1327df8261077958b47b2bdbb15.diff

LOG: [clang][driver][wasm] Remove unneeded default labels

Fix build fallout from b5787a0c6cc4da47b7d7b218e23f780076ad2f5f

Added: 


Modified: 
clang/lib/Driver/ToolChains/WebAssembly.cpp

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 5f64792b45014..4fdfb7e1762e0 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -435,8 +435,6 @@ void WebAssembly::AddClangCXXStdlibIncludeArgs(const 
ArgList &DriverArgs,
   case ToolChain::CST_Libstdcxx:
 addLibStdCXXIncludePaths(DriverArgs, CC1Args);
 break;
-  default:
-llvm_unreachable("Unknown stdlib type");
   }
 }
 
@@ -451,8 +449,6 @@ void WebAssembly::AddCXXStdlibLibArgs(const 
llvm::opt::ArgList &Args,
   case ToolChain::CST_Libstdcxx:
 CmdArgs.push_back("-lstdc++");
 break;
-  default:
-llvm_unreachable("invalid stdlib name");
   }
 }
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] ce07de2 - [clang][tests] Add test for C++ DR2406

2022-02-10 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-02-10T14:52:30+01:00
New Revision: ce07de234b77dc6cc263cdf4081eace5761d6b5a

URL: 
https://github.com/llvm/llvm-project/commit/ce07de234b77dc6cc263cdf4081eace5761d6b5a
DIFF: 
https://github.com/llvm/llvm-project/commit/ce07de234b77dc6cc263cdf4081eace5761d6b5a.diff

LOG: [clang][tests] Add test for C++ DR2406

Clang already handles this fine, so add a test case to let the
make_cxx_dr_status script pick it up.

Differential Revision: https://reviews.llvm.org/D119224

Added: 
clang/test/CXX/drs/dr2406.cpp

Modified: 


Removed: 




diff  --git a/clang/test/CXX/drs/dr2406.cpp b/clang/test/CXX/drs/dr2406.cpp
new file mode 100644
index 0..7ea0870fb70b3
--- /dev/null
+++ b/clang/test/CXX/drs/dr2406.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -x c++ %s  -verify
+
+// dr2406: yes
+
+void fallthrough(int n) {
+  void g(), h(), i();
+  switch (n) {
+  case 1:
+  case 2:
+g();
+[[fallthrough]];
+  case 3: // warning on fallthrough discouraged
+do {
+  [[fallthrough]]; // expected-error {{fallthrough annotation does not 
directly precede switch label}}
+} while (false);
+  case 6:
+do {
+  [[fallthrough]]; // expected-error {{fallthrough annotation does not 
directly precede switch label}}
+} while (n);
+  case 7:
+while (false) {
+  [[fallthrough]]; // expected-error {{fallthrough annotation does not 
directly precede switch label}}
+}
+  case 5:
+h();
+  case 4: // implementation may warn on fallthrough
+i();
+[[fallthrough]]; // expected-error {{fallthrough annotation does not 
directly precede switch label}}
+  }
+}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] ef2c827 - [clang] Add test for C++ DR2390

2022-02-10 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-02-10T14:52:30+01:00
New Revision: ef2c8274dfa216078436c6acfe0274a43a737242

URL: 
https://github.com/llvm/llvm-project/commit/ef2c8274dfa216078436c6acfe0274a43a737242
DIFF: 
https://github.com/llvm/llvm-project/commit/ef2c8274dfa216078436c6acfe0274a43a737242.diff

LOG: [clang] Add test for C++ DR2390

DR2390 clarifies that the argument to __has_cpp_attribute() needs to be
macro-expanded. Clang already supports this and tests it explicitly in
clang/test/Preprocessor/has_attribute.cpp.

Copy the test over to clang/test/CXX/drs/ so the make_cxx_drs script
picks it up.

Differential Revision: https://reviews.llvm.org/D119230

Added: 
clang/test/CXX/drs/dr2390.cpp

Modified: 


Removed: 




diff  --git a/clang/test/CXX/drs/dr2390.cpp b/clang/test/CXX/drs/dr2390.cpp
new file mode 100644
index 0..d8ab1e9a1b385
--- /dev/null
+++ b/clang/test/CXX/drs/dr2390.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -E -P %s -o - | FileCheck %s
+
+// dr2390: yes
+
+namespace PR48462 {
+// Test that macro expansion of the builtin argument works.
+#define C clang
+#define F fallthrough
+#define CF clang::fallthrough
+
+#if __has_cpp_attribute(F)
+int has_fallthrough;
+#endif
+// CHECK: int has_fallthrough;
+
+#if __has_cpp_attribute(C::F)
+int has_clang_fallthrough_1;
+#endif
+// CHECK: int has_clang_fallthrough_1;
+
+#if __has_cpp_attribute(clang::F)
+int has_clang_fallthrough_2;
+#endif
+// CHECK: int has_clang_fallthrough_2;
+
+#if __has_cpp_attribute(C::fallthrough)
+int has_clang_fallthrough_3;
+#endif
+// CHECK: int has_clang_fallthrough_3;
+
+#if __has_cpp_attribute(CF)
+int has_clang_fallthrough_4;
+#endif
+// CHECK: int has_clang_fallthrough_4;
+
+#define FUNCLIKE1(x) clang::x
+#if __has_cpp_attribute(FUNCLIKE1(fallthrough))
+int funclike_1;
+#endif
+// CHECK: int funclike_1;
+
+#define FUNCLIKE2(x) _Clang::x
+#if __has_cpp_attribute(FUNCLIKE2(fallthrough))
+int funclike_2;
+#endif
+// CHECK: int funclike_2;
+} // namespace PR48462



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] b91073d - [clang][preprocessor] Fix unsigned-ness of utf8 char literals

2022-05-12 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-05-13T07:57:10+02:00
New Revision: b91073db6ac3b9abefcf6211ea755e55e5879991

URL: 
https://github.com/llvm/llvm-project/commit/b91073db6ac3b9abefcf6211ea755e55e5879991
DIFF: 
https://github.com/llvm/llvm-project/commit/b91073db6ac3b9abefcf6211ea755e55e5879991.diff

LOG: [clang][preprocessor] Fix unsigned-ness of utf8 char literals

UTF8 char literals are always unsigned.

Fixes https://github.com/llvm/llvm-project/issues/54886

Differential Revision: https://reviews.llvm.org/D124996

Added: 


Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Lex/PPExpressions.cpp
clang/test/Lexer/utf8-char-literal.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7c25456adb25..0b0aba080e12 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -347,6 +347,8 @@ C++ Language Changes in Clang
   template parameter, to conform to the Itanium C++ ABI and be compatible with
   GCC. This breaks binary compatibility with code compiled with earlier 
versions
   of clang; use the ``-fclang-abi-compat=14`` option to get the old mangling.
+- Preprocessor character literals with a ``u8`` prefix are now correctly 
treated as
+  unsigned character literals. This fixes `Issue 54886 
`_.
 
 C++20 Feature Support
 ^

diff  --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp
index 3c33369ed5f2..bd35689f18e7 100644
--- a/clang/lib/Lex/PPExpressions.cpp
+++ b/clang/lib/Lex/PPExpressions.cpp
@@ -408,9 +408,18 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, 
DefinedTracker &DT,
 // Set the value.
 Val = Literal.getValue();
 // Set the signedness. UTF-16 and UTF-32 are always unsigned
+// UTF-8 is unsigned if -fchar8_t is specified.
 if (Literal.isWide())
   Val.setIsUnsigned(!TargetInfo::isTypeSigned(TI.getWCharType()));
-else if (!Literal.isUTF16() && !Literal.isUTF32())
+else if (Literal.isUTF16() || Literal.isUTF32())
+  Val.setIsUnsigned(true);
+else if (Literal.isUTF8()) {
+  if (PP.getLangOpts().CPlusPlus)
+Val.setIsUnsigned(
+PP.getLangOpts().Char8 ? true : !PP.getLangOpts().CharIsSigned);
+  else
+Val.setIsUnsigned(true);
+} else
   Val.setIsUnsigned(!PP.getLangOpts().CharIsSigned);
 
 if (Result.Val.getBitWidth() > Val.getBitWidth()) {

diff  --git a/clang/test/Lexer/utf8-char-literal.cpp 
b/clang/test/Lexer/utf8-char-literal.cpp
index ababc8b9c21b..70df447e2a33 100644
--- a/clang/test/Lexer/utf8-char-literal.cpp
+++ b/clang/test/Lexer/utf8-char-literal.cpp
@@ -1,7 +1,10 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -fsyntax-only 
-verify %s
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c11 -x c -fsyntax-only 
-verify %s
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c2x -x c -fsyntax-only 
-verify %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++1z -fsyntax-only 
-verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -fsyntax-only 
-verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++17 -fsyntax-only 
-verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++17 -fsyntax-only 
-fchar8_t -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++20 -fsyntax-only 
-verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++20 -fsyntax-only 
-fno-char8_t -verify %s
 
 int array0[u'ñ' == u'\xf1'? 1 : -1];
 int array1['\xF1' !=  u'\xf1'? 1 : -1];
@@ -13,7 +16,7 @@ char c = u8'\u0080'; // expected-error {{character too large 
for enclosing chara
 char d = u8'\u1234'; // expected-error {{character too large for enclosing 
character literal type}}
 char e = u8'ሴ'; // expected-error {{character too large for enclosing 
character literal type}}
 char f = u8'ab'; // expected-error {{Unicode character literals may not 
contain multiple characters}}
-#elif __STDC_VERSION__ > 202000L
+#elif __STDC_VERSION__ >= 202000L
 char a = u8'ñ';  // expected-error {{character too large for enclosing 
character literal type}}
 char b = u8'\x80';   // ok
 char c = u8'\u0080'; // expected-error {{universal character name refers to a 
control character}}
@@ -26,3 +29,29 @@ _Static_assert(
  unsigned char : 1),
 "Surprise!");
 #endif
+
+
+// UTF-8 character literals are enabled in C++17 and later. If `-fchar8_t` is 
not enabled
+// (as is the case in C++17), then UTF-8 character literals may produce signed 
or
+// unsigned values depending on whether char is a signed type. If `-fchar8_t` 
is enabled
+// (which is the default behavior for C++20), then UTF-8 character literals 
always
+// produce unsigned values. The tests below depend on the target having a 
signed
+// 8-bit char so that '\xff' produces a negative value.
+#if __cplusplus >= 201703L
+#  if !defined(__cp

[clang] 8717b49 - [clang][driver] Dynamically select gcc-toolset/devtoolset version

2022-05-23 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-05-23T11:34:38+02:00
New Revision: 8717b492dfcd12d6387543a2f8322e0cf9059982

URL: 
https://github.com/llvm/llvm-project/commit/8717b492dfcd12d6387543a2f8322e0cf9059982
DIFF: 
https://github.com/llvm/llvm-project/commit/8717b492dfcd12d6387543a2f8322e0cf9059982.diff

LOG: [clang][driver] Dynamically select gcc-toolset/devtoolset version

And pick the highest one, instead of adding all possibilities to the
prefixes.

Differential Revision: https://reviews.llvm.org/D125862

Added: 


Modified: 
clang/lib/Driver/ToolChains/Gnu.cpp
clang/unittests/Driver/ToolChainTest.cpp

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/Gnu.cpp 
b/clang/lib/Driver/ToolChains/Gnu.cpp
index 38280a2e36526..29e6295103c7a 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -2130,17 +2130,31 @@ void 
Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
   // and gcc-toolsets.
   if (SysRoot.empty() && TargetTriple.getOS() == llvm::Triple::Linux &&
   D.getVFS().exists("/opt/rh")) {
-Prefixes.push_back("/opt/rh/gcc-toolset-11/root/usr");
-Prefixes.push_back("/opt/rh/gcc-toolset-10/root/usr");
-Prefixes.push_back("/opt/rh/devtoolset-11/root/usr");
-Prefixes.push_back("/opt/rh/devtoolset-10/root/usr");
-Prefixes.push_back("/opt/rh/devtoolset-9/root/usr");
-Prefixes.push_back("/opt/rh/devtoolset-8/root/usr");
-Prefixes.push_back("/opt/rh/devtoolset-7/root/usr");
-Prefixes.push_back("/opt/rh/devtoolset-6/root/usr");
-Prefixes.push_back("/opt/rh/devtoolset-4/root/usr");
-Prefixes.push_back("/opt/rh/devtoolset-3/root/usr");
-Prefixes.push_back("/opt/rh/devtoolset-2/root/usr");
+// Find the directory in /opt/rh/ starting with gcc-toolset-* or
+// devtoolset-* with the highest version number and add that
+// one to our prefixes.
+std::string ChosenToolsetDir;
+unsigned ChosenToolsetVersion = 0;
+std::error_code EC;
+for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin("/opt/rh", 
EC),
+   LE;
+ !EC && LI != LE; LI = LI.increment(EC)) {
+  StringRef ToolsetDir = llvm::sys::path::filename(LI->path());
+  unsigned ToolsetVersion;
+  if ((!ToolsetDir.startswith("gcc-toolset-") &&
+   !ToolsetDir.startswith("devtoolset-")) ||
+  ToolsetDir.substr(ToolsetDir.rfind('-') + 1)
+  .getAsInteger(10, ToolsetVersion))
+continue;
+
+  if (ToolsetVersion > ChosenToolsetVersion) {
+ChosenToolsetVersion = ToolsetVersion;
+ChosenToolsetDir = "/opt/rh/" + ToolsetDir.str();
+  }
+}
+
+if (ChosenToolsetVersion > 0)
+  Prefixes.push_back(ChosenToolsetDir);
   }
 
   // Fall back to /usr which is used by most non-Solaris systems.

diff  --git a/clang/unittests/Driver/ToolChainTest.cpp 
b/clang/unittests/Driver/ToolChainTest.cpp
index c652b093dc993..4d2d938a50005 100644
--- a/clang/unittests/Driver/ToolChainTest.cpp
+++ b/clang/unittests/Driver/ToolChainTest.cpp
@@ -610,4 +610,92 @@ TEST(DxcModeTest, ValidatorVersionValidation) {
   DiagConsumer->clear();
 }
 
+TEST(ToolChainTest, Toolsets) {
+  IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions();
+  IntrusiveRefCntPtr DiagID(new DiagnosticIDs());
+  struct TestDiagnosticConsumer : public DiagnosticConsumer {};
+
+  // Check (newer) GCC toolset installation.
+  {
+IntrusiveRefCntPtr InMemoryFileSystem(
+new llvm::vfs::InMemoryFileSystem);
+
+// These should be ignored
+InMemoryFileSystem->addFile("/opt/rh/gcc-toolset-2", 0,
+llvm::MemoryBuffer::getMemBuffer("\n"));
+InMemoryFileSystem->addFile("/opt/rh/gcc-toolset-", 0,
+llvm::MemoryBuffer::getMemBuffer("\n"));
+InMemoryFileSystem->addFile("/opt/rh/gcc-toolset--", 0,
+llvm::MemoryBuffer::getMemBuffer("\n"));
+InMemoryFileSystem->addFile("/opt/rh/gcc-toolset--1", 0,
+llvm::MemoryBuffer::getMemBuffer("\n"));
+
+// File needed for GCC installation detection.
+InMemoryFileSystem->addFile(
+"/opt/rh/gcc-toolset-12/lib/gcc/x86_64-redhat-linux/11/crtbegin.o", 0,
+llvm::MemoryBuffer::getMemBuffer("\n"));
+
+DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
+Driver TheDriver("/bin/clang", "x86_64-redhat-linux", Diags,
+ "clang LLVM compiler", InMemoryFileSystem);
+std::unique_ptr C(TheDriver.BuildCompilation({"-v"}));
+ASSERT_TRUE(C);
+std::string S;
+{
+  llvm::raw_string_ostream OS(S);
+  C->getDefaultToolChain().printVerboseInfo(OS);
+}
+if (is_style_windows(llvm::sys::path::Style::native))
+  std::replace(S.begin(), S.end(), '\\', '/');
+EXPECT_EQ("Found candidate GCC installation: "
+  "/opt/rh/gcc

[clang] 0eccc92 - Revert "[clang][driver] Dynamically select gcc-toolset/devtoolset version"

2022-05-23 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2022-05-23T15:22:27+02:00
New Revision: 0eccc92fa0fd1794988cd6bfeca2314107567fdb

URL: 
https://github.com/llvm/llvm-project/commit/0eccc92fa0fd1794988cd6bfeca2314107567fdb
DIFF: 
https://github.com/llvm/llvm-project/commit/0eccc92fa0fd1794988cd6bfeca2314107567fdb.diff

LOG: Revert "[clang][driver] Dynamically select gcc-toolset/devtoolset version"

This reverts commit 8717b492dfcd12d6387543a2f8322e0cf9059982.

The new unittest fails on Windows buildbots, e.g.
https://lab.llvm.org/buildbot/#/builders/119/builds/8647

Added: 


Modified: 
clang/lib/Driver/ToolChains/Gnu.cpp
clang/unittests/Driver/ToolChainTest.cpp

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/Gnu.cpp 
b/clang/lib/Driver/ToolChains/Gnu.cpp
index 29e6295103c7..38280a2e3652 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -2130,31 +2130,17 @@ void 
Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
   // and gcc-toolsets.
   if (SysRoot.empty() && TargetTriple.getOS() == llvm::Triple::Linux &&
   D.getVFS().exists("/opt/rh")) {
-// Find the directory in /opt/rh/ starting with gcc-toolset-* or
-// devtoolset-* with the highest version number and add that
-// one to our prefixes.
-std::string ChosenToolsetDir;
-unsigned ChosenToolsetVersion = 0;
-std::error_code EC;
-for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin("/opt/rh", 
EC),
-   LE;
- !EC && LI != LE; LI = LI.increment(EC)) {
-  StringRef ToolsetDir = llvm::sys::path::filename(LI->path());
-  unsigned ToolsetVersion;
-  if ((!ToolsetDir.startswith("gcc-toolset-") &&
-   !ToolsetDir.startswith("devtoolset-")) ||
-  ToolsetDir.substr(ToolsetDir.rfind('-') + 1)
-  .getAsInteger(10, ToolsetVersion))
-continue;
-
-  if (ToolsetVersion > ChosenToolsetVersion) {
-ChosenToolsetVersion = ToolsetVersion;
-ChosenToolsetDir = "/opt/rh/" + ToolsetDir.str();
-  }
-}
-
-if (ChosenToolsetVersion > 0)
-  Prefixes.push_back(ChosenToolsetDir);
+Prefixes.push_back("/opt/rh/gcc-toolset-11/root/usr");
+Prefixes.push_back("/opt/rh/gcc-toolset-10/root/usr");
+Prefixes.push_back("/opt/rh/devtoolset-11/root/usr");
+Prefixes.push_back("/opt/rh/devtoolset-10/root/usr");
+Prefixes.push_back("/opt/rh/devtoolset-9/root/usr");
+Prefixes.push_back("/opt/rh/devtoolset-8/root/usr");
+Prefixes.push_back("/opt/rh/devtoolset-7/root/usr");
+Prefixes.push_back("/opt/rh/devtoolset-6/root/usr");
+Prefixes.push_back("/opt/rh/devtoolset-4/root/usr");
+Prefixes.push_back("/opt/rh/devtoolset-3/root/usr");
+Prefixes.push_back("/opt/rh/devtoolset-2/root/usr");
   }
 
   // Fall back to /usr which is used by most non-Solaris systems.

diff  --git a/clang/unittests/Driver/ToolChainTest.cpp 
b/clang/unittests/Driver/ToolChainTest.cpp
index 4d2d938a5000..c652b093dc99 100644
--- a/clang/unittests/Driver/ToolChainTest.cpp
+++ b/clang/unittests/Driver/ToolChainTest.cpp
@@ -610,92 +610,4 @@ TEST(DxcModeTest, ValidatorVersionValidation) {
   DiagConsumer->clear();
 }
 
-TEST(ToolChainTest, Toolsets) {
-  IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions();
-  IntrusiveRefCntPtr DiagID(new DiagnosticIDs());
-  struct TestDiagnosticConsumer : public DiagnosticConsumer {};
-
-  // Check (newer) GCC toolset installation.
-  {
-IntrusiveRefCntPtr InMemoryFileSystem(
-new llvm::vfs::InMemoryFileSystem);
-
-// These should be ignored
-InMemoryFileSystem->addFile("/opt/rh/gcc-toolset-2", 0,
-llvm::MemoryBuffer::getMemBuffer("\n"));
-InMemoryFileSystem->addFile("/opt/rh/gcc-toolset-", 0,
-llvm::MemoryBuffer::getMemBuffer("\n"));
-InMemoryFileSystem->addFile("/opt/rh/gcc-toolset--", 0,
-llvm::MemoryBuffer::getMemBuffer("\n"));
-InMemoryFileSystem->addFile("/opt/rh/gcc-toolset--1", 0,
-llvm::MemoryBuffer::getMemBuffer("\n"));
-
-// File needed for GCC installation detection.
-InMemoryFileSystem->addFile(
-"/opt/rh/gcc-toolset-12/lib/gcc/x86_64-redhat-linux/11/crtbegin.o", 0,
-llvm::MemoryBuffer::getMemBuffer("\n"));
-
-DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
-Driver TheDriver("/bin/clang", "x86_64-redhat-linux", Diags,
- "clang LLVM compiler", InMemoryFileSystem);
-std::unique_ptr C(TheDriver.BuildCompilation({"-v"}));
-ASSERT_TRUE(C);
-std::string S;
-{
-  llvm::raw_string_ostream OS(S);
-  C->getDefaultToolChain().printVerboseInfo(OS);
-}
-if (is_style_windows(llvm::sys::path::Style::native))
-  std::replace(S.begin(), S.end(), '\\', '/');
-EXPECT_EQ("Found candidate GCC inst

[clang] 72d300a - [clang][Interp][NFC] Move a varible declaration in the closest scope

2024-03-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-14T13:50:05+01:00
New Revision: 72d300adad4022b150c24e4a44488d3b9334e999

URL: 
https://github.com/llvm/llvm-project/commit/72d300adad4022b150c24e4a44488d3b9334e999
DIFF: 
https://github.com/llvm/llvm-project/commit/72d300adad4022b150c24e4a44488d3b9334e999.diff

LOG: [clang][Interp][NFC] Move a varible declaration in the closest scope

Added: 


Modified: 
clang/lib/AST/Interp/Pointer.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/Pointer.cpp 
b/clang/lib/AST/Interp/Pointer.cpp
index 3f85635f43674d..af60ced0e10e9e 100644
--- a/clang/lib/AST/Interp/Pointer.cpp
+++ b/clang/lib/AST/Interp/Pointer.cpp
@@ -320,10 +320,10 @@ std::optional Pointer::toRValue(const Context 
&Ctx) const {
 // Complex types.
 if (const auto *CT = Ty->getAs()) {
   QualType ElemTy = CT->getElementType();
-  std::optional ElemT = Ctx.classify(ElemTy);
-  assert(ElemT);
 
   if (ElemTy->isIntegerType()) {
+std::optional ElemT = Ctx.classify(ElemTy);
+assert(ElemT);
 INT_TYPE_SWITCH(*ElemT, {
   auto V1 = Ptr.atIndex(0).deref();
   auto V2 = Ptr.atIndex(1).deref();



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] b97c129 - [clang][Interp] Fix non-primitive ltor casts

2024-03-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-14T13:55:55+01:00
New Revision: b97c12936dd8d520a5565ace3d51a460939a5c61

URL: 
https://github.com/llvm/llvm-project/commit/b97c12936dd8d520a5565ace3d51a460939a5c61
DIFF: 
https://github.com/llvm/llvm-project/commit/b97c12936dd8d520a5565ace3d51a460939a5c61.diff

LOG: [clang][Interp] Fix non-primitive ltor casts

This doesn't happen in C++ since it will instead call the
struct's copy constructor. However, in C, this needs to work.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/Descriptor.cpp
clang/lib/AST/Interp/Descriptor.h
clang/lib/AST/Interp/Interp.h
clang/lib/AST/Interp/InterpBuiltin.cpp
clang/lib/AST/Interp/Opcodes.td
clang/test/AST/Interp/c.c

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 86304a54473cea..ae5e2dadac951b 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -82,15 +82,27 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr 
*CE) {
 if (DiscardResult)
   return this->discard(SubExpr);
 
-if (SubExpr->getType()->isAnyComplexType())
-  return this->delegate(SubExpr);
+std::optional SubExprT = classify(SubExpr->getType());
+// Prepare storage for the result.
+if (!Initializing && !SubExprT) {
+  std::optional LocalIndex =
+  allocateLocal(SubExpr, /*IsExtended=*/false);
+  if (!LocalIndex)
+return false;
+  if (!this->emitGetPtrLocal(*LocalIndex, CE))
+return false;
+}
 
 if (!this->visit(SubExpr))
   return false;
 
-if (std::optional SubExprT = classify(SubExpr->getType()))
+if (SubExprT)
   return this->emitLoadPop(*SubExprT, CE);
-return false;
+
+// If the subexpr type is not primitive, we need to perform a copy here.
+// This happens for example in C when dereferencing a pointer of struct
+// type.
+return this->emitMemcpy(CE);
   }
 
   case CK_UncheckedDerivedToBase:
@@ -3247,53 +3259,20 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const 
DeclRefExpr *E) {
   // pointer to the actual value) instead of a pointer to the pointer to the
   // value.
   bool IsReference = D->getType()->isReferenceType();
-  // Complex values are copied in the AST via a simply assignment or
-  // ltor cast. But we represent them as two-element arrays, which means
-  // we pass them around as pointers. So, to assignm from them, we will
-  // have to copy both (primitive) elements instead.
-  bool IsComplex = D->getType()->isAnyComplexType();
 
   // Check for local/global variables and parameters.
   if (auto It = Locals.find(D); It != Locals.end()) {
 const unsigned Offset = It->second.Offset;
-// FIXME: Fix the code duplication here with the code in the global case.
-if (Initializing && IsComplex) {
-  PrimType ElemT = classifyComplexElementType(D->getType());
-  for (unsigned I = 0; I != 2; ++I) {
-if (!this->emitGetPtrLocal(Offset, E))
-  return false;
-if (!this->emitArrayElemPop(ElemT, I, E))
-  return false;
-if (!this->emitInitElem(ElemT, I, E))
-  return false;
-  }
-  return true;
-}
-
 if (IsReference)
   return this->emitGetLocal(PT_Ptr, Offset, E);
 return this->emitGetPtrLocal(Offset, E);
   } else if (auto GlobalIndex = P.getGlobal(D)) {
-if (Initializing && IsComplex) {
-  PrimType ElemT = classifyComplexElementType(D->getType());
-  for (unsigned I = 0; I != 2; ++I) {
-if (!this->emitGetPtrGlobal(*GlobalIndex, E))
-  return false;
-if (!this->emitArrayElemPop(ElemT, I, E))
-  return false;
-if (!this->emitInitElem(ElemT, I, E))
-  return false;
-  }
-  return true;
-}
-
 if (IsReference)
   return this->emitGetGlobalPtr(*GlobalIndex, E);
 
 return this->emitGetPtrGlobal(*GlobalIndex, E);
   } else if (const auto *PVD = dyn_cast(D)) {
 if (auto It = this->Params.find(PVD); It != this->Params.end()) {
-  // FIXME: _Complex initializing case?
   if (IsReference || !It->second.IsPtr)
 return this->emitGetParamPtr(It->second.Offset, E);
 

diff  --git a/clang/lib/AST/Interp/Descriptor.cpp 
b/clang/lib/AST/Interp/Descriptor.cpp
index ce7ed9cec3db3f..dff8eed12428ec 100644
--- a/clang/lib/AST/Interp/Descriptor.cpp
+++ b/clang/lib/AST/Interp/Descriptor.cpp
@@ -233,9 +233,10 @@ static BlockMoveFn getMoveArrayPrim(PrimType Type) {
 Descriptor::Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD,
bool IsConst, bool IsTemporary, bool IsMutable)
 : Source(D), ElemSize(primSize(Type)), Size(ElemSize),
-  MDSize(MD.value_or(0)), AllocSize(align(Size + MDSize)), 
IsConst(IsConst),
-  IsMutable(IsMutable), IsTemporary(IsTemporary), 
CtorFn(getCtorPrim(Type)),
-   

[clang] a551cce - [clang][Interp][NFC] Print primitive global values in dump()

2024-03-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-14T14:05:33+01:00
New Revision: a551ccee66fc70b5ecd03a2c8b9db5a7330820f0

URL: 
https://github.com/llvm/llvm-project/commit/a551ccee66fc70b5ecd03a2c8b9db5a7330820f0
DIFF: 
https://github.com/llvm/llvm-project/commit/a551ccee66fc70b5ecd03a2c8b9db5a7330820f0.diff

LOG: [clang][Interp][NFC] Print primitive global values in dump()

Added: 


Modified: 
clang/lib/AST/Interp/Disasm.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/Disasm.cpp b/clang/lib/AST/Interp/Disasm.cpp
index 315ddb293044b7..160701f4d4a760 100644
--- a/clang/lib/AST/Interp/Disasm.cpp
+++ b/clang/lib/AST/Interp/Disasm.cpp
@@ -10,8 +10,11 @@
 //
 
//===--===//
 
+#include "Boolean.h"
 #include "Floating.h"
 #include "Function.h"
+#include "FunctionPointer.h"
+#include "Integral.h"
 #include "IntegralAP.h"
 #include "Opcode.h"
 #include "PrimType.h"
@@ -86,6 +89,40 @@ LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) 
const {
 
 LLVM_DUMP_METHOD void Program::dump() const { dump(llvm::errs()); }
 
+static const char *primTypeToString(PrimType T) {
+  switch (T) {
+  case PT_Sint8:
+return "Sint8";
+  case PT_Uint8:
+return "Uint8";
+  case PT_Sint16:
+return "Sint16";
+  case PT_Uint16:
+return "Uint16";
+  case PT_Sint32:
+return "Sint32";
+  case PT_Uint32:
+return "Uint32";
+  case PT_Sint64:
+return "Sint64";
+  case PT_Uint64:
+return "Uint64";
+  case PT_IntAP:
+return "IntAP";
+  case PT_IntAPS:
+return "IntAPS";
+  case PT_Bool:
+return "Bool";
+  case PT_Float:
+return "Float";
+  case PT_Ptr:
+return "Ptr";
+  case PT_FnPtr:
+return "FnPtr";
+  }
+  llvm_unreachable("Unhandled PrimType");
+}
+
 LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) const {
   {
 ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_RED, true});
@@ -100,9 +137,10 @@ LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) 
const {
   unsigned GI = 0;
   for (const Global *G : Globals) {
 const Descriptor *Desc = G->block()->getDescriptor();
+Pointer GP = getPtrGlobal(GI);
+
 OS << GI << ": " << (void *)G->block() << " ";
 {
-  Pointer GP = getPtrGlobal(GI);
   ColorScope SC(OS, true,
 GP.isInitialized()
 ? TerminalColor{llvm::raw_ostream::GREEN, false}
@@ -111,6 +149,15 @@ LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) 
const {
 }
 Desc->dump(OS);
 OS << "\n";
+if (Desc->isPrimitive() && !Desc->isDummy()) {
+  OS << "   ";
+  {
+ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_CYAN, false});
+OS << primTypeToString(Desc->getPrimType()) << " ";
+  }
+  TYPE_SWITCH(Desc->getPrimType(), { GP.deref().print(OS); });
+  OS << "\n";
+}
 ++GI;
   }
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 2421e76 - [clang][Interp][NFC] Add more _Complex tests

2024-03-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-14T14:05:33+01:00
New Revision: 2421e76159536ec4d2224e17fd10dfc4df6a2bc5

URL: 
https://github.com/llvm/llvm-project/commit/2421e76159536ec4d2224e17fd10dfc4df6a2bc5
DIFF: 
https://github.com/llvm/llvm-project/commit/2421e76159536ec4d2224e17fd10dfc4df6a2bc5.diff

LOG: [clang][Interp][NFC] Add more _Complex tests

Added: 


Modified: 
clang/test/AST/Interp/complex.cpp

Removed: 




diff  --git a/clang/test/AST/Interp/complex.cpp 
b/clang/test/AST/Interp/complex.cpp
index 6a42afc68d26c7..d4e3d5a46a64fb 100644
--- a/clang/test/AST/Interp/complex.cpp
+++ b/clang/test/AST/Interp/complex.cpp
@@ -313,3 +313,53 @@ namespace Cmp {
   static_assert((0.0 + 0.0j) > (0.0 + 0.0j)); // both-error {{invalid operands 
to binary expression}}
   static_assert((0.0 + 0.0j) ^ (0.0 + 0.0j)); // both-error {{invalid operands 
to binary expression}}
 }
+
+/// From test/SemaCXX/constant-expression-cxx11.cpp
+///
+/// Some of the diagnostics we emit are 
diff erent than the one of the
+/// current interpreter.
+///
+/// FIXME: For the '&test3 + 1' test, we are _not_ creating an explicit 
pointer variable
+/// anywhere and so the &test3+1 is the same as __imag(test3) for us.
+namespace ComplexConstexpr {
+  constexpr _Complex float test1 = {};
+  constexpr _Complex float test2 = {1};
+  constexpr _Complex double test3 = {1,2};
+  constexpr _Complex int test4 = {4};
+  constexpr _Complex int test5 = 4;
+  constexpr _Complex int test6 = {5,6};
+  typedef _Complex float fcomplex;
+  constexpr fcomplex test7 = fcomplex();
+
+  constexpr const double &t2r = __real test3;
+  constexpr const double &t2i = __imag test3;
+  static_assert(&t2r + 1 == &t2i, "");
+  static_assert(t2r == 1.0, "");
+  static_assert(t2i == 2.0, "");
+  constexpr const double *t2p = &t2r;
+  static_assert(t2p[-1] == 0.0, ""); // both-error {{constant expr}} \
+ // both-note {{cannot refer to element -1 
of array of 2 elements}}
+  static_assert(t2p[0] == 1.0, "");
+  static_assert(t2p[1] == 2.0, "");
+  static_assert(t2p[2] == 0.0, ""); // both-error {{constant expr}} \
+// both-note {{one-past-the-end pointer}}
+  static_assert(t2p[3] == 0.0, ""); // both-error {{constant expr}} \
+// both-note {{cannot refer to element 3 
of array of 2 elements}}
+  constexpr _Complex float *p = 0;
+  constexpr float pr = __real *p; // both-error {{constant expr}} \
+  // ref-note {{cannot access real component 
of null}} \
+  // expected-note {{read of dereferenced null 
pointer}}
+  constexpr float pi = __imag *p; // both-error {{constant expr}} \
+  // ref-note {{cannot access imaginary 
component of null}} \
+  // expected-note {{cannot perform pointer 
arithmetic on null pointer}}
+  constexpr const _Complex double *q = &test3 + 1;
+  constexpr double qr = __real *q; // ref-error {{constant expr}} \
+   // ref-note {{cannot access real component 
of pointer past the end}}
+  constexpr double qi = __imag *q; // both-error {{constant expr}} \
+   // ref-note {{cannot access imaginary 
component of pointer past the end}} \
+   // expected-note {{read of dereferenced 
one-past-the-end pointer}}
+
+  static_assert(__real test6 == 5, "");
+  static_assert(__imag test6 == 6, "");
+  static_assert(&__imag test6 == &__real test6 + 1, "");
+}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 21d8085 - [clang][Interp][NFC] Rename DummyParams to DummyVariables

2024-03-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-14T14:05:33+01:00
New Revision: 21d80859df3fb416efac13ce8178fdf6d6489292

URL: 
https://github.com/llvm/llvm-project/commit/21d80859df3fb416efac13ce8178fdf6d6489292
DIFF: 
https://github.com/llvm/llvm-project/commit/21d80859df3fb416efac13ce8178fdf6d6489292.diff

LOG: [clang][Interp][NFC] Rename DummyParams to DummyVariables

We create dummy descriptors for variables other than parameters
these days.

Added: 


Modified: 
clang/lib/AST/Interp/Program.cpp
clang/lib/AST/Interp/Program.h

Removed: 




diff  --git a/clang/lib/AST/Interp/Program.cpp 
b/clang/lib/AST/Interp/Program.cpp
index 86e18ede638114..58bddb991fd6de 100644
--- a/clang/lib/AST/Interp/Program.cpp
+++ b/clang/lib/AST/Interp/Program.cpp
@@ -145,7 +145,7 @@ std::optional Program::getOrCreateGlobal(const 
ValueDecl *VD,
 
 std::optional Program::getOrCreateDummy(const ValueDecl *VD) {
   // Dedup blocks since they are immutable and pointers cannot be compared.
-  if (auto It = DummyParams.find(VD); It != DummyParams.end())
+  if (auto It = DummyVariables.find(VD); It != DummyVariables.end())
 return It->second;
 
   // Create dummy descriptor.
@@ -158,7 +158,7 @@ std::optional Program::getOrCreateDummy(const 
ValueDecl *VD) {
   G->block()->invokeCtor();
 
   Globals.push_back(G);
-  DummyParams[VD] = I;
+  DummyVariables[VD] = I;
   return I;
 }
 

diff  --git a/clang/lib/AST/Interp/Program.h b/clang/lib/AST/Interp/Program.h
index 50bdb575e805cf..36b5a1faa513a9 100644
--- a/clang/lib/AST/Interp/Program.h
+++ b/clang/lib/AST/Interp/Program.h
@@ -208,7 +208,7 @@ class Program final {
   llvm::DenseMap Records;
 
   /// Dummy parameter to generate pointers from.
-  llvm::DenseMap DummyParams;
+  llvm::DenseMap DummyVariables;
 
   /// Creates a new descriptor.
   template 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] a99b912 - [clang][Interp] Create dummy pointers for external variables

2024-03-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-14T14:35:44+01:00
New Revision: a99b912c9b74f6ef91786b4dfbc25160c27d3b41

URL: 
https://github.com/llvm/llvm-project/commit/a99b912c9b74f6ef91786b4dfbc25160c27d3b41
DIFF: 
https://github.com/llvm/llvm-project/commit/a99b912c9b74f6ef91786b4dfbc25160c27d3b41.diff

LOG: [clang][Interp] Create dummy pointers for external variables

This way we can use their address, which is necessary in some
scenarios. This requires us to create different descriptors
for dummy arrays so we can get the diagnostics right.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/Descriptor.cpp
clang/lib/AST/Interp/Descriptor.h
clang/lib/AST/Interp/Interp.h
clang/lib/AST/Interp/Pointer.h
clang/lib/AST/Interp/Program.cpp
clang/test/AST/Interp/arrays.cpp
clang/test/AST/Interp/literals.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index ae5e2dadac951b..2d8ab4e40809a5 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -3301,9 +3301,6 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const 
DeclRefExpr *E) {
 // Retry.
 return this->VisitDeclRefExpr(E);
   }
-
-  if (VD->hasExternalStorage())
-return this->emitInvalidDeclRef(E, E);
 }
   } else {
 if (const auto *VD = dyn_cast(D);

diff  --git a/clang/lib/AST/Interp/Descriptor.cpp 
b/clang/lib/AST/Interp/Descriptor.cpp
index dff8eed12428ec..a4ccc0236d292c 100644
--- a/clang/lib/AST/Interp/Descriptor.cpp
+++ b/clang/lib/AST/Interp/Descriptor.cpp
@@ -301,10 +301,19 @@ Descriptor::Descriptor(const DeclTy &D, const Record *R, 
MetadataSize MD,
   assert(Source && "Missing source");
 }
 
-Descriptor::Descriptor(const DeclTy &D, MetadataSize MD)
-: Source(D), ElemSize(1), Size(ElemSize), MDSize(MD.value_or(0)),
-  AllocSize(Size + MDSize), ElemRecord(nullptr), IsConst(true),
-  IsMutable(false), IsTemporary(false), IsDummy(true) {
+/// Dummy.
+Descriptor::Descriptor(const DeclTy &D)
+: Source(D), ElemSize(1), Size(1), MDSize(0), AllocSize(MDSize),
+  ElemRecord(nullptr), IsConst(true), IsMutable(false), IsTemporary(false),
+  IsDummy(true) {
+  assert(Source && "Missing source");
+}
+
+/// Dummy array.
+Descriptor::Descriptor(const DeclTy &D, UnknownSize)
+: Source(D), ElemSize(1), Size(UnknownSizeMark), MDSize(0),
+  AllocSize(MDSize), ElemRecord(nullptr), IsConst(true), IsMutable(false),
+  IsTemporary(false), IsArray(true), IsDummy(true) {
   assert(Source && "Missing source");
 }
 

diff  --git a/clang/lib/AST/Interp/Descriptor.h 
b/clang/lib/AST/Interp/Descriptor.h
index 5160f07466fba7..4e257361ad146b 100644
--- a/clang/lib/AST/Interp/Descriptor.h
+++ b/clang/lib/AST/Interp/Descriptor.h
@@ -156,7 +156,11 @@ struct Descriptor final {
   Descriptor(const DeclTy &D, const Record *R, MetadataSize MD, bool IsConst,
  bool IsTemporary, bool IsMutable);
 
-  Descriptor(const DeclTy &D, MetadataSize MD);
+  /// Allocates a dummy descriptor.
+  Descriptor(const DeclTy &D);
+
+  /// Allocates a dummy array descriptor.
+  Descriptor(const DeclTy &D, UnknownSize);
 
   QualType getType() const;
   QualType getElemQualType() const;

diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 507d91129d6886..336cf2a1103395 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1946,8 +1946,15 @@ inline bool ArrayElemPtr(InterpState &S, CodePtr OpPC) {
   const T &Offset = S.Stk.pop();
   const Pointer &Ptr = S.Stk.peek();
 
-  if (Ptr.isDummy())
-return true;
+  if (!Ptr.isZero()) {
+if (!CheckArray(S, OpPC, Ptr))
+  return false;
+
+if (Ptr.isDummy()) {
+  S.Stk.push(Ptr);
+  return true;
+}
+  }
 
   if (!OffsetHelper(S, OpPC, Offset, Ptr))
 return false;
@@ -1960,9 +1967,14 @@ inline bool ArrayElemPtrPop(InterpState &S, CodePtr 
OpPC) {
   const T &Offset = S.Stk.pop();
   const Pointer &Ptr = S.Stk.pop();
 
-  if (Ptr.isDummy()) {
-S.Stk.push(Ptr);
-return true;
+  if (!Ptr.isZero()) {
+if (!CheckArray(S, OpPC, Ptr))
+  return false;
+
+if (Ptr.isDummy()) {
+  S.Stk.push(Ptr);
+  return true;
+}
   }
 
   if (!OffsetHelper(S, OpPC, Offset, Ptr))

diff  --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h
index 34ecdb967960d5..fffb4aba492fc8 100644
--- a/clang/lib/AST/Interp/Pointer.h
+++ b/clang/lib/AST/Interp/Pointer.h
@@ -285,6 +285,11 @@ class Pointer {
   bool inPrimitiveArray() const { return getFieldDesc()->isPrimitiveArray(); }
   /// Checks if the structure is an array of unknown size.
   bool isUnknownSizeArray() const {
+// If this points inside a dummy block, return true.
+// FIXME: This might change in the future. If it does, we need
+// to set the proper Ctor/Dt

[clang] 160693d - [clang][Interp][NFC] allocateLocalPrimitive never fails

2024-03-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-14T14:57:24+01:00
New Revision: 160693dbde2837af4237954edd38b08b2bb17a29

URL: 
https://github.com/llvm/llvm-project/commit/160693dbde2837af4237954edd38b08b2bb17a29
DIFF: 
https://github.com/llvm/llvm-project/commit/160693dbde2837af4237954edd38b08b2bb17a29.diff

LOG: [clang][Interp][NFC] allocateLocalPrimitive never fails

It returns the local offset, not an std::optional.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 2d8ab4e40809a5..33d50d7c2b4f2b 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -308,14 +308,11 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
 // Location for the SubExpr.
 // Since SubExpr is of complex type, visiting it results in a pointer
 // anyway, so we just create a temporary pointer variable.
-std::optional SubExprOffset = allocateLocalPrimitive(
+unsigned SubExprOffset = allocateLocalPrimitive(
 SubExpr, PT_Ptr, /*IsConst=*/true, /*IsExtended=*/false);
-if (!SubExprOffset)
-  return false;
-
 if (!this->visit(SubExpr))
   return false;
-if (!this->emitSetLocal(PT_Ptr, *SubExprOffset, CE))
+if (!this->emitSetLocal(PT_Ptr, SubExprOffset, CE))
   return false;
 
 PrimType SourceElemT = classifyComplexElementType(SubExpr->getType());
@@ -324,7 +321,7 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr 
*CE) {
 PrimType DestElemT = classifyPrim(DestElemType);
 // Cast both elements individually.
 for (unsigned I = 0; I != 2; ++I) {
-  if (!this->emitGetLocal(PT_Ptr, *SubExprOffset, CE))
+  if (!this->emitGetLocal(PT_Ptr, SubExprOffset, CE))
 return false;
   if (!this->emitArrayElemPop(SourceElemT, I, CE))
 return false;
@@ -1245,22 +1242,19 @@ bool 
ByteCodeExprGen::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
   // At this point we either have the evaluated source expression or a pointer
   // to an object on the stack. We want to create a local variable that stores
   // this value.
-  std::optional LocalIndex =
-  allocateLocalPrimitive(E, SubExprT, /*IsConst=*/true);
-  if (!LocalIndex)
-return false;
-  if (!this->emitSetLocal(SubExprT, *LocalIndex, E))
+  unsigned LocalIndex = allocateLocalPrimitive(E, SubExprT, /*IsConst=*/true);
+  if (!this->emitSetLocal(SubExprT, LocalIndex, E))
 return false;
 
   // Here the local variable is created but the value is removed from the 
stack,
   // so we put it back if the caller needs it.
   if (!DiscardResult) {
-if (!this->emitGetLocal(SubExprT, *LocalIndex, E))
+if (!this->emitGetLocal(SubExprT, LocalIndex, E))
   return false;
   }
 
   // This is cleaned up when the local variable is destroyed.
-  OpaqueExprs.insert({E, *LocalIndex});
+  OpaqueExprs.insert({E, LocalIndex});
 
   return true;
 }
@@ -1654,14 +1648,13 @@ bool 
ByteCodeExprGen::VisitMaterializeTemporaryExpr(
 
   // For everyhing else, use local variables.
   if (SubExprT) {
-if (std::optional LocalIndex = allocateLocalPrimitive(
-SubExpr, *SubExprT, /*IsConst=*/true, /*IsExtended=*/true)) {
-  if (!this->visit(SubExpr))
-return false;
-  if (!this->emitSetLocal(*SubExprT, *LocalIndex, E))
-return false;
-  return this->emitGetPtrLocal(*LocalIndex, E);
-}
+unsigned LocalIndex = allocateLocalPrimitive(
+SubExpr, *SubExprT, /*IsConst=*/true, /*IsExtended=*/true);
+if (!this->visit(SubExpr))
+  return false;
+if (!this->emitSetLocal(*SubExprT, LocalIndex, E))
+  return false;
+return this->emitGetPtrLocal(LocalIndex, E);
   } else {
 const Expr *Inner = E->getSubExpr()->skipRValueSubobjectAdjustments();
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 2cd19df - [clang][Interp] Allow visiting extern variables

2024-03-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-14T15:39:28+01:00
New Revision: 2cd19df792056bbac38ed64c028e335d0c7ef05d

URL: 
https://github.com/llvm/llvm-project/commit/2cd19df792056bbac38ed64c028e335d0c7ef05d
DIFF: 
https://github.com/llvm/llvm-project/commit/2cd19df792056bbac38ed64c028e335d0c7ef05d.diff

LOG: [clang][Interp] Allow visiting extern variables

If the variable is additionally const(expr), visit them like normal
but omit the initializer.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/AST/Interp/literals.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 33d50d7c2b4f2b..25f4e1ead7e3c9 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2665,18 +2665,12 @@ bool ByteCodeExprGen::visitVarDecl(const 
VarDecl *VD) {
 if (P.getGlobal(VD))
   return true;
 
-// Ignore external declarations. We will instead emit a dummy
-// pointer when we see a DeclRefExpr for them.
-if (VD->hasExternalStorage())
-  return true;
-
 std::optional GlobalIndex = P.createGlobal(VD, Init);
 
 if (!GlobalIndex)
   return false;
 
-assert(Init);
-{
+if (Init) {
   DeclScope LocalScope(this, VD);
 
   if (VarT) {
@@ -2686,6 +2680,7 @@ bool ByteCodeExprGen::visitVarDecl(const VarDecl 
*VD) {
   }
   return this->visitGlobalInitializer(Init, *GlobalIndex);
 }
+return true;
   } else {
 VariableScope LocalScope(this);
 if (VarT) {

diff  --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index 2b1001dbd3baee..0a9580b6f664b0 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -1190,6 +1190,11 @@ namespace incdecbool {
 constexpr int externvar1() { // both-error {{never produces a constant 
expression}}
   extern char arr[]; // ref-note {{declared here}}
return arr[0]; // ref-note {{read of non-constexpr variable 'arr'}} \
-  // expected-note {{indexing of array without known bound}}
+  // expected-note {{array-to-pointer decay of array member 
without known bound is not supported}}
 }
 #endif
+
+namespace Extern {
+  constexpr extern char Oops = 1;
+  static_assert(Oops == 1, "");
+}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 68360dc - [clang][Interp] Don't abort on float div-by-zero

2024-03-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-14T16:25:23+01:00
New Revision: 68360dc85507350c9d38bcc6916debe29fd58fee

URL: 
https://github.com/llvm/llvm-project/commit/68360dc85507350c9d38bcc6916debe29fd58fee
DIFF: 
https://github.com/llvm/llvm-project/commit/68360dc85507350c9d38bcc6916debe29fd58fee.diff

LOG: [clang][Interp] Don't abort on float div-by-zero

The result in that case can still be computed, and it's inf.

Added: 
clang/test/AST/Interp/c23.c

Modified: 
clang/lib/AST/Interp/Interp.h

Removed: 




diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 336cf2a1103395..08e272cbc005bd 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -168,7 +168,8 @@ bool CheckDivRem(InterpState &S, CodePtr OpPC, const T 
&LHS, const T &RHS) {
 const auto *Op = cast(S.Current->getExpr(OpPC));
 S.FFDiag(Op, diag::note_expr_divide_by_zero)
 << Op->getRHS()->getSourceRange();
-return false;
+if constexpr (!std::is_same_v)
+  return false;
   }
 
   if (LHS.isSigned() && LHS.isMin() && RHS.isNegative() && RHS.isMinusOne()) {

diff  --git a/clang/test/AST/Interp/c23.c b/clang/test/AST/Interp/c23.c
new file mode 100644
index 00..cf1bf4d4e7d905
--- /dev/null
+++ b/clang/test/AST/Interp/c23.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -std=c23 -fexperimental-new-constant-interpreter 
-verify=expected,both %s
+// RUN: %clang_cc1 -std=c23 -verify=ref,both %s
+
+
+
+const _Bool inf1 =  (1.0/0.0 == __builtin_inf());
+constexpr _Bool inf2 = (1.0/0.0 == __builtin_inf()); // both-error {{must be 
initialized by a constant expression}} \
+ // both-note {{division 
by zero}}
+constexpr _Bool inf3 = __builtin_inf() == __builtin_inf();
+
+



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 65c0143 - [clang][Interp] Fix rotate builtins with differently-typed arguments

2024-03-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-14T16:34:07+01:00
New Revision: 65c0143296e3d8aafe819cbae4a48a3d53f8e7b3

URL: 
https://github.com/llvm/llvm-project/commit/65c0143296e3d8aafe819cbae4a48a3d53f8e7b3
DIFF: 
https://github.com/llvm/llvm-project/commit/65c0143296e3d8aafe819cbae4a48a3d53f8e7b3.diff

LOG: [clang][Interp] Fix rotate builtins with differently-typed arguments

We were assuming (and asserting) that both arguments have the same
type, but at least for the ms versions, that's not always the case.

Added: 
clang/test/AST/Interp/ms.cpp

Modified: 
clang/lib/AST/Interp/InterpBuiltin.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 8bbe881bb4b928..7e29d6183bdadd 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -533,11 +533,12 @@ static bool interp__builtin_rotate(InterpState &S, 
CodePtr OpPC,
const InterpFrame *Frame,
const Function *Func, const CallExpr *Call,
bool Right) {
-  PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
-  assert(ArgT == *S.getContext().classify(Call->getArg(1)->getType()));
+  PrimType AmountT = *S.getContext().classify(Call->getArg(1)->getType());
+  PrimType ValueT = *S.getContext().classify(Call->getArg(0)->getType());
 
-  APSInt Amount = peekToAPSInt(S.Stk, ArgT);
-  APSInt Value = peekToAPSInt(S.Stk, ArgT, align(primSize(ArgT)) * 2);
+  APSInt Amount = peekToAPSInt(S.Stk, AmountT);
+  APSInt Value = peekToAPSInt(
+  S.Stk, ValueT, align(primSize(AmountT)) + align(primSize(ValueT)));
 
   APSInt Result;
   if (Right)

diff  --git a/clang/test/AST/Interp/ms.cpp b/clang/test/AST/Interp/ms.cpp
new file mode 100644
index 00..99716e90c7a1db
--- /dev/null
+++ b/clang/test/AST/Interp/ms.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -verify=ref,both %s -fms-extensions
+// RUN: %clang_cc1 -verify=expected,both %s 
-fexperimental-new-constant-interpreter -fms-extensions
+
+// ref-no-diagnostics
+// expected-no-diagnostics
+
+/// Used to assert because the two parameters to _rotl do not have the same 
type.
+static_assert(_rotl(0x01, 5) == 32);



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 797994d - [clang][Interp] Strip _Atomic from _Complex types

2024-03-14 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-14T16:55:38+01:00
New Revision: 797994da3c3b0ff40201ac0045740370d2c39cbb

URL: 
https://github.com/llvm/llvm-project/commit/797994da3c3b0ff40201ac0045740370d2c39cbb
DIFF: 
https://github.com/llvm/llvm-project/commit/797994da3c3b0ff40201ac0045740370d2c39cbb.diff

LOG: [clang][Interp] Strip _Atomic from _Complex types

... when doing binary operations on them.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/AST/Interp/complex.c

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 25f4e1ead7e3c9..088301c08b81bb 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -685,11 +685,17 @@ bool ByteCodeExprGen::VisitComplexBinOp(const 
BinaryOperator *E) {
 if (!this->emitSetLocal(PT_Ptr, ResultOffset, E))
   return false;
   }
+  QualType LHSType = LHS->getType();
+  if (const auto *AT = LHSType->getAs())
+LHSType = AT->getValueType();
+  QualType RHSType = RHS->getType();
+  if (const auto *AT = RHSType->getAs())
+RHSType = AT->getValueType();
 
   // Evaluate LHS and save value to LHSOffset.
   bool LHSIsComplex;
   unsigned LHSOffset;
-  if (LHS->getType()->isAnyComplexType()) {
+  if (LHSType->isAnyComplexType()) {
 LHSIsComplex = true;
 LHSOffset = this->allocateLocalPrimitive(LHS, PT_Ptr, true, false);
 if (!this->visit(LHS))
@@ -698,7 +704,7 @@ bool ByteCodeExprGen::VisitComplexBinOp(const 
BinaryOperator *E) {
   return false;
   } else {
 LHSIsComplex = false;
-PrimType LHST = classifyPrim(LHS->getType());
+PrimType LHST = classifyPrim(LHSType);
 LHSOffset = this->allocateLocalPrimitive(LHS, LHST, true, false);
 if (!this->visit(LHS))
   return false;
@@ -709,7 +715,7 @@ bool ByteCodeExprGen::VisitComplexBinOp(const 
BinaryOperator *E) {
   // Same with RHS.
   bool RHSIsComplex;
   unsigned RHSOffset;
-  if (RHS->getType()->isAnyComplexType()) {
+  if (RHSType->isAnyComplexType()) {
 RHSIsComplex = true;
 RHSOffset = this->allocateLocalPrimitive(RHS, PT_Ptr, true, false);
 if (!this->visit(RHS))
@@ -718,7 +724,7 @@ bool ByteCodeExprGen::VisitComplexBinOp(const 
BinaryOperator *E) {
   return false;
   } else {
 RHSIsComplex = false;
-PrimType RHST = classifyPrim(RHS->getType());
+PrimType RHST = classifyPrim(RHSType);
 RHSOffset = this->allocateLocalPrimitive(RHS, RHST, true, false);
 if (!this->visit(RHS))
   return false;

diff  --git a/clang/test/AST/Interp/complex.c b/clang/test/AST/Interp/complex.c
index b5f30b87baa79a..a39f83160ef8ca 100644
--- a/clang/test/AST/Interp/complex.c
+++ b/clang/test/AST/Interp/complex.c
@@ -19,3 +19,12 @@ const _Complex float FC = {0.0f, 0.0f};
 _Static_assert(!FC, "");
 const _Complex float FI = {0, 0};
 _Static_assert(!FI, "");
+
+
+/// Make sure we're stripping the _Atomic part from the
+/// complex type.
+void testComplexFloat(_Atomic(_Complex float) *fp) {
+  _Atomic(_Complex float) x = 2.0f;
+  _Complex float f = *fp;
+  *fp = f;
+}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 0a739eb - [clang][Interp] Implement __builtin___{CF,NS}StringMakeConstantString

2024-03-15 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-15T08:46:13+01:00
New Revision: 0a739eb75fe68b1cec4e4aaad8b5395bb5da9a89

URL: 
https://github.com/llvm/llvm-project/commit/0a739eb75fe68b1cec4e4aaad8b5395bb5da9a89
DIFF: 
https://github.com/llvm/llvm-project/commit/0a739eb75fe68b1cec4e4aaad8b5395bb5da9a89.diff

LOG: [clang][Interp] Implement __builtin___{CF,NS}StringMakeConstantString

By doing the same thing the current interpreter does: Just passing on
the first parameter.

Added: 


Modified: 
clang/lib/AST/Interp/InterpBuiltin.cpp
clang/test/AST/Interp/builtin-functions.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 7e29d6183bdadd..b5bd4e99ba84b1 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -606,10 +606,9 @@ static bool 
interp__builtin_eh_return_data_regno(InterpState &S, CodePtr OpPC,
   return true;
 }
 
-static bool interp__builtin_launder(InterpState &S, CodePtr OpPC,
-const InterpFrame *Frame,
-const Function *Func,
-const CallExpr *Call) {
+/// Just takes the first Argument to the call and puts it on the stack.
+static bool noopPointer(InterpState &S, CodePtr OpPC, const InterpFrame *Frame,
+const Function *Func, const CallExpr *Call) {
   const Pointer &Arg = S.Stk.peek();
   S.Stk.push(Arg);
   return true;
@@ -1144,7 +1143,9 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const 
Function *F,
 break;
 
   case Builtin::BI__builtin_launder:
-if (!interp__builtin_launder(S, OpPC, Frame, F, Call))
+  case Builtin::BI__builtin___CFStringMakeConstantString:
+  case Builtin::BI__builtin___NSStringMakeConstantString:
+if (!noopPointer(S, OpPC, Frame, F, Call))
   return false;
 break;
 

diff  --git a/clang/test/AST/Interp/builtin-functions.cpp 
b/clang/test/AST/Interp/builtin-functions.cpp
index 08fca8428cf5e8..6c8df99a159730 100644
--- a/clang/test/AST/Interp/builtin-functions.cpp
+++ b/clang/test/AST/Interp/builtin-functions.cpp
@@ -510,3 +510,12 @@ namespace bswap {
   int h4 = __builtin_bswap32(0x1234) == 0x3412 ? 1 : f();
   int h5 = __builtin_bswap64(0x1234) == 0x3412 ? 1 : f();
 }
+
+#define CFSTR __builtin___CFStringMakeConstantString
+void test7(void) {
+  const void *X;
+  X = CFSTR("\242"); // both-warning {{input conversion stopped}}
+  X = CFSTR("\0"); // no-warning
+  X = CFSTR(242); // both-error {{cannot initialize a parameter of type 'const 
char *' with an rvalue of type 'int'}}
+  X = CFSTR("foo", "bar"); // both-error {{too many arguments to function 
call}}
+}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] c42bc2e - [clang][NFC] Make some local pointers const

2024-03-15 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-15T09:57:27+01:00
New Revision: c42bc2ea8f66def31ca9a381e995ec61e9fa9b05

URL: 
https://github.com/llvm/llvm-project/commit/c42bc2ea8f66def31ca9a381e995ec61e9fa9b05
DIFF: 
https://github.com/llvm/llvm-project/commit/c42bc2ea8f66def31ca9a381e995ec61e9fa9b05.diff

LOG: [clang][NFC] Make some local pointers const

The function returns a const Expr* anyway.

Added: 


Modified: 
clang/lib/AST/ExprConstant.cpp

Removed: 




diff  --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index b154a196e11c7d..7137efb7876de2 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -11858,8 +11858,8 @@ static QualType getObjectType(APValue::LValueBase B) {
 static const Expr *ignorePointerCastsAndParens(const Expr *E) {
   assert(E->isPRValue() && E->getType()->hasPointerRepresentation());
 
-  auto *NoParens = E->IgnoreParens();
-  auto *Cast = dyn_cast(NoParens);
+  const Expr *NoParens = E->IgnoreParens();
+  const auto *Cast = dyn_cast(NoParens);
   if (Cast == nullptr)
 return NoParens;
 
@@ -11870,7 +11870,7 @@ static const Expr *ignorePointerCastsAndParens(const 
Expr *E) {
   CastKind != CK_AddressSpaceConversion)
 return NoParens;
 
-  auto *SubExpr = Cast->getSubExpr();
+  const auto *SubExpr = Cast->getSubExpr();
   if (!SubExpr->getType()->hasPointerRepresentation() || !SubExpr->isPRValue())
 return NoParens;
   return ignorePointerCastsAndParens(SubExpr);



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 8ab0632 - [clang][Interp] Handle goto and label statements

2024-03-15 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-15T09:57:28+01:00
New Revision: 8ab0632735f87961d27094a1076a41264e2fd3ed

URL: 
https://github.com/llvm/llvm-project/commit/8ab0632735f87961d27094a1076a41264e2fd3ed
DIFF: 
https://github.com/llvm/llvm-project/commit/8ab0632735f87961d27094a1076a41264e2fd3ed.diff

LOG: [clang][Interp] Handle goto and label statements

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeStmtGen.cpp
clang/lib/AST/Interp/ByteCodeStmtGen.h
clang/test/AST/Interp/cxx23.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp 
b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
index 6da3860f98d8c0..b9e8e6a77a7205 100644
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -273,15 +273,18 @@ bool ByteCodeStmtGen::visitStmt(const Stmt *S) {
 return visitCaseStmt(cast(S));
   case Stmt::DefaultStmtClass:
 return visitDefaultStmt(cast(S));
-  case Stmt::GCCAsmStmtClass:
-  case Stmt::MSAsmStmtClass:
-return visitAsmStmt(cast(S));
   case Stmt::AttributedStmtClass:
 return visitAttributedStmt(cast(S));
   case Stmt::CXXTryStmtClass:
 return visitCXXTryStmt(cast(S));
   case Stmt::NullStmtClass:
 return true;
+  // Always invalid statements.
+  case Stmt::GCCAsmStmtClass:
+  case Stmt::MSAsmStmtClass:
+  case Stmt::GotoStmtClass:
+  case Stmt::LabelStmtClass:
+return this->emitInvalid(S);
   default: {
 if (auto *Exp = dyn_cast(S))
   return this->discard(Exp);
@@ -657,11 +660,6 @@ bool ByteCodeStmtGen::visitDefaultStmt(const 
DefaultStmt *S) {
   return this->visitStmt(S->getSubStmt());
 }
 
-template 
-bool ByteCodeStmtGen::visitAsmStmt(const AsmStmt *S) {
-  return this->emitInvalid(S);
-}
-
 template 
 bool ByteCodeStmtGen::visitAttributedStmt(const AttributedStmt *S) {
   // Ignore all attributes.

diff  --git a/clang/lib/AST/Interp/ByteCodeStmtGen.h 
b/clang/lib/AST/Interp/ByteCodeStmtGen.h
index 64e03587ab2112..ab7a591fb798ee 100644
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.h
+++ b/clang/lib/AST/Interp/ByteCodeStmtGen.h
@@ -63,7 +63,6 @@ class ByteCodeStmtGen final : public ByteCodeExprGen 
{
   bool visitSwitchStmt(const SwitchStmt *S);
   bool visitCaseStmt(const CaseStmt *S);
   bool visitDefaultStmt(const DefaultStmt *S);
-  bool visitAsmStmt(const AsmStmt *S);
   bool visitAttributedStmt(const AttributedStmt *S);
   bool visitCXXTryStmt(const CXXTryStmt *S);
 

diff  --git a/clang/test/AST/Interp/cxx23.cpp b/clang/test/AST/Interp/cxx23.cpp
index 127b58915127cf..9ca3a38254b2d1 100644
--- a/clang/test/AST/Interp/cxx23.cpp
+++ b/clang/test/AST/Interp/cxx23.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions 
-verify=ref20,all,all-20 %s
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions 
-verify=ref20,all,all20 %s
 // RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=ref23,all 
%s
-// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions 
-verify=expected20,all,all-20 %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions 
-verify=expected20,all,all20 %s -fexperimental-new-constant-interpreter
 // RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions 
-verify=expected23,all %s -fexperimental-new-constant-interpreter
 
 /// FIXME: The new interpreter is missing all the 'control flows through...' 
diagnostics.
@@ -108,9 +108,9 @@ namespace StaticOperators {
   static_assert(f2() == 3);
 
   struct S1 {
-constexpr S1() { // all-20-error {{never produces a constant expression}}
+constexpr S1() { // all20-error {{never produces a constant expression}}
   throw; // all-note {{not valid in a constant expression}} \
- // all-20-note {{not valid in a constant expression}}
+ // all20-note {{not valid in a constant expression}}
 }
 static constexpr int operator()() { return 3; } // ref20-warning {{C++23 
extension}} \
 // expected20-warning 
{{C++23 extension}}
@@ -121,3 +121,19 @@ namespace StaticOperators {
 
 
 }
+
+int test_in_lambdas() {
+  auto c = [](int n) constexpr {
+if (n == 0)
+  return 0;
+else
+  goto test; // all-note {{subexpression not valid in a constant 
expression}} \
+ // all20-warning {{use of this statement in a constexpr 
function is a C++23 extension}}
+  test:
+return 1;
+  };
+  c(0);
+  constexpr auto A = c(1); // all-error {{must be initialized by a constant 
expression}} \
+   // all-note {{in call to}}
+  return 0;
+}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 719e077 - [clang][Interp] Handle PackIndexExprs

2024-03-15 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-15T10:04:23+01:00
New Revision: 719e077a5680ccfd6601195754c1702b03ba3645

URL: 
https://github.com/llvm/llvm-project/commit/719e077a5680ccfd6601195754c1702b03ba3645
DIFF: 
https://github.com/llvm/llvm-project/commit/719e077a5680ccfd6601195754c1702b03ba3645.diff

LOG: [clang][Interp] Handle PackIndexExprs

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/test/AST/Interp/cxx23.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 088301c08b81bb..39bacbebb5ba7b 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2226,6 +2226,12 @@ bool ByteCodeExprGen::VisitPseudoObjectExpr(
   return true;
 }
 
+template 
+bool ByteCodeExprGen::VisitPackIndexingExpr(
+const PackIndexingExpr *E) {
+  return this->delegate(E->getSelectedExpr());
+}
+
 template  bool ByteCodeExprGen::discard(const Expr *E) 
{
   if (E->containsErrors())
 return false;

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 5ad2e74d7c2693..969598c9780513 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -119,6 +119,7 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   bool VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
   bool VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *E);
   bool VisitPseudoObjectExpr(const PseudoObjectExpr *E);
+  bool VisitPackIndexingExpr(const PackIndexingExpr *E);
 
 protected:
   bool visitExpr(const Expr *E) override;

diff  --git a/clang/test/AST/Interp/cxx23.cpp b/clang/test/AST/Interp/cxx23.cpp
index 9ca3a38254b2d1..042e29613aa753 100644
--- a/clang/test/AST/Interp/cxx23.cpp
+++ b/clang/test/AST/Interp/cxx23.cpp
@@ -137,3 +137,12 @@ int test_in_lambdas() {
// all-note {{in call to}}
   return 0;
 }
+
+/// PackIndexExpr.
+template 
+struct check_ice {
+enum e {
+x = p...[0] // all-warning {{is a C++2c extension}}
+};
+};
+static_assert(check_ice<42>::x == 42);



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 72d85b0 - [clang][Interp] Emit Error op for contains-error expressions

2024-03-15 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-15T10:52:58+01:00
New Revision: 72d85b0315628c982be21c7aada59b6f9274de90

URL: 
https://github.com/llvm/llvm-project/commit/72d85b0315628c982be21c7aada59b6f9274de90
DIFF: 
https://github.com/llvm/llvm-project/commit/72d85b0315628c982be21c7aada59b6f9274de90.diff

LOG: [clang][Interp] Emit Error op for contains-error expressions

Instead of aborting interpretation right away. This way we can still
successfully evaluate such functions provided we don't reach the
Error op at all.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/Interp.h
clang/lib/AST/Interp/Opcodes.td
clang/test/AST/Interp/if.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 39bacbebb5ba7b..f07e430e279d22 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2244,7 +2244,7 @@ template  bool 
ByteCodeExprGen::discard(const Expr *E) {
 template 
 bool ByteCodeExprGen::delegate(const Expr *E) {
   if (E->containsErrors())
-return false;
+return this->emitError(E);
 
   // We're basically doing:
   // OptionScope Scope(this, DicardResult, Initializing);
@@ -2254,7 +2254,7 @@ bool ByteCodeExprGen::delegate(const Expr *E) {
 
 template  bool ByteCodeExprGen::visit(const Expr *E) {
   if (E->containsErrors())
-return false;
+return this->emitError(E);
 
   if (E->getType()->isVoidType())
 return this->discard(E);
@@ -2283,7 +2283,7 @@ bool ByteCodeExprGen::visitInitializer(const 
Expr *E) {
   assert(!classify(E->getType()));
 
   if (E->containsErrors())
-return false;
+return this->emitError(E);
 
   OptionScope Scope(this, /*NewDiscardResult=*/false,
  /*NewInitializing=*/true);

diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 08e272cbc005bd..405993eb827036 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -2227,6 +2227,9 @@ inline bool Invalid(InterpState &S, CodePtr OpPC) {
   return false;
 }
 
+/// Do nothing and just abort execution.
+inline bool Error(InterpState &S, CodePtr OpPC) { return false; }
+
 /// Same here, but only for casts.
 inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind) {
   const SourceLocation &Loc = S.Current->getLocation(OpPC);

diff  --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index 0ed214af3548aa..cc1310f4c0d52a 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -706,6 +706,7 @@ def Dup : Opcode {
 
 // [] -> []
 def Invalid : Opcode {}
+def Error : Opcode {}
 def InvalidCast : Opcode {
   let Args = [ArgCastKind];
 }

diff  --git a/clang/test/AST/Interp/if.cpp b/clang/test/AST/Interp/if.cpp
index 86ae8de6f73ebb..37289d69d32554 100644
--- a/clang/test/AST/Interp/if.cpp
+++ b/clang/test/AST/Interp/if.cpp
@@ -1,8 +1,5 @@
-// RUN: %clang_cc1 -std=c++23 -fsyntax-only 
-fexperimental-new-constant-interpreter %s -verify
-// RUN: %clang_cc1 -std=c++23 -fsyntax-only %s -verify=ref
-
-// expected-no-diagnostics
-// ref-no-diagnostics
+// RUN: %clang_cc1 -std=c++23 -fsyntax-only 
-fexperimental-new-constant-interpreter %s -verify=expected,both
+// RUN: %clang_cc1 -std=c++23 -fsyntax-only %s -verify=ref,both
 
 namespace ConstEval {
   constexpr int f() {
@@ -51,3 +48,13 @@ namespace InitDecl {
   }
   static_assert(attrs() == 1, "");
 };
+
+/// The faulty if statement creates a RecoveryExpr with contains-errors,
+/// but the execution will never reach that.
+constexpr char g(char const (&x)[2]) {
+return 'x';
+  if (auto [a, b] = x) // both-error {{an array type is not allowed here}} \
+   // both-warning {{ISO C++17 does not permit structured 
binding declaration in a condition}}
+;
+}
+static_assert(g("x") == 'x');



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 5334afc - [clang][Interp] Don't forget to visit condition variable decls

2024-03-15 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-15T12:30:37+01:00
New Revision: 5334afcad827a6284ff56f5bde81d4e3416aae8c

URL: 
https://github.com/llvm/llvm-project/commit/5334afcad827a6284ff56f5bde81d4e3416aae8c
DIFF: 
https://github.com/llvm/llvm-project/commit/5334afcad827a6284ff56f5bde81d4e3416aae8c.diff

LOG: [clang][Interp] Don't forget to visit condition variable decls

We did this for if statements, but switch and loop constructs
need to do it as well.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeStmtGen.cpp
clang/test/SemaCXX/decomposed-condition.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp 
b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
index b9e8e6a77a7205..675063e7489886 100644
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -423,6 +423,11 @@ bool ByteCodeStmtGen::visitWhileStmt(const 
WhileStmt *S) {
   LoopScope LS(this, EndLabel, CondLabel);
 
   this->emitLabel(CondLabel);
+
+  if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
+if (!visitDeclStmt(CondDecl))
+  return false;
+
   if (!this->visitBool(Cond))
 return false;
   if (!this->jumpFalse(EndLabel))
@@ -487,6 +492,10 @@ bool ByteCodeStmtGen::visitForStmt(const ForStmt 
*S) {
   if (Init && !this->visitStmt(Init))
 return false;
   this->emitLabel(CondLabel);
+
+  if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
+if (!visitDeclStmt(CondDecl))
+  return false;
   if (Cond) {
 if (!this->visitBool(Cond))
   return false;
@@ -585,17 +594,21 @@ bool ByteCodeStmtGen::visitContinueStmt(const 
ContinueStmt *S) {
 template 
 bool ByteCodeStmtGen::visitSwitchStmt(const SwitchStmt *S) {
   const Expr *Cond = S->getCond();
-  PrimType CondT = this->classifyPrim(Cond->getType());
 
   LabelTy EndLabel = this->getLabel();
   OptLabelTy DefaultLabel = std::nullopt;
-  unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT, true, false);
 
   if (const auto *CondInit = S->getInit())
 if (!visitStmt(CondInit))
   return false;
 
+  if (const DeclStmt *CondDecl = S->getConditionVariableDeclStmt())
+if (!visitDeclStmt(CondDecl))
+  return false;
+
   // Initialize condition variable.
+  PrimType CondT = this->classifyPrim(Cond->getType());
+  unsigned CondVar = this->allocateLocalPrimitive(Cond, CondT, true, false);
   if (!this->visit(Cond))
 return false;
   if (!this->emitSetLocal(CondT, CondVar, S))

diff  --git a/clang/test/SemaCXX/decomposed-condition.cpp 
b/clang/test/SemaCXX/decomposed-condition.cpp
index ab011f6ae4ba43..e55bbee3134ca2 100644
--- a/clang/test/SemaCXX/decomposed-condition.cpp
+++ b/clang/test/SemaCXX/decomposed-condition.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++1z -Wno-binding-in-condition -verify %s
+// RUN: %clang_cc1 -std=c++1z -Wno-binding-in-condition -verify %s 
-fexperimental-new-constant-interpreter
 
 struct X {
   bool flag;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 4f69c4b - [clang][Interp] Don't diagnose reading const ints in C++98

2024-03-15 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-15T16:43:43+01:00
New Revision: 4f69c4b158969386deaf42028d4511ef7a015a20

URL: 
https://github.com/llvm/llvm-project/commit/4f69c4b158969386deaf42028d4511ef7a015a20
DIFF: 
https://github.com/llvm/llvm-project/commit/4f69c4b158969386deaf42028d4511ef7a015a20.diff

LOG: [clang][Interp] Don't diagnose reading const ints in C++98

We _can_ read them, even in C++98.

Added: 


Modified: 
clang/lib/AST/Interp/Interp.cpp
clang/test/AST/Interp/cxx98.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index 4f3cd6cd21a151..1b9f3cfd3a1670 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -254,10 +254,10 @@ bool CheckConstant(InterpState &S, CodePtr OpPC, const 
Descriptor *Desc) {
 if (VD->isConstexpr())
   return true;
 
+QualType T = VD->getType();
 if (S.getLangOpts().CPlusPlus && !S.getLangOpts().CPlusPlus11)
-  return false;
+  return T->isSignedIntegerOrEnumerationType() || 
T->isUnsignedIntegerOrEnumerationType();
 
-QualType T = VD->getType();
 if (T.isConstQualified())
   return true;
 

diff  --git a/clang/test/AST/Interp/cxx98.cpp b/clang/test/AST/Interp/cxx98.cpp
index 73e45372066334..ba6bcd97d920dd 100644
--- a/clang/test/AST/Interp/cxx98.cpp
+++ b/clang/test/AST/Interp/cxx98.cpp
@@ -18,13 +18,12 @@ template struct C;
 
 /// FIXME: This example does not get properly diagnosed in the new interpreter.
 extern const int recurse1;
-const int recurse2 = recurse1; // both-note {{declared here}}
+const int recurse2 = recurse1; // ref-note {{declared here}}
 const int recurse1 = 1;
 int array1[recurse1];
 int array2[recurse2]; // ref-warning 2{{variable length array}} \
   // ref-note {{initializer of 'recurse2' is not a 
constant expression}} \
   // expected-warning {{variable length array}} \
-  // expected-note {{read of non-const variable 
'recurse2'}} \
   // expected-error {{variable length array}}
 
 int NCI; // both-note {{declared here}}
@@ -39,3 +38,10 @@ struct V {
  // both-error {{constructor cannot have a return 
type}}
 };
 _Static_assert(V().c[0], ""); // both-error {{is not an integral constant 
expression}}
+
+struct C0 {
+  template static U Data; // both-warning {{C++14 extension}}
+  template static const U Data = U();
+};
+const int c0_test = C0::Data;
+_Static_assert(c0_test == 0, "");



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 4476913 - [clang][Interp] Don't suppress diagnostics for undefined+external funcs

2024-03-15 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-15T16:43:43+01:00
New Revision: 447691333f0a50a159a9924287d48a8266c8a480

URL: 
https://github.com/llvm/llvm-project/commit/447691333f0a50a159a9924287d48a8266c8a480
DIFF: 
https://github.com/llvm/llvm-project/commit/447691333f0a50a159a9924287d48a8266c8a480.diff

LOG: [clang][Interp] Don't suppress diagnostics for undefined+external funcs

Calling them should still generate a diagnostic.

Added: 


Modified: 
clang/lib/AST/Interp/Interp.cpp
clang/test/AST/Interp/records.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index 1b9f3cfd3a1670..0ce64a572c263f 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -485,7 +485,9 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const 
Function *F) {
 // Don't emit anything if the function isn't defined and we're checking
 // for a constant expression. It might be defined at the point we're
 // actually calling it.
-if (!DiagDecl->isDefined() && S.checkingPotentialConstantExpression())
+bool IsExtern = DiagDecl->getStorageClass() == SC_Extern;
+if (!DiagDecl->isDefined() && !IsExtern &&
+S.checkingPotentialConstantExpression())
   return false;
 
 // If the declaration is defined _and_ declared 'constexpr', the below

diff  --git a/clang/test/AST/Interp/records.cpp 
b/clang/test/AST/Interp/records.cpp
index 7ddc56c9b5dfc4..769e48fe478a5f 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -1238,3 +1238,9 @@ namespace InvalidCtorInitializer {
   // no crash on evaluating the constexpr ctor.
   constexpr int Z = X().Y; // both-error {{constexpr variable 'Z' must be 
initialized by a constant expression}}
 }
+
+extern int f(); // both-note {{here}}
+struct HasNonConstExprMemInit {
+  int x = f(); // both-note {{non-constexpr function}}
+  constexpr HasNonConstExprMemInit() {} // both-error {{never produces a 
constant expression}}
+};



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 426bf0c - [clang][Interp] Try to fix builtin-functions test on AIX

2024-03-15 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-16T06:05:03+01:00
New Revision: 426bf0c915aca9e9d78b6192898b95a44d9afcf4

URL: 
https://github.com/llvm/llvm-project/commit/426bf0c915aca9e9d78b6192898b95a44d9afcf4
DIFF: 
https://github.com/llvm/llvm-project/commit/426bf0c915aca9e9d78b6192898b95a44d9afcf4.diff

LOG: [clang][Interp] Try to fix builtin-functions test on AIX

See
https://github.com/llvm/llvm-project/commit/0a739eb75fe68b1cec4e4aaad8b5395bb5da9a89#commitcomment-139850284

Added: 


Modified: 
clang/test/AST/Interp/builtin-functions.cpp

Removed: 




diff  --git a/clang/test/AST/Interp/builtin-functions.cpp 
b/clang/test/AST/Interp/builtin-functions.cpp
index 6c8df99a159730..a09c6d3acca5da 100644
--- a/clang/test/AST/Interp/builtin-functions.cpp
+++ b/clang/test/AST/Interp/builtin-functions.cpp
@@ -514,7 +514,9 @@ namespace bswap {
 #define CFSTR __builtin___CFStringMakeConstantString
 void test7(void) {
   const void *X;
+#if !defined(_AIX)
   X = CFSTR("\242"); // both-warning {{input conversion stopped}}
+#endif
   X = CFSTR("\0"); // no-warning
   X = CFSTR(242); // both-error {{cannot initialize a parameter of type 'const 
char *' with an rvalue of type 'int'}}
   X = CFSTR("foo", "bar"); // both-error {{too many arguments to function 
call}}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 8e69052 - [clang][Interp] Handle ArrayTypeTraitExprs

2024-03-16 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-16T12:46:28+01:00
New Revision: 8e69052b0e2f3b1bc7dbcf56a0c771e30d2edbf7

URL: 
https://github.com/llvm/llvm-project/commit/8e69052b0e2f3b1bc7dbcf56a0c771e30d2edbf7
DIFF: 
https://github.com/llvm/llvm-project/commit/8e69052b0e2f3b1bc7dbcf56a0c771e30d2edbf7.diff

LOG: [clang][Interp] Handle ArrayTypeTraitExprs

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/test/AST/Interp/literals.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index f07e430e279d22..2e48ec2c508775 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1755,6 +1755,14 @@ bool ByteCodeExprGen::VisitTypeTraitExpr(const 
TypeTraitExpr *E) {
   return this->emitConst(E->getValue(), E);
 }
 
+template 
+bool ByteCodeExprGen::VisitArrayTypeTraitExpr(
+const ArrayTypeTraitExpr *E) {
+  if (DiscardResult)
+return true;
+  return this->emitConst(E->getValue(), E);
+}
+
 template 
 bool ByteCodeExprGen::VisitLambdaExpr(const LambdaExpr *E) {
   if (DiscardResult)

diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 969598c9780513..db0d73ce23f7c4 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -99,6 +99,7 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E);
   bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
   bool VisitTypeTraitExpr(const TypeTraitExpr *E);
+  bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
   bool VisitLambdaExpr(const LambdaExpr *E);
   bool VisitPredefinedExpr(const PredefinedExpr *E);
   bool VisitCXXThrowExpr(const CXXThrowExpr *E);

diff  --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index 0a9580b6f664b0..277438d2e63114 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -910,6 +910,18 @@ namespace TypeTraits {
   struct U {};
   static_assert(S3{}.foo(), "");
   static_assert(!S3{}.foo(), "");
+
+  typedef int Int;
+  typedef Int IntAr[10];
+  typedef const IntAr ConstIntAr;
+  typedef ConstIntAr ConstIntArAr[4];
+
+  static_assert(__array_rank(IntAr) == 1, "");
+  static_assert(__array_rank(ConstIntArAr) == 2, "");
+
+  static_assert(__array_extent(IntAr, 0) == 10, "");
+  static_assert(__array_extent(ConstIntArAr, 0) == 4, "");
+  static_assert(__array_extent(ConstIntArAr, 1) == 10, "");
 }
 
 #if __cplusplus >= 201402L



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 0211389 - [clang][Interp] Handle __datasizeof.

2024-03-17 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-17T16:33:39+01:00
New Revision: 0211389064a1d493e826512a54ae547cb9859223

URL: 
https://github.com/llvm/llvm-project/commit/0211389064a1d493e826512a54ae547cb9859223
DIFF: 
https://github.com/llvm/llvm-project/commit/0211389064a1d493e826512a54ae547cb9859223.diff

LOG: [clang][Interp] Handle __datasizeof.

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/SemaCXX/datasizeof.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 2e48ec2c508775..2557126e7b91bb 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1096,9 +1096,9 @@ template 
 bool ByteCodeExprGen::VisitUnaryExprOrTypeTraitExpr(
 const UnaryExprOrTypeTraitExpr *E) {
   UnaryExprOrTypeTrait Kind = E->getKind();
-  ASTContext &ASTCtx = Ctx.getASTContext();
+  const ASTContext &ASTCtx = Ctx.getASTContext();
 
-  if (Kind == UETT_SizeOf) {
+  if (Kind == UETT_SizeOf || Kind == UETT_DataSizeOf) {
 QualType ArgType = E->getTypeOfArgument();
 
 // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
@@ -1113,7 +1113,10 @@ bool 
ByteCodeExprGen::VisitUnaryExprOrTypeTraitExpr(
   if (ArgType->isDependentType() || !ArgType->isConstantSizeType())
 return false;
 
-  Size = ASTCtx.getTypeSizeInChars(ArgType);
+  if (Kind == UETT_SizeOf)
+Size = ASTCtx.getTypeSizeInChars(ArgType);
+  else
+Size = ASTCtx.getTypeInfoDataSizeInChars(ArgType).Width;
 }
 
 if (DiscardResult)

diff  --git a/clang/test/SemaCXX/datasizeof.cpp 
b/clang/test/SemaCXX/datasizeof.cpp
index 5baf2ecb24ed7a..43135c00496638 100644
--- a/clang/test/SemaCXX/datasizeof.cpp
+++ b/clang/test/SemaCXX/datasizeof.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-gnu -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-gnu -verify %s 
-fexperimental-new-constant-interpreter
 
 #if !__has_extension(datasizeof)
 #  error "Expected datasizeof extension"



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] a4b39f6 - [clang][Interp] Lazily visit const-qualified static data members in C++

2024-03-17 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-17T18:07:51+01:00
New Revision: a4b39f651536c5cd8835a93cdea61039db004252

URL: 
https://github.com/llvm/llvm-project/commit/a4b39f651536c5cd8835a93cdea61039db004252
DIFF: 
https://github.com/llvm/llvm-project/commit/a4b39f651536c5cd8835a93cdea61039db004252.diff

LOG: [clang][Interp] Lazily visit const-qualified static data members in C++

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/AST/Interp/records.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 2557126e7b91bb..6cee3c1af9f66a 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -3306,7 +3306,8 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const 
DeclRefExpr *E) {
   if (Ctx.getLangOpts().CPlusPlus) {
 if (const auto *VD = dyn_cast(D)) {
   // Visit local const variables like normal.
-  if (VD->isLocalVarDecl() && VD->getType().isConstQualified()) {
+  if ((VD->isLocalVarDecl() || VD->isStaticDataMember()) &&
+  VD->getType().isConstQualified()) {
 if (!this->visitVarDecl(VD))
   return false;
 // Retry.

diff  --git a/clang/test/AST/Interp/records.cpp 
b/clang/test/AST/Interp/records.cpp
index 769e48fe478a5f..d37d4410c763fb 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -1244,3 +1244,23 @@ struct HasNonConstExprMemInit {
   int x = f(); // both-note {{non-constexpr function}}
   constexpr HasNonConstExprMemInit() {} // both-error {{never produces a 
constant expression}}
 };
+
+namespace {
+  template 
+  struct integral_constant {
+static const Tp value = v;
+  };
+
+  template 
+  const Tp integral_constant::value;
+
+  typedef integral_constant true_type;
+  typedef integral_constant false_type;
+
+  /// This might look innocent, but we get an evaluateAsInitializer call for 
the
+  /// static bool member before evaluating the first static_assert, but we do 
NOT
+  /// get such a call for the second one. So the second one needs to lazily 
visit
+  /// the data member itself.
+  static_assert(true_type::value, "");
+  static_assert(true_type::value, "");
+}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] dff3e28 - [clang][Interp][NFC] Print qualified name of Descriptor sources

2024-03-17 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-17T18:07:51+01:00
New Revision: dff3e28df9b92e4d3102a0f8012352cebfc9461d

URL: 
https://github.com/llvm/llvm-project/commit/dff3e28df9b92e4d3102a0f8012352cebfc9461d
DIFF: 
https://github.com/llvm/llvm-project/commit/dff3e28df9b92e4d3102a0f8012352cebfc9461d.diff

LOG: [clang][Interp][NFC] Print qualified name of Descriptor sources

Added: 


Modified: 
clang/lib/AST/Interp/Disasm.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/Disasm.cpp b/clang/lib/AST/Interp/Disasm.cpp
index 160701f4d4a760..390d79d44b0a74 100644
--- a/clang/lib/AST/Interp/Disasm.cpp
+++ b/clang/lib/AST/Interp/Disasm.cpp
@@ -183,7 +183,7 @@ LLVM_DUMP_METHOD void Descriptor::dump(llvm::raw_ostream 
&OS) const {
   {
 ColorScope SC(OS, true, {llvm::raw_ostream::BLUE, true});
 if (const auto *ND = dyn_cast_if_present(asDecl()))
-  OS << ND->getName();
+  ND->printQualifiedName(OS);
 else if (asExpr())
   OS << "expr (TODO)";
   }



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] ca87671 - [clang][Interp][NFC] Make local pointer const

2024-03-17 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-17T18:07:51+01:00
New Revision: ca876711aee31e5ec7f4f6f0210de664c8ec7ce4

URL: 
https://github.com/llvm/llvm-project/commit/ca876711aee31e5ec7f4f6f0210de664c8ec7ce4
DIFF: 
https://github.com/llvm/llvm-project/commit/ca876711aee31e5ec7f4f6f0210de664c8ec7ce4.diff

LOG: [clang][Interp][NFC] Make local pointer const

Added: 


Modified: 
clang/lib/AST/Interp/InterpBuiltin.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index b5bd4e99ba84b1..45bac41ff7782a 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -917,7 +917,7 @@ static bool interp__builtin_complex(InterpState &S, CodePtr 
OpPC,
 
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
   const CallExpr *Call) {
-  InterpFrame *Frame = S.Current;
+  const InterpFrame *Frame = S.Current;
   APValue Dummy;
 
   std::optional ReturnT = S.getContext().classify(Call);



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 5143a12 - [clang][Interp] Add __builtin_is_constant_evaluated warnings

2024-03-17 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-17T18:07:51+01:00
New Revision: 5143a1241362616840af826d18c067025dae

URL: 
https://github.com/llvm/llvm-project/commit/5143a1241362616840af826d18c067025dae
DIFF: 
https://github.com/llvm/llvm-project/commit/5143a1241362616840af826d18c067025dae.diff

LOG: [clang][Interp] Add __builtin_is_constant_evaluated warnings

Add the same warnings the current interpreter emits.

Added: 


Modified: 
clang/lib/AST/Interp/InterpBuiltin.cpp
clang/lib/AST/Interp/InterpFrame.cpp
clang/test/AST/Interp/builtins.cpp
clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 45bac41ff7782a..1bf5d55314f1f2 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -119,6 +119,36 @@ static bool retPrimValue(InterpState &S, CodePtr OpPC, 
APValue &Result,
 #undef RET_CASE
 }
 
+static bool interp__builtin_is_constant_evaluated(InterpState &S, CodePtr OpPC,
+  const InterpFrame *Frame,
+  const CallExpr *Call) {
+  // The current frame is the one for __builtin_is_constant_evaluated.
+  // The one above that, potentially the one for std::is_constant_evaluated().
+  if (S.inConstantContext() && !S.checkingPotentialConstantExpression() &&
+  Frame->Caller && S.getEvalStatus().Diag) {
+auto isStdCall = [](const FunctionDecl *F) -> bool {
+  return F && F->isInStdNamespace() && F->getIdentifier() &&
+ F->getIdentifier()->isStr("is_constant_evaluated");
+};
+const InterpFrame *Caller = Frame->Caller;
+
+if (Caller->Caller && isStdCall(Caller->getCallee())) {
+  const Expr *E = Caller->Caller->getExpr(Caller->getRetPC());
+  S.report(E->getExprLoc(),
+   diag::warn_is_constant_evaluated_always_true_constexpr)
+  << "std::is_constant_evaluated";
+} else {
+  const Expr *E = Frame->Caller->getExpr(Frame->getRetPC());
+  S.report(E->getExprLoc(),
+   diag::warn_is_constant_evaluated_always_true_constexpr)
+  << "__builtin_is_constant_evaluated";
+}
+  }
+
+  S.Stk.push(Boolean::from(S.inConstantContext()));
+  return true;
+}
+
 static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const CallExpr *Call) {
@@ -924,7 +954,8 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const 
Function *F,
 
   switch (F->getBuiltinID()) {
   case Builtin::BI__builtin_is_constant_evaluated:
-S.Stk.push(Boolean::from(S.inConstantContext()));
+if (!interp__builtin_is_constant_evaluated(S, OpPC, Frame, Call))
+  return false;
 break;
   case Builtin::BI__builtin_assume:
   case Builtin::BI__assume:

diff  --git a/clang/lib/AST/Interp/InterpFrame.cpp 
b/clang/lib/AST/Interp/InterpFrame.cpp
index f69ff06b5e81b5..12e2e6ff9155b9 100644
--- a/clang/lib/AST/Interp/InterpFrame.cpp
+++ b/clang/lib/AST/Interp/InterpFrame.cpp
@@ -190,6 +190,8 @@ SourceRange InterpFrame::getCallRange() const {
 }
 
 const FunctionDecl *InterpFrame::getCallee() const {
+  if (!Func)
+return nullptr;
   return Func->getDecl();
 }
 

diff  --git a/clang/test/AST/Interp/builtins.cpp 
b/clang/test/AST/Interp/builtins.cpp
index 06a22b16b2dcbb..9095d1bf8d6a3a 100644
--- a/clang/test/AST/Interp/builtins.cpp
+++ b/clang/test/AST/Interp/builtins.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -verify 
-fms-extensions
-// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s -fms-extensions 
-S -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s 
-Wno-constant-evaluated -verify -fms-extensions
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter %s 
-Wno-constant-evaluated -fms-extensions -S -emit-llvm -o - | FileCheck %s
 // RUN: %clang_cc1 -verify=ref %s -Wno-constant-evaluated -fms-extensions
 // RUN: %clang_cc1 -verify=ref %s -Wno-constant-evaluated %s -fms-extensions 
-S -emit-llvm -o - | FileCheck %s
 

diff  --git a/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp 
b/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp
index 35dc69cccb3a2e..fa40c13971118d 100644
--- a/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp
+++ b/clang/test/SemaCXX/warn-constant-evaluated-constexpr.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++2a -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only -verify %s 
-fexperimental-new-constant-interpreter
 
 namespace std {
 constexpr bool is_constant_evaluated() noexcept {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman

[clang] c2f75c7 - [clang][Interp] Handle CXXDefaultInitExpr of composite type

2024-03-18 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-18T12:59:56+01:00
New Revision: c2f75c7159518e238e0185c0f4e615fedcd8a167

URL: 
https://github.com/llvm/llvm-project/commit/c2f75c7159518e238e0185c0f4e615fedcd8a167
DIFF: 
https://github.com/llvm/llvm-project/commit/c2f75c7159518e238e0185c0f4e615fedcd8a167.diff

LOG: [clang][Interp] Handle CXXDefaultInitExpr of composite type

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/AST/Interp/records.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 6cee3c1af9f66a..d943dcbe06507b 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2916,11 +2916,7 @@ template 
 bool ByteCodeExprGen::VisitCXXDefaultInitExpr(
 const CXXDefaultInitExpr *E) {
   SourceLocScope SLS(this, E);
-  if (Initializing)
-return this->visitInitializer(E->getExpr());
-
-  assert(classify(E->getType()));
-  return this->visit(E->getExpr());
+  return this->delegate(E->getExpr());
 }
 
 template 

diff  --git a/clang/test/AST/Interp/records.cpp 
b/clang/test/AST/Interp/records.cpp
index d37d4410c763fb..0f76e0cfe99277 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -1264,3 +1264,24 @@ namespace {
   static_assert(true_type::value, "");
   static_assert(true_type::value, "");
 }
+
+#if __cplusplus >= 202002L
+namespace {
+  /// Used to crash because the CXXDefaultInitExpr is of compound type.
+  struct A {
+int &x;
+constexpr ~A() { --x; }
+  };
+  struct B {
+int &x;
+const A &a = A{x};
+  };
+  constexpr int a() {
+int x = 1;
+int f = B{x}.x;
+B{x}; // both-warning {{expression result unused}}
+
+return 1;
+  }
+}
+#endif



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 1d9fb2e - [clang][Interp] Disable CFStringMakeConstantString test on AIX

2024-03-18 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-18T14:53:04+01:00
New Revision: 1d9fb2ee612f0ccf588d40dc4b5445cffd36e8af

URL: 
https://github.com/llvm/llvm-project/commit/1d9fb2ee612f0ccf588d40dc4b5445cffd36e8af
DIFF: 
https://github.com/llvm/llvm-project/commit/1d9fb2ee612f0ccf588d40dc4b5445cffd36e8af.diff

LOG: [clang][Interp] Disable CFStringMakeConstantString test on AIX

It's not only the fist CFSTR call that's broken on AIX.
See 
https://github.com/llvm/llvm-project/commit/0a739eb75fe68b1cec4e4aaad8b5395bb5da9a89#commitcomment-139910542

Added: 


Modified: 
clang/test/AST/Interp/builtin-functions.cpp

Removed: 




diff  --git a/clang/test/AST/Interp/builtin-functions.cpp 
b/clang/test/AST/Interp/builtin-functions.cpp
index a09c6d3acca5da..2e9d1a831dcf6e 100644
--- a/clang/test/AST/Interp/builtin-functions.cpp
+++ b/clang/test/AST/Interp/builtin-functions.cpp
@@ -516,8 +516,8 @@ void test7(void) {
   const void *X;
 #if !defined(_AIX)
   X = CFSTR("\242"); // both-warning {{input conversion stopped}}
-#endif
   X = CFSTR("\0"); // no-warning
   X = CFSTR(242); // both-error {{cannot initialize a parameter of type 'const 
char *' with an rvalue of type 'int'}}
   X = CFSTR("foo", "bar"); // both-error {{too many arguments to function 
call}}
+#endif
 }



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] e2e3624 - [clang][test] Try to fix constexpr-void-cast test

2024-03-18 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-18T15:35:39+01:00
New Revision: e2e3624fae669f85de1445bf7037ff29feb30905

URL: 
https://github.com/llvm/llvm-project/commit/e2e3624fae669f85de1445bf7037ff29feb30905
DIFF: 
https://github.com/llvm/llvm-project/commit/e2e3624fae669f85de1445bf7037ff29feb30905.diff

LOG: [clang][test] Try to fix constexpr-void-cast test

The test currenlty fails:
https://lab.llvm.org/buildbot/#/builders/139/builds/61628

because it emits a C11 warning when compiling as C. Try to fix that
be defining the C standard to use.

Added: 


Modified: 
clang/test/Sema/constexpr-void-cast.c

Removed: 




diff  --git a/clang/test/Sema/constexpr-void-cast.c 
b/clang/test/Sema/constexpr-void-cast.c
index c5caa3b9e58feb..91e4027f67fe38 100644
--- a/clang/test/Sema/constexpr-void-cast.c
+++ b/clang/test/Sema/constexpr-void-cast.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -x c -fsyntax-only %s -verify=c
-// RUN: %clang_cc1 -x c -fsyntax-only %s -pedantic -verify=c-pedantic
+// RUN: %clang_cc1 -x c -fsyntax-only %s -verify=c -std=c11
+// RUN: %clang_cc1 -x c -fsyntax-only %s -pedantic -verify=c-pedantic -std=c11
 //
 // RUN: %clang_cc1 -x c++ -fsyntax-only %s -verify=cxx
 // RUN: %clang_cc1 -x c++ -fsyntax-only %s -pedantic -verify=cxx-pedantic



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] d56110f - [clang][Interp] Fix _Complex comma operators

2024-03-18 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-18T16:02:40+01:00
New Revision: d56110fa025b58e57602a254c841e6e41ea46a42

URL: 
https://github.com/llvm/llvm-project/commit/d56110fa025b58e57602a254c841e6e41ea46a42
DIFF: 
https://github.com/llvm/llvm-project/commit/d56110fa025b58e57602a254c841e6e41ea46a42.diff

LOG: [clang][Interp] Fix _Complex comma operators

Handle them before shelling out to visitComplexBinOp().

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/test/AST/Interp/complex.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index d943dcbe06507b..af214d4a8577c6 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -401,6 +401,17 @@ bool ByteCodeExprGen::VisitBinaryOperator(const 
BinaryOperator *BO) {
   const Expr *LHS = BO->getLHS();
   const Expr *RHS = BO->getRHS();
 
+  // Handle comma operators. Just discard the LHS
+  // and delegate to RHS.
+  if (BO->isCommaOp()) {
+if (!this->discard(LHS))
+  return false;
+if (RHS->getType()->isVoidType())
+  return this->discard(RHS);
+
+return this->delegate(RHS);
+  }
+
   if (BO->getType()->isAnyComplexType())
 return this->VisitComplexBinOp(BO);
   if ((LHS->getType()->isAnyComplexType() ||
@@ -416,16 +427,6 @@ bool ByteCodeExprGen::VisitBinaryOperator(const 
BinaryOperator *BO) {
   std::optional RT = classify(RHS->getType());
   std::optional T = classify(BO->getType());
 
-  // Deal with operations which have composite or void types.
-  if (BO->isCommaOp()) {
-if (!this->discard(LHS))
-  return false;
-if (RHS->getType()->isVoidType())
-  return this->discard(RHS);
-
-return this->delegate(RHS);
-  }
-
   // Special case for C++'s three-way/spaceship operator <=>, which
   // returns a std::{strong,weak,partial}_ordering (which is a class, so 
doesn't
   // have a PrimType).

diff  --git a/clang/test/AST/Interp/complex.cpp 
b/clang/test/AST/Interp/complex.cpp
index d4e3d5a46a64fb..09cb620d7b7c39 100644
--- a/clang/test/AST/Interp/complex.cpp
+++ b/clang/test/AST/Interp/complex.cpp
@@ -9,6 +9,9 @@ static_assert(&__imag z1 == &__real z1 + 1, "");
 static_assert((*(&__imag z1)) == __imag z1, "");
 static_assert((*(&__real z1)) == __real z1, "");
 
+constexpr _Complex int Comma1 = {1, 2};
+constexpr _Complex int Comma2 = (0, Comma1);
+static_assert(Comma1 == Comma1, "");
 
 constexpr double setter() {
   _Complex float d = {1.0, 2.0};



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 6aaf9c8 - [clang][Interp][NFC] Sanitize collectBaseOffset parameters

2024-03-19 Thread Timm Bäder via cfe-commits

Author: Timm Bäder
Date: 2024-03-19T10:07:23+01:00
New Revision: 6aaf9c83099b80e73ef2208ae9f7f300c7808659

URL: 
https://github.com/llvm/llvm-project/commit/6aaf9c83099b80e73ef2208ae9f7f300c7808659
DIFF: 
https://github.com/llvm/llvm-project/commit/6aaf9c83099b80e73ef2208ae9f7f300c7808659.diff

LOG: [clang][Interp][NFC] Sanitize collectBaseOffset parameters

Added: 


Modified: 
clang/lib/AST/Interp/ByteCodeExprGen.cpp

Removed: 




diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index af214d4a8577c6..73831eefba4568 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -3337,6 +3337,8 @@ template 
 unsigned
 ByteCodeExprGen::collectBaseOffset(const RecordType *BaseType,
 const RecordType *DerivedType) {
+  assert(BaseType);
+  assert(DerivedType);
   const auto *FinalDecl = cast(BaseType->getDecl());
   const RecordDecl *CurDecl = DerivedType->getDecl();
   const Record *CurRecord = getRecord(CurDecl);



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   3   4   5   6   7   8   9   10   >