[clang] [clang][Interp] Fix returning nullptr from functions (PR #67229)

2023-10-09 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/67229
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle variadic functions (PR #67814)

2023-10-09 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/67814
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle delegating constructors (PR #67823)

2023-10-09 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/67823
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Emit dummy values for unknown C variables (PR #66749)

2023-10-07 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/66749
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Emit dummy values for unknown C variables (PR #66749)

2023-10-07 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/66749

>From 1d36bdbd1e876adb5c39cf8e06c8387d5de1ab71 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 19 Sep 2023 08:47:01 +0200
Subject: [PATCH] [clang][Interp] Emit dummy values for unknown C variables

We can't load anything from them, but we can still take their address or
return them as lvalues.
---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp |  3 +++
 clang/lib/AST/Interp/Interp.cpp  |  2 +-
 clang/lib/AST/Interp/Program.cpp |  9 -
 clang/lib/AST/Interp/Program.h   |  6 +++---
 clang/test/AST/Interp/c.c| 22 --
 5 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index c813f9b6d9991c5..24d4991a0308097 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -2493,6 +2493,9 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const 
DeclRefExpr *E) {
   // Retry.
   return this->VisitDeclRefExpr(E);
 }
+
+if (std::optional I = P.getOrCreateDummy(D))
+  return this->emitGetPtrGlobal(*I, E);
   }
 
   return this->emitInvalidDeclRef(E, E);
diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index e1951574edb6288..4f2d120407e942a 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -139,7 +139,7 @@ bool CheckExtern(InterpState , CodePtr OpPC, const 
Pointer ) {
   if (!Ptr.isExtern())
 return true;
 
-  if (!S.checkingPotentialConstantExpression()) {
+  if (!S.checkingPotentialConstantExpression() && S.getLangOpts().CPlusPlus) {
 const auto *VD = Ptr.getDeclDesc()->asValueDecl();
 const SourceInfo  = S.Current->getSource(OpPC);
 S.FFDiag(Loc, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
diff --git a/clang/lib/AST/Interp/Program.cpp b/clang/lib/AST/Interp/Program.cpp
index 63901d90703dc46..65e170881e313d7 100644
--- a/clang/lib/AST/Interp/Program.cpp
+++ b/clang/lib/AST/Interp/Program.cpp
@@ -138,17 +138,16 @@ std::optional Program::getOrCreateGlobal(const 
ValueDecl *VD,
   return std::nullopt;
 }
 
-std::optional Program::getOrCreateDummy(const ParmVarDecl *PD) {
-
+std::optional Program::getOrCreateDummy(const ValueDecl *PD) {
   // Dedup blocks since they are immutable and pointers cannot be compared.
   if (auto It = DummyParams.find(PD);
   It != DummyParams.end())
 return It->second;
 
-  auto  = Ctx.getASTContext();
   // Create a pointer to an incomplete array of the specified elements.
-  QualType ElemTy = PD->getType()->castAs()->getPointeeType();
-  QualType Ty = ASTCtx.getIncompleteArrayType(ElemTy, ArrayType::Normal, 0);
+  QualType ElemTy = PD->getType();
+  QualType Ty =
+  Ctx.getASTContext().getIncompleteArrayType(ElemTy, ArrayType::Normal, 0);
 
   if (auto Idx = createGlobal(PD, Ty, /*isStatic=*/true, /*isExtern=*/true)) {
 DummyParams[PD] = *Idx;
diff --git a/clang/lib/AST/Interp/Program.h b/clang/lib/AST/Interp/Program.h
index d880a738e733e31..d843fa06538f514 100644
--- a/clang/lib/AST/Interp/Program.h
+++ b/clang/lib/AST/Interp/Program.h
@@ -82,8 +82,8 @@ class Program final {
   std::optional getOrCreateGlobal(const ValueDecl *VD,
 const Expr *Init = nullptr);
 
-  /// Returns or creates a dummy value for parameters.
-  std::optional getOrCreateDummy(const ParmVarDecl *PD);
+  /// Returns or creates a dummy value for unknown declarations.
+  std::optional getOrCreateDummy(const ValueDecl *PD);
 
   /// Creates a global and returns its index.
   std::optional createGlobal(const ValueDecl *VD, const Expr *E);
@@ -208,7 +208,7 @@ class Program final {
   llvm::DenseMap Records;
 
   /// Dummy parameter to generate pointers from.
-  llvm::DenseMap DummyParams;
+  llvm::DenseMap DummyParams;
 
   /// Creates a new descriptor.
   template 
diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c
index c0ec5f8339dd1d7..24ece8f26399031 100644
--- a/clang/test/AST/Interp/c.c
+++ b/clang/test/AST/Interp/c.c
@@ -24,15 +24,25 @@ const int b = 3;
 _Static_assert(b == 3, ""); // pedantic-ref-warning {{not an integer constant 
expression}} \
 // pedantic-expected-warning {{not an integer 
constant expression}}
 
+/// FIXME: The new interpreter is missing the "initializer of 'c' unknown" 
diagnostics.
 const int c; // ref-note {{declared here}} \
- // pedantic-ref-note {{declared here}} \
- // expected-note {{declared here}} \
- // pedantic-expected-note {{declared here}}
+ // pedantic-ref-note {{declared here}}
 _Static_assert(c == 0, ""); // ref-error {{not an integral constant 
expression}} \
 // ref-note {{initializer of 'c' is unknown}} \
 // pedantic-ref-error {{not an integral constant 

[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)

2023-10-07 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 



@@ -878,15 +879,46 @@ bool Preprocessor::HandleIdentifier(Token ) {
   return true;
 }
 
+void Preprocessor::saveCheckPoint(const char *P) {
+  static constexpr ptrdiff_t Limit = 1000;
+  if (CheckPoints.empty()) {
+CheckPoints.push_back(P);
+return;
+  }
+
+  const char *Cur = CheckPoints.back();
+  if (Cur == P)
+return;
+  if ((P - Cur) > Limit)
+CheckPoints.push_back(P);
+}
+
+const char *Preprocessor::getSaveFor(const char *S) const {
+  const char *C = S;
+  // FIXME: Use std::lower_bound or something smart. Aaron knows what I'm
+  // talking about.
+  for (ssize_t I = CheckPoints.size() - 1; I >= 0; --I) {
+C = CheckPoints[I];
+if (CheckPoints[I] <= S)
+  break;
+  }
+  return C;
+}
+
 void Preprocessor::Lex(Token ) {
   ++LexLevel;
 
   // We loop here until a lex function returns a token; this avoids recursion.
   bool ReturnedToken;
+  // const char *Save = nullptr;
   do {
 switch (CurLexerKind) {
 case CLK_Lexer:
   ReturnedToken = CurLexer->Lex(Result);
+  if (ReturnedToken && CurLexer &&
+  CurLexer->getFileID() == SourceMgr.getMainFileID()) {

tbaederr wrote:

I guess we should be doing that for all files and not just the main file.

https://github.com/llvm/llvm-project/pull/66514
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)

2023-10-07 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/66514

>From 259ce1a3febe0c3996ecd7e55b9e79381eba8f67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 15 Sep 2023 15:51:39 +0200
Subject: [PATCH 01/11] [clang][Diagnostics] Highlight code snippets

Add some primitive syntax highlighting to our code snippet output.
---
 .../clang/Frontend/CodeSnippetHighlighter.h   |  46 +++
 clang/include/clang/Frontend/TextDiagnostic.h |   2 +
 clang/lib/Frontend/CMakeLists.txt |   1 +
 clang/lib/Frontend/CodeSnippetHighlighter.cpp | 120 ++
 clang/lib/Frontend/TextDiagnostic.cpp |  26 
 5 files changed, 195 insertions(+)
 create mode 100644 clang/include/clang/Frontend/CodeSnippetHighlighter.h
 create mode 100644 clang/lib/Frontend/CodeSnippetHighlighter.cpp

diff --git a/clang/include/clang/Frontend/CodeSnippetHighlighter.h 
b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
new file mode 100644
index 000..776954b59e2e1a8
--- /dev/null
+++ b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
@@ -0,0 +1,46 @@
+//===--- CodeSnippetHighlighter.h - Code snippet highlighting ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+#define LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+
+struct StyleRange {
+  unsigned Start;
+  unsigned End;
+  const enum llvm::raw_ostream::Colors c;
+};
+
+class CodeSnippetHighlighter final {
+public:
+  CodeSnippetHighlighter() = default;
+
+  /// Produce StyleRanges for the given line.
+  /// The returned vector contains non-overlapping style ranges. They are 
sorted
+  /// from beginning of the line to the end.
+  std::vector highlightLine(llvm::StringRef SourceLine,
+const LangOptions );
+
+private:
+  bool Initialized = false;
+  /// Fills Keywords and Literals.
+  void ensureTokenData();
+
+  llvm::SmallSet Keywords;
+  llvm::SmallSet Literals;
+};
+
+} // namespace clang
+
+#endif
diff --git a/clang/include/clang/Frontend/TextDiagnostic.h 
b/clang/include/clang/Frontend/TextDiagnostic.h
index 7eb0ab0cdc9bca8..59fd4d4f9408d48 100644
--- a/clang/include/clang/Frontend/TextDiagnostic.h
+++ b/clang/include/clang/Frontend/TextDiagnostic.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 #define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 
+#include "clang/Frontend/CodeSnippetHighlighter.h"
 #include "clang/Frontend/DiagnosticRenderer.h"
 
 namespace clang {
@@ -33,6 +34,7 @@ namespace clang {
 /// printing coming out of libclang.
 class TextDiagnostic : public DiagnosticRenderer {
   raw_ostream 
+  CodeSnippetHighlighter SnippetHighlighter;
 
 public:
   TextDiagnostic(raw_ostream ,
diff --git a/clang/lib/Frontend/CMakeLists.txt 
b/clang/lib/Frontend/CMakeLists.txt
index 1e5f0a859dfd568..f3547f771593093 100644
--- a/clang/lib/Frontend/CMakeLists.txt
+++ b/clang/lib/Frontend/CMakeLists.txt
@@ -42,6 +42,7 @@ add_clang_library(clangFrontend
   TextDiagnosticPrinter.cpp
   VerifyDiagnosticConsumer.cpp
   InterfaceStubFunctionsConsumer.cpp
+  CodeSnippetHighlighter.cpp
 
   DEPENDS
   ClangDriverOptions
diff --git a/clang/lib/Frontend/CodeSnippetHighlighter.cpp 
b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
new file mode 100644
index 000..829a533ad2692e5
--- /dev/null
+++ b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
@@ -0,0 +1,120 @@
+
+#include "clang/Frontend/CodeSnippetHighlighter.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+void CodeSnippetHighlighter::ensureTokenData() {
+  if (Initialized)
+return;
+
+  // List of keywords, literals and types we want to highlight.
+  // These are best-effort, as is everything we do wrt. highlighting.
+  Keywords.insert("_Static_assert");
+  Keywords.insert("auto");
+  Keywords.insert("concept");
+  Keywords.insert("const");
+  Keywords.insert("consteval");
+  Keywords.insert("constexpr");
+  Keywords.insert("delete");
+  Keywords.insert("do");
+  Keywords.insert("else");
+  Keywords.insert("final");
+  Keywords.insert("for");
+  Keywords.insert("if");
+  Keywords.insert("mutable");
+  

[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)

2023-10-07 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/66514

>From 259ce1a3febe0c3996ecd7e55b9e79381eba8f67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 15 Sep 2023 15:51:39 +0200
Subject: [PATCH 01/10] [clang][Diagnostics] Highlight code snippets

Add some primitive syntax highlighting to our code snippet output.
---
 .../clang/Frontend/CodeSnippetHighlighter.h   |  46 +++
 clang/include/clang/Frontend/TextDiagnostic.h |   2 +
 clang/lib/Frontend/CMakeLists.txt |   1 +
 clang/lib/Frontend/CodeSnippetHighlighter.cpp | 120 ++
 clang/lib/Frontend/TextDiagnostic.cpp |  26 
 5 files changed, 195 insertions(+)
 create mode 100644 clang/include/clang/Frontend/CodeSnippetHighlighter.h
 create mode 100644 clang/lib/Frontend/CodeSnippetHighlighter.cpp

diff --git a/clang/include/clang/Frontend/CodeSnippetHighlighter.h 
b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
new file mode 100644
index 000..776954b59e2e1a8
--- /dev/null
+++ b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
@@ -0,0 +1,46 @@
+//===--- CodeSnippetHighlighter.h - Code snippet highlighting ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+#define LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+
+struct StyleRange {
+  unsigned Start;
+  unsigned End;
+  const enum llvm::raw_ostream::Colors c;
+};
+
+class CodeSnippetHighlighter final {
+public:
+  CodeSnippetHighlighter() = default;
+
+  /// Produce StyleRanges for the given line.
+  /// The returned vector contains non-overlapping style ranges. They are 
sorted
+  /// from beginning of the line to the end.
+  std::vector highlightLine(llvm::StringRef SourceLine,
+const LangOptions );
+
+private:
+  bool Initialized = false;
+  /// Fills Keywords and Literals.
+  void ensureTokenData();
+
+  llvm::SmallSet Keywords;
+  llvm::SmallSet Literals;
+};
+
+} // namespace clang
+
+#endif
diff --git a/clang/include/clang/Frontend/TextDiagnostic.h 
b/clang/include/clang/Frontend/TextDiagnostic.h
index 7eb0ab0cdc9bca8..59fd4d4f9408d48 100644
--- a/clang/include/clang/Frontend/TextDiagnostic.h
+++ b/clang/include/clang/Frontend/TextDiagnostic.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 #define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 
+#include "clang/Frontend/CodeSnippetHighlighter.h"
 #include "clang/Frontend/DiagnosticRenderer.h"
 
 namespace clang {
@@ -33,6 +34,7 @@ namespace clang {
 /// printing coming out of libclang.
 class TextDiagnostic : public DiagnosticRenderer {
   raw_ostream 
+  CodeSnippetHighlighter SnippetHighlighter;
 
 public:
   TextDiagnostic(raw_ostream ,
diff --git a/clang/lib/Frontend/CMakeLists.txt 
b/clang/lib/Frontend/CMakeLists.txt
index 1e5f0a859dfd568..f3547f771593093 100644
--- a/clang/lib/Frontend/CMakeLists.txt
+++ b/clang/lib/Frontend/CMakeLists.txt
@@ -42,6 +42,7 @@ add_clang_library(clangFrontend
   TextDiagnosticPrinter.cpp
   VerifyDiagnosticConsumer.cpp
   InterfaceStubFunctionsConsumer.cpp
+  CodeSnippetHighlighter.cpp
 
   DEPENDS
   ClangDriverOptions
diff --git a/clang/lib/Frontend/CodeSnippetHighlighter.cpp 
b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
new file mode 100644
index 000..829a533ad2692e5
--- /dev/null
+++ b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
@@ -0,0 +1,120 @@
+
+#include "clang/Frontend/CodeSnippetHighlighter.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+void CodeSnippetHighlighter::ensureTokenData() {
+  if (Initialized)
+return;
+
+  // List of keywords, literals and types we want to highlight.
+  // These are best-effort, as is everything we do wrt. highlighting.
+  Keywords.insert("_Static_assert");
+  Keywords.insert("auto");
+  Keywords.insert("concept");
+  Keywords.insert("const");
+  Keywords.insert("consteval");
+  Keywords.insert("constexpr");
+  Keywords.insert("delete");
+  Keywords.insert("do");
+  Keywords.insert("else");
+  Keywords.insert("final");
+  Keywords.insert("for");
+  Keywords.insert("if");
+  Keywords.insert("mutable");
+  Keywords.insert("namespace");
+  

[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)

2023-10-07 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Preliminary results show a slight degradation: 
http://llvm-compile-time-tracker.com/?config=NewPM-O3=instructions%3Au=tbaederr

Might have to create fewer check points.

https://github.com/llvm/llvm-project/pull/66514
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)

2023-10-06 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/66514

>From 259ce1a3febe0c3996ecd7e55b9e79381eba8f67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 15 Sep 2023 15:51:39 +0200
Subject: [PATCH 01/10] [clang][Diagnostics] Highlight code snippets

Add some primitive syntax highlighting to our code snippet output.
---
 .../clang/Frontend/CodeSnippetHighlighter.h   |  46 +++
 clang/include/clang/Frontend/TextDiagnostic.h |   2 +
 clang/lib/Frontend/CMakeLists.txt |   1 +
 clang/lib/Frontend/CodeSnippetHighlighter.cpp | 120 ++
 clang/lib/Frontend/TextDiagnostic.cpp |  26 
 5 files changed, 195 insertions(+)
 create mode 100644 clang/include/clang/Frontend/CodeSnippetHighlighter.h
 create mode 100644 clang/lib/Frontend/CodeSnippetHighlighter.cpp

diff --git a/clang/include/clang/Frontend/CodeSnippetHighlighter.h 
b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
new file mode 100644
index 000..776954b59e2e1a8
--- /dev/null
+++ b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
@@ -0,0 +1,46 @@
+//===--- CodeSnippetHighlighter.h - Code snippet highlighting ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+#define LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+
+struct StyleRange {
+  unsigned Start;
+  unsigned End;
+  const enum llvm::raw_ostream::Colors c;
+};
+
+class CodeSnippetHighlighter final {
+public:
+  CodeSnippetHighlighter() = default;
+
+  /// Produce StyleRanges for the given line.
+  /// The returned vector contains non-overlapping style ranges. They are 
sorted
+  /// from beginning of the line to the end.
+  std::vector highlightLine(llvm::StringRef SourceLine,
+const LangOptions );
+
+private:
+  bool Initialized = false;
+  /// Fills Keywords and Literals.
+  void ensureTokenData();
+
+  llvm::SmallSet Keywords;
+  llvm::SmallSet Literals;
+};
+
+} // namespace clang
+
+#endif
diff --git a/clang/include/clang/Frontend/TextDiagnostic.h 
b/clang/include/clang/Frontend/TextDiagnostic.h
index 7eb0ab0cdc9bca8..59fd4d4f9408d48 100644
--- a/clang/include/clang/Frontend/TextDiagnostic.h
+++ b/clang/include/clang/Frontend/TextDiagnostic.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 #define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 
+#include "clang/Frontend/CodeSnippetHighlighter.h"
 #include "clang/Frontend/DiagnosticRenderer.h"
 
 namespace clang {
@@ -33,6 +34,7 @@ namespace clang {
 /// printing coming out of libclang.
 class TextDiagnostic : public DiagnosticRenderer {
   raw_ostream 
+  CodeSnippetHighlighter SnippetHighlighter;
 
 public:
   TextDiagnostic(raw_ostream ,
diff --git a/clang/lib/Frontend/CMakeLists.txt 
b/clang/lib/Frontend/CMakeLists.txt
index 1e5f0a859dfd568..f3547f771593093 100644
--- a/clang/lib/Frontend/CMakeLists.txt
+++ b/clang/lib/Frontend/CMakeLists.txt
@@ -42,6 +42,7 @@ add_clang_library(clangFrontend
   TextDiagnosticPrinter.cpp
   VerifyDiagnosticConsumer.cpp
   InterfaceStubFunctionsConsumer.cpp
+  CodeSnippetHighlighter.cpp
 
   DEPENDS
   ClangDriverOptions
diff --git a/clang/lib/Frontend/CodeSnippetHighlighter.cpp 
b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
new file mode 100644
index 000..829a533ad2692e5
--- /dev/null
+++ b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
@@ -0,0 +1,120 @@
+
+#include "clang/Frontend/CodeSnippetHighlighter.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+void CodeSnippetHighlighter::ensureTokenData() {
+  if (Initialized)
+return;
+
+  // List of keywords, literals and types we want to highlight.
+  // These are best-effort, as is everything we do wrt. highlighting.
+  Keywords.insert("_Static_assert");
+  Keywords.insert("auto");
+  Keywords.insert("concept");
+  Keywords.insert("const");
+  Keywords.insert("consteval");
+  Keywords.insert("constexpr");
+  Keywords.insert("delete");
+  Keywords.insert("do");
+  Keywords.insert("else");
+  Keywords.insert("final");
+  Keywords.insert("for");
+  Keywords.insert("if");
+  Keywords.insert("mutable");
+  Keywords.insert("namespace");
+  

[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)

2023-10-06 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

The latest commit keeps a list of pointers into the buffer and (potentially) 
updates it after every regular token lex (when we have a `Lexer`). We can then 
simply use that to get a starting point to lex from.

I'll have a look at the performance impact of regular parsing later.

https://github.com/llvm/llvm-project/pull/66514
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)

2023-10-06 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr converted_to_draft 
https://github.com/llvm/llvm-project/pull/66514
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)

2023-10-06 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/66514

>From 259ce1a3febe0c3996ecd7e55b9e79381eba8f67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 15 Sep 2023 15:51:39 +0200
Subject: [PATCH 01/10] [clang][Diagnostics] Highlight code snippets

Add some primitive syntax highlighting to our code snippet output.
---
 .../clang/Frontend/CodeSnippetHighlighter.h   |  46 +++
 clang/include/clang/Frontend/TextDiagnostic.h |   2 +
 clang/lib/Frontend/CMakeLists.txt |   1 +
 clang/lib/Frontend/CodeSnippetHighlighter.cpp | 120 ++
 clang/lib/Frontend/TextDiagnostic.cpp |  26 
 5 files changed, 195 insertions(+)
 create mode 100644 clang/include/clang/Frontend/CodeSnippetHighlighter.h
 create mode 100644 clang/lib/Frontend/CodeSnippetHighlighter.cpp

diff --git a/clang/include/clang/Frontend/CodeSnippetHighlighter.h 
b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
new file mode 100644
index 000..776954b59e2e1a8
--- /dev/null
+++ b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
@@ -0,0 +1,46 @@
+//===--- CodeSnippetHighlighter.h - Code snippet highlighting ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+#define LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+
+struct StyleRange {
+  unsigned Start;
+  unsigned End;
+  const enum llvm::raw_ostream::Colors c;
+};
+
+class CodeSnippetHighlighter final {
+public:
+  CodeSnippetHighlighter() = default;
+
+  /// Produce StyleRanges for the given line.
+  /// The returned vector contains non-overlapping style ranges. They are 
sorted
+  /// from beginning of the line to the end.
+  std::vector highlightLine(llvm::StringRef SourceLine,
+const LangOptions );
+
+private:
+  bool Initialized = false;
+  /// Fills Keywords and Literals.
+  void ensureTokenData();
+
+  llvm::SmallSet Keywords;
+  llvm::SmallSet Literals;
+};
+
+} // namespace clang
+
+#endif
diff --git a/clang/include/clang/Frontend/TextDiagnostic.h 
b/clang/include/clang/Frontend/TextDiagnostic.h
index 7eb0ab0cdc9bca8..59fd4d4f9408d48 100644
--- a/clang/include/clang/Frontend/TextDiagnostic.h
+++ b/clang/include/clang/Frontend/TextDiagnostic.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 #define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 
+#include "clang/Frontend/CodeSnippetHighlighter.h"
 #include "clang/Frontend/DiagnosticRenderer.h"
 
 namespace clang {
@@ -33,6 +34,7 @@ namespace clang {
 /// printing coming out of libclang.
 class TextDiagnostic : public DiagnosticRenderer {
   raw_ostream 
+  CodeSnippetHighlighter SnippetHighlighter;
 
 public:
   TextDiagnostic(raw_ostream ,
diff --git a/clang/lib/Frontend/CMakeLists.txt 
b/clang/lib/Frontend/CMakeLists.txt
index 1e5f0a859dfd568..f3547f771593093 100644
--- a/clang/lib/Frontend/CMakeLists.txt
+++ b/clang/lib/Frontend/CMakeLists.txt
@@ -42,6 +42,7 @@ add_clang_library(clangFrontend
   TextDiagnosticPrinter.cpp
   VerifyDiagnosticConsumer.cpp
   InterfaceStubFunctionsConsumer.cpp
+  CodeSnippetHighlighter.cpp
 
   DEPENDS
   ClangDriverOptions
diff --git a/clang/lib/Frontend/CodeSnippetHighlighter.cpp 
b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
new file mode 100644
index 000..829a533ad2692e5
--- /dev/null
+++ b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
@@ -0,0 +1,120 @@
+
+#include "clang/Frontend/CodeSnippetHighlighter.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+void CodeSnippetHighlighter::ensureTokenData() {
+  if (Initialized)
+return;
+
+  // List of keywords, literals and types we want to highlight.
+  // These are best-effort, as is everything we do wrt. highlighting.
+  Keywords.insert("_Static_assert");
+  Keywords.insert("auto");
+  Keywords.insert("concept");
+  Keywords.insert("const");
+  Keywords.insert("consteval");
+  Keywords.insert("constexpr");
+  Keywords.insert("delete");
+  Keywords.insert("do");
+  Keywords.insert("else");
+  Keywords.insert("final");
+  Keywords.insert("for");
+  Keywords.insert("if");
+  Keywords.insert("mutable");
+  Keywords.insert("namespace");
+  

[clang] [clang] Avoid evaluating the BitWidth expression over and over again (PR #66203)

2023-10-06 Thread Timm Baeder via cfe-commits

tbaederr wrote:

^ Removing integer and boolean expressions seems to have some negative impact 
though.

https://github.com/llvm/llvm-project/pull/66203
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Avoid evaluating the BitWidth expression over and over again (PR #66203)

2023-10-06 Thread Timm Baeder via cfe-commits

tbaederr wrote:

http://llvm-compile-time-tracker.com/index.php?config=NewPM-O3=instructions%3Au=tbaederr

https://github.com/llvm/llvm-project/pull/66203
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Avoid evaluating the BitWidth expression over and over again (PR #66203)

2023-10-06 Thread Timm Baeder via cfe-commits

tbaederr wrote:

> > Well, this is not going to make a noticeable difference in runtime. 
> > https://reviews.llvm.org/D155548 didn't land because there are no 
> > measurements to make where this makes a measurable difference.
> 
> Those changes didn't land because no measurements were attempted. Putting up 
> a branch at https://llvm-compile-time-tracker.com/ would help get those 
> measurements to at least start to see if there's benefit or harm from the 
> changes.

I did measure it, but only by myself, I can ask Nikita do use the compile-time 
tracker as well.

> 
> > As for my earlier comment, it would also make sense to rename that function 
> > to `computeBitWidth()` or just cache the computed value (we compute it when 
> > parsing anyway to diagnose 0 size, etc. right?).
> 
> Caching the computed value would make sense, but that's sort of the goal of 
> D155548, right? That's a generalized caching mechanism that should mean when 
> we compute it to diagnose 0 size, we never need to re-compute it again.

Well yes, we would never compute it again, but we still go through quite a few 
function calls to figure out that we've already computed it before. For a 
function called `getBitWidthValue()` I basically assume it has exactly one 
statement: `return BitWidthValue`.

I thought the bitwidth expression will always be a `ConstantExpr`, unless it's 
value-dependent (in which case it will be a `ConstantExpr` when we instantiate 
it, right?), but I might be wrong.



https://github.com/llvm/llvm-project/pull/66203
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Avoid evaluating the BitWidth expression over and over again (PR #66203)

2023-10-06 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Well, this is not going to make a noticeable difference in runtime. 
https://reviews.llvm.org/D155548 didn't land because there are no measurements 
to make where this makes a measurable difference.

As for my earlier comment, it would also make sense to rename that function to 
`computeBitWidth()` or just cache the computed value (we compute it when 
parsing anyway to diagnose 0 size, etc. right?).

https://github.com/llvm/llvm-project/pull/66203
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Sema] Only check RVV types if we have them (PR #67669)

2023-10-06 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/67669
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Sema] Only check RVV types if we have them (PR #67669)

2023-10-06 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/67669
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Diagnostics] Add bitfield source range to zero width diags (PR #68312)

2023-10-06 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/68312
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)

2023-10-05 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:


> Also, redirecting output to a file doesn't always disable color output. From 
> our precommit CI pipeline: 
> https://buildkite.com/llvm-project/clang-ci/builds/4334#018af546-9a63-45f1-a8f9-6262f3d45b75
>  -- click on the raw log and you'll see it has contents like:
> 
> ```
> �_bk;t=1696332172990�~~~ Running global pre-checkout hook
> �_bk;t=1696332172991��[90m$�[0m /etc/buildkite-agent/hooks/pre-checkout
> �_bk;t=1696332173007�BUILDKITE_REPO: 
> https://github.com/llvm-premerge-tests/llvm-project.git
> 
> �_bk;t=1696332173008�current remote URL: 
> https://github.com/llvm-premerge-tests/llvm-project.git
> 
> �_bk;t=1696332173010�GC counter 16/20
> 
> �_bk;t=1696332173026��[90m$�[0m cd 
> /var/lib/buildkite-agent/builds/linux-56-7f758798dd-v9p4k-1/llvm-project/clang-ci
> �_bk;t=1696332173026��[90m# OLDPWD added�[0m
> �_bk;t=1696332173026��[90m# PWD changed�[0m
> ```

Is that on purpose?

> Did you investigate what Richard was suggesting with caching "we should be 
> back to normal lexing here" information and re-lexing from that point? That 
> would make me feel a lot more comfortable than re-lexing the entire file.

I am looking at it, but I'm not certain where to get the information. I 
definitely want to avoid adding overhead to regular, diagnostic-less lexing.



https://github.com/llvm/llvm-project/pull/66514
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][NFC] Refactor Builtins.def to be a tablegen file (PR #68324)

2023-10-05 Thread Timm Baeder via cfe-commits


@@ -172,6 +173,8 @@ cl::opt Action(
"Generate clang attribute text node dumper"),
 clEnumValN(GenClangAttrNodeTraverse, "gen-clang-attr-node-traverse",
"Generate clang attribute traverser"),
+clEnumValN(GenClangBuiltins, "gen-clang-builtins",
+   "Generate clanhg builtins list"),

tbaederr wrote:

```suggestion
   "Generate clang builtins list"),
```

https://github.com/llvm/llvm-project/pull/68324
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Diagnostics] Add bitfield source range to zero width diags (PR #68312)

2023-10-05 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/68312

Before:
```
array.cpp:157:8: error: named bit-field 'a' has zero width
  157 |   char a : 12 - 12;
  |^
1 error generated.
```

After:

```
array.cpp:157:8: error: named bit-field 'a' has zero width
  157 |   char a : 12 - 12;
  |^   ~~~
1 error generated.
```

>From 853b6d8a92ec466e474e70f9c3e73c58bfd70c4c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Thu, 5 Oct 2023 16:14:10 +0200
Subject: [PATCH] [clang][Diagnostics] Add bitfield source range to zero width
 diags

---
 clang/lib/Sema/SemaDecl.cpp| 3 ++-
 clang/test/Misc/misc-source-ranges.cpp | 7 +++
 2 files changed, 9 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Misc/misc-source-ranges.cpp

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 28d9a0ac654b81f..8fff33c49f2e5c7 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -18161,7 +18161,8 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
 
   // Zero-width bitfield is ok for anonymous field.
   if (Value == 0 && FieldName)
-return Diag(FieldLoc, diag::err_bitfield_has_zero_width) << FieldName;
+return Diag(FieldLoc, diag::err_bitfield_has_zero_width)
+   << FieldName << BitWidth->getSourceRange();
 
   if (Value.isSigned() && Value.isNegative()) {
 if (FieldName)
diff --git a/clang/test/Misc/misc-source-ranges.cpp 
b/clang/test/Misc/misc-source-ranges.cpp
new file mode 100644
index 000..7a9d9d057dac407
--- /dev/null
+++ b/clang/test/Misc/misc-source-ranges.cpp
@@ -0,0 +1,7 @@
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-print-source-range-info %s 
2>&1 | FileCheck %s
+
+struct S {
+  char a : 12 - 12;
+};
+// CHECK: misc-source-ranges.cpp:[[@LINE-2]]:8:{[[@LINE-2]]:12-[[@LINE-2]]:19}
+

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


[clang] [clang][Interp] Implement __builtin_bit_cast (PR #68288)

2023-10-05 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/68288

>From e208c2fc7932d80d441d90bfa0fd949b8910a4c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 11 Jul 2023 13:45:04 +0200
Subject: [PATCH 1/2] Bitcasts

---
 clang/lib/AST/CMakeLists.txt   |   1 +
 clang/lib/AST/Interp/Boolean.h |  15 +-
 clang/lib/AST/Interp/ByteCodeExprGen.cpp   |  71 +++
 clang/lib/AST/Interp/ByteCodeExprGen.h |   1 +
 clang/lib/AST/Interp/Floating.h|  11 +
 clang/lib/AST/Interp/Integral.h|  19 +-
 clang/lib/AST/Interp/Interp.cpp|  17 +
 clang/lib/AST/Interp/Interp.h  |  66 ++
 clang/lib/AST/Interp/InterpBitcast.cpp | 482 +++
 clang/lib/AST/Interp/Opcodes.td|  17 +
 clang/lib/AST/Interp/PrimType.h|   4 +
 clang/test/AST/Interp/builtin-bit-cast.cpp | 683 +
 clang/test/AST/Interp/literals.cpp |   5 +
 13 files changed, 1389 insertions(+), 3 deletions(-)
 create mode 100644 clang/lib/AST/Interp/InterpBitcast.cpp
 create mode 100644 clang/test/AST/Interp/builtin-bit-cast.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index fe3f8c485ec1c56..5a188b583022bda 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -74,6 +74,7 @@ add_clang_library(clangAST
   Interp/Frame.cpp
   Interp/Function.cpp
   Interp/InterpBuiltin.cpp
+  Interp/InterpBitcast.cpp
   Interp/Floating.cpp
   Interp/Interp.cpp
   Interp/InterpBlock.cpp
diff --git a/clang/lib/AST/Interp/Boolean.h b/clang/lib/AST/Interp/Boolean.h
index c3ed3d61f76ca1c..d395264ab2de448 100644
--- a/clang/lib/AST/Interp/Boolean.h
+++ b/clang/lib/AST/Interp/Boolean.h
@@ -9,14 +9,15 @@
 #ifndef LLVM_CLANG_AST_INTERP_BOOLEAN_H
 #define LLVM_CLANG_AST_INTERP_BOOLEAN_H
 
-#include 
-#include 
 #include "Integral.h"
 #include "clang/AST/APValue.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/ComparisonCategories.h"
 #include "llvm/ADT/APSInt.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
+#include 
+#include 
 
 namespace clang {
 namespace interp {
@@ -65,6 +66,9 @@ class Boolean final {
   Boolean toUnsigned() const { return *this; }
 
   constexpr static unsigned bitWidth() { return 1; }
+  constexpr static unsigned objectReprBits() { return 8; }
+  constexpr static unsigned valueReprBytes(const ASTContext ) { return 1; }
+
   bool isZero() const { return !V; }
   bool isMin() const { return isZero(); }
 
@@ -106,6 +110,13 @@ class Boolean final {
 return Boolean(!Value.isZero());
   }
 
+  static Boolean bitcastFromMemory(const std::byte *Buff) {
+bool Val = static_cast(*Buff);
+return Boolean(Val);
+  }
+
+  void bitcastToMemory(std::byte *Buff) { std::memcpy(Buff, , sizeof(V)); }
+
   static Boolean zero() { return from(false); }
 
   template 
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 3cf8bf874b1d210..8cc010d6f100ccb 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -67,6 +67,74 @@ template  class OptionScope final {
 } // namespace interp
 } // namespace clang
 
+//  This function is constexpr if and only if To, From, and the types of
+//  all subobjects of To and From are types T such that...
+//  (3.1) - is_union_v is false;
+//  (3.2) - is_pointer_v is false;
+//  (3.3) - is_member_pointer_v is false;
+//  (3.4) - is_volatile_v is false; and
+//  (3.5) - T has no non-static data members of reference type
+template 
+bool ByteCodeExprGen::emitBuiltinBitCast(const CastExpr *E) {
+  const Expr *SubExpr = E->getSubExpr();
+  QualType FromType = SubExpr->getType();
+  QualType ToType = E->getType();
+  std::optional ToT = classify(ToType);
+
+  // FIXME: This is wrong. We need to do the bitcast and then
+  //   throw away the result, so we still get the diagnostics.
+  if (DiscardResult)
+return this->discard(SubExpr);
+
+  if (ToType->isNullPtrType()) {
+if (!this->discard(SubExpr))
+  return false;
+
+return this->emitNullPtr(E);
+  }
+
+  if (FromType->isNullPtrType() && ToT) {
+if (!this->discard(SubExpr))
+  return false;
+
+return visitZeroInitializer(ToType, E);
+  }
+  assert(!ToType->isReferenceType());
+
+  // Get a pointer to the value-to-cast on the stack.
+  if (!this->visit(SubExpr))
+return false;
+
+  if (!ToT || ToT == PT_Ptr) {
+// Conversion to an array or record type.
+return this->emitBitCastPtr(E);
+  }
+
+  assert(ToT);
+
+  // Conversion to a primitive type. FromType can be another
+  // primitive type, or a record/array.
+  //
+  // Same thing for floats, but we need the target
+  // semantics here.
+  if (ToT == PT_Float) {
+const auto *TargetSemantics = (ToType);
+CharUnits FloatSize = Ctx.getASTContext().getTypeSizeInChars(ToType);
+return 

[clang] [clang] WIP: Warn on mismatched RequiresCapability attributes (PR #67520)

2023-10-05 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/67520
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Implement __builtin_bit_cast (PR #68288)

2023-10-05 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/68288

>From https://reviews.llvm.org/D154951 - which is never gonna make it out of 
>Phabricator anyway.


The tests are failing because https://reviews.llvm.org/D154581 is not pushed.

Aaron's review mentioned that we should support bitfields before pushing this.

>From e208c2fc7932d80d441d90bfa0fd949b8910a4c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 11 Jul 2023 13:45:04 +0200
Subject: [PATCH] Bitcasts

---
 clang/lib/AST/CMakeLists.txt   |   1 +
 clang/lib/AST/Interp/Boolean.h |  15 +-
 clang/lib/AST/Interp/ByteCodeExprGen.cpp   |  71 +++
 clang/lib/AST/Interp/ByteCodeExprGen.h |   1 +
 clang/lib/AST/Interp/Floating.h|  11 +
 clang/lib/AST/Interp/Integral.h|  19 +-
 clang/lib/AST/Interp/Interp.cpp|  17 +
 clang/lib/AST/Interp/Interp.h  |  66 ++
 clang/lib/AST/Interp/InterpBitcast.cpp | 482 +++
 clang/lib/AST/Interp/Opcodes.td|  17 +
 clang/lib/AST/Interp/PrimType.h|   4 +
 clang/test/AST/Interp/builtin-bit-cast.cpp | 683 +
 clang/test/AST/Interp/literals.cpp |   5 +
 13 files changed, 1389 insertions(+), 3 deletions(-)
 create mode 100644 clang/lib/AST/Interp/InterpBitcast.cpp
 create mode 100644 clang/test/AST/Interp/builtin-bit-cast.cpp

diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt
index fe3f8c485ec1c56..5a188b583022bda 100644
--- a/clang/lib/AST/CMakeLists.txt
+++ b/clang/lib/AST/CMakeLists.txt
@@ -74,6 +74,7 @@ add_clang_library(clangAST
   Interp/Frame.cpp
   Interp/Function.cpp
   Interp/InterpBuiltin.cpp
+  Interp/InterpBitcast.cpp
   Interp/Floating.cpp
   Interp/Interp.cpp
   Interp/InterpBlock.cpp
diff --git a/clang/lib/AST/Interp/Boolean.h b/clang/lib/AST/Interp/Boolean.h
index c3ed3d61f76ca1c..d395264ab2de448 100644
--- a/clang/lib/AST/Interp/Boolean.h
+++ b/clang/lib/AST/Interp/Boolean.h
@@ -9,14 +9,15 @@
 #ifndef LLVM_CLANG_AST_INTERP_BOOLEAN_H
 #define LLVM_CLANG_AST_INTERP_BOOLEAN_H
 
-#include 
-#include 
 #include "Integral.h"
 #include "clang/AST/APValue.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/ComparisonCategories.h"
 #include "llvm/ADT/APSInt.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
+#include 
+#include 
 
 namespace clang {
 namespace interp {
@@ -65,6 +66,9 @@ class Boolean final {
   Boolean toUnsigned() const { return *this; }
 
   constexpr static unsigned bitWidth() { return 1; }
+  constexpr static unsigned objectReprBits() { return 8; }
+  constexpr static unsigned valueReprBytes(const ASTContext ) { return 1; }
+
   bool isZero() const { return !V; }
   bool isMin() const { return isZero(); }
 
@@ -106,6 +110,13 @@ class Boolean final {
 return Boolean(!Value.isZero());
   }
 
+  static Boolean bitcastFromMemory(const std::byte *Buff) {
+bool Val = static_cast(*Buff);
+return Boolean(Val);
+  }
+
+  void bitcastToMemory(std::byte *Buff) { std::memcpy(Buff, , sizeof(V)); }
+
   static Boolean zero() { return from(false); }
 
   template 
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 3cf8bf874b1d210..8cc010d6f100ccb 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -67,6 +67,74 @@ template  class OptionScope final {
 } // namespace interp
 } // namespace clang
 
+//  This function is constexpr if and only if To, From, and the types of
+//  all subobjects of To and From are types T such that...
+//  (3.1) - is_union_v is false;
+//  (3.2) - is_pointer_v is false;
+//  (3.3) - is_member_pointer_v is false;
+//  (3.4) - is_volatile_v is false; and
+//  (3.5) - T has no non-static data members of reference type
+template 
+bool ByteCodeExprGen::emitBuiltinBitCast(const CastExpr *E) {
+  const Expr *SubExpr = E->getSubExpr();
+  QualType FromType = SubExpr->getType();
+  QualType ToType = E->getType();
+  std::optional ToT = classify(ToType);
+
+  // FIXME: This is wrong. We need to do the bitcast and then
+  //   throw away the result, so we still get the diagnostics.
+  if (DiscardResult)
+return this->discard(SubExpr);
+
+  if (ToType->isNullPtrType()) {
+if (!this->discard(SubExpr))
+  return false;
+
+return this->emitNullPtr(E);
+  }
+
+  if (FromType->isNullPtrType() && ToT) {
+if (!this->discard(SubExpr))
+  return false;
+
+return visitZeroInitializer(ToType, E);
+  }
+  assert(!ToType->isReferenceType());
+
+  // Get a pointer to the value-to-cast on the stack.
+  if (!this->visit(SubExpr))
+return false;
+
+  if (!ToT || ToT == PT_Ptr) {
+// Conversion to an array or record type.
+return this->emitBitCastPtr(E);
+  }
+
+  assert(ToT);
+
+  // Conversion to a primitive type. FromType can be another
+  // primitive type, or a record/array.
+  //
+  // Same thing for floats, 

[clang] [Sema] Add check for bitfield assignments to larger integral types (PR #68276)

2023-10-05 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr edited 
https://github.com/llvm/llvm-project/pull/68276
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExprConst] Don't try to evaluate value-dependent DeclRefExprs (PR #67778)

2023-10-05 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/67778
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExprConst] Don't try to evaluate value-dependent DeclRefExprs (PR #67778)

2023-10-05 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67778

>From 55a0f4abbb9ad9270aa18e2eec08b4a0bfb4dae0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 29 Sep 2023 11:23:55 +0200
Subject: [PATCH] [clang][ExprConst] Don't try to evaluate value-dependent
 DeclRefExprs

The Expression here migth be value dependent, which makes us run into an
assertion later on. Just bail out early.

Fixes #67690
---
 clang/docs/ReleaseNotes.rst  |  3 +++
 clang/lib/AST/ExprConstant.cpp   |  3 +++
 clang/test/SemaCXX/constant-expression-cxx1z.cpp | 13 +
 3 files changed, 19 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 21b76292bca965e..2362e479dfbbc5a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -339,6 +339,9 @@ Bug Fixes in This Version
   (`#64462 `_)
 - Fixes a regression where the ``UserDefinedLiteral`` was not properly 
preserved
   while evaluating consteval functions. (`#63898 
`_).
+- Fix a crash when evaluating value-dependent structured binding
+  variables at compile time.
+  Fixes (`#67690 `_)
 
 Bug Fixes to Compiler Builtins
 ^^
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index a142ea7c47a4730..d0e27de743604da 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3357,6 +3357,9 @@ static bool evaluateVarDeclInit(EvalInfo , const 
Expr *E,
 return false;
   }
 
+  if (E->isValueDependent())
+return false;
+
   // Dig out the initializer, and use the declaration which it's attached to.
   // FIXME: We should eventually check whether the variable has a reachable
   // initializing declaration.
diff --git a/clang/test/SemaCXX/constant-expression-cxx1z.cpp 
b/clang/test/SemaCXX/constant-expression-cxx1z.cpp
index 9335626a5c90a4f..c0766f70cf88158 100644
--- a/clang/test/SemaCXX/constant-expression-cxx1z.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx1z.cpp
@@ -177,3 +177,16 @@ namespace LambdaCallOp {
 p();
   }
 }
+
+// This used to crash due to an assertion failure,
+// see gh#67690
+namespace {
+  struct C {
+int x;
+  };
+
+  template  void f() {
+const auto &[c] = *p;
+ // expected-warning {{expression result unused}}
+  }
+}

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


[clang] [clang] Avoid evaluating the BitWidth expression over and over again (PR #66203)

2023-10-04 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/66203
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Emit dummy values for unknown C variables (PR #66749)

2023-10-04 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/66749
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExprConst] Don't try to evaluate value-dependent DeclRefExprs (PR #67778)

2023-10-03 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67778

>From 1b6fcc49f5ef9b99b4b2f7019de6d8d24a03f232 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 3 Oct 2023 08:35:57 +0200
Subject: [PATCH 1/2] [clang][Interp] Add basic support for _BitInt

Make sure we pass the expected bitwidth around when casting to
IntAP/IntAPS and move the tests to their own file.
---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp | 12 
 clang/lib/AST/Interp/Context.h   |  2 +
 clang/lib/AST/Interp/IntegralAP.h| 17 +++--
 clang/lib/AST/Interp/Interp.h| 58 +++-
 clang/lib/AST/Interp/InterpBuiltin.cpp   |  3 +-
 clang/lib/AST/Interp/Opcodes.td  | 30 +++-
 clang/test/AST/Interp/intap.cpp  | 88 
 clang/test/AST/Interp/literals.cpp   | 75 
 8 files changed, 199 insertions(+), 86 deletions(-)
 create mode 100644 clang/test/AST/Interp/intap.cpp

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index e266804a4e75dea..f899c2fe22ecd8f 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -138,6 +138,13 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
 if (!this->visit(SubExpr))
   return false;
 
+if (ToT == PT_IntAP)
+  return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->getType()),
+  CE);
+if (ToT == PT_IntAPS)
+  return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->getType()),
+   CE);
+
 return this->emitCastFloatingIntegral(*ToT, CE);
   }
 
@@ -183,6 +190,11 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
   return true;
 }
 
+if (ToT == PT_IntAP)
+  return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->getType()), CE);
+if (ToT == PT_IntAPS)
+  return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->getType()), CE);
+
 return this->emitCast(*FromT, *ToT, CE);
   }
 
diff --git a/clang/lib/AST/Interp/Context.h b/clang/lib/AST/Interp/Context.h
index 958b50b1615ad18..6df61e93ad83abc 100644
--- a/clang/lib/AST/Interp/Context.h
+++ b/clang/lib/AST/Interp/Context.h
@@ -64,6 +64,8 @@ class Context final {
   unsigned getCharBit() const;
   /// Return the floating-point semantics for T.
   const llvm::fltSemantics (QualType T) const;
+  /// Return the size of T in bits.
+  uint32_t getBitWidth(QualType T) const { return Ctx.getIntWidth(T); }
 
   /// Classifies an expression.
   std::optional classify(QualType T) const;
diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index a8df431bef11784..363fcd2eacb2f23 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -37,8 +37,12 @@ template  class IntegralAP final {
   APSInt V;
 
   template  static T truncateCast(const APSInt ) {
-return std::is_signed_v ? V.trunc(sizeof(T) * 8).getSExtValue()
-   : V.trunc(sizeof(T) * 8).getZExtValue();
+constexpr unsigned BitSize = sizeof(T) * 8;
+if (BitSize >= V.getBitWidth())
+  return std::is_signed_v ? V.getSExtValue() : V.getZExtValue();
+
+return std::is_signed_v ? V.trunc(BitSize).getSExtValue()
+   : V.trunc(BitSize).getZExtValue();
   }
 
 public:
@@ -89,10 +93,10 @@ template  class IntegralAP final {
   }
 
   template 
-  static IntegralAP from(Integral I) {
-// FIXME: Take bits parameter.
+  static IntegralAP from(Integral I, unsigned BitWidth) {
+llvm::errs() << __PRETTY_FUNCTION__ << ": " << BitWidth << "\n";
 APSInt Copy =
-APSInt(APInt(128, static_cast(I), InputSigned), !Signed);
+APSInt(APInt(BitWidth, static_cast(I), InputSigned), !Signed);
 Copy.setIsSigned(Signed);
 
 assert(Copy.isSigned() == Signed);
@@ -108,8 +112,7 @@ template  class IntegralAP final {
 return IntegralAP(0);
   }
 
-  // FIXME: This can't be static if the bitwidth depends on V.
-  static constexpr unsigned bitWidth() { return 128; }
+  constexpr unsigned bitWidth() const { return V.getBitWidth(); }
 
   APSInt toAPSInt(unsigned Bits = 0) const { return V; }
   APValue toAPValue() const { return APValue(V); }
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 9d5ec3315415cf7..d3ee28c0315cda8 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1561,6 +1561,22 @@ inline bool CastFP(InterpState , CodePtr OpPC, const 
llvm::fltSemantics *Sem,
   return true;
 }
 
+/// Like Cast(), but we cast to an arbitrary-bitwidth integral, so we need
+/// to know what bitwidth the result should be.
+template ::T>
+bool CastAP(InterpState , CodePtr OpPC, uint32_t BitWidth) {
+  S.Stk.push>(
+  IntegralAP::from(S.Stk.pop(), BitWidth));
+  return true;
+}

[clang] [Clang] Fix constant evaluating a captured variable in a lambda (PR #68090)

2023-10-03 Thread Timm Baeder via cfe-commits


@@ -8366,8 +8366,14 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr *E, 
const VarDecl *VD) {
   return false;
 
 if (auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
+  auto *MD = cast(Info.CurrentCall->Callee);
   // Start with 'Result' referring to the complete closure object...
-  Result = *Info.CurrentCall->This;
+  if (MD->isExplicitObjectMemberFunction()) {
+APValue *RefValue =
+Info.getParamSlot(Info.CurrentCall->Arguments, 
MD->getParamDecl(0));
+Result.setFrom(Info.Ctx, *RefValue);
+  } else
+Result = *Info.CurrentCall->This;

tbaederr wrote:

Shouldn't the `CurrentCall->this` be set to the first argument for explicit 
member functions, somewhere where the  stack frame is created?

https://github.com/llvm/llvm-project/pull/68090
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang] Fix constant evaluating a captured variable in a lambda (PR #68090)

2023-10-03 Thread Timm Baeder via cfe-commits


@@ -8366,8 +8366,14 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr *E, 
const VarDecl *VD) {
   return false;
 
 if (auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
+  auto *MD = cast(Info.CurrentCall->Callee);
   // Start with 'Result' referring to the complete closure object...
-  Result = *Info.CurrentCall->This;
+  if (MD->isExplicitObjectMemberFunction()) {

tbaederr wrote:

```suggestion
  if (const auto *MD = cast(Info.CurrentCall->Callee);
  MD && MD->isExplicitObjectMemberFunction()) {
```

Does that work?

https://github.com/llvm/llvm-project/pull/68090
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] IntegralAP zero-init (PR #68081)

2023-10-03 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/68081

Not adding any tests since I'm waiting for 
https://github.com/llvm/llvm-project/pull/68069/

>From dabd2ea3311929d446499e94fc2647e18183ea8d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 3 Oct 2023 11:05:27 +0200
Subject: [PATCH] [clang][Interp] IntegralAP zero-init

---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp |  4 ++--
 clang/lib/AST/Interp/IntegralAP.h|  9 +
 clang/lib/AST/Interp/Interp.h| 10 ++
 clang/lib/AST/Interp/Opcodes.td  | 15 ++-
 4 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index e266804a4e75dea..9a2bbe5c1841208 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1642,9 +1642,9 @@ bool 
ByteCodeExprGen::visitZeroInitializer(QualType QT,
   case PT_Uint64:
 return this->emitZeroUint64(E);
   case PT_IntAP:
+return this->emitZeroIntAP(128, E); // FIXME: Ctx.getBitWidth()
   case PT_IntAPS:
-assert(false);
-return false;
+return this->emitZeroIntAPS(128, E); // FIXME: Ctx.getBitWidth()
   case PT_Ptr:
 return this->emitNullPtr(E);
   case PT_FnPtr:
diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index a8df431bef11784..bca39884ac1de88 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -100,12 +100,13 @@ template  class IntegralAP final {
   }
   static IntegralAP from(const Boolean ) {
 assert(false);
-return IntegralAP::zero();
+return IntegralAP::zero(1);
   }
 
-  static IntegralAP zero() {
-assert(false);
-return IntegralAP(0);
+  static IntegralAP zero(int32_t BitWidth) {
+APSInt V =
+APSInt(APInt(BitWidth, static_cast(0), Signed), !Signed);
+return IntegralAP(V);
   }
 
   // FIXME: This can't be static if the bitwidth depends on V.
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 9d5ec3315415cf7..f768deca62b8b0a 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1622,6 +1622,16 @@ bool Zero(InterpState , CodePtr OpPC) {
   return true;
 }
 
+static inline bool ZeroIntAP(InterpState , CodePtr OpPC, uint32_t BitWidth) {
+  S.Stk.push>(IntegralAP::zero(BitWidth));
+  return true;
+}
+
+static inline bool ZeroIntAPS(InterpState , CodePtr OpPC, uint32_t BitWidth) 
{
+  S.Stk.push>(IntegralAP::zero(BitWidth));
+  return true;
+}
+
 template ::T>
 inline bool Null(InterpState , CodePtr OpPC) {
   S.Stk.push();
diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index 9fc4938bb37bde8..d78431c56645629 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -72,6 +72,11 @@ def IntegerTypeClass : TypeClass {
Uint32, Sint64, Uint64, IntAP, IntAPS];
 }
 
+def FixedSizeIntegralTypeClass : TypeClass {
+  let Types = [Sint8, Uint8, Sint16, Uint16, Sint32,
+   Uint32, Sint64, Uint64, Bool];
+}
+
 def NumberTypeClass : TypeClass {
   let Types = !listconcat(IntegerTypeClass.Types, [Float]);
 }
@@ -243,10 +248,18 @@ def ConstBool : ConstOpcode;
 
 // [] -> [Integer]
 def Zero : Opcode {
-  let Types = [AluTypeClass];
+  let Types = [FixedSizeIntegralTypeClass];
   let HasGroup = 1;
 }
 
+def ZeroIntAP : Opcode {
+  let Args = [ArgUint32];
+}
+
+def ZeroIntAPS : Opcode {
+  let Args = [ArgUint32];
+}
+
 // [] -> [Pointer]
 def Null : Opcode {
   let Types = [PtrTypeClass];

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


[clang] [clang][ExprConst] Don't try to evaluate value-dependent DeclRefExprs (PR #67778)

2023-10-03 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67778

>From 1b6fcc49f5ef9b99b4b2f7019de6d8d24a03f232 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 3 Oct 2023 08:35:57 +0200
Subject: [PATCH 1/2] [clang][Interp] Add basic support for _BitInt

Make sure we pass the expected bitwidth around when casting to
IntAP/IntAPS and move the tests to their own file.
---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp | 12 
 clang/lib/AST/Interp/Context.h   |  2 +
 clang/lib/AST/Interp/IntegralAP.h| 17 +++--
 clang/lib/AST/Interp/Interp.h| 58 +++-
 clang/lib/AST/Interp/InterpBuiltin.cpp   |  3 +-
 clang/lib/AST/Interp/Opcodes.td  | 30 +++-
 clang/test/AST/Interp/intap.cpp  | 88 
 clang/test/AST/Interp/literals.cpp   | 75 
 8 files changed, 199 insertions(+), 86 deletions(-)
 create mode 100644 clang/test/AST/Interp/intap.cpp

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index e266804a4e75dea..f899c2fe22ecd8f 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -138,6 +138,13 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
 if (!this->visit(SubExpr))
   return false;
 
+if (ToT == PT_IntAP)
+  return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->getType()),
+  CE);
+if (ToT == PT_IntAPS)
+  return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->getType()),
+   CE);
+
 return this->emitCastFloatingIntegral(*ToT, CE);
   }
 
@@ -183,6 +190,11 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
   return true;
 }
 
+if (ToT == PT_IntAP)
+  return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->getType()), CE);
+if (ToT == PT_IntAPS)
+  return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->getType()), CE);
+
 return this->emitCast(*FromT, *ToT, CE);
   }
 
diff --git a/clang/lib/AST/Interp/Context.h b/clang/lib/AST/Interp/Context.h
index 958b50b1615ad18..6df61e93ad83abc 100644
--- a/clang/lib/AST/Interp/Context.h
+++ b/clang/lib/AST/Interp/Context.h
@@ -64,6 +64,8 @@ class Context final {
   unsigned getCharBit() const;
   /// Return the floating-point semantics for T.
   const llvm::fltSemantics (QualType T) const;
+  /// Return the size of T in bits.
+  uint32_t getBitWidth(QualType T) const { return Ctx.getIntWidth(T); }
 
   /// Classifies an expression.
   std::optional classify(QualType T) const;
diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index a8df431bef11784..363fcd2eacb2f23 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -37,8 +37,12 @@ template  class IntegralAP final {
   APSInt V;
 
   template  static T truncateCast(const APSInt ) {
-return std::is_signed_v ? V.trunc(sizeof(T) * 8).getSExtValue()
-   : V.trunc(sizeof(T) * 8).getZExtValue();
+constexpr unsigned BitSize = sizeof(T) * 8;
+if (BitSize >= V.getBitWidth())
+  return std::is_signed_v ? V.getSExtValue() : V.getZExtValue();
+
+return std::is_signed_v ? V.trunc(BitSize).getSExtValue()
+   : V.trunc(BitSize).getZExtValue();
   }
 
 public:
@@ -89,10 +93,10 @@ template  class IntegralAP final {
   }
 
   template 
-  static IntegralAP from(Integral I) {
-// FIXME: Take bits parameter.
+  static IntegralAP from(Integral I, unsigned BitWidth) {
+llvm::errs() << __PRETTY_FUNCTION__ << ": " << BitWidth << "\n";
 APSInt Copy =
-APSInt(APInt(128, static_cast(I), InputSigned), !Signed);
+APSInt(APInt(BitWidth, static_cast(I), InputSigned), !Signed);
 Copy.setIsSigned(Signed);
 
 assert(Copy.isSigned() == Signed);
@@ -108,8 +112,7 @@ template  class IntegralAP final {
 return IntegralAP(0);
   }
 
-  // FIXME: This can't be static if the bitwidth depends on V.
-  static constexpr unsigned bitWidth() { return 128; }
+  constexpr unsigned bitWidth() const { return V.getBitWidth(); }
 
   APSInt toAPSInt(unsigned Bits = 0) const { return V; }
   APValue toAPValue() const { return APValue(V); }
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 9d5ec3315415cf7..d3ee28c0315cda8 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1561,6 +1561,22 @@ inline bool CastFP(InterpState , CodePtr OpPC, const 
llvm::fltSemantics *Sem,
   return true;
 }
 
+/// Like Cast(), but we cast to an arbitrary-bitwidth integral, so we need
+/// to know what bitwidth the result should be.
+template ::T>
+bool CastAP(InterpState , CodePtr OpPC, uint32_t BitWidth) {
+  S.Stk.push>(
+  IntegralAP::from(S.Stk.pop(), BitWidth));
+  return true;
+}

[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)

2023-10-03 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/66514
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][TSA] Make RequiresCapability a DeclOrType attribute (PR #67095)

2023-10-03 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/67095
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Add basic support for _BitInt (PR #68069)

2023-10-03 Thread Timm Baeder via cfe-commits


@@ -582,11 +598,21 @@ def CastIntegralFloating : Opcode {
 
 // Cast a floating to an integer type
 def CastFloatingIntegral : Opcode {
-  let Types = [AluTypeClass];
+  let Types = [FixedSizeIntegralTypes];

tbaederr wrote:

The type classes for these get kinda confusing... but I just can't come up with 
the correct syntax to define them inline.

https://github.com/llvm/llvm-project/pull/68069
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Add basic support for _BitInt (PR #68069)

2023-10-03 Thread Timm Baeder via cfe-commits


@@ -1601,6 +1617,46 @@ bool CastFloatingIntegral(InterpState , CodePtr OpPC) {
   }
 }
 
+static inline bool CastFloatingIntegralAP(InterpState , CodePtr OpPC,
+  uint32_t BitWidth) {
+  const Floating  = S.Stk.pop();
+
+  APSInt Result(BitWidth, /*IsUnsigned=*/true);
+  auto Status = F.convertToInteger(Result);
+
+  // Float-to-Integral overflow check.
+  if ((Status & APFloat::opStatus::opInvalidOp) && F.isFinite()) {
+const Expr *E = S.Current->getExpr(OpPC);
+QualType Type = E->getType();
+
+S.CCEDiag(E, diag::note_constexpr_overflow) << F.getAPFloat() << Type;
+return S.noteUndefinedBehavior();
+  }
+
+  S.Stk.push>(IntegralAP(Result));
+  return CheckFloatResult(S, OpPC, F, Status);
+}
+
+static inline bool CastFloatingIntegralAPS(InterpState , CodePtr OpPC,
+   uint32_t BitWidth) {
+  const Floating  = S.Stk.pop();
+
+  APSInt Result(BitWidth, /*IsUnsigned=*/false);
+  auto Status = F.convertToInteger(Result);
+
+  // Float-to-Integral overflow check.
+  if ((Status & APFloat::opStatus::opInvalidOp) && F.isFinite()) {
+const Expr *E = S.Current->getExpr(OpPC);
+QualType Type = E->getType();
+
+S.CCEDiag(E, diag::note_constexpr_overflow) << F.getAPFloat() << Type;
+return S.noteUndefinedBehavior();
+  }
+
+  S.Stk.push>(IntegralAP(Result));
+  return CheckFloatResult(S, OpPC, F, Status);
+}
+

tbaederr wrote:

`CastFloatingIntegralAP(S)` needs a helper function to get rid of the code 
duplication.

https://github.com/llvm/llvm-project/pull/68069
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Add basic support for _BitInt (PR #68069)

2023-10-03 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/68069

Make sure we pass the expected bitwidth around when casting to IntAP/IntAPS and 
move the tests to their own file.

This makes it easier to test the `IntegralAP` code for different bit widths 
than 128.

>From d7b0ac02cfd1bb2e679fb1ab086f38082d48963e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 3 Oct 2023 08:35:57 +0200
Subject: [PATCH] [clang][Interp] Add basic support for _BitInt

Make sure we pass the expected bitwidth around when casting to
IntAP/IntAPS and move the tests to their own file.
---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp | 12 
 clang/lib/AST/Interp/Context.h   |  2 +
 clang/lib/AST/Interp/IntegralAP.h| 16 +++--
 clang/lib/AST/Interp/Interp.h| 58 -
 clang/lib/AST/Interp/InterpBuiltin.cpp   |  3 +-
 clang/lib/AST/Interp/Opcodes.td  | 30 -
 clang/test/AST/Interp/intap.cpp  | 83 
 clang/test/AST/Interp/literals.cpp   | 75 -
 8 files changed, 193 insertions(+), 86 deletions(-)
 create mode 100644 clang/test/AST/Interp/intap.cpp

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index e266804a4e75dea..f899c2fe22ecd8f 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -138,6 +138,13 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
 if (!this->visit(SubExpr))
   return false;
 
+if (ToT == PT_IntAP)
+  return this->emitCastFloatingIntegralAP(Ctx.getBitWidth(CE->getType()),
+  CE);
+if (ToT == PT_IntAPS)
+  return this->emitCastFloatingIntegralAPS(Ctx.getBitWidth(CE->getType()),
+   CE);
+
 return this->emitCastFloatingIntegral(*ToT, CE);
   }
 
@@ -183,6 +190,11 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
   return true;
 }
 
+if (ToT == PT_IntAP)
+  return this->emitCastAP(*FromT, Ctx.getBitWidth(CE->getType()), CE);
+if (ToT == PT_IntAPS)
+  return this->emitCastAPS(*FromT, Ctx.getBitWidth(CE->getType()), CE);
+
 return this->emitCast(*FromT, *ToT, CE);
   }
 
diff --git a/clang/lib/AST/Interp/Context.h b/clang/lib/AST/Interp/Context.h
index 958b50b1615ad18..6df61e93ad83abc 100644
--- a/clang/lib/AST/Interp/Context.h
+++ b/clang/lib/AST/Interp/Context.h
@@ -64,6 +64,8 @@ class Context final {
   unsigned getCharBit() const;
   /// Return the floating-point semantics for T.
   const llvm::fltSemantics (QualType T) const;
+  /// Return the size of T in bits.
+  uint32_t getBitWidth(QualType T) const { return Ctx.getIntWidth(T); }
 
   /// Classifies an expression.
   std::optional classify(QualType T) const;
diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index a8df431bef11784..f9a33bbcd7bd7fa 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -37,8 +37,12 @@ template  class IntegralAP final {
   APSInt V;
 
   template  static T truncateCast(const APSInt ) {
-return std::is_signed_v ? V.trunc(sizeof(T) * 8).getSExtValue()
-   : V.trunc(sizeof(T) * 8).getZExtValue();
+constexpr unsigned BitSize = sizeof(T) * 8;
+if (BitSize >= V.getBitWidth())
+  return std::is_signed_v ? V.getSExtValue() : V.getZExtValue();
+
+return std::is_signed_v ? V.trunc(BitSize).getSExtValue()
+   : V.trunc(BitSize).getZExtValue();
   }
 
 public:
@@ -89,10 +93,9 @@ template  class IntegralAP final {
   }
 
   template 
-  static IntegralAP from(Integral I) {
-// FIXME: Take bits parameter.
+  static IntegralAP from(Integral I, unsigned BitWidth) {
 APSInt Copy =
-APSInt(APInt(128, static_cast(I), InputSigned), !Signed);
+APSInt(APInt(BitWidth, static_cast(I), InputSigned), !Signed);
 Copy.setIsSigned(Signed);
 
 assert(Copy.isSigned() == Signed);
@@ -108,8 +111,7 @@ template  class IntegralAP final {
 return IntegralAP(0);
   }
 
-  // FIXME: This can't be static if the bitwidth depends on V.
-  static constexpr unsigned bitWidth() { return 128; }
+  constexpr unsigned bitWidth() const { return V.getBitWidth(); }
 
   APSInt toAPSInt(unsigned Bits = 0) const { return V; }
   APValue toAPValue() const { return APValue(V); }
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 9d5ec3315415cf7..d3ee28c0315cda8 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1561,6 +1561,22 @@ inline bool CastFP(InterpState , CodePtr OpPC, const 
llvm::fltSemantics *Sem,
   return true;
 }
 
+/// Like Cast(), but we cast to an arbitrary-bitwidth integral, so we need
+/// to know what bitwidth the result should be.
+template ::T>
+bool CastAP(InterpState , CodePtr OpPC, uint32_t BitWidth) {
+  

[clang] [clang][Interp] Diagnose uninitialized bases (PR #67131)

2023-10-02 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/67131
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Diagnose uninitialized bases (PR #67131)

2023-10-02 Thread Timm Baeder via cfe-commits

tbaederr wrote:

> Maybe we should change the existing evaluator to be consistent? Otherwise LGTM

I'm not 100% sure what output is better, but we can change that later. This 
change is more about correctness.

https://github.com/llvm/llvm-project/pull/67131
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Ignore GCC 11 `[[malloc(x)]]` attribute (PR #68059)

2023-10-02 Thread Timm Baeder via cfe-commits


@@ -4122,6 +4122,9 @@ def RestrictDocs : Documentation {
 The ``malloc`` attribute indicates that the function acts like a system memory
 allocation function, returning a pointer to allocated storage disjoint from the
 storage for any other object accessible to the caller.
+
+The form of ``malloc`` with one or two arguments (supported by GCC 11) is
+currently ignored by Clang.

tbaederr wrote:

Is it really ignored or is it just treated as if it had no arguments?

https://github.com/llvm/llvm-project/pull/68059
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/67961
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67961

>From 377e0b069ff0d68ff4a4cdd690b62e555bdf8d8a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 2 Oct 2023 10:46:22 +0200
Subject: [PATCH] [clang][Interp] Fix value truncation when casting int128 to
 smaller size

---
 clang/lib/AST/Interp/IntegralAP.h  | 22 ++
 clang/test/AST/Interp/literals.cpp | 10 +-
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index 42f44354cbd2599..0876d7fae958a54 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -32,6 +32,12 @@ template  class Integral;
 class Boolean;
 
 template  class IntegralAP final {
+private:
+  template  static T truncateCast(const APSInt ) {
+return std::is_signed_v ? V.trunc(sizeof(T) * 8).getSExtValue()
+   : V.trunc(sizeof(T) * 8).getZExtValue();
+  }
+
 public:
   APSInt V;
 
@@ -55,14 +61,14 @@ template  class IntegralAP final {
   bool operator<=(IntegralAP RHS) const { return V <= RHS.V; }
 
   explicit operator bool() const { return !V.isZero(); }
-  explicit operator int8_t() const { return V.getSExtValue(); }
-  explicit operator uint8_t() const { return V.getZExtValue(); }
-  explicit operator int16_t() const { return V.getSExtValue(); }
-  explicit operator uint16_t() const { return V.getZExtValue(); }
-  explicit operator int32_t() const { return V.getSExtValue(); }
-  explicit operator uint32_t() const { return V.getZExtValue(); }
-  explicit operator int64_t() const { return V.getSExtValue(); }
-  explicit operator uint64_t() const { return V.getZExtValue(); }
+  explicit operator int8_t() const { return truncateCast(V); }
+  explicit operator uint8_t() const { return truncateCast(V); }
+  explicit operator int16_t() const { return truncateCast(V); }
+  explicit operator uint16_t() const { return truncateCast(V); }
+  explicit operator int32_t() const { return truncateCast(V); }
+  explicit operator uint32_t() const { return truncateCast(V); }
+  explicit operator int64_t() const { return truncateCast(V); }
+  explicit operator uint64_t() const { return truncateCast(V); }
 
   template  static IntegralAP from(T Value, unsigned NumBits = 0) {
 assert(NumBits > 0);
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index 00182ba4ab1d918..00875bcf44dc8e6 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -53,7 +53,7 @@ namespace i128 {
   static_assert(Two == 2, "");
 
   constexpr uint128_t AllOnes = ~static_cast(0);
-  static_assert(AllOnes == static_cast(-1), "");
+  static_assert(AllOnes == UINT128_MAX, "");
 
 #if __cplusplus >= 201402L
   template 
@@ -70,6 +70,14 @@ namespace i128 {
   static_assert(CastFrom(12) == 12, "");
   static_assert(CastFrom(12) == 12, "");
 
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0xFF, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0x, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == AllOnes, "");
+
   template 
   constexpr __int128 CastTo(T A) {
 int128_t B = (int128_t)A;

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


[clang] [clang][Interp] Implement IntegralAP::comp (PR #67954)

2023-10-02 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/67954
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Implement __builtin_popcount() (PR #67929)

2023-10-02 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/67929
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67961

>From d7ee51b3736ee65279f07bb0f4d5ccc31911cfda Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 1 Oct 2023 19:57:03 +0200
Subject: [PATCH 1/2] [clang][Interp] Implement IntegralAP::comp

---
 clang/lib/AST/Interp/IntegralAP.h  | 1 -
 clang/test/AST/Interp/literals.cpp | 3 +++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index a9e34a5b237a195..42f44354cbd2599 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -210,7 +210,6 @@ template  class IntegralAP final {
   }
 
   static bool comp(IntegralAP A, IntegralAP *R) {
-assert(false);
 *R = IntegralAP(~A.V);
 return false;
   }
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index eca0e4c2cbd26f1..00182ba4ab1d918 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -52,6 +52,9 @@ namespace i128 {
   constexpr int128_t Two = (int128_t)1 << 1ul;
   static_assert(Two == 2, "");
 
+  constexpr uint128_t AllOnes = ~static_cast(0);
+  static_assert(AllOnes == static_cast(-1), "");
+
 #if __cplusplus >= 201402L
   template 
   constexpr T CastFrom(__int128_t A) {

>From 7f551e9f971f3a9a74efda169e5765657ba3c8fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 2 Oct 2023 10:46:22 +0200
Subject: [PATCH 2/2] [clang][Interp] Fix value truncation when casting int128
 to smaller size

---
 clang/lib/AST/Interp/IntegralAP.h  | 22 ++
 clang/test/AST/Interp/literals.cpp | 10 +-
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index 42f44354cbd2599..0876d7fae958a54 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -32,6 +32,12 @@ template  class Integral;
 class Boolean;
 
 template  class IntegralAP final {
+private:
+  template  static T truncateCast(const APSInt ) {
+return std::is_signed_v ? V.trunc(sizeof(T) * 8).getSExtValue()
+   : V.trunc(sizeof(T) * 8).getZExtValue();
+  }
+
 public:
   APSInt V;
 
@@ -55,14 +61,14 @@ template  class IntegralAP final {
   bool operator<=(IntegralAP RHS) const { return V <= RHS.V; }
 
   explicit operator bool() const { return !V.isZero(); }
-  explicit operator int8_t() const { return V.getSExtValue(); }
-  explicit operator uint8_t() const { return V.getZExtValue(); }
-  explicit operator int16_t() const { return V.getSExtValue(); }
-  explicit operator uint16_t() const { return V.getZExtValue(); }
-  explicit operator int32_t() const { return V.getSExtValue(); }
-  explicit operator uint32_t() const { return V.getZExtValue(); }
-  explicit operator int64_t() const { return V.getSExtValue(); }
-  explicit operator uint64_t() const { return V.getZExtValue(); }
+  explicit operator int8_t() const { return truncateCast(V); }
+  explicit operator uint8_t() const { return truncateCast(V); }
+  explicit operator int16_t() const { return truncateCast(V); }
+  explicit operator uint16_t() const { return truncateCast(V); }
+  explicit operator int32_t() const { return truncateCast(V); }
+  explicit operator uint32_t() const { return truncateCast(V); }
+  explicit operator int64_t() const { return truncateCast(V); }
+  explicit operator uint64_t() const { return truncateCast(V); }
 
   template  static IntegralAP from(T Value, unsigned NumBits = 0) {
 assert(NumBits > 0);
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index 00182ba4ab1d918..00875bcf44dc8e6 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -53,7 +53,7 @@ namespace i128 {
   static_assert(Two == 2, "");
 
   constexpr uint128_t AllOnes = ~static_cast(0);
-  static_assert(AllOnes == static_cast(-1), "");
+  static_assert(AllOnes == UINT128_MAX, "");
 
 #if __cplusplus >= 201402L
   template 
@@ -70,6 +70,14 @@ namespace i128 {
   static_assert(CastFrom(12) == 12, "");
   static_assert(CastFrom(12) == 12, "");
 
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0xFF, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0x, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == AllOnes, "");
+
   template 
   constexpr __int128 CastTo(T A) {
 int128_t B = (int128_t)A;

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


[clang] [clang][Interp] Implement __builtin_popcount() (PR #67929)

2023-10-02 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67929

>From a3633c87cd53ee1d092a68e21d9dd41945a848d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 1 Oct 2023 19:41:15 +0200
Subject: [PATCH] [clang][Interp] Implement __builtin_popcount()

---
 clang/lib/AST/Interp/InterpBuiltin.cpp  | 20 +++
 clang/test/AST/Interp/builtin-functions.cpp | 22 +
 2 files changed, 42 insertions(+)

diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index d816145598049b0..bba0255219bc0d7 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -398,6 +398,16 @@ static bool interp__builtin_fabs(InterpState , CodePtr 
OpPC,
   return true;
 }
 
+static bool interp__builtin_popcount(InterpState , CodePtr OpPC,
+ const InterpFrame *Frame,
+ const Function *Func,
+ const CallExpr *Call) {
+  PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
+  APSInt Val = peekToAPSInt(S.Stk, ArgT);
+  pushInt(S, Val.popcount());
+  return true;
+}
+
 bool InterpretBuiltin(InterpState , CodePtr OpPC, const Function *F,
   const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
@@ -513,6 +523,16 @@ bool InterpretBuiltin(InterpState , CodePtr OpPC, const 
Function *F,
   return Ret(S, OpPC, Dummy);
 break;
 
+  case Builtin::BI__builtin_popcount:
+  case Builtin::BI__builtin_popcountl:
+  case Builtin::BI__builtin_popcountll:
+  case Builtin::BI__popcnt16: // Microsoft variants of popcount
+  case Builtin::BI__popcnt:
+  case Builtin::BI__popcnt64:
+if (interp__builtin_popcount(S, OpPC, Frame, F, Call))
+  return retInt(S, OpPC, Dummy);
+break;
+
   default:
 return false;
   }
diff --git a/clang/test/AST/Interp/builtin-functions.cpp 
b/clang/test/AST/Interp/builtin-functions.cpp
index cd4ad010af12220..65361d67d68d578 100644
--- a/clang/test/AST/Interp/builtin-functions.cpp
+++ b/clang/test/AST/Interp/builtin-functions.cpp
@@ -260,3 +260,25 @@ namespace SourceLocation {
 static_assert(c.a.n == __LINE__ - 1, "");
   }
 }
+
+namespace popcount {
+  static_assert(__builtin_popcount(~0u) == __CHAR_BIT__ * sizeof(unsigned 
int), "");
+  static_assert(__builtin_popcount(0) == 0, "");
+  static_assert(__builtin_popcountl(~0ul) == __CHAR_BIT__ * sizeof(unsigned 
long), "");
+  static_assert(__builtin_popcountl(0) == 0, "");
+  static_assert(__builtin_popcountll(~0ull) == __CHAR_BIT__ * sizeof(unsigned 
long long), "");
+  static_assert(__builtin_popcountll(0) == 0, "");
+
+  /// From test/Sema/constant-builtins-2.c
+#define BITSIZE(x) (sizeof(x) * 8)
+  char popcount1[__builtin_popcount(0) == 0 ? 1 : -1];
+  char popcount2[__builtin_popcount(0xF0F0) == 8 ? 1 : -1];
+  char popcount3[__builtin_popcount(~0) == BITSIZE(int) ? 1 : -1];
+  char popcount4[__builtin_popcount(~0L) == BITSIZE(int) ? 1 : -1];
+  char popcount5[__builtin_popcountl(0L) == 0 ? 1 : -1];
+  char popcount6[__builtin_popcountl(0xF0F0L) == 8 ? 1 : -1];
+  char popcount7[__builtin_popcountl(~0L) == BITSIZE(long) ? 1 : -1];
+  char popcount8[__builtin_popcountll(0LL) == 0 ? 1 : -1];
+  char popcount9[__builtin_popcountll(0xF0F0LL) == 8 ? 1 : -1];
+  char popcount10[__builtin_popcountll(~0LL) == BITSIZE(long long) ? 1 : -1];
+}

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


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67961

>From 80bd890c332654458014c4acc20709b9cbb6eb90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 1 Oct 2023 19:57:03 +0200
Subject: [PATCH 1/2] [clang][Interp] Implement IntegralAP::comp

---
 clang/lib/AST/Interp/IntegralAP.h  | 1 -
 clang/test/AST/Interp/literals.cpp | 3 +++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index b2b367f30c238fe..b29aac2a73e3243 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -210,7 +210,6 @@ template  class IntegralAP final {
   }
 
   static bool comp(IntegralAP A, IntegralAP *R) {
-assert(false);
 *R = IntegralAP(~A.V);
 return false;
   }
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index eca0e4c2cbd26f1..00182ba4ab1d918 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -52,6 +52,9 @@ namespace i128 {
   constexpr int128_t Two = (int128_t)1 << 1ul;
   static_assert(Two == 2, "");
 
+  constexpr uint128_t AllOnes = ~static_cast(0);
+  static_assert(AllOnes == static_cast(-1), "");
+
 #if __cplusplus >= 201402L
   template 
   constexpr T CastFrom(__int128_t A) {

>From 3c8924be41121056b60b0aa4d2a3de43dd2db9e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 2 Oct 2023 10:46:22 +0200
Subject: [PATCH 2/2] [clang][Interp] Fix value truncation when casting int128
 to smaller size

---
 clang/lib/AST/Interp/IntegralAP.h  | 23 +++
 clang/test/AST/Interp/literals.cpp | 10 +-
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index b29aac2a73e3243..ca45c7e243e20ba 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -32,6 +32,13 @@ template  class Integral;
 class Boolean;
 
 template  class IntegralAP final {
+private:
+
+  template  static T truncateCast(const APSInt ) {
+return std::is_signed_v ? V.trunc(sizeof(T) * 8).getSExtValue()
+   : V.trunc(sizeof(T) * 8).getZExtValue();
+  }
+
 public:
   APSInt V;
 
@@ -55,14 +62,14 @@ template  class IntegralAP final {
   bool operator<=(IntegralAP RHS) const { return V <= RHS.V; }
 
   explicit operator bool() const { return !V.isZero(); }
-  explicit operator int8_t() const { return V.getSExtValue(); }
-  explicit operator uint8_t() const { return V.getZExtValue(); }
-  explicit operator int16_t() const { return V.getSExtValue(); }
-  explicit operator uint16_t() const { return V.getZExtValue(); }
-  explicit operator int32_t() const { return V.getSExtValue(); }
-  explicit operator uint32_t() const { return V.getZExtValue(); }
-  explicit operator int64_t() const { return V.getSExtValue(); }
-  explicit operator uint64_t() const { return V.getZExtValue(); }
+  explicit operator int8_t() const { return truncateCast(V); }
+  explicit operator uint8_t() const { return truncateCast(V); }
+  explicit operator int16_t() const { return truncateCast(V); }
+  explicit operator uint16_t() const { return truncateCast(V); }
+  explicit operator int32_t() const { return truncateCast(V); }
+  explicit operator uint32_t() const { return truncateCast(V); }
+  explicit operator int64_t() const { return truncateCast(V); }
+  explicit operator uint64_t() const { return truncateCast(V); }
 
   template  static IntegralAP from(T Value, unsigned NumBits = 0) {
 assert(NumBits > 0);
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index 00182ba4ab1d918..00875bcf44dc8e6 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -53,7 +53,7 @@ namespace i128 {
   static_assert(Two == 2, "");
 
   constexpr uint128_t AllOnes = ~static_cast(0);
-  static_assert(AllOnes == static_cast(-1), "");
+  static_assert(AllOnes == UINT128_MAX, "");
 
 #if __cplusplus >= 201402L
   template 
@@ -70,6 +70,14 @@ namespace i128 {
   static_assert(CastFrom(12) == 12, "");
   static_assert(CastFrom(12) == 12, "");
 
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0xFF, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0x, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == AllOnes, "");
+
   template 
   constexpr __int128 CastTo(T A) {
 int128_t B = (int128_t)A;

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


[clang] [clang][Interp] Only emit function_param_value_unknown in C++11 (PR #67990)

2023-10-02 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/67990

This is also what the current interpreter does.

No test for now since the only reproducer I have is from 
https://reviews.llvm.org/D156565 and doesn't work without that patch.

>From 5e43ab378e64ea8a852f8bf5571dab537f293c77 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 2 Oct 2023 16:26:46 +0200
Subject: [PATCH] [clang][Interp] Only emit function_param_value_unknown in
 C++11

---
 clang/lib/AST/Interp/Interp.cpp | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index e1951574edb6288..9772f612b409ea3 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -549,8 +549,12 @@ bool CheckDeclRef(InterpState , CodePtr OpPC, const 
DeclRefExpr *DR) {
   const SourceInfo  = S.Current->getSource(OpPC);
 
   if (isa(D)) {
-S.FFDiag(E, diag::note_constexpr_function_param_value_unknown) << D;
-S.Note(D->getLocation(), diag::note_declared_at) << D->getSourceRange();
+if (S.getLangOpts().CPlusPlus11) {
+  S.FFDiag(E, diag::note_constexpr_function_param_value_unknown) << D;
+  S.Note(D->getLocation(), diag::note_declared_at) << D->getSourceRange();
+} else {
+  S.FFDiag(E);
+}
   } else if (const auto *VD = dyn_cast(D)) {
 if (!VD->getType().isConstQualified()) {
   S.FFDiag(E,

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


[clang] [clang][Interp] Add IntegralAP for arbitrary-precision integers (PR #65844)

2023-10-02 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Sigh, will push a fix as soon as my local build is done.

https://github.com/llvm/llvm-project/pull/65844
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Diagnose uninitialized bases (PR #67131)

2023-10-02 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/67131
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Implement compound assign operators on bitfields (PR #67306)

2023-10-02 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/67306
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67961

>From 80bd890c332654458014c4acc20709b9cbb6eb90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 1 Oct 2023 19:57:03 +0200
Subject: [PATCH 1/2] [clang][Interp] Implement IntegralAP::comp

---
 clang/lib/AST/Interp/IntegralAP.h  | 1 -
 clang/test/AST/Interp/literals.cpp | 3 +++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index b2b367f30c238fe..b29aac2a73e3243 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -210,7 +210,6 @@ template  class IntegralAP final {
   }
 
   static bool comp(IntegralAP A, IntegralAP *R) {
-assert(false);
 *R = IntegralAP(~A.V);
 return false;
   }
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index eca0e4c2cbd26f1..00182ba4ab1d918 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -52,6 +52,9 @@ namespace i128 {
   constexpr int128_t Two = (int128_t)1 << 1ul;
   static_assert(Two == 2, "");
 
+  constexpr uint128_t AllOnes = ~static_cast(0);
+  static_assert(AllOnes == static_cast(-1), "");
+
 #if __cplusplus >= 201402L
   template 
   constexpr T CastFrom(__int128_t A) {

>From c39f0d9b69d00c08be93e5843efeb185fc292741 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 2 Oct 2023 10:46:22 +0200
Subject: [PATCH 2/2] [clang][Interp] Fix value truncation when casting int128
 to smaller size

---
 clang/lib/AST/Interp/IntegralAP.h  | 21 +
 clang/test/AST/Interp/literals.cpp | 10 +-
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index b29aac2a73e3243..f67b15dbc9b31ac 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -55,14 +55,14 @@ template  class IntegralAP final {
   bool operator<=(IntegralAP RHS) const { return V <= RHS.V; }
 
   explicit operator bool() const { return !V.isZero(); }
-  explicit operator int8_t() const { return V.getSExtValue(); }
-  explicit operator uint8_t() const { return V.getZExtValue(); }
-  explicit operator int16_t() const { return V.getSExtValue(); }
-  explicit operator uint16_t() const { return V.getZExtValue(); }
-  explicit operator int32_t() const { return V.getSExtValue(); }
-  explicit operator uint32_t() const { return V.getZExtValue(); }
-  explicit operator int64_t() const { return V.getSExtValue(); }
-  explicit operator uint64_t() const { return V.getZExtValue(); }
+  explicit operator int8_t() const { return truncateCast(V); }
+  explicit operator uint8_t() const { return truncateCast(V); }
+  explicit operator int16_t() const { return truncateCast(V); }
+  explicit operator uint16_t() const { return truncateCast(V); }
+  explicit operator int32_t() const { return truncateCast(V); }
+  explicit operator uint32_t() const { return truncateCast(V); }
+  explicit operator int64_t() const { return truncateCast(V); }
+  explicit operator uint64_t() const { return truncateCast(V); }
 
   template  static IntegralAP from(T Value, unsigned NumBits = 0) {
 assert(NumBits > 0);
@@ -248,6 +248,11 @@ template  class IntegralAP final {
 R->V = A.V - B.V;
 return false; // Success!
   }
+
+  template  static T truncateCast(const APSInt ) {
+return std::is_signed_v ? V.trunc(sizeof(T) * 8).getSExtValue()
+   : V.trunc(sizeof(T) * 8).getZExtValue();
+  }
 };
 
 template 
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index 00182ba4ab1d918..00875bcf44dc8e6 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -53,7 +53,7 @@ namespace i128 {
   static_assert(Two == 2, "");
 
   constexpr uint128_t AllOnes = ~static_cast(0);
-  static_assert(AllOnes == static_cast(-1), "");
+  static_assert(AllOnes == UINT128_MAX, "");
 
 #if __cplusplus >= 201402L
   template 
@@ -70,6 +70,14 @@ namespace i128 {
   static_assert(CastFrom(12) == 12, "");
   static_assert(CastFrom(12) == 12, "");
 
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0xFF, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0x, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == AllOnes, "");
+
   template 
   constexpr __int128 CastTo(T A) {
 int128_t B = (int128_t)A;

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


[clang] [clang][Interp] Fix value truncation when casting int128 to smaller size (PR #67961)

2023-10-02 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID: 
In-Reply-To:


https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/67961

Before this patch, we would run into an assertion in 
`APInt::get{S,Z}ExtValue()` because the `AllOnes` value had more than 64 active 
bits.

>From 80bd890c332654458014c4acc20709b9cbb6eb90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 1 Oct 2023 19:57:03 +0200
Subject: [PATCH 1/2] [clang][Interp] Implement IntegralAP::comp

---
 clang/lib/AST/Interp/IntegralAP.h  | 1 -
 clang/test/AST/Interp/literals.cpp | 3 +++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index b2b367f30c238fe..b29aac2a73e3243 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -210,7 +210,6 @@ template  class IntegralAP final {
   }
 
   static bool comp(IntegralAP A, IntegralAP *R) {
-assert(false);
 *R = IntegralAP(~A.V);
 return false;
   }
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index eca0e4c2cbd26f1..00182ba4ab1d918 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -52,6 +52,9 @@ namespace i128 {
   constexpr int128_t Two = (int128_t)1 << 1ul;
   static_assert(Two == 2, "");
 
+  constexpr uint128_t AllOnes = ~static_cast(0);
+  static_assert(AllOnes == static_cast(-1), "");
+
 #if __cplusplus >= 201402L
   template 
   constexpr T CastFrom(__int128_t A) {

>From 31ed85d44562ed1e5fe4714a5b659e5da8720f02 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Mon, 2 Oct 2023 10:46:22 +0200
Subject: [PATCH 2/2] [clang][Interp] Fix value truncation when casting int128
 to smaller size

---
 clang/lib/AST/Interp/IntegralAP.h  | 21 +
 clang/test/AST/Interp/literals.cpp |  8 +++-
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index b29aac2a73e3243..f67b15dbc9b31ac 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -55,14 +55,14 @@ template  class IntegralAP final {
   bool operator<=(IntegralAP RHS) const { return V <= RHS.V; }
 
   explicit operator bool() const { return !V.isZero(); }
-  explicit operator int8_t() const { return V.getSExtValue(); }
-  explicit operator uint8_t() const { return V.getZExtValue(); }
-  explicit operator int16_t() const { return V.getSExtValue(); }
-  explicit operator uint16_t() const { return V.getZExtValue(); }
-  explicit operator int32_t() const { return V.getSExtValue(); }
-  explicit operator uint32_t() const { return V.getZExtValue(); }
-  explicit operator int64_t() const { return V.getSExtValue(); }
-  explicit operator uint64_t() const { return V.getZExtValue(); }
+  explicit operator int8_t() const { return truncateCast(V); }
+  explicit operator uint8_t() const { return truncateCast(V); }
+  explicit operator int16_t() const { return truncateCast(V); }
+  explicit operator uint16_t() const { return truncateCast(V); }
+  explicit operator int32_t() const { return truncateCast(V); }
+  explicit operator uint32_t() const { return truncateCast(V); }
+  explicit operator int64_t() const { return truncateCast(V); }
+  explicit operator uint64_t() const { return truncateCast(V); }
 
   template  static IntegralAP from(T Value, unsigned NumBits = 0) {
 assert(NumBits > 0);
@@ -248,6 +248,11 @@ template  class IntegralAP final {
 R->V = A.V - B.V;
 return false; // Success!
   }
+
+  template  static T truncateCast(const APSInt ) {
+return std::is_signed_v ? V.trunc(sizeof(T) * 8).getSExtValue()
+   : V.trunc(sizeof(T) * 8).getZExtValue();
+  }
 };
 
 template 
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index 00182ba4ab1d918..65d211422ddac92 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -53,7 +53,7 @@ namespace i128 {
   static_assert(Two == 2, "");
 
   constexpr uint128_t AllOnes = ~static_cast(0);
-  static_assert(AllOnes == static_cast(-1), "");
+  static_assert(AllOnes == UINT128_MAX, "");
 
 #if __cplusplus >= 201402L
   template 
@@ -70,6 +70,12 @@ namespace i128 {
   static_assert(CastFrom(12) == 12, "");
   static_assert(CastFrom(12) == 12, "");
 
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0xFF, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+  static_assert(CastFrom(AllOnes) == 0x, "");
+  static_assert(CastFrom(AllOnes) == -1, "");
+
   template 
   constexpr __int128 CastTo(T A) {
 int128_t B = (int128_t)A;

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


[clang] [clang][Interp] Implement IntegralAP::comp (PR #67954)

2023-10-02 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67954

>From 80bd890c332654458014c4acc20709b9cbb6eb90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 1 Oct 2023 19:57:03 +0200
Subject: [PATCH] [clang][Interp] Implement IntegralAP::comp

---
 clang/lib/AST/Interp/IntegralAP.h  | 1 -
 clang/test/AST/Interp/literals.cpp | 3 +++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index b2b367f30c238fe..b29aac2a73e3243 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -210,7 +210,6 @@ template  class IntegralAP final {
   }
 
   static bool comp(IntegralAP A, IntegralAP *R) {
-assert(false);
 *R = IntegralAP(~A.V);
 return false;
   }
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index eca0e4c2cbd26f1..00182ba4ab1d918 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -52,6 +52,9 @@ namespace i128 {
   constexpr int128_t Two = (int128_t)1 << 1ul;
   static_assert(Two == 2, "");
 
+  constexpr uint128_t AllOnes = ~static_cast(0);
+  static_assert(AllOnes == static_cast(-1), "");
+
 #if __cplusplus >= 201402L
   template 
   constexpr T CastFrom(__int128_t A) {

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


[clang] [clang][Interp] Implement IntegralAP::comp (PR #67954)

2023-10-02 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/67954

None

>From fe7f8cddb7f4590f481fce3b99c7b56f8163d889 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 1 Oct 2023 19:57:03 +0200
Subject: [PATCH] [clang][Interp] Implement IntegralAP::comp

---
 clang/lib/AST/Interp/IntegralAP.h  | 1 -
 clang/test/AST/Interp/literals.cpp | 3 +++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/IntegralAP.h 
b/clang/lib/AST/Interp/IntegralAP.h
index b2b367f30c238fe..b29aac2a73e3243 100644
--- a/clang/lib/AST/Interp/IntegralAP.h
+++ b/clang/lib/AST/Interp/IntegralAP.h
@@ -210,7 +210,6 @@ template  class IntegralAP final {
   }
 
   static bool comp(IntegralAP A, IntegralAP *R) {
-assert(false);
 *R = IntegralAP(~A.V);
 return false;
   }
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index b57a0e64c5fac32..864c91dd0003b9e 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -87,6 +87,9 @@ constexpr int128_t Error = __LDBL_MAX__; // ref-warning 
{{implicit conversion of
  // expected-warning {{implicit 
conversion of out of range value}} \
  // expected-error {{must be 
initialized by a constant expression}} \
  // expected-note {{is outside the 
range of representable values of type}}
+
+  constexpr uint128_t UINT128_MAX = ~static_cast(0);
+  static_assert(UINT128_MAX == static_cast(-1), "");
 }
 #endif
 

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


[clang] [clang][Interp] Add IntegralAP for arbitrary-precision integers (PR #65844)

2023-10-02 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= ,
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

I pushed a fix that hopefully works, let me know if it doesn't.

https://github.com/llvm/llvm-project/pull/65844
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Implement __builtin_popcount() (PR #67929)

2023-10-01 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/67929

None

>From ce44117306858aa1bff3766dc640201ffd99a89f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sun, 1 Oct 2023 19:41:15 +0200
Subject: [PATCH] [clang][Interp] Implement __builtin_popcount()

---
 clang/lib/AST/Interp/InterpBuiltin.cpp  | 20 
 clang/test/AST/Interp/builtin-functions.cpp |  9 +
 2 files changed, 29 insertions(+)

diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index d816145598049b0..bba0255219bc0d7 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -398,6 +398,16 @@ static bool interp__builtin_fabs(InterpState , CodePtr 
OpPC,
   return true;
 }
 
+static bool interp__builtin_popcount(InterpState , CodePtr OpPC,
+ const InterpFrame *Frame,
+ const Function *Func,
+ const CallExpr *Call) {
+  PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
+  APSInt Val = peekToAPSInt(S.Stk, ArgT);
+  pushInt(S, Val.popcount());
+  return true;
+}
+
 bool InterpretBuiltin(InterpState , CodePtr OpPC, const Function *F,
   const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
@@ -513,6 +523,16 @@ bool InterpretBuiltin(InterpState , CodePtr OpPC, const 
Function *F,
   return Ret(S, OpPC, Dummy);
 break;
 
+  case Builtin::BI__builtin_popcount:
+  case Builtin::BI__builtin_popcountl:
+  case Builtin::BI__builtin_popcountll:
+  case Builtin::BI__popcnt16: // Microsoft variants of popcount
+  case Builtin::BI__popcnt:
+  case Builtin::BI__popcnt64:
+if (interp__builtin_popcount(S, OpPC, Frame, F, Call))
+  return retInt(S, OpPC, Dummy);
+break;
+
   default:
 return false;
   }
diff --git a/clang/test/AST/Interp/builtin-functions.cpp 
b/clang/test/AST/Interp/builtin-functions.cpp
index cd4ad010af12220..755f2b755412ef6 100644
--- a/clang/test/AST/Interp/builtin-functions.cpp
+++ b/clang/test/AST/Interp/builtin-functions.cpp
@@ -260,3 +260,12 @@ namespace SourceLocation {
 static_assert(c.a.n == __LINE__ - 1, "");
   }
 }
+
+namespace popcount {
+  static_assert(__builtin_popcount(~0u) == __CHAR_BIT__ * sizeof(unsigned 
int), "");
+  static_assert(__builtin_popcount(0) == 0, "");
+  static_assert(__builtin_popcountl(~0ul) == __CHAR_BIT__ * sizeof(unsigned 
long), "");
+  static_assert(__builtin_popcountl(0) == 0, "");
+  static_assert(__builtin_popcountll(~0ull) == __CHAR_BIT__ * sizeof(unsigned 
long long), "");
+  static_assert(__builtin_popcountll(0) == 0, "");
+}

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


[clang] [clang][Interp] Add IntegralAP for arbitrary-precision integers (PR #65844)

2023-10-01 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 



@@ -26,6 +28,66 @@ static_assert(number != 10, ""); // expected-error{{failed}} 
\
  // expected-note{{evaluates to}} \
  // ref-note{{evaluates to}}
 
+
+namespace i128 {

tbaederr wrote:

Oof, sorry. Everything was fine this morning and then I left the house... Will 
fix immediately.

https://github.com/llvm/llvm-project/pull/65844
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Add IntegralAP for arbitrary-precision integers (PR #65844)

2023-09-30 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/65844
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle variadic functions (PR #67814)

2023-09-30 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67814

>From 64aae1cdf960f3edb34f1cf82ae3e66eb692247a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 29 Sep 2023 16:43:59 +0200
Subject: [PATCH] [clang][Interp] Handle variadic functions

Similarly to the code we already had for builtin functions, we need to
check the call expression for the arguments passed.
---
 clang/lib/AST/Interp/Function.cpp   |  2 +-
 clang/lib/AST/Interp/Function.h |  3 ++
 clang/lib/AST/Interp/Interp.cpp | 49 +++--
 clang/lib/AST/Interp/Interp.h   | 18 +++
 clang/test/AST/Interp/functions.cpp | 21 +
 5 files changed, 69 insertions(+), 24 deletions(-)

diff --git a/clang/lib/AST/Interp/Function.cpp 
b/clang/lib/AST/Interp/Function.cpp
index 0b7cfc4e28883f0..357aff7fe6229b9 100644
--- a/clang/lib/AST/Interp/Function.cpp
+++ b/clang/lib/AST/Interp/Function.cpp
@@ -24,7 +24,7 @@ Function::Function(Program , const FunctionDecl *F, 
unsigned ArgSize,
 : P(P), Loc(F->getBeginLoc()), F(F), ArgSize(ArgSize),
   ParamTypes(std::move(ParamTypes)), Params(std::move(Params)),
   ParamOffsets(std::move(ParamOffsets)), HasThisPointer(HasThisPointer),
-  HasRVO(HasRVO) {}
+  HasRVO(HasRVO), Variadic(F->isVariadic()) {}
 
 Function::ParamDescriptor Function::getParamDescriptor(unsigned Offset) const {
   auto It = Params.find(Offset);
diff --git a/clang/lib/AST/Interp/Function.h b/clang/lib/AST/Interp/Function.h
index 0bae314e97701d9..15bdd39dfde9d99 100644
--- a/clang/lib/AST/Interp/Function.h
+++ b/clang/lib/AST/Interp/Function.h
@@ -172,6 +172,8 @@ class Function final {
   /// Checks if the function is defined.
   bool isDefined() const { return Defined; }
 
+  bool isVariadic() const { return Variadic; }
+
   unsigned getBuiltinID() const { return F->getBuiltinID(); }
 
   bool isBuiltin() const { return F->getBuiltinID() != 0; }
@@ -250,6 +252,7 @@ class Function final {
   /// If we've already compiled the function's body.
   bool HasBody = false;
   bool Defined = false;
+  bool Variadic = false;
 
 public:
   /// Dumps the disassembled bytecode to \c llvm::errs().
diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index e1951574edb6288..639ceb140e99de3 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -121,18 +121,47 @@ static bool CheckGlobal(InterpState , CodePtr OpPC, 
const Pointer ) {
 
 namespace clang {
 namespace interp {
+static void popArg(InterpState , const Expr *Arg) {
+  PrimType Ty = S.getContext().classify(Arg->getType()).value_or(PT_Ptr);
+  TYPE_SWITCH(Ty, S.Stk.discard());
+}
+
+void cleanupAfterFunctionCall(InterpState , CodePtr OpPC) {
+  assert(S.Current);
+  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 CallExpr *CE = cast(S.Current->getExpr(OpPC));
+for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
+  popArg(S, CE->getArg(I));
+}
+return;
+  }
 
-bool popBuiltinArgs(InterpState , CodePtr OpPC) {
-  assert(S.Current && 
S.Current->getFunction()->needsRuntimeArgPop(S.getCtx()));
-  const Expr *E = S.Current->getExpr(OpPC);
-  assert(isa(E));
-  const CallExpr *CE = cast(E);
-  for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
-const Expr *A = CE->getArg(I);
-PrimType Ty = S.getContext().classify(A->getType()).value_or(PT_Ptr);
-TYPE_SWITCH(Ty, S.Stk.discard());
+  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.
+// This code path should be executed very rarely.
+const CallExpr *CE =
+cast(S.Current->Caller->getExpr(S.Current->getRetPC()));
+unsigned FixedParams = CurFunc->getNumParams();
+int32_t ArgsToPop = CE->getNumArgs() - FixedParams;
+assert(ArgsToPop >= 0);
+for (int32_t I = ArgsToPop - 1; I >= 0; --I) {
+  const Expr *A = CE->getArg(FixedParams + I);
+  popArg(S, A);
+}
   }
-  return true;
+  // And in any case, remove the fixed parameters (the non-variadic ones)
+  // at the end.
+  S.Current->popArgs();
 }
 
 bool CheckExtern(InterpState , CodePtr OpPC, const Pointer ) {
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index dd37150b63f6db0..d67b8b978031aac 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -200,8 +200,7 @@ enum class ArithOp { Add, Sub };
 // Returning values
 

[clang] [clang][Interp] Handle variadic functions (PR #67814)

2023-09-30 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67814

>From 64aae1cdf960f3edb34f1cf82ae3e66eb692247a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 29 Sep 2023 16:43:59 +0200
Subject: [PATCH 1/2] [clang][Interp] Handle variadic functions

Similarly to the code we already had for builtin functions, we need to
check the call expression for the arguments passed.
---
 clang/lib/AST/Interp/Function.cpp   |  2 +-
 clang/lib/AST/Interp/Function.h |  3 ++
 clang/lib/AST/Interp/Interp.cpp | 49 +++--
 clang/lib/AST/Interp/Interp.h   | 18 +++
 clang/test/AST/Interp/functions.cpp | 21 +
 5 files changed, 69 insertions(+), 24 deletions(-)

diff --git a/clang/lib/AST/Interp/Function.cpp 
b/clang/lib/AST/Interp/Function.cpp
index 0b7cfc4e28883f0..357aff7fe6229b9 100644
--- a/clang/lib/AST/Interp/Function.cpp
+++ b/clang/lib/AST/Interp/Function.cpp
@@ -24,7 +24,7 @@ Function::Function(Program , const FunctionDecl *F, 
unsigned ArgSize,
 : P(P), Loc(F->getBeginLoc()), F(F), ArgSize(ArgSize),
   ParamTypes(std::move(ParamTypes)), Params(std::move(Params)),
   ParamOffsets(std::move(ParamOffsets)), HasThisPointer(HasThisPointer),
-  HasRVO(HasRVO) {}
+  HasRVO(HasRVO), Variadic(F->isVariadic()) {}
 
 Function::ParamDescriptor Function::getParamDescriptor(unsigned Offset) const {
   auto It = Params.find(Offset);
diff --git a/clang/lib/AST/Interp/Function.h b/clang/lib/AST/Interp/Function.h
index 0bae314e97701d9..15bdd39dfde9d99 100644
--- a/clang/lib/AST/Interp/Function.h
+++ b/clang/lib/AST/Interp/Function.h
@@ -172,6 +172,8 @@ class Function final {
   /// Checks if the function is defined.
   bool isDefined() const { return Defined; }
 
+  bool isVariadic() const { return Variadic; }
+
   unsigned getBuiltinID() const { return F->getBuiltinID(); }
 
   bool isBuiltin() const { return F->getBuiltinID() != 0; }
@@ -250,6 +252,7 @@ class Function final {
   /// If we've already compiled the function's body.
   bool HasBody = false;
   bool Defined = false;
+  bool Variadic = false;
 
 public:
   /// Dumps the disassembled bytecode to \c llvm::errs().
diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index e1951574edb6288..639ceb140e99de3 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -121,18 +121,47 @@ static bool CheckGlobal(InterpState , CodePtr OpPC, 
const Pointer ) {
 
 namespace clang {
 namespace interp {
+static void popArg(InterpState , const Expr *Arg) {
+  PrimType Ty = S.getContext().classify(Arg->getType()).value_or(PT_Ptr);
+  TYPE_SWITCH(Ty, S.Stk.discard());
+}
+
+void cleanupAfterFunctionCall(InterpState , CodePtr OpPC) {
+  assert(S.Current);
+  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 CallExpr *CE = cast(S.Current->getExpr(OpPC));
+for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
+  popArg(S, CE->getArg(I));
+}
+return;
+  }
 
-bool popBuiltinArgs(InterpState , CodePtr OpPC) {
-  assert(S.Current && 
S.Current->getFunction()->needsRuntimeArgPop(S.getCtx()));
-  const Expr *E = S.Current->getExpr(OpPC);
-  assert(isa(E));
-  const CallExpr *CE = cast(E);
-  for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
-const Expr *A = CE->getArg(I);
-PrimType Ty = S.getContext().classify(A->getType()).value_or(PT_Ptr);
-TYPE_SWITCH(Ty, S.Stk.discard());
+  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.
+// This code path should be executed very rarely.
+const CallExpr *CE =
+cast(S.Current->Caller->getExpr(S.Current->getRetPC()));
+unsigned FixedParams = CurFunc->getNumParams();
+int32_t ArgsToPop = CE->getNumArgs() - FixedParams;
+assert(ArgsToPop >= 0);
+for (int32_t I = ArgsToPop - 1; I >= 0; --I) {
+  const Expr *A = CE->getArg(FixedParams + I);
+  popArg(S, A);
+}
   }
-  return true;
+  // And in any case, remove the fixed parameters (the non-variadic ones)
+  // at the end.
+  S.Current->popArgs();
 }
 
 bool CheckExtern(InterpState , CodePtr OpPC, const Pointer ) {
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index dd37150b63f6db0..d67b8b978031aac 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -200,8 +200,7 @@ enum 

[clang] [clang][Interp] Fix returning nullptr from functions (PR #67229)

2023-09-30 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67229

>From c3fcded8f926789ee6b00dcb676231b3c8285ac6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sat, 23 Sep 2023 11:41:52 +0200
Subject: [PATCH] [clang][Interp] Fix returning nullptr from functions

isLive() is false for null pointers, so we need to special-case
this here.
---
 clang/lib/AST/Interp/Interp.h   | 3 ++-
 clang/test/AST/Interp/functions.cpp | 7 +++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index dd37150b63f6db0..84ce164480bc36e 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -214,7 +214,8 @@ bool Ret(InterpState , CodePtr , APValue ) {
 // FIXME: We could be calling isLive() here, but the emitted diagnostics
 // seem a little weird, at least if the returned expression is of
 // pointer type.
-if (!Ret.isLive())
+// Null pointers are considered live here.
+if (!Ret.isZero() && !Ret.isLive())
   return false;
   }
 
diff --git a/clang/test/AST/Interp/functions.cpp 
b/clang/test/AST/Interp/functions.cpp
index 5cdecbff1e9d3d4..68082576f2735e9 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -343,3 +343,10 @@ namespace TemplateUndefined {
   constexpr int l = consume(0);
   static_assert(l == 0, "");
 }
+
+namespace PtrReturn {
+  constexpr void *a() {
+return nullptr;
+  }
+  static_assert(a() == nullptr, "");
+}

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


[clang] [clang][Interp] Zero-init remaining string literal elements (PR #66862)

2023-09-30 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/66862
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle CXXScalarValueInitExprs (PR #67147)

2023-09-30 Thread Timm Baeder via cfe-commits


@@ -31,6 +31,33 @@ static_assert(b, "");
 constexpr int one = true;
 static_assert(one == 1, "");
 
+constexpr bool b2 = bool();
+static_assert(!b2, "");
+
+namespace ScalarTypes {
+  constexpr int ScalarInitInt = int();
+  static_assert(ScalarInitInt == 0, "");
+  constexpr float ScalarInitFloat = float();
+  static_assert(ScalarInitFloat == 0.0f, "");
+
+  static_assert(decltype(nullptr)() == nullptr, "");
+
+  template
+  constexpr T getScalar() { return T(); }
+
+  static_assert(getScalar() == 0, "");
+  static_assert(getScalar() == 0.0, "");
+
+  static_assert(getScalar() == nullptr, "");
+  static_assert(getScalar() == nullptr, "");
+
+  enum E {
+First = 0,
+  };
+  static_assert(getScalar() == First, "");
+  /// FIXME: Member pointers.

tbaederr wrote:

Yes, because member pointers just don't work at all right now.

https://github.com/llvm/llvm-project/pull/67147
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle delegating constructors (PR #67823)

2023-09-29 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67823

>From 5e37e30bc9200f71a4ac2a8111a7e6d54d381b69 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 29 Sep 2023 18:00:08 +0200
Subject: [PATCH] [clang][Interp] Handle delegating constructors

---
 clang/lib/AST/Interp/ByteCodeStmtGen.cpp |  8 
 clang/test/AST/Interp/records.cpp| 23 +++
 2 files changed, 31 insertions(+)

diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp 
b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
index 15eae8e20b3a678..838e7bb67d0c076 100644
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -193,6 +193,14 @@ bool ByteCodeStmtGen::visitFunc(const 
FunctionDecl *F) {
   return false;
 if (!this->emitPopPtr(InitExpr))
   return false;
+  } else {
+assert(Init->isDelegatingInitializer());
+if (!this->emitThis(InitExpr))
+  return false;
+if (!this->visitInitializer(Init->getInit()))
+  return false;
+if (!this->emitPopPtr(InitExpr))
+  return false;
   }
 }
   }
diff --git a/clang/test/AST/Interp/records.cpp 
b/clang/test/AST/Interp/records.cpp
index bcc84087fc54020..3c866825d1f077c 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -1066,3 +1066,26 @@ namespace ParenInit {
   constexpr B b(A(1),2);
 }
 #endif
+
+namespace DelegatingConstructors {
+  struct S {
+int a;
+constexpr S() : S(10) {}
+constexpr S(int a) : a(a) {}
+  };
+  constexpr S s = {};
+  static_assert(s.a == 10, "");
+
+  struct B {
+int a;
+int b;
+
+constexpr B(int a) : a(a), b(a + 2) {}
+  };
+  struct A : B {
+constexpr A() : B(10) {};
+  };
+  constexpr A d4 = {};
+  static_assert(d4.a == 10, "");
+  static_assert(d4.b == 12, "");
+}

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


[clang] [clang][Interp] Handle delegating constructors (PR #67823)

2023-09-29 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/67823

None

>From d858d4b61c6d0e469debb9c8b865b4b5d4c7244b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 29 Sep 2023 18:00:08 +0200
Subject: [PATCH] [clang][Interp] Handle delegating constructors

---
 clang/lib/AST/Interp/ByteCodeStmtGen.cpp  |  8 +++
 clang/test/AST/Interp/records.cpp | 23 +++
 .../SemaCXX/constant-expression-cxx1z.cpp |  1 +
 3 files changed, 32 insertions(+)

diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp 
b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
index 15eae8e20b3a678..838e7bb67d0c076 100644
--- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -193,6 +193,14 @@ bool ByteCodeStmtGen::visitFunc(const 
FunctionDecl *F) {
   return false;
 if (!this->emitPopPtr(InitExpr))
   return false;
+  } else {
+assert(Init->isDelegatingInitializer());
+if (!this->emitThis(InitExpr))
+  return false;
+if (!this->visitInitializer(Init->getInit()))
+  return false;
+if (!this->emitPopPtr(InitExpr))
+  return false;
   }
 }
   }
diff --git a/clang/test/AST/Interp/records.cpp 
b/clang/test/AST/Interp/records.cpp
index bcc84087fc54020..3c866825d1f077c 100644
--- a/clang/test/AST/Interp/records.cpp
+++ b/clang/test/AST/Interp/records.cpp
@@ -1066,3 +1066,26 @@ namespace ParenInit {
   constexpr B b(A(1),2);
 }
 #endif
+
+namespace DelegatingConstructors {
+  struct S {
+int a;
+constexpr S() : S(10) {}
+constexpr S(int a) : a(a) {}
+  };
+  constexpr S s = {};
+  static_assert(s.a == 10, "");
+
+  struct B {
+int a;
+int b;
+
+constexpr B(int a) : a(a), b(a + 2) {}
+  };
+  struct A : B {
+constexpr A() : B(10) {};
+  };
+  constexpr A d4 = {};
+  static_assert(d4.a == 10, "");
+  static_assert(d4.b == 12, "");
+}
diff --git a/clang/test/SemaCXX/constant-expression-cxx1z.cpp 
b/clang/test/SemaCXX/constant-expression-cxx1z.cpp
index 9335626a5c90a4f..8b5fcf439a7da26 100644
--- a/clang/test/SemaCXX/constant-expression-cxx1z.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx1z.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++1z -verify %s -fcxx-exceptions 
-triple=x86_64-linux-gnu
+// RUN: %clang_cc1 -std=c++1z -verify %s -fcxx-exceptions 
-triple=x86_64-linux-gnu -fexperimental-new-constant-interpreter
 
 namespace BaseClassAggregateInit {
   struct A {

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


[clang] [clang][ExprConst] Fix crash on uninitialized array subobject (PR #67817)

2023-09-29 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Unfortunate, but the changes look good to me. Since the crash was introduced in 
clang 17, this should also be backported.

https://github.com/llvm/llvm-project/pull/67817
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle variadic functions (PR #67814)

2023-09-29 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67814

>From 64aae1cdf960f3edb34f1cf82ae3e66eb692247a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 29 Sep 2023 16:43:59 +0200
Subject: [PATCH] [clang][Interp] Handle variadic functions

Similarly to the code we already had for builtin functions, we need to
check the call expression for the arguments passed.
---
 clang/lib/AST/Interp/Function.cpp   |  2 +-
 clang/lib/AST/Interp/Function.h |  3 ++
 clang/lib/AST/Interp/Interp.cpp | 49 +++--
 clang/lib/AST/Interp/Interp.h   | 18 +++
 clang/test/AST/Interp/functions.cpp | 21 +
 5 files changed, 69 insertions(+), 24 deletions(-)

diff --git a/clang/lib/AST/Interp/Function.cpp 
b/clang/lib/AST/Interp/Function.cpp
index 0b7cfc4e28883f0..357aff7fe6229b9 100644
--- a/clang/lib/AST/Interp/Function.cpp
+++ b/clang/lib/AST/Interp/Function.cpp
@@ -24,7 +24,7 @@ Function::Function(Program , const FunctionDecl *F, 
unsigned ArgSize,
 : P(P), Loc(F->getBeginLoc()), F(F), ArgSize(ArgSize),
   ParamTypes(std::move(ParamTypes)), Params(std::move(Params)),
   ParamOffsets(std::move(ParamOffsets)), HasThisPointer(HasThisPointer),
-  HasRVO(HasRVO) {}
+  HasRVO(HasRVO), Variadic(F->isVariadic()) {}
 
 Function::ParamDescriptor Function::getParamDescriptor(unsigned Offset) const {
   auto It = Params.find(Offset);
diff --git a/clang/lib/AST/Interp/Function.h b/clang/lib/AST/Interp/Function.h
index 0bae314e97701d9..15bdd39dfde9d99 100644
--- a/clang/lib/AST/Interp/Function.h
+++ b/clang/lib/AST/Interp/Function.h
@@ -172,6 +172,8 @@ class Function final {
   /// Checks if the function is defined.
   bool isDefined() const { return Defined; }
 
+  bool isVariadic() const { return Variadic; }
+
   unsigned getBuiltinID() const { return F->getBuiltinID(); }
 
   bool isBuiltin() const { return F->getBuiltinID() != 0; }
@@ -250,6 +252,7 @@ class Function final {
   /// If we've already compiled the function's body.
   bool HasBody = false;
   bool Defined = false;
+  bool Variadic = false;
 
 public:
   /// Dumps the disassembled bytecode to \c llvm::errs().
diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index e1951574edb6288..639ceb140e99de3 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -121,18 +121,47 @@ static bool CheckGlobal(InterpState , CodePtr OpPC, 
const Pointer ) {
 
 namespace clang {
 namespace interp {
+static void popArg(InterpState , const Expr *Arg) {
+  PrimType Ty = S.getContext().classify(Arg->getType()).value_or(PT_Ptr);
+  TYPE_SWITCH(Ty, S.Stk.discard());
+}
+
+void cleanupAfterFunctionCall(InterpState , CodePtr OpPC) {
+  assert(S.Current);
+  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 CallExpr *CE = cast(S.Current->getExpr(OpPC));
+for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
+  popArg(S, CE->getArg(I));
+}
+return;
+  }
 
-bool popBuiltinArgs(InterpState , CodePtr OpPC) {
-  assert(S.Current && 
S.Current->getFunction()->needsRuntimeArgPop(S.getCtx()));
-  const Expr *E = S.Current->getExpr(OpPC);
-  assert(isa(E));
-  const CallExpr *CE = cast(E);
-  for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
-const Expr *A = CE->getArg(I);
-PrimType Ty = S.getContext().classify(A->getType()).value_or(PT_Ptr);
-TYPE_SWITCH(Ty, S.Stk.discard());
+  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.
+// This code path should be executed very rarely.
+const CallExpr *CE =
+cast(S.Current->Caller->getExpr(S.Current->getRetPC()));
+unsigned FixedParams = CurFunc->getNumParams();
+int32_t ArgsToPop = CE->getNumArgs() - FixedParams;
+assert(ArgsToPop >= 0);
+for (int32_t I = ArgsToPop - 1; I >= 0; --I) {
+  const Expr *A = CE->getArg(FixedParams + I);
+  popArg(S, A);
+}
   }
-  return true;
+  // And in any case, remove the fixed parameters (the non-variadic ones)
+  // at the end.
+  S.Current->popArgs();
 }
 
 bool CheckExtern(InterpState , CodePtr OpPC, const Pointer ) {
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index dd37150b63f6db0..d67b8b978031aac 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -200,8 +200,7 @@ enum class ArithOp { Add, Sub };
 // Returning values
 

[clang] [clang][Interp] Handle variadic functions (PR #67814)

2023-09-29 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/67814

Similarly to the code we already had for builtin functions, we need to check 
the call expression for the arguments passed.

>From 0628b5c9cdfb712936e47bbac278bc579c253d4f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 29 Sep 2023 16:43:59 +0200
Subject: [PATCH] [clang][Interp] Handle variadic functions

Similarly to the code we already had for builtin functions, we need to
check the call expression for the arguments passed.
---
 clang/lib/AST/Interp/Function.cpp   |  2 +-
 clang/lib/AST/Interp/Function.h |  3 ++
 clang/lib/AST/Interp/Interp.cpp | 48 +++--
 clang/lib/AST/Interp/Interp.h   | 18 +++
 clang/test/AST/Interp/functions.cpp | 21 +
 5 files changed, 68 insertions(+), 24 deletions(-)

diff --git a/clang/lib/AST/Interp/Function.cpp 
b/clang/lib/AST/Interp/Function.cpp
index 0b7cfc4e28883f0..357aff7fe6229b9 100644
--- a/clang/lib/AST/Interp/Function.cpp
+++ b/clang/lib/AST/Interp/Function.cpp
@@ -24,7 +24,7 @@ Function::Function(Program , const FunctionDecl *F, 
unsigned ArgSize,
 : P(P), Loc(F->getBeginLoc()), F(F), ArgSize(ArgSize),
   ParamTypes(std::move(ParamTypes)), Params(std::move(Params)),
   ParamOffsets(std::move(ParamOffsets)), HasThisPointer(HasThisPointer),
-  HasRVO(HasRVO) {}
+  HasRVO(HasRVO), Variadic(F->isVariadic()) {}
 
 Function::ParamDescriptor Function::getParamDescriptor(unsigned Offset) const {
   auto It = Params.find(Offset);
diff --git a/clang/lib/AST/Interp/Function.h b/clang/lib/AST/Interp/Function.h
index 0bae314e97701d9..15bdd39dfde9d99 100644
--- a/clang/lib/AST/Interp/Function.h
+++ b/clang/lib/AST/Interp/Function.h
@@ -172,6 +172,8 @@ class Function final {
   /// Checks if the function is defined.
   bool isDefined() const { return Defined; }
 
+  bool isVariadic() const { return Variadic; }
+
   unsigned getBuiltinID() const { return F->getBuiltinID(); }
 
   bool isBuiltin() const { return F->getBuiltinID() != 0; }
@@ -250,6 +252,7 @@ class Function final {
   /// If we've already compiled the function's body.
   bool HasBody = false;
   bool Defined = false;
+  bool Variadic = false;
 
 public:
   /// Dumps the disassembled bytecode to \c llvm::errs().
diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index e1951574edb6288..c2f0e693151ce93 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -121,18 +121,46 @@ static bool CheckGlobal(InterpState , CodePtr OpPC, 
const Pointer ) {
 
 namespace clang {
 namespace interp {
+static void popArg(InterpState , const Expr *Arg) {
+  PrimType Ty = S.getContext().classify(Arg->getType()).value_or(PT_Ptr);
+  TYPE_SWITCH(Ty, S.Stk.discard());
+}
+
+void cleanupAfterFunctionCall(InterpState , CodePtr OpPC) {
+  assert(S.Current);
+  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 CallExpr *CE = cast(S.Current->getExpr(OpPC));
+for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
+  popArg(S, CE->getArg(I));
+}
+return;
+  }
 
-bool popBuiltinArgs(InterpState , CodePtr OpPC) {
-  assert(S.Current && 
S.Current->getFunction()->needsRuntimeArgPop(S.getCtx()));
-  const Expr *E = S.Current->getExpr(OpPC);
-  assert(isa(E));
-  const CallExpr *CE = cast(E);
-  for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
-const Expr *A = CE->getArg(I);
-PrimType Ty = S.getContext().classify(A->getType()).value_or(PT_Ptr);
-TYPE_SWITCH(Ty, S.Stk.discard());
+  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.
+const CallExpr *CE =
+cast(S.Current->Caller->getExpr(S.Current->getRetPC()));
+unsigned FixedParams = CurFunc->getNumParams();
+int32_t ArgsToPop = CE->getNumArgs() - FixedParams;
+assert(ArgsToPop >= 0);
+for (int32_t I = ArgsToPop - 1; I >= 0; --I) {
+  const Expr *A = CE->getArg(FixedParams + I);
+  popArg(S, A);
+}
   }
-  return true;
+  // And in any case, remove the fixed parameters (the non-variadic ones)
+  // at the end.
+  S.Current->popArgs();
 }
 
 bool CheckExtern(InterpState , CodePtr OpPC, const Pointer ) {
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index dd37150b63f6db0..d67b8b978031aac 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -200,8 

[clang] [clang] Fix a crash from nested ArrayInitLoopExpr (PR #67722)

2023-09-29 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr approved this pull request.


https://github.com/llvm/llvm-project/pull/67722
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix a crash from nested ArrayInitLoopExpr (PR #67722)

2023-09-29 Thread Timm Baeder via cfe-commits


@@ -352,10 +352,6 @@ namespace ZeroInit {
 }
 
 namespace ArrayInitLoop {
-  /// FIXME: The ArrayInitLoop for the decomposition initializer in g() has
-  /// f(n) as its CommonExpr. We need to evaluate that exactly once and not
-  /// N times as we do right now.

tbaederr wrote:

This comment needs to stay.

https://github.com/llvm/llvm-project/pull/67722
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExprConst] Don't try to evaluate value-dependent DeclRefExprs (PR #67778)

2023-09-29 Thread Timm Baeder via cfe-commits


@@ -177,3 +177,16 @@ namespace LambdaCallOp {
 p();
   }
 }
+
+/// This used to crash due to an assertion failure,
+/// see gh#67690

tbaederr wrote:

Because it's not a RUN or expected-* line.

https://github.com/llvm/llvm-project/pull/67778
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExprConst] Don't try to evaluate value-dependent DeclRefExprs (PR #67778)

2023-09-29 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Should we get crash fixes like this into clang 17 as well?

https://github.com/llvm/llvm-project/pull/67778
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExprConst] Don't try to evaluate value-dependent DeclRefExprs (PR #67778)

2023-09-29 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67778

>From 04abbd57c0325ea0c1d5d5af6fafa18c0c0410ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 29 Sep 2023 11:23:55 +0200
Subject: [PATCH] [clang][ExprConst] Don't try to evaluate value-dependent
 DeclRefExprs

The Expression here migth be value dependent, which makes us run into an
assertion later on. Just bail out early.

Fixes #67690
---
 clang/lib/AST/ExprConstant.cpp   |  3 +++
 clang/test/SemaCXX/constant-expression-cxx1z.cpp | 13 +
 2 files changed, 16 insertions(+)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index fea06b97259fe31..8372d81234669fd 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3357,6 +3357,9 @@ static bool evaluateVarDeclInit(EvalInfo , const 
Expr *E,
 return false;
   }
 
+  if (E->isValueDependent())
+return false;
+
   // Dig out the initializer, and use the declaration which it's attached to.
   // FIXME: We should eventually check whether the variable has a reachable
   // initializing declaration.
diff --git a/clang/test/SemaCXX/constant-expression-cxx1z.cpp 
b/clang/test/SemaCXX/constant-expression-cxx1z.cpp
index 9335626a5c90a4f..45f87f0cfcf808b 100644
--- a/clang/test/SemaCXX/constant-expression-cxx1z.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx1z.cpp
@@ -177,3 +177,16 @@ namespace LambdaCallOp {
 p();
   }
 }
+
+/// This used to crash due to an assertion failure,
+/// see gh#67690
+namespace {
+  struct C {
+int x;
+  };
+
+  template  void f() {
+const auto &[c] = *p;
+ // expected-warning {{expression result unused}}
+  }
+}

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


[clang] [clang][ExprConst] Don't try to evaluate value-dependent DeclRefExprs (PR #67778)

2023-09-29 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/67778

The Expression here migth be value dependent, which makes us run into an 
assertion later on. Just bail out early.

Fixes #67690

>From c696a6e15404235cf9cab8fc69a39e828d5da03e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 29 Sep 2023 11:23:55 +0200
Subject: [PATCH] [clang][ExprConst] Don't try to evaluate value-dependent
 DeclRefExprs

The Expression here migth be value dependent, which makes us run into an
assertion later on. Just bail out early.

Fixes #67690
---
 clang/lib/AST/ExprConstant.cpp   |  3 +++
 clang/test/SemaCXX/constant-expression-cxx1z.cpp | 13 +
 2 files changed, 16 insertions(+)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index fea06b97259fe31..8372d81234669fd 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3357,6 +3357,9 @@ static bool evaluateVarDeclInit(EvalInfo , const 
Expr *E,
 return false;
   }
 
+  if (E->isValueDependent())
+return false;
+
   // Dig out the initializer, and use the declaration which it's attached to.
   // FIXME: We should eventually check whether the variable has a reachable
   // initializing declaration.
diff --git a/clang/test/SemaCXX/constant-expression-cxx1z.cpp 
b/clang/test/SemaCXX/constant-expression-cxx1z.cpp
index 9335626a5c90a4f..a36b8f15f826f41 100644
--- a/clang/test/SemaCXX/constant-expression-cxx1z.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx1z.cpp
@@ -177,3 +177,16 @@ namespace LambdaCallOp {
 p();
   }
 }
+
+/// This used to crash due to an assertion failure,
+/// see gh#67690
+namespace {
+  struct C {
+int x;
+  };
+
+  template  void f() {
+const auto &[c] = *p;
+
+  }
+}

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


[clang] [clang][Interp] Add IntegralAP for arbitrary-precision integers (PR #65844)

2023-09-29 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/65844

>From 0d879e0dc2ae8bb24e396dc0cf1a6e7215fb1e2e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Sat, 9 Sep 2023 10:34:26 +0200
Subject: [PATCH 1/6] [clang][Interp] Add IntegralAP for arbitrary-precision
 integers

---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp |  11 +-
 clang/lib/AST/Interp/Context.cpp |   6 +-
 clang/lib/AST/Interp/Descriptor.cpp  |   9 +
 clang/lib/AST/Interp/EvalEmitter.cpp |   1 +
 clang/lib/AST/Interp/Integral.h  |   4 +
 clang/lib/AST/Interp/IntegralAP.h| 253 +++
 clang/lib/AST/Interp/Interp.h|  21 +-
 clang/lib/AST/Interp/InterpStack.h   |   5 +
 clang/lib/AST/Interp/Opcodes.td  |   8 +-
 clang/lib/AST/Interp/PrimType.cpp|   1 +
 clang/lib/AST/Interp/PrimType.h  |  13 ++
 clang/test/AST/Interp/literals.cpp   |  24 +++
 12 files changed, 343 insertions(+), 13 deletions(-)
 create mode 100644 clang/lib/AST/Interp/IntegralAP.h

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index e813d4fa651ceaf..ca762e795ec6f4b 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -171,14 +171,17 @@ bool ByteCodeExprGen::VisitCastExpr(const 
CastExpr *CE) {
   return this->discard(SubExpr);
 std::optional FromT = classify(SubExpr->getType());
 std::optional ToT = classify(CE->getType());
+
 if (!FromT || !ToT)
   return false;
 
 if (!this->visit(SubExpr))
   return false;
 
-if (FromT == ToT)
+if (FromT == ToT) {
+  assert(ToT != PT_IntAP && ToT != PT_IntAPS);
   return true;
+}
 
 return this->emitCast(*FromT, *ToT, CE);
   }
@@ -1598,6 +1601,9 @@ bool 
ByteCodeExprGen::visitZeroInitializer(QualType QT,
 return this->emitZeroSint64(E);
   case PT_Uint64:
 return this->emitZeroUint64(E);
+  case PT_IntAP:
+  case PT_IntAPS:
+assert(false);
   case PT_Ptr:
 return this->emitNullPtr(E);
   case PT_FnPtr:
@@ -1837,6 +1843,9 @@ bool ByteCodeExprGen::emitConst(T Value, 
PrimType Ty, const Expr *E) {
 return this->emitConstSint64(Value, E);
   case PT_Uint64:
 return this->emitConstUint64(Value, E);
+  case PT_IntAP:
+  case PT_IntAPS:
+assert(false);
   case PT_Bool:
 return this->emitConstBool(Value, E);
   case PT_Ptr:
diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp
index e84c0f6aae7ee93..b94fd1ab6d53574 100644
--- a/clang/lib/AST/Interp/Context.cpp
+++ b/clang/lib/AST/Interp/Context.cpp
@@ -103,7 +103,8 @@ std::optional Context::classify(QualType T) const 
{
 case 8:
   return PT_Sint8;
 default:
-  return std::nullopt;
+  return PT_IntAPS;
+  // return std::nullopt;
 }
   }
 
@@ -118,7 +119,8 @@ std::optional Context::classify(QualType T) const 
{
 case 8:
   return PT_Uint8;
 default:
-  return std::nullopt;
+  return PT_IntAP;
+  // return std::nullopt;
 }
   }
 
diff --git a/clang/lib/AST/Interp/Descriptor.cpp 
b/clang/lib/AST/Interp/Descriptor.cpp
index db49a569eff33ea..4ecb7466998e705 100644
--- a/clang/lib/AST/Interp/Descriptor.cpp
+++ b/clang/lib/AST/Interp/Descriptor.cpp
@@ -10,6 +10,7 @@
 #include "Boolean.h"
 #include "Floating.h"
 #include "FunctionPointer.h"
+#include "IntegralAP.h"
 #include "Pointer.h"
 #include "PrimType.h"
 #include "Record.h"
@@ -182,6 +183,10 @@ static BlockCtorFn getCtorPrim(PrimType Type) {
   // constructor called.
   if (Type == PT_Float)
 return ctorTy::T>;
+  if (Type == PT_IntAP)
+return ctorTy::T>;
+  if (Type == PT_IntAPS)
+return ctorTy::T>;
 
   COMPOSITE_TYPE_SWITCH(Type, return ctorTy, return nullptr);
 }
@@ -191,6 +196,10 @@ static BlockDtorFn getDtorPrim(PrimType Type) {
   // destructor called, since they might allocate memory.
   if (Type == PT_Float)
 return dtorTy::T>;
+  if (Type == PT_IntAP)
+return dtorTy::T>;
+  if (Type == PT_IntAPS)
+return dtorTy::T>;
 
   COMPOSITE_TYPE_SWITCH(Type, return dtorTy, return nullptr);
 }
diff --git a/clang/lib/AST/Interp/EvalEmitter.cpp 
b/clang/lib/AST/Interp/EvalEmitter.cpp
index bdf800c60f1723f..f46ef1067cf52a0 100644
--- a/clang/lib/AST/Interp/EvalEmitter.cpp
+++ b/clang/lib/AST/Interp/EvalEmitter.cpp
@@ -9,6 +9,7 @@
 #include "EvalEmitter.h"
 #include "ByteCodeGenError.h"
 #include "Context.h"
+#include "IntegralAP.h"
 #include "Interp.h"
 #include "Opcode.h"
 #include "clang/AST/DeclCXX.h"
diff --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h
index 72285cabcbbf8ce..f8e529aa3392696 100644
--- a/clang/lib/AST/Interp/Integral.h
+++ b/clang/lib/AST/Interp/Integral.h
@@ -29,6 +29,8 @@ namespace interp {
 using APInt = llvm::APInt;
 using APSInt = 

[clang] [clang][Interp] Add IntegralAP for arbitrary-precision integers (PR #65844)

2023-09-29 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr resolved 
https://github.com/llvm/llvm-project/pull/65844
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Three-way comparisons (PR #65901)

2023-09-29 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/65901
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle CXXScalarValueInitExprs (PR #67147)

2023-09-29 Thread Timm Baeder via cfe-commits

tbaederr wrote:

I've removed the second commit, so this needs 
https://github.com/llvm/llvm-project/pull/67229 to be merged first.

https://github.com/llvm/llvm-project/pull/67147
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle CXXScalarValueInitExprs (PR #67147)

2023-09-29 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/67147

>From a64adec2680206523c99122dc53c2c5c2778e961 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 22 Sep 2023 16:27:11 +0200
Subject: [PATCH] [clang][Interp] Handle CXXScalarValueInitExprs

---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp |  6 ++
 clang/lib/AST/Interp/ByteCodeExprGen.h   |  1 +
 clang/test/AST/Interp/literals.cpp   | 27 
 3 files changed, 34 insertions(+)

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index e813d4fa651ceaf..c804bab7ce567d0 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1488,6 +1488,12 @@ bool ByteCodeExprGen::VisitOffsetOfExpr(const 
OffsetOfExpr *E) {
   return this->emitOffsetOf(T, E, E);
 }
 
+template 
+bool ByteCodeExprGen::VisitCXXScalarValueInitExpr(
+const CXXScalarValueInitExpr *E) {
+  return this->visitZeroInitializer(E->getType(), E);
+}
+
 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 47a3f75f13459d0..7cfe4d9251c5f05 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -106,6 +106,7 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   bool VisitCXXConstructExpr(const CXXConstructExpr *E);
   bool VisitSourceLocExpr(const SourceLocExpr *E);
   bool VisitOffsetOfExpr(const OffsetOfExpr *E);
+  bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
 
 protected:
   bool visitExpr(const Expr *E) override;
diff --git a/clang/test/AST/Interp/literals.cpp 
b/clang/test/AST/Interp/literals.cpp
index ceda59405ea9105..a83dcd234111587 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -31,6 +31,33 @@ static_assert(b, "");
 constexpr int one = true;
 static_assert(one == 1, "");
 
+constexpr bool b2 = bool();
+static_assert(!b2, "");
+
+namespace ScalarTypes {
+  constexpr int ScalarInitInt = int();
+  static_assert(ScalarInitInt == 0, "");
+  constexpr float ScalarInitFloat = float();
+  static_assert(ScalarInitFloat == 0.0f, "");
+
+  static_assert(decltype(nullptr)() == nullptr, "");
+
+  template
+  constexpr T getScalar() { return T(); }
+
+  static_assert(getScalar() == 0, "");
+  static_assert(getScalar() == 0.0, "");
+
+  static_assert(getScalar() == nullptr, "");
+  static_assert(getScalar() == nullptr, "");
+
+  enum E {
+First = 0,
+  };
+  static_assert(getScalar() == First, "");
+  /// FIXME: Member pointers.
+}
+
 namespace IntegralCasts {
   constexpr int i = 12;
   constexpr unsigned int ui = i;

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


[clang] [clang] Fix a crash from nested ArrayInitLoopExpr (PR #67722)

2023-09-29 Thread Timm Baeder via cfe-commits

tbaederr wrote:

I've pushed 
https://github.com/llvm/llvm-project/commit/38018ecf965fda81d15edfb904b5b28adb6051b0
 since, so you could remove the `CUR_INTERP` stuff from there and get a new 
test case for free.

https://github.com/llvm/llvm-project/pull/67722
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Zero-init remaining string literal elements (PR #66862)

2023-09-29 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/66862

>From f2b9dec7ccf73258eb74c1823e4a954a459b5d51 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Wed, 20 Sep 2023 08:18:51 +0200
Subject: [PATCH] [clang][Interp] Zero-init remaining string literal elements

---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp | 21 +++--
 clang/test/AST/Interp/arrays.cpp | 21 +
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp 
b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index e813d4fa651ceaf..c2b107cef7c9708 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -858,8 +858,8 @@ bool ByteCodeExprGen::VisitStringLiteral(const 
StringLiteral *E) {
 
   // If the initializer string is too long, a diagnostic has already been
   // emitted. Read only the array length from the string literal.
-  unsigned N =
-  std::min(unsigned(CAT->getSize().getZExtValue()), E->getLength());
+  unsigned ArraySize = CAT->getSize().getZExtValue();
+  unsigned N = std::min(ArraySize, E->getLength());
   size_t CharWidth = E->getCharByteWidth();
 
   for (unsigned I = 0; I != N; ++I) {
@@ -878,6 +878,23 @@ bool ByteCodeExprGen::VisitStringLiteral(const 
StringLiteral *E) {
   llvm_unreachable("unsupported character width");
 }
   }
+
+  // Fill up the rest of the char array with NUL bytes.
+  for (unsigned I = N; I != ArraySize; ++I) {
+if (CharWidth == 1) {
+  this->emitConstSint8(0, E);
+  this->emitInitElemSint8(I, E);
+} else if (CharWidth == 2) {
+  this->emitConstUint16(0, E);
+  this->emitInitElemUint16(I, E);
+} else if (CharWidth == 4) {
+  this->emitConstUint32(0, E);
+  this->emitInitElemUint32(I, E);
+} else {
+  llvm_unreachable("unsupported character width");
+}
+  }
+
   return true;
 }
 
diff --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp
index 5640f57f6aeb826..73d918e75db0fb5 100644
--- a/clang/test/AST/Interp/arrays.cpp
+++ b/clang/test/AST/Interp/arrays.cpp
@@ -371,3 +371,24 @@ namespace ArrayInitLoop {
// expected-note {{15 == 6}}
 #endif
 }
+
+namespace StringZeroFill {
+  struct A {
+char c[6];
+  };
+  constexpr A a = { "abc" };
+  static_assert(a.c[0] == 'a', "");
+  static_assert(a.c[1] == 'b', "");
+  static_assert(a.c[2] == 'c', "");
+  static_assert(a.c[3] == '\0', "");
+  static_assert(a.c[4] == '\0', "");
+  static_assert(a.c[5] == '\0', "");
+
+  constexpr char b[6] = "foo";
+  static_assert(b[0] == 'f', "");
+  static_assert(b[1] == 'o', "");
+  static_assert(b[2] == 'o', "");
+  static_assert(b[3] == '\0', "");
+  static_assert(b[4] == '\0', "");
+  static_assert(b[5] == '\0', "");
+}

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


[clang] [clang][Interp] Zero-init remaining string literal elements (PR #66862)

2023-09-29 Thread Timm Baeder via cfe-commits


@@ -858,8 +858,8 @@ bool ByteCodeExprGen::VisitStringLiteral(const 
StringLiteral *E) {
 
   // If the initializer string is too long, a diagnostic has already been
   // emitted. Read only the array length from the string literal.
-  unsigned N =
-  std::min(unsigned(CAT->getSize().getZExtValue()), E->getLength());
+  unsigned ArraySize = CAT->getSize().getZExtValue();

tbaederr wrote:

It's a bit tricky since `StringLiteral::getLength()` returns `unsigned` again, 
so we can't use the extra bytes anyway and need to cast to `unsigned` for the 
`std::min()`.

https://github.com/llvm/llvm-project/pull/66862
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] Fix a crash from nested ArrayInitLoopExpr (PR #67722)

2023-09-28 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Remove the `Interp/` changes please, I'll have a look at that later.

https://github.com/llvm/llvm-project/pull/67722
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExprConst] Don't create useless temporary variable (PR #67716)

2023-09-28 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/67716
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExprConst] Don't create useless temporary variable (PR #67716)

2023-09-28 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ah, didn't realize that. We should have a test case for this.

https://github.com/llvm/llvm-project/pull/67716
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][ExprConst] Don't create useless temporary variable (PR #67716)

2023-09-28 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/67716

We never use it anyway.

This code has been introduced in
410306bf6ed906af77978caa199e5d96376bae66, but it didn't really do anything back 
then either, as far as I can tell.

Fixes #57135

>From 9d2444645dfe72889a3e2be152992e708b2c2c42 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Thu, 28 Sep 2023 19:31:09 +0200
Subject: [PATCH] [clang][ExprConst] Don't create useless temporary variable

We never use it anyway.

This code has been introduced in
410306bf6ed906af77978caa199e5d96376bae66, but it didn't really do
anything back then either, as far as I can tell.

Fixes #57135
---
 clang/lib/AST/ExprConstant.cpp | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index fea06b97259fe31..04a751f1b4d09fb 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10950,16 +10950,8 @@ bool 
ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
 }
 
 bool ArrayExprEvaluator::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {
-  LValue CommonLV;
-  if (E->getCommonExpr() &&
-  !Evaluate(Info.CurrentCall->createTemporary(
-E->getCommonExpr(),
-getStorageType(Info.Ctx, E->getCommonExpr()),
-ScopeKind::FullExpression, CommonLV),
-Info, E->getCommonExpr()->getSourceExpr()))
-return false;
-
-  auto *CAT = cast(E->getType()->castAsArrayTypeUnsafe());
+  const auto *CAT =
+  cast(E->getType()->castAsArrayTypeUnsafe());
 
   uint64_t Elements = CAT->getSize().getZExtValue();
   Result = APValue(APValue::UninitArray(), Elements, Elements);

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


[clang] [clang][Sema] Only check RVV types if we have them (PR #67669)

2023-09-28 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr edited 
https://github.com/llvm/llvm-project/pull/67669
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Sema] Only check RVV types is we have them (PR #67669)

2023-09-28 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/67669

isRVVType() is suprisingly expensive, so do the checks only if the target has 
rvv types.

>From 847451fdf8c70b1deebdd4d4cf4ce3ce84845f5d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Thu, 28 Sep 2023 14:41:55 +0200
Subject: [PATCH] [clang][Sema] Only check RVV types is we have them

isRVVType() is suprisingly expensive, so do the checks only if the
target has rvv types.
---
 clang/lib/Sema/Sema.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index a401017d4c1c0b8..2d175c9b9a791dd 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -2050,7 +2050,7 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation 
Loc, ValueDecl *D) {
 targetDiag(D->getLocation(), diag::note_defined_here, FD) << D;
 }
 
-if (Ty->isRVVType())
+if (TI.hasRISCVVTypes() && Ty->isRVVType())
   checkRVVTypeSupport(Ty, Loc, D);
 
 // Don't allow SVE types in functions without a SVE target.

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


[clang] [clang][Interp] Zero-init remaining string literal elements (PR #66862)

2023-09-27 Thread Timm Baeder via cfe-commits

tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/66862
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang] WIP: Warn on mismatched RequiresCapability attributes (PR #67520)

2023-09-27 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr converted_to_draft 
https://github.com/llvm/llvm-project/pull/67520
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Diagnostics] Make 'note' color CYAN (PR #66997)

2023-09-27 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/66997
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Diagnostics] Make 'note' color CYAN (PR #66997)

2023-09-27 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/66997

>From 5670ee4eab71549c686cb583e7ab0a14c51dce68 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Thu, 21 Sep 2023 12:01:30 +0200
Subject: [PATCH] [clang][Diagnostics] Make 'note' color CYAN

Just using BLACK makes it invisible in terminals with a dark background.
---
 clang/docs/ReleaseNotes.rst   | 2 ++
 clang/lib/Frontend/TextDiagnostic.cpp | 3 +--
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a17efab57bcdfa3..fb52b90ae4a3cb9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -212,6 +212,8 @@ Improvements to Clang's diagnostics
   (`#51567: `_)
 - Clang now diagnoses narrowing implicit conversions on variable initializers 
in immediate
   function context and on constexpr variable template initializers.
+- Clang now prints its 'note' diagnostic in cyan instead of black, to be more 
compatible
+  with terminals with dark background colors. This is also more consistent 
with GCC.
 
 Bug Fixes in This Version
 -
diff --git a/clang/lib/Frontend/TextDiagnostic.cpp 
b/clang/lib/Frontend/TextDiagnostic.cpp
index eaa6e8d29a1dece..779dead5d058d1a 100644
--- a/clang/lib/Frontend/TextDiagnostic.cpp
+++ b/clang/lib/Frontend/TextDiagnostic.cpp
@@ -24,8 +24,7 @@
 
 using namespace clang;
 
-static const enum raw_ostream::Colors noteColor =
-  raw_ostream::BLACK;
+static const enum raw_ostream::Colors noteColor = raw_ostream::CYAN;
 static const enum raw_ostream::Colors remarkColor =
   raw_ostream::BLUE;
 static const enum raw_ostream::Colors fixitColor =

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


[clang] [clang][Diagnostics] Make 'note' color CYAN (PR #66997)

2023-09-27 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/66997

>From 8d7c79946f8afecf3313bcccbb5b45133242bf8d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Thu, 21 Sep 2023 12:01:30 +0200
Subject: [PATCH] [clang][Diagnostics] Make 'note' color CYAN

Just using BLACK makes it invisible in terminals with a dark background.
---
 clang/docs/ReleaseNotes.rst   | 2 ++
 clang/lib/Frontend/TextDiagnostic.cpp | 3 +--
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7abcb8d799e09dc..f227c05e76f0702 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -204,6 +204,8 @@ Improvements to Clang's diagnostics
 - Clang no longer emits irrelevant notes about unsatisfied constraint 
expressions
   on the left-hand side of ``||`` when the right-hand side constraint is 
satisfied.
   (`#54678: `_).
+- Clang now prints its 'note' diagnostic in cyan instead of black, to be more 
compatible
+  with terminals with dark background colors. This is also more consistent 
with GCC.
 
 Bug Fixes in This Version
 -
diff --git a/clang/lib/Frontend/TextDiagnostic.cpp 
b/clang/lib/Frontend/TextDiagnostic.cpp
index eaa6e8d29a1dece..779dead5d058d1a 100644
--- a/clang/lib/Frontend/TextDiagnostic.cpp
+++ b/clang/lib/Frontend/TextDiagnostic.cpp
@@ -24,8 +24,7 @@
 
 using namespace clang;
 
-static const enum raw_ostream::Colors noteColor =
-  raw_ostream::BLACK;
+static const enum raw_ostream::Colors noteColor = raw_ostream::CYAN;
 static const enum raw_ostream::Colors remarkColor =
   raw_ostream::BLUE;
 static const enum raw_ostream::Colors fixitColor =

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


[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)

2023-09-27 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/66514

>From 42e20781dda9ca269b6152f4e02377a32b70be1e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 15 Sep 2023 15:51:39 +0200
Subject: [PATCH 1/9] [clang][Diagnostics] Highlight code snippets

Add some primitive syntax highlighting to our code snippet output.
---
 .../clang/Frontend/CodeSnippetHighlighter.h   |  46 +++
 clang/include/clang/Frontend/TextDiagnostic.h |   2 +
 clang/lib/Frontend/CMakeLists.txt |   1 +
 clang/lib/Frontend/CodeSnippetHighlighter.cpp | 120 ++
 clang/lib/Frontend/TextDiagnostic.cpp |  26 
 5 files changed, 195 insertions(+)
 create mode 100644 clang/include/clang/Frontend/CodeSnippetHighlighter.h
 create mode 100644 clang/lib/Frontend/CodeSnippetHighlighter.cpp

diff --git a/clang/include/clang/Frontend/CodeSnippetHighlighter.h 
b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
new file mode 100644
index 000..776954b59e2e1a8
--- /dev/null
+++ b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
@@ -0,0 +1,46 @@
+//===--- CodeSnippetHighlighter.h - Code snippet highlighting ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+#define LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+
+struct StyleRange {
+  unsigned Start;
+  unsigned End;
+  const enum llvm::raw_ostream::Colors c;
+};
+
+class CodeSnippetHighlighter final {
+public:
+  CodeSnippetHighlighter() = default;
+
+  /// Produce StyleRanges for the given line.
+  /// The returned vector contains non-overlapping style ranges. They are 
sorted
+  /// from beginning of the line to the end.
+  std::vector highlightLine(llvm::StringRef SourceLine,
+const LangOptions );
+
+private:
+  bool Initialized = false;
+  /// Fills Keywords and Literals.
+  void ensureTokenData();
+
+  llvm::SmallSet Keywords;
+  llvm::SmallSet Literals;
+};
+
+} // namespace clang
+
+#endif
diff --git a/clang/include/clang/Frontend/TextDiagnostic.h 
b/clang/include/clang/Frontend/TextDiagnostic.h
index 7eb0ab0cdc9bca8..59fd4d4f9408d48 100644
--- a/clang/include/clang/Frontend/TextDiagnostic.h
+++ b/clang/include/clang/Frontend/TextDiagnostic.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 #define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 
+#include "clang/Frontend/CodeSnippetHighlighter.h"
 #include "clang/Frontend/DiagnosticRenderer.h"
 
 namespace clang {
@@ -33,6 +34,7 @@ namespace clang {
 /// printing coming out of libclang.
 class TextDiagnostic : public DiagnosticRenderer {
   raw_ostream 
+  CodeSnippetHighlighter SnippetHighlighter;
 
 public:
   TextDiagnostic(raw_ostream ,
diff --git a/clang/lib/Frontend/CMakeLists.txt 
b/clang/lib/Frontend/CMakeLists.txt
index 1e5f0a859dfd568..f3547f771593093 100644
--- a/clang/lib/Frontend/CMakeLists.txt
+++ b/clang/lib/Frontend/CMakeLists.txt
@@ -42,6 +42,7 @@ add_clang_library(clangFrontend
   TextDiagnosticPrinter.cpp
   VerifyDiagnosticConsumer.cpp
   InterfaceStubFunctionsConsumer.cpp
+  CodeSnippetHighlighter.cpp
 
   DEPENDS
   ClangDriverOptions
diff --git a/clang/lib/Frontend/CodeSnippetHighlighter.cpp 
b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
new file mode 100644
index 000..829a533ad2692e5
--- /dev/null
+++ b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
@@ -0,0 +1,120 @@
+
+#include "clang/Frontend/CodeSnippetHighlighter.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+void CodeSnippetHighlighter::ensureTokenData() {
+  if (Initialized)
+return;
+
+  // List of keywords, literals and types we want to highlight.
+  // These are best-effort, as is everything we do wrt. highlighting.
+  Keywords.insert("_Static_assert");
+  Keywords.insert("auto");
+  Keywords.insert("concept");
+  Keywords.insert("const");
+  Keywords.insert("consteval");
+  Keywords.insert("constexpr");
+  Keywords.insert("delete");
+  Keywords.insert("do");
+  Keywords.insert("else");
+  Keywords.insert("final");
+  Keywords.insert("for");
+  Keywords.insert("if");
+  Keywords.insert("mutable");
+  Keywords.insert("namespace");
+  Keywords.insert("new");
+  

[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)

2023-09-27 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/66514

>From 42e20781dda9ca269b6152f4e02377a32b70be1e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Fri, 15 Sep 2023 15:51:39 +0200
Subject: [PATCH 1/9] [clang][Diagnostics] Highlight code snippets

Add some primitive syntax highlighting to our code snippet output.
---
 .../clang/Frontend/CodeSnippetHighlighter.h   |  46 +++
 clang/include/clang/Frontend/TextDiagnostic.h |   2 +
 clang/lib/Frontend/CMakeLists.txt |   1 +
 clang/lib/Frontend/CodeSnippetHighlighter.cpp | 120 ++
 clang/lib/Frontend/TextDiagnostic.cpp |  26 
 5 files changed, 195 insertions(+)
 create mode 100644 clang/include/clang/Frontend/CodeSnippetHighlighter.h
 create mode 100644 clang/lib/Frontend/CodeSnippetHighlighter.cpp

diff --git a/clang/include/clang/Frontend/CodeSnippetHighlighter.h 
b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
new file mode 100644
index 000..776954b59e2e1a8
--- /dev/null
+++ b/clang/include/clang/Frontend/CodeSnippetHighlighter.h
@@ -0,0 +1,46 @@
+//===--- CodeSnippetHighlighter.h - Code snippet highlighting ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+#define LLVM_CLANG_FRONTEND_CODESNIPPETHIGHLIGHTER_H
+
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/raw_ostream.h"
+#include 
+
+namespace clang {
+
+struct StyleRange {
+  unsigned Start;
+  unsigned End;
+  const enum llvm::raw_ostream::Colors c;
+};
+
+class CodeSnippetHighlighter final {
+public:
+  CodeSnippetHighlighter() = default;
+
+  /// Produce StyleRanges for the given line.
+  /// The returned vector contains non-overlapping style ranges. They are 
sorted
+  /// from beginning of the line to the end.
+  std::vector highlightLine(llvm::StringRef SourceLine,
+const LangOptions );
+
+private:
+  bool Initialized = false;
+  /// Fills Keywords and Literals.
+  void ensureTokenData();
+
+  llvm::SmallSet Keywords;
+  llvm::SmallSet Literals;
+};
+
+} // namespace clang
+
+#endif
diff --git a/clang/include/clang/Frontend/TextDiagnostic.h 
b/clang/include/clang/Frontend/TextDiagnostic.h
index 7eb0ab0cdc9bca8..59fd4d4f9408d48 100644
--- a/clang/include/clang/Frontend/TextDiagnostic.h
+++ b/clang/include/clang/Frontend/TextDiagnostic.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 #define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H
 
+#include "clang/Frontend/CodeSnippetHighlighter.h"
 #include "clang/Frontend/DiagnosticRenderer.h"
 
 namespace clang {
@@ -33,6 +34,7 @@ namespace clang {
 /// printing coming out of libclang.
 class TextDiagnostic : public DiagnosticRenderer {
   raw_ostream 
+  CodeSnippetHighlighter SnippetHighlighter;
 
 public:
   TextDiagnostic(raw_ostream ,
diff --git a/clang/lib/Frontend/CMakeLists.txt 
b/clang/lib/Frontend/CMakeLists.txt
index 1e5f0a859dfd568..f3547f771593093 100644
--- a/clang/lib/Frontend/CMakeLists.txt
+++ b/clang/lib/Frontend/CMakeLists.txt
@@ -42,6 +42,7 @@ add_clang_library(clangFrontend
   TextDiagnosticPrinter.cpp
   VerifyDiagnosticConsumer.cpp
   InterfaceStubFunctionsConsumer.cpp
+  CodeSnippetHighlighter.cpp
 
   DEPENDS
   ClangDriverOptions
diff --git a/clang/lib/Frontend/CodeSnippetHighlighter.cpp 
b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
new file mode 100644
index 000..829a533ad2692e5
--- /dev/null
+++ b/clang/lib/Frontend/CodeSnippetHighlighter.cpp
@@ -0,0 +1,120 @@
+
+#include "clang/Frontend/CodeSnippetHighlighter.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+void CodeSnippetHighlighter::ensureTokenData() {
+  if (Initialized)
+return;
+
+  // List of keywords, literals and types we want to highlight.
+  // These are best-effort, as is everything we do wrt. highlighting.
+  Keywords.insert("_Static_assert");
+  Keywords.insert("auto");
+  Keywords.insert("concept");
+  Keywords.insert("const");
+  Keywords.insert("consteval");
+  Keywords.insert("constexpr");
+  Keywords.insert("delete");
+  Keywords.insert("do");
+  Keywords.insert("else");
+  Keywords.insert("final");
+  Keywords.insert("for");
+  Keywords.insert("if");
+  Keywords.insert("mutable");
+  Keywords.insert("namespace");
+  Keywords.insert("new");
+  

<    4   5   6   7   8   9   10   11   >