[clang] [clang][Interp] Fix IntAP(s) to IntAP(s) casts (PR #69915)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/69915 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Fix IntAP(s) to IntAP(s) casts (PR #69915)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/69915 >From b82acd12f1217468d6fc53ab2b2f5856802b9b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Mon, 23 Oct 2023 12:46:25 +0200 Subject: [PATCH] [clang][Interp] Fix IntAP(s) to IntAP(s) casts --- clang/lib/AST/Interp/ByteCodeExprGen.cpp | 7 ++- clang/test/AST/Interp/intap.cpp | 11 +++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 485893d58f487ae..a2cf682b2532bde 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -200,16 +200,13 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { if (!this->visit(SubExpr)) return false; -if (FromT == ToT) { - assert(ToT != PT_IntAP && ToT != PT_IntAPS); - 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); +if (FromT == ToT) + return true; return this->emitCast(*FromT, *ToT, CE); } diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp index 02a860eb0986c15..c7df32b70d20a45 100644 --- a/clang/test/AST/Interp/intap.cpp +++ b/clang/test/AST/Interp/intap.cpp @@ -30,6 +30,17 @@ static_assert(UBitIntZero1 == 0, ""); constexpr unsigned _BitInt(2) BI1 = 3u; static_assert(BI1 == 3, ""); +namespace APCast { + constexpr _BitInt(10) A = 1; + constexpr _BitInt(11) B = A; + static_assert(B == 1, ""); + constexpr _BitInt(16) B2 = A; + static_assert(B2 == 1, ""); + constexpr _BitInt(32) B3 = A; + static_assert(B3 == 1, ""); + constexpr unsigned _BitInt(32) B4 = A; + static_assert(B4 == 1, ""); +} #ifdef __SIZEOF_INT128__ namespace i128 { ___ 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)
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?= , 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?= , 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)
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: @@ -1894,6 +1894,8 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, case attr::ArmMveStrictPolymorphism: OS << "__clang_arm_mve_strict_polymorphism"; break; + case attr::RequiresCapability: +OS << "requires_capability(blah)"; tbaederr wrote: I was a little confused why none of the other attributes in that function seem to print any arguments. Is this really such a special case or am I just doing something wrong to end up here at all? 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] Fix IntAP(s) to IntAP(s) casts (PR #69915)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/69915 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use new interpreter in EvaluateAsConstantExpr if requested (PR #70763)
tbaederr wrote: > I don't have a good idea how a release note could be phrased here, but if you > could try one, it would be appreciated and I think it is worth doing. You mean about this change specifically? > Side note: it would be really cool if at the end of the release cycle, you > did a section in the release-notes with a 'status' of the new interpreter. > Basically a 'things that don't work', or a 'percent of tests we have that > work', etc? I could force the new interpreter and run the test suite, but that would only be a very rough estimate. https://github.com/llvm/llvm-project/pull/70763 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Fix creating APSInt from IntegralAP (PR #71410)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/71410 The boolean argument in the APSInt constructor is IsUnsigned, not IsSigned. This marks the 10th time I've run into this issue. Happy anniversary. >From 81836da057f2703f49f30d31955306577a0e1170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Mon, 6 Nov 2023 16:59:33 +0100 Subject: [PATCH] [clang][Interp] Fix creating APSInt from IntegralAP The boolean argument in the APSInt constructor is IsUnsigned, not IsSigned. This marks the 10th time I've run into this issue. Happy anniversary. --- clang/lib/AST/Interp/IntegralAP.h | 4 ++-- clang/test/AST/Interp/intap.cpp | 4 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index 1f535d420bcd54b..134b602d1bb61ca 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -119,8 +119,8 @@ template class IntegralAP final { constexpr unsigned bitWidth() const { return V.getBitWidth(); } - APSInt toAPSInt(unsigned Bits = 0) const { return APSInt(V, Signed); } - APValue toAPValue() const { return APValue(APSInt(V, Signed)); } + APSInt toAPSInt(unsigned Bits = 0) const { return APSInt(V, !Signed); } + APValue toAPValue() const {return APValue(APSInt(V, !Signed)); } bool isZero() const { return V.isZero(); } bool isPositive() const { return V.isNonNegative(); } diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp index 45961e6fc74b7a7..5f08b76a565c25a 100644 --- a/clang/test/AST/Interp/intap.cpp +++ b/clang/test/AST/Interp/intap.cpp @@ -56,6 +56,10 @@ namespace i128 { static const __uint128_t UINT128_MAX =__uint128_t(__int128_t(-1L)); static_assert(UINT128_MAX == -1, ""); + static_assert(UINT128_MAX == 1, ""); // expected-error {{static assertion failed}} \ + // expected-note {{'340282366920938463463374607431768211455 == 1'}} \ + // ref-error {{static assertion failed}} \ + // ref-note {{'340282366920938463463374607431768211455 == 1'}} static const __int128_t INT128_MAX = UINT128_MAX >> (__int128_t)1; static_assert(INT128_MAX != 0, ""); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Fix creating APSInt from IntegralAP (PR #71410)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/71410 >From 8984ebb39a4bb2ba475440b0ed41c534f586a4c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Mon, 6 Nov 2023 16:59:33 +0100 Subject: [PATCH] [clang][Interp] Fix creating APSInt from IntegralAP The boolean argument in the APSInt constructor is IsUnsigned, not IsSigned. This marks the 10th time I've run into this issue. Happy anniversary. --- clang/lib/AST/Interp/IntegralAP.h | 4 ++-- clang/test/AST/Interp/intap.cpp | 4 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index 1f535d420bcd54b..f88e7cd193477f6 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -119,8 +119,8 @@ template class IntegralAP final { constexpr unsigned bitWidth() const { return V.getBitWidth(); } - APSInt toAPSInt(unsigned Bits = 0) const { return APSInt(V, Signed); } - APValue toAPValue() const { return APValue(APSInt(V, Signed)); } + APSInt toAPSInt(unsigned Bits = 0) const { return APSInt(V, !Signed); } + APValue toAPValue() const { return APValue(APSInt(V, !Signed)); } bool isZero() const { return V.isZero(); } bool isPositive() const { return V.isNonNegative(); } diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp index 45961e6fc74b7a7..5f08b76a565c25a 100644 --- a/clang/test/AST/Interp/intap.cpp +++ b/clang/test/AST/Interp/intap.cpp @@ -56,6 +56,10 @@ namespace i128 { static const __uint128_t UINT128_MAX =__uint128_t(__int128_t(-1L)); static_assert(UINT128_MAX == -1, ""); + static_assert(UINT128_MAX == 1, ""); // expected-error {{static assertion failed}} \ + // expected-note {{'340282366920938463463374607431768211455 == 1'}} \ + // ref-error {{static assertion failed}} \ + // ref-note {{'340282366920938463463374607431768211455 == 1'}} static const __int128_t INT128_MAX = UINT128_MAX >> (__int128_t)1; static_assert(INT128_MAX != 0, ""); ___ 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)
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?= , 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: @@ -0,0 +1,187 @@ +//===-- CodeSnippetHighlighter.cpp - 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 +// +//===--===// + +#include "clang/Frontend/CodeSnippetHighlighter.h" +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Lex/Lexer.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Lex/PreprocessorOptions.h" +#include "llvm/Support/raw_ostream.h" +#include + +using namespace clang; + +static constexpr raw_ostream::Colors CommentColor = raw_ostream::GREEN; +static constexpr raw_ostream::Colors LiteralColor = raw_ostream::CYAN; +static constexpr raw_ostream::Colors KeywordColor = raw_ostream::BLUE; + +llvm::SmallVector CodeSnippetHighlighter::highlightLine( +unsigned LineNumber, const Preprocessor *PP, const LangOptions &LangOpts, +FileID FID, const SourceManager &SM, const char *LineStart) { + std::chrono::steady_clock::time_point begin = + std::chrono::steady_clock::now(); + + if (!PP) +return {}; + + // Might cause emission of another diagnostic. + if (PP->getIdentifierTable().getExternalIdentifierLookup()) +return {}; + + size_t NTokens = 0; + // Classify the given token and append it to the given vector. + auto appendStyle = [PP, &LangOpts](llvm::SmallVector &Vec, + const Token &T, unsigned Start, + unsigned Length) -> void { +if (T.is(tok::raw_identifier)) { + StringRef RawIdent = T.getRawIdentifier(); + // Special case true/false/nullptr literals, since they will otherwise be + // treated as keywords. + if (RawIdent == "true" || RawIdent == "false" || RawIdent == "nullptr") { +Vec.push_back(StyleRange{Start, Start + Length, LiteralColor}); + } else { +const IdentifierInfo *II = PP->getIdentifierInfo(RawIdent); +assert(II); +if (II->isKeyword(LangOpts)) + Vec.push_back(StyleRange{Start, Start + Length, KeywordColor}); + } +} else if (tok::isLiteral(T.getKind())) { + Vec.push_back(StyleRange{Start, Start + Length, LiteralColor}); +} else { + assert(T.is(tok::comment)); + Vec.push_back(StyleRange{Start, Start + Length, CommentColor}); +} + }; + + // Figure out where to start lexing from. + auto Buff = SM.getBufferOrNone(FID); + assert(Buff); + Lexer L = Lexer(FID, *Buff, SM, LangOpts); + L.SetKeepWhitespaceMode(true); + + // Seek to the last save point before the start of the line. + if (const char *Save = PP->getSaveFor(LineStart); + Buff->getBufferStart() <= Save && Save < Buff->getBufferEnd()) { +size_t Offset = Save - Buff->getBufferStart(); +assert(Save >= Buff->getBufferStart()); +assert(Save <= Buff->getBufferEnd()); + +L.seek(Offset, /*IsAtStartOfLine=*/true); + } + + llvm::SmallVector LineRanges; + bool Stop = false; + while (!Stop) { +++NTokens; +Token T; +Stop = L.LexFromRawLexer(T); +if (T.is(tok::unknown)) + continue; + +// We are only interested in identifiers, literals and comments. +if (!T.is(tok::raw_identifier) && !T.is(tok::comment) && +!tok::isLiteral(T.getKind())) + continue; + +bool Invalid = false; +unsigned EndLine = SM.getSpellingLineNumber(T.getEndLoc(), &Invalid) - 1; +if (Invalid) + continue; + +if (EndLine < LineNumber) + continue; +unsigned StartLine = +SM.getSpellingLineNumber(T.getLocation(), &Invalid) - 1; +if (Invalid) + continue; +if (StartLine > LineNumber) + break; + +// Must have an intersection at this point +assert(StartLine <= LineNumber && EndLine >= LineNumber); + +unsigned StartCol = +SM.getSpellingColumnNumber(T.getLocation(), &Invalid) - 1; +if (Invalid) + continue; + +// Simple tokens. +if (StartLine == EndLine) { + appendStyle(LineRanges, T, StartCol, T.getLength()); + continue; +} +unsigned NumLines = EndLine - StartLine; +assert(NumLines >= 1); + +// For tokens that span multiple lines (think multiline comments), we +// divide them into multiple StyleRanges. +unsigned EndCol = SM.getSpellingColum
[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)
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?= , 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: @@ -0,0 +1,185 @@ +//===-- CodeSnippetHighlighter.cpp - 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 +// +//===--===// + +#include "clang/Frontend/CodeSnippetHighlighter.h" +#include "clang/Basic/CharInfo.h" +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Lex/Lexer.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Lex/PreprocessorOptions.h" +#include "llvm/Support/raw_ostream.h" +#include + +using namespace clang; + +// Magenta is taken for 'warning'. Red is already 'error' and 'cyan' +// is already taken for 'note'. Green is already used to underline +// source ranges. White and black are bad because of the usual +// terminal backgrounds. Which leaves us only with TWO options. +static constexpr raw_ostream::Colors CommentColor = raw_ostream::YELLOW; +static constexpr raw_ostream::Colors LiteralColor = raw_ostream::GREEN; +static constexpr raw_ostream::Colors KeywordColor = raw_ostream::BLUE; +/// Maximum size of file we still highlight. +static constexpr size_t MaxBufferSize = 1024 * 1024; // 1MB. + +llvm::SmallVector CodeSnippetHighlighter::highlightLine( +unsigned LineNumber, const Preprocessor *PP, const LangOptions &LangOpts, +FileID FID, const SourceManager &SM, const char *LineStart) { + std::chrono::steady_clock::time_point begin = + std::chrono::steady_clock::now(); + + if (!PP) +return {}; + tbaederr wrote: `Preprocessor*` is what's passed to `TextDiagnosticPrinter::BeginSourceFile()`, and there are a couple of places that pass `nullptr`, here an excerpt from `ag`: ``` ../clang/lib/Frontend/FrontendAction.cpp 580:bool FrontendAction::BeginSourceFile(CompilerInstance &CI, 699:CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr); 715:if (!BeginSourceFileAction(CI)) 759:CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr); 763:if (!BeginSourceFileAction(CI)) 815: CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 914: if (!BeginSourceFileAction(CI)) 1207:bool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI) { 1210: auto Ret = WrappedAction->BeginSourceFileAction(CI); 1211: // BeginSourceFileAction may change CurrentInput, e.g. during module builds. `` 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][Interp] Fix stack peek offset for This ptr (PR #70663)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/70663 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C++20] [Modules] Introduce thin BMI (PR #71622)
@@ -270,6 +274,35 @@ namespace clang { }; } +bool clang::MayDefAffectABI(const Decl *D) { + if (auto *FD = dyn_cast(D)) { +if (FD->isInlined() || FD->isConstexpr()) + return true; + +// Non-user-provided functions get emitted as weak definitions with every +// use, no matter whether they've been explicitly instantiated etc. +if (!FD->isUserProvided()) + return true; + +if (FD->isDependentContext()) + return true; + +if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) + return true; + } + + if (auto *VD = dyn_cast(D)) { tbaederr wrote: ```suggestion if (const auto *VD = dyn_cast(D)) { ``` https://github.com/llvm/llvm-project/pull/71622 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C++20] [Modules] Introduce thin BMI (PR #71622)
@@ -270,6 +274,35 @@ namespace clang { }; } +bool clang::MayDefAffectABI(const Decl *D) { + if (auto *FD = dyn_cast(D)) { tbaederr wrote: ```suggestion if (const auto *FD = dyn_cast(D)) { ``` https://github.com/llvm/llvm-project/pull/71622 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Consider bit width in toAPSInt() (PR #71646)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/71646 In `Interp.h`, when a add/sub/mul fails, we call this code and expect to get an `APSInt` back that can handle more than the current bitwidth of the type. >From a5a7c82862990475630a21d6aabb319acc6a80b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 8 Nov 2023 06:08:04 +0100 Subject: [PATCH] [clang][Interp] Consider bit width in toAPSInt() --- clang/lib/AST/Interp/IntegralAP.h | 10 +- clang/test/AST/Interp/intap.cpp | 9 +++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index 6d301bad784af47..a24e283cb2e7cda 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -119,7 +119,15 @@ template class IntegralAP final { constexpr unsigned bitWidth() const { return V.getBitWidth(); } - APSInt toAPSInt(unsigned Bits = 0) const { return APSInt(V, Signed); } + APSInt toAPSInt(unsigned Bits = 0) const { +if (Bits == 0) + Bits = bitWidth(); + +if constexpr (Signed) + return APSInt(V.sext(Bits), !Signed); +else + return APSInt(V.zext(Bits), !Signed); + } APValue toAPValue() const { return APValue(APSInt(V, Signed)); } bool isZero() const { return V.isZero(); } diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp index 45961e6fc74b7a7..898d5795e1ffd5a 100644 --- a/clang/test/AST/Interp/intap.cpp +++ b/clang/test/AST/Interp/intap.cpp @@ -59,11 +59,16 @@ namespace i128 { static const __int128_t INT128_MAX = UINT128_MAX >> (__int128_t)1; static_assert(INT128_MAX != 0, ""); + static_assert(INT128_MAX == 0, ""); // expected-error {{failed}} \ + // expected-note {{evaluates to '170141183460469231731687303715884105727 == 0'}} \ + // ref-error {{failed}} \ + // ref-note {{evaluates to '170141183460469231731687303715884105727 == 0'}} + static const __int128_t INT128_MIN = -INT128_MAX - 1; constexpr __int128 A = INT128_MAX + 1; // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{outside the range}} \ + // expected-note {{value 170141183460469231731687303715884105728 is outside the range}} \ // ref-error {{must be initialized by a constant expression}} \ - // ref-note {{outside the range}} + // ref-note {{value 170141183460469231731687303715884105728 is outside the range}} constexpr int128_t Two = (int128_t)1 << 1ul; static_assert(Two == 2, ""); static_assert(Two, ""); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Consider bit width in IntegralAP::toAPSInt() (PR #71646)
https://github.com/tbaederr edited https://github.com/llvm/llvm-project/pull/71646 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Fix creating APSInt from IntegralAP (PR #71410)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/71410 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement IntegralAP subtraction (PR #71648)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/71648 The tests currently fail because they need one of the other open `IntegralAP` PRs. Will update this once they are pushed. >From 068feee9c34a8fc22675d17e257f166235a8803e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 8 Nov 2023 06:49:41 +0100 Subject: [PATCH] [clang][Interp] Implement IntegralAP subtraction --- clang/lib/AST/Interp/IntegralAP.h | 34 +-- clang/test/AST/Interp/intap.cpp | 15 ++ 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index 6d301bad784af47..9a9a886ede47216 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -183,12 +183,11 @@ template class IntegralAP final { } static bool add(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { -return CheckAddUB(A, B, OpBits, R); +return CheckAddSubUB(A, B, OpBits, R); } static bool sub(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { -/// FIXME: Gotta check if the result fits into OpBits bits. -return CheckSubUB(A, B, R); +return CheckAddSubUB(A, B, OpBits, R); } static bool mul(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { @@ -256,28 +255,23 @@ template class IntegralAP final { } private: - static bool CheckAddUB(const IntegralAP &A, const IntegralAP &B, - unsigned BitWidth, IntegralAP *R) { -if (!A.isSigned()) { - R->V = A.V + B.V; + template class Op> + static bool CheckAddSubUB(const IntegralAP &A, const IntegralAP &B, +unsigned BitWidth, IntegralAP *R) { +if constexpr (!Signed) { + auto UOp = Op(); + R->V = UOp(A.V, B.V); return false; } -const APSInt &LHS = APSInt(A.V, A.isSigned()); -const APSInt &RHS = APSInt(B.V, B.isSigned()); - -APSInt Value(LHS.extend(BitWidth) + RHS.extend(BitWidth), false); +auto SOp = Op(); +const APSInt &LHS = A.toAPSInt(); +const APSInt &RHS = B.toAPSInt(); +APSInt Value(SOp(LHS.extend(BitWidth), RHS.extend(BitWidth)), false); APSInt Result = Value.trunc(LHS.getBitWidth()); -if (Result.extend(BitWidth) != Value) - return true; - R->V = Result; -return false; - } - static bool CheckSubUB(const IntegralAP &A, const IntegralAP &B, - IntegralAP *R) { -R->V = A.V - B.V; -return false; // Success! + +return Result.extend(BitWidth) != Value; } }; diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp index 45961e6fc74b7a7..a6f1fc4e38dfca6 100644 --- a/clang/test/AST/Interp/intap.cpp +++ b/clang/test/AST/Interp/intap.cpp @@ -11,7 +11,12 @@ constexpr _BitInt(2) B = A + 1; constexpr _BitInt(2) C = B + 1; // expected-warning {{from 2 to -2}} \ // ref-warning {{from 2 to -2}} static_assert(C == -2, ""); +static_assert(C - B == A, ""); // expected-error {{not an integral constant expression}} \ + // expected-note {{value -3 is outside the range of representable values}} \ + // ref-error {{not an integral constant expression}} \ + // ref-note {{value -3 is outside the range of representable values}} +static_assert(B - 1 == 0, ""); constexpr MaxBitInt A_ = 0; constexpr MaxBitInt B_ = A_ + 1; @@ -121,6 +126,16 @@ namespace i128 { // 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 Zero = 0; + static_assert((Zero -1) == -1, ""); + constexpr int128_t Five = 5; + static_assert(Five - Zero == Five, ""); + + constexpr int128_t Sub1 = INT128_MIN - 1; // expected-error {{must be initialized by a constant expression}} \ +// expected-note {{-170141183460469231731687303715884105729 is outside the range}} \ +// ref-error {{must be initialized by a constant expression}} \ +// ref-note {{-170141183460469231731687303715884105729 is outside the range}} } namespace AddSubOffset { ___ 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)
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?= , 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 001149c81ddeca2488597ebae3604efeaee1c490 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/21] [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 &LangOpts); + +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 &OS; + CodeSnippetHighlighter SnippetHighlighter; public: TextDiagnostic(raw_ostream &OS, 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("consteva
[clang] [clang] Only build static analyzer sources if requested (PR #71653)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/71653 There used to be a patch similar to this on Phabricator. I asked a long time ago if I can pick it up but the author told me they will work on it, which never happened. IIRC there also was a problem with this simple patch since some other component depends on the static analyzer being built. Let's see what CI says. >From aec458976c007f2666c2a1939bf8e48b1840a3fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 8 Nov 2023 11:43:22 +0100 Subject: [PATCH] [clang] Only build static analyzer sources if requested --- clang/lib/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/lib/CMakeLists.txt b/clang/lib/CMakeLists.txt index 1526d65795f8adf..e897fbb16c60d78 100644 --- a/clang/lib/CMakeLists.txt +++ b/clang/lib/CMakeLists.txt @@ -23,7 +23,9 @@ add_subdirectory(Tooling) add_subdirectory(DirectoryWatcher) add_subdirectory(Index) add_subdirectory(IndexSerialization) -add_subdirectory(StaticAnalyzer) +if(CLANG_ENABLE_STATIC_ANALYZER) + add_subdirectory(StaticAnalyzer) +endif() add_subdirectory(Format) if(CLANG_INCLUDE_TESTS) add_subdirectory(Testing) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_parity (PR #71662)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/71662 None >From a4a04d1ef43a680d9ced9d1cdd7db05cbc567436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 8 Nov 2023 12:28:52 +0100 Subject: [PATCH] [clang][Interp] Implement __builtin_parity --- clang/lib/AST/Interp/InterpBuiltin.cpp | 16 clang/test/AST/Interp/builtin-functions.cpp | 17 - 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index f26d298f5b60045..0536fe44b9dcb03 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -439,6 +439,15 @@ static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC, return true; } +static bool interp__builtin_parity(InterpState &S, 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() % 2); + return true; +} + bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *Call) { InterpFrame *Frame = S.Current; @@ -576,6 +585,13 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, return retInt(S, OpPC, Dummy); break; + case Builtin::BI__builtin_parity: + case Builtin::BI__builtin_parityl: + case Builtin::BI__builtin_parityll: +if (interp__builtin_parity(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 a78a0fbdf11b1d7..14604a2b553f151 100644 --- a/clang/test/AST/Interp/builtin-functions.cpp +++ b/clang/test/AST/Interp/builtin-functions.cpp @@ -274,6 +274,7 @@ namespace SourceLocation { } } +#define BITSIZE(x) (sizeof(x) * 8) namespace popcount { static_assert(__builtin_popcount(~0u) == __CHAR_BIT__ * sizeof(unsigned int), ""); static_assert(__builtin_popcount(0) == 0, ""); @@ -283,7 +284,6 @@ namespace popcount { 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]; @@ -295,3 +295,18 @@ namespace popcount { char popcount9[__builtin_popcountll(0xF0F0LL) == 8 ? 1 : -1]; char popcount10[__builtin_popcountll(~0LL) == BITSIZE(long long) ? 1 : -1]; } + +namespace parity { + /// From test/Sema/constant-builtins-2.c + char parity1[__builtin_parity(0) == 0 ? 1 : -1]; + char parity2[__builtin_parity(0xb821) == 0 ? 1 : -1]; + char parity3[__builtin_parity(0xb822) == 0 ? 1 : -1]; + char parity4[__builtin_parity(0xb823) == 1 ? 1 : -1]; + char parity5[__builtin_parity(0xb824) == 0 ? 1 : -1]; + char parity6[__builtin_parity(0xb825) == 1 ? 1 : -1]; + char parity7[__builtin_parity(0xb826) == 1 ? 1 : -1]; + char parity8[__builtin_parity(~0) == 0 ? 1 : -1]; + char parity9[__builtin_parityl(1L << (BITSIZE(long) - 1)) == 1 ? 1 : -1]; + char parity10[__builtin_parityll(1LL << (BITSIZE(long long) - 1)) == 1 ? 1 : -1]; +} + ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Print static_assert values of arithmetic binary operators (PR #71671)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/71671 These are actually quite useful to print. >From 2b257a11a78db4769af6751dbc9bd2f37a2b4c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 8 Nov 2023 13:32:41 +0100 Subject: [PATCH] [clang] Print static_assert values of arithmetic binary operators These are actually quite useful to print. --- clang/lib/Sema/SemaDeclCXX.cpp | 8 clang/test/SemaCXX/complex-folding.cpp | 27 +- clang/test/SemaCXX/static-assert.cpp | 10 ++ 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 60786a880b9d3fd..b326d87a72c2815 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -17219,10 +17219,10 @@ static bool UsefulToPrintExpr(const Expr *E) { if (const auto *UnaryOp = dyn_cast(E)) return UsefulToPrintExpr(UnaryOp->getSubExpr()); - // Ignore nested binary operators. This could be a FIXME for improvements - // to the diagnostics in the future. - if (isa(E)) -return false; + // Only print nested arithmetic operators. + if (const auto *BO = dyn_cast(E)) +return (BO->isShiftOp() || BO->isAdditiveOp() || BO->isMultiplicativeOp() || +BO->isBitwiseOp()); return true; } diff --git a/clang/test/SemaCXX/complex-folding.cpp b/clang/test/SemaCXX/complex-folding.cpp index 8c56cf0e5d984b0..054f159e9ce0dd2 100644 --- a/clang/test/SemaCXX/complex-folding.cpp +++ b/clang/test/SemaCXX/complex-folding.cpp @@ -3,7 +3,8 @@ // Test the constant folding of builtin complex numbers. static_assert((0.0 + 0.0j) == (0.0 + 0.0j)); -static_assert((0.0 + 0.0j) != (0.0 + 0.0j)); // expected-error {{static assertion}} +static_assert((0.0 + 0.0j) != (0.0 + 0.0j)); // expected-error {{static assertion}} \ + // expected-note {{evaluates to}} static_assert((0.0 + 0.0j) == 0.0); static_assert(0.0 == (0.0 + 0.0j)); @@ -14,21 +15,29 @@ static_assert(0.0 != 1.0j); // Walk around the complex plane stepping between angular differences and // equality. -static_assert((1.0 + 0.0j) == (0.0 + 0.0j)); // expected-error {{static assertion}} +static_assert((1.0 + 0.0j) == (0.0 + 0.0j)); // expected-error {{static assertion}} \ + // expected-note {{evaluates to}} static_assert((1.0 + 0.0j) == (1.0 + 0.0j)); -static_assert((1.0 + 1.0j) == (1.0 + 0.0j)); // expected-error {{static assertion}} +static_assert((1.0 + 1.0j) == (1.0 + 0.0j)); // expected-error {{static assertion}} \ + // expected-note {{evaluates to}} static_assert((1.0 + 1.0j) == (1.0 + 1.0j)); -static_assert((0.0 + 1.0j) == (1.0 + 1.0j)); // expected-error {{static assertion}} +static_assert((0.0 + 1.0j) == (1.0 + 1.0j)); // expected-error {{static assertion}} \ + // expected-note {{evaluates to}} static_assert((0.0 + 1.0j) == (0.0 + 1.0j)); -static_assert((-1.0 + 1.0j) == (0.0 + 1.0j)); // expected-error {{static assertion}} +static_assert((-1.0 + 1.0j) == (0.0 + 1.0j)); // expected-error {{static assertion}} \ + // expected-note {{evaluates to}} static_assert((-1.0 + 1.0j) == (-1.0 + 1.0j)); -static_assert((-1.0 + 0.0j) == (-1.0 + 1.0j)); // expected-error {{static assertion}} +static_assert((-1.0 + 0.0j) == (-1.0 + 1.0j)); // expected-error {{static assertion}} \ + // expected-note {{evaluates to}} static_assert((-1.0 + 0.0j) == (-1.0 + 0.0j)); -static_assert((-1.0 - 1.0j) == (-1.0 + 0.0j)); // expected-error {{static assertion}} +static_assert((-1.0 - 1.0j) == (-1.0 + 0.0j)); // expected-error {{static assertion}} \ + // expected-note {{evaluates to}} static_assert((-1.0 - 1.0j) == (-1.0 - 1.0j)); -static_assert((0.0 - 1.0j) == (-1.0 - 1.0j)); // expected-error {{static assertion}} +static_assert((0.0 - 1.0j) == (-1.0 - 1.0j)); // expected-error {{static assertion}} \ + // expected-note {{evaluates to}} static_assert((0.0 - 1.0j) == (0.0 - 1.0j)); -static_assert((1.0 - 1.0j) == (0.0 - 1.0j)); // expected-error {{static assertion}} +static_assert((1.0 - 1.0j) == (0.0 - 1.0j)); // expected-error {{static assertion}} \ + // expected-note {{evaluates to}} static_assert((1.0 - 1.0j) == (1.0 - 1.0j)); // Test basic mathematical folding of both complex and real operands. diff --git a/clang/test/SemaCXX/static-assert.cpp b/clang/test/SemaCXX/static-assert.cpp index 4200d821339edeb..6e1701602ae30cf 100644 --- a/clang/test/SemaCXX/static-assert.cpp +++ b/clang/test/SemaCXX/static-assert.cpp @@ -351,4 +351,14 @@ namespace Diagnostics { "" ); + static_asser
[clang] [clang][Interp] Implement __builtin_bitreverse (PR #71687)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/71687 Since the return value of this function is slightly more involved than the void/bool/int/size_t return values we've seen so far, also refactor this. >From 140555c8af75fcf117d10d7877f4cd248b9f7480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 8 Nov 2023 15:51:44 +0100 Subject: [PATCH] [clang][Interp] Implement __builtin_bitreverse Since the return value of this function is slightly more involved than the void/bool/int/size_t return values we've seen so far, also refactor this. --- clang/lib/AST/Interp/InterpBuiltin.cpp | 199 +--- clang/test/AST/Interp/builtin-functions.cpp | 7 + 2 files changed, 143 insertions(+), 63 deletions(-) diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index f26d298f5b60045..b5a9af7e334624e 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -59,13 +59,54 @@ static void pushInt(InterpState &S, int32_t Val) { llvm_unreachable("Int isn't 16 or 32 bit?"); } -static bool retInt(InterpState &S, CodePtr OpPC, APValue &Result) { - PrimType IntType = getIntPrimType(S); - if (IntType == PT_Sint32) -return Ret(S, OpPC, Result); - else if (IntType == PT_Sint16) -return Ret(S, OpPC, Result); - llvm_unreachable("Int isn't 16 or 32 bit?"); +static void pushAPSInt(InterpState &S, const APSInt &Val) { + bool Signed = Val.isSigned(); + + if (Signed) { +switch (Val.getBitWidth()) { +case 64: + S.Stk.push>( + Integral<64, true>::from(Val.getSExtValue())); + break; +case 32: + S.Stk.push>( + Integral<32, true>::from(Val.getSExtValue())); + break; +case 16: + S.Stk.push>( + Integral<16, true>::from(Val.getSExtValue())); + break; +case 8: + S.Stk.push>( + Integral<8, true>::from(Val.getSExtValue())); + break; +default: + llvm_unreachable("Invalid integer bitwidth"); +} +return; + } + + // Unsigned. + switch (Val.getBitWidth()) { + case 64: +S.Stk.push>( +Integral<64, false>::from(Val.getZExtValue())); +break; + case 32: +S.Stk.push>( +Integral<32, false>::from(Val.getZExtValue())); +break; + case 16: +S.Stk.push>( +Integral<16, false>::from(Val.getZExtValue())); +break; + case 8: +S.Stk.push>( +Integral<8, false>::from(Val.getZExtValue())); +break; + default: +llvm_unreachable("Invalid integer bitwidth"); + } } static void pushSizeT(InterpState &S, uint64_t Val) { @@ -87,20 +128,29 @@ static void pushSizeT(InterpState &S, uint64_t Val) { } } -static bool retSizeT(InterpState &S, CodePtr OpPC, APValue &Result) { - const TargetInfo &TI = S.getCtx().getTargetInfo(); - unsigned SizeTWidth = TI.getTypeWidth(TI.getSizeType()); - - switch (SizeTWidth) { - case 64: -return Ret(S, OpPC, Result); - case 32: -return Ret(S, OpPC, Result); - case 16: -return Ret(S, OpPC, Result); +static bool retPrimValue(InterpState &S, CodePtr OpPC, APValue &Result, + std::optional &T) { + if (!T) +return RetVoid(S, OpPC, Result); + +#define RET_CASE(X) \ + case X: \ +return Ret(S, OpPC, Result); + switch (*T) { +RET_CASE(PT_Float); +RET_CASE(PT_Bool); +RET_CASE(PT_Sint8); +RET_CASE(PT_Uint8); +RET_CASE(PT_Sint16); +RET_CASE(PT_Uint16); +RET_CASE(PT_Sint32); +RET_CASE(PT_Uint32); +RET_CASE(PT_Sint64); +RET_CASE(PT_Uint64); + default: +llvm_unreachable("Unsupported return type for builtin function"); } - - llvm_unreachable("size_t isn't 64 or 32 bit?"); +#undef RET_CASE } static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, @@ -439,40 +489,55 @@ static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC, return true; } +static bool interp__builtin_bitreverse(InterpState &S, 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); + pushAPSInt(S, APSInt(Val.reverseBits(), /*IsUnsigend=*/true)); + return true; +} + bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *Call) { InterpFrame *Frame = S.Current; APValue Dummy; + QualType ReturnType = Call->getCallReturnType(S.getCtx()); + std::optional ReturnT = S.getContext().classify(ReturnType); + // If classify failed, we assume void. + assert(ReturnT || ReturnType->isVoidType()); + switch (F->getBuiltinID()) { case Builtin::BI__builtin_is_co
[clang] [clang][Interp] Consider bit width in IntegralAP::toAPSInt() (PR #71646)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/71646 >From 8761ed0d3f0630dd53ed7ff8b6ce30c19dbd9e5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 8 Nov 2023 06:08:04 +0100 Subject: [PATCH] [clang][Interp] Consider bit width in toAPSInt() --- clang/lib/AST/Interp/IntegralAP.h | 12 ++-- clang/test/AST/Interp/intap.cpp | 9 +++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index b674082d9ea5812..88de1f1392e6813 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -119,8 +119,16 @@ template class IntegralAP final { constexpr unsigned bitWidth() const { return V.getBitWidth(); } - APSInt toAPSInt(unsigned Bits = 0) const { return APSInt(V, !Signed); } - APValue toAPValue() const { return APValue(APSInt(V, !Signed)); } + APSInt toAPSInt(unsigned Bits = 0) const { +if (Bits == 0) + Bits = bitWidth(); + +if constexpr (Signed) + return APSInt(V.sext(Bits), !Signed); +else + return APSInt(V.zext(Bits), !Signed); + } + APValue toAPValue() const { return APValue(toAPSInt()); } bool isZero() const { return V.isZero(); } bool isPositive() const { return V.isNonNegative(); } diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp index 5f08b76a565c25a..34c8d0565082994 100644 --- a/clang/test/AST/Interp/intap.cpp +++ b/clang/test/AST/Interp/intap.cpp @@ -63,11 +63,16 @@ namespace i128 { static const __int128_t INT128_MAX = UINT128_MAX >> (__int128_t)1; static_assert(INT128_MAX != 0, ""); + static_assert(INT128_MAX == 0, ""); // expected-error {{failed}} \ + // expected-note {{evaluates to '170141183460469231731687303715884105727 == 0'}} \ + // ref-error {{failed}} \ + // ref-note {{evaluates to '170141183460469231731687303715884105727 == 0'}} + static const __int128_t INT128_MIN = -INT128_MAX - 1; constexpr __int128 A = INT128_MAX + 1; // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{outside the range}} \ + // expected-note {{value 170141183460469231731687303715884105728 is outside the range}} \ // ref-error {{must be initialized by a constant expression}} \ - // ref-note {{outside the range}} + // ref-note {{value 170141183460469231731687303715884105728 is outside the range}} constexpr int128_t Two = (int128_t)1 << 1ul; static_assert(Two == 2, ""); static_assert(Two, ""); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement IntegralAP subtraction (PR #71648)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/71648 >From fa03e5b0141c4f106811b3738d4895bfcbe358c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 8 Nov 2023 06:49:41 +0100 Subject: [PATCH] [clang][Interp] Implement IntegralAP subtraction --- clang/lib/AST/Interp/IntegralAP.h | 33 --- clang/test/AST/Interp/intap.cpp | 15 ++ 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index b674082d9ea5812..2112f6f46f78ef9 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -183,12 +183,11 @@ template class IntegralAP final { } static bool add(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { -return CheckAddUB(A, B, OpBits, R); +return CheckAddSubUB(A, B, OpBits, R); } static bool sub(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { -/// FIXME: Gotta check if the result fits into OpBits bits. -return CheckSubUB(A, B, R); +return CheckAddSubUB(A, B, OpBits, R); } static bool mul(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { @@ -256,28 +255,22 @@ template class IntegralAP final { } private: - static bool CheckAddUB(const IntegralAP &A, const IntegralAP &B, - unsigned BitWidth, IntegralAP *R) { -if (!A.isSigned()) { - R->V = A.V + B.V; + template class Op> + static bool CheckAddSubUB(const IntegralAP &A, const IntegralAP &B, +unsigned BitWidth, IntegralAP *R) { +if constexpr (!Signed) { + R->V = Op{}(A.V, B.V); return false; } -const APSInt &LHS = APSInt(A.V, A.isSigned()); -const APSInt &RHS = APSInt(B.V, B.isSigned()); - -APSInt Value(LHS.extend(BitWidth) + RHS.extend(BitWidth), false); +const APSInt &LHS = A.toAPSInt(); +const APSInt &RHS = B.toAPSInt(); +APSInt Value(Op{}(LHS.extend(BitWidth), RHS.extend(BitWidth)), + /*IsUnsigned=*/false); APSInt Result = Value.trunc(LHS.getBitWidth()); -if (Result.extend(BitWidth) != Value) - return true; - R->V = Result; -return false; - } - static bool CheckSubUB(const IntegralAP &A, const IntegralAP &B, - IntegralAP *R) { -R->V = A.V - B.V; -return false; // Success! + +return Result.extend(BitWidth) != Value; } }; diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp index 5f08b76a565c25a..ce5b698a1fe664d 100644 --- a/clang/test/AST/Interp/intap.cpp +++ b/clang/test/AST/Interp/intap.cpp @@ -11,7 +11,12 @@ constexpr _BitInt(2) B = A + 1; constexpr _BitInt(2) C = B + 1; // expected-warning {{from 2 to -2}} \ // ref-warning {{from 2 to -2}} static_assert(C == -2, ""); +static_assert(C - B == A, ""); // expected-error {{not an integral constant expression}} \ + // expected-note {{value -3 is outside the range of representable values}} \ + // ref-error {{not an integral constant expression}} \ + // ref-note {{value -3 is outside the range of representable values}} +static_assert(B - 1 == 0, ""); constexpr MaxBitInt A_ = 0; constexpr MaxBitInt B_ = A_ + 1; @@ -125,6 +130,16 @@ namespace i128 { // 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 Zero = 0; + static_assert((Zero -1) == -1, ""); + constexpr int128_t Five = 5; + static_assert(Five - Zero == Five, ""); + + constexpr int128_t Sub1 = INT128_MIN - 1; // expected-error {{must be initialized by a constant expression}} \ +// expected-note {{-170141183460469231731687303715884105729 is outside the range}} \ +// ref-error {{must be initialized by a constant expression}} \ +// ref-note {{-170141183460469231731687303715884105729 is outside the range}} } namespace AddSubOffset { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement IntegralAP subtraction (PR #71648)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/71648 >From 2c67326eedeea4ddfc3774600370abe1d8d99dd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 8 Nov 2023 06:49:41 +0100 Subject: [PATCH] [clang][Interp] Implement IntegralAP subtraction --- clang/lib/AST/Interp/IntegralAP.h | 32 --- clang/test/AST/Interp/intap.cpp | 15 +++ 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index b674082d9ea5812..9f52d3f15d6c874 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -183,12 +183,11 @@ template class IntegralAP final { } static bool add(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { -return CheckAddUB(A, B, OpBits, R); +return CheckAddSubUB(A, B, OpBits, R); } static bool sub(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { -/// FIXME: Gotta check if the result fits into OpBits bits. -return CheckSubUB(A, B, R); +return CheckAddSubUB(A, B, OpBits, R); } static bool mul(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { @@ -256,28 +255,21 @@ template class IntegralAP final { } private: - static bool CheckAddUB(const IntegralAP &A, const IntegralAP &B, - unsigned BitWidth, IntegralAP *R) { -if (!A.isSigned()) { - R->V = A.V + B.V; + template class Op> + static bool CheckAddSubUB(const IntegralAP &A, const IntegralAP &B, +unsigned BitWidth, IntegralAP *R) { +if constexpr (!Signed) { + R->V = Op{}(A.V, B.V); return false; } -const APSInt &LHS = APSInt(A.V, A.isSigned()); -const APSInt &RHS = APSInt(B.V, B.isSigned()); - -APSInt Value(LHS.extend(BitWidth) + RHS.extend(BitWidth), false); +const APSInt &LHS = A.toAPSInt(); +const APSInt &RHS = B.toAPSInt(); +APSInt Value = Op{}(LHS.extend(BitWidth), RHS.extend(BitWidth)); APSInt Result = Value.trunc(LHS.getBitWidth()); -if (Result.extend(BitWidth) != Value) - return true; - R->V = Result; -return false; - } - static bool CheckSubUB(const IntegralAP &A, const IntegralAP &B, - IntegralAP *R) { -R->V = A.V - B.V; -return false; // Success! + +return Result.extend(BitWidth) != Value; } }; diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp index 5f08b76a565c25a..ce5b698a1fe664d 100644 --- a/clang/test/AST/Interp/intap.cpp +++ b/clang/test/AST/Interp/intap.cpp @@ -11,7 +11,12 @@ constexpr _BitInt(2) B = A + 1; constexpr _BitInt(2) C = B + 1; // expected-warning {{from 2 to -2}} \ // ref-warning {{from 2 to -2}} static_assert(C == -2, ""); +static_assert(C - B == A, ""); // expected-error {{not an integral constant expression}} \ + // expected-note {{value -3 is outside the range of representable values}} \ + // ref-error {{not an integral constant expression}} \ + // ref-note {{value -3 is outside the range of representable values}} +static_assert(B - 1 == 0, ""); constexpr MaxBitInt A_ = 0; constexpr MaxBitInt B_ = A_ + 1; @@ -125,6 +130,16 @@ namespace i128 { // 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 Zero = 0; + static_assert((Zero -1) == -1, ""); + constexpr int128_t Five = 5; + static_assert(Five - Zero == Five, ""); + + constexpr int128_t Sub1 = INT128_MIN - 1; // expected-error {{must be initialized by a constant expression}} \ +// expected-note {{-170141183460469231731687303715884105729 is outside the range}} \ +// ref-error {{must be initialized by a constant expression}} \ +// ref-note {{-170141183460469231731687303715884105729 is outside the range}} } namespace AddSubOffset { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)
Timm =?utf-8?q?B=C3=A4der?= Message-ID: In-Reply-To: tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/70772 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[lld] [compiler-rt] [libunwind] [lldb] [libc] [libcxx] [flang] [clang-tools-extra] [llvm] [clang] Test branch (PR #70505)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/70505 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Consider bit width in IntegralAP::toAPSInt() (PR #71646)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/71646 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement inc/dec for IntegralAP (PR #69597)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/69597 >From be120871fa8486ce9dd6cabb0a0b27d8371896b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 18 Oct 2023 15:36:13 +0200 Subject: [PATCH] [clang][Interp] Implement inc/dec for IntegralAP --- clang/lib/AST/Interp/IntegralAP.h | 12 ++--- clang/test/AST/Interp/intap.cpp | 81 --- 2 files changed, 68 insertions(+), 25 deletions(-) diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index 88de1f1392e6813..82da79a55b05312 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -177,17 +177,13 @@ template class IntegralAP final { } static bool increment(IntegralAP A, IntegralAP *R) { -// FIXME: Implement. -assert(false); -*R = IntegralAP(A.V - 1); -return false; +IntegralAP One(1, A.bitWidth()); +return add(A, One, A.bitWidth() + 1, R); } static bool decrement(IntegralAP A, IntegralAP *R) { -// FIXME: Implement. -assert(false); -*R = IntegralAP(A.V - 1); -return false; +IntegralAP One(1, A.bitWidth()); +return sub(A, One, A.bitWidth() + 1, R); } static bool add(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp index 34c8d0565082994..73c795732ff1055 100644 --- a/clang/test/AST/Interp/intap.cpp +++ b/clang/test/AST/Interp/intap.cpp @@ -43,9 +43,25 @@ namespace APCast { } #ifdef __SIZEOF_INT128__ +typedef __int128 int128_t; +typedef unsigned __int128 uint128_t; +static const __uint128_t UINT128_MAX =__uint128_t(__int128_t(-1L)); +static_assert(UINT128_MAX == -1, ""); +static_assert(UINT128_MAX == 1, ""); // expected-error {{static assertion failed}} \ + // expected-note {{'340282366920938463463374607431768211455 == 1'}} \ + // ref-error {{static assertion failed}} \ + // ref-note {{'340282366920938463463374607431768211455 == 1'}} + +static const __int128_t INT128_MAX = UINT128_MAX >> (__int128_t)1; +static_assert(INT128_MAX != 0, ""); +static_assert(INT128_MAX == 0, ""); // expected-error {{failed}} \ +// expected-note {{evaluates to '170141183460469231731687303715884105727 == 0'}} \ +// ref-error {{failed}} \ +// ref-note {{evaluates to '170141183460469231731687303715884105727 == 0'}} +static const __int128_t INT128_MIN = -INT128_MAX - 1; + namespace i128 { - typedef __int128 int128_t; - typedef unsigned __int128 uint128_t; + constexpr int128_t I128_1 = 12; static_assert(I128_1 == 12, ""); static_assert(I128_1 != 10, ""); @@ -54,21 +70,6 @@ namespace i128 { // expected-note{{evaluates to}} \ // ref-note{{evaluates to}} - static const __uint128_t UINT128_MAX =__uint128_t(__int128_t(-1L)); - static_assert(UINT128_MAX == -1, ""); - static_assert(UINT128_MAX == 1, ""); // expected-error {{static assertion failed}} \ - // expected-note {{'340282366920938463463374607431768211455 == 1'}} \ - // ref-error {{static assertion failed}} \ - // ref-note {{'340282366920938463463374607431768211455 == 1'}} - - static const __int128_t INT128_MAX = UINT128_MAX >> (__int128_t)1; - static_assert(INT128_MAX != 0, ""); - static_assert(INT128_MAX == 0, ""); // expected-error {{failed}} \ - // expected-note {{evaluates to '170141183460469231731687303715884105727 == 0'}} \ - // ref-error {{failed}} \ - // ref-note {{evaluates to '170141183460469231731687303715884105727 == 0'}} - - static const __int128_t INT128_MIN = -INT128_MAX - 1; constexpr __int128 A = INT128_MAX + 1; // expected-error {{must be initialized by a constant expression}} \ // expected-note {{value 170141183460469231731687303715884105728 is outside the range}} \ // ref-error {{must be initialized by a constant expression}} \ @@ -157,4 +158,50 @@ namespace Bitfields { // expected-warning {{changes value from 100 to 0}} } +namespace IncDec { +#if __cplusplus >= 201402L + constexpr int128_t maxPlus1(bool Pre) { +int128_t a = INT128_MAX; + +if (Pre) + ++a; // ref-note {{value 170141183460469231731687303715884105728 is outside the range}} \ + // expected-note {{value 170141183460469231731687303715884105728 is outside the range}} +else + a++; // ref-note {{value 170141183460469231731687303715884105728 is outside the rang
[clang] [clang][Interp] Implement IntegralAP subtraction (PR #71648)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/71648 >From f1421c190fd480a664bab80281db1e8abb1056a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Wed, 8 Nov 2023 06:49:41 +0100 Subject: [PATCH] [clang][Interp] Implement IntegralAP subtraction --- clang/lib/AST/Interp/IntegralAP.h | 32 --- clang/test/AST/Interp/intap.cpp | 15 +++ 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index 88de1f1392e6813..b8e37878ce2f848 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -191,12 +191,11 @@ template class IntegralAP final { } static bool add(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { -return CheckAddUB(A, B, OpBits, R); +return CheckAddSubUB(A, B, OpBits, R); } static bool sub(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { -/// FIXME: Gotta check if the result fits into OpBits bits. -return CheckSubUB(A, B, R); +return CheckAddSubUB(A, B, OpBits, R); } static bool mul(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { @@ -264,28 +263,21 @@ template class IntegralAP final { } private: - static bool CheckAddUB(const IntegralAP &A, const IntegralAP &B, - unsigned BitWidth, IntegralAP *R) { -if (!A.isSigned()) { - R->V = A.V + B.V; + template class Op> + static bool CheckAddSubUB(const IntegralAP &A, const IntegralAP &B, +unsigned BitWidth, IntegralAP *R) { +if constexpr (!Signed) { + R->V = Op{}(A.V, B.V); return false; } -const APSInt &LHS = APSInt(A.V, A.isSigned()); -const APSInt &RHS = APSInt(B.V, B.isSigned()); - -APSInt Value(LHS.extend(BitWidth) + RHS.extend(BitWidth), false); +const APSInt &LHS = A.toAPSInt(); +const APSInt &RHS = B.toAPSInt(); +APSInt Value = Op{}(LHS.extend(BitWidth), RHS.extend(BitWidth)); APSInt Result = Value.trunc(LHS.getBitWidth()); -if (Result.extend(BitWidth) != Value) - return true; - R->V = Result; -return false; - } - static bool CheckSubUB(const IntegralAP &A, const IntegralAP &B, - IntegralAP *R) { -R->V = A.V - B.V; -return false; // Success! + +return Result.extend(BitWidth) != Value; } }; diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp index 34c8d0565082994..c3cae9a64780d5c 100644 --- a/clang/test/AST/Interp/intap.cpp +++ b/clang/test/AST/Interp/intap.cpp @@ -11,7 +11,12 @@ constexpr _BitInt(2) B = A + 1; constexpr _BitInt(2) C = B + 1; // expected-warning {{from 2 to -2}} \ // ref-warning {{from 2 to -2}} static_assert(C == -2, ""); +static_assert(C - B == A, ""); // expected-error {{not an integral constant expression}} \ + // expected-note {{value -3 is outside the range of representable values}} \ + // ref-error {{not an integral constant expression}} \ + // ref-note {{value -3 is outside the range of representable values}} +static_assert(B - 1 == 0, ""); constexpr MaxBitInt A_ = 0; constexpr MaxBitInt B_ = A_ + 1; @@ -130,6 +135,16 @@ namespace i128 { // 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 Zero = 0; + static_assert((Zero -1) == -1, ""); + constexpr int128_t Five = 5; + static_assert(Five - Zero == Five, ""); + + constexpr int128_t Sub1 = INT128_MIN - 1; // expected-error {{must be initialized by a constant expression}} \ +// expected-note {{-170141183460469231731687303715884105729 is outside the range}} \ +// ref-error {{must be initialized by a constant expression}} \ +// ref-note {{-170141183460469231731687303715884105729 is outside the range}} } namespace AddSubOffset { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement IntegralAP subtraction (PR #71648)
tbaederr wrote: Tests should work now https://github.com/llvm/llvm-project/pull/71648 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement builtin_expect (PR #69713)
Timm =?utf-8?q?B=C3=A4der?= Message-ID: In-Reply-To: tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/69713 ___ 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)
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: @@ -0,0 +1,816 @@ +// RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -fexperimental-new-constant-interpreter %s +// RUN: %clang_cc1 -verify=ref -std=c++2a -fsyntax-only %s +// RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu -fexperimental-new-constant-interpreter %s +// RUN: %clang_cc1 -verify=ref -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu %s +// RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -fexperimental-new-constant-interpreter -triple powerpc64le-unknown-unknown -mabi=ieeelongdouble %s +// RUN: %clang_cc1 -verify=ref -std=c++2a -fsyntax-only -triple powerpc64le-unknown-unknown -mabi=ieeelongdouble %s +// RUN: %clang_cc1 -verify -std=c++2a -fsyntax-only -fexperimental-new-constant-interpreter -triple powerpc64-unknown-unknown -mabi=ieeelongdouble %s +// RUN: %clang_cc1 -verify=ref -std=c++2a -fsyntax-only -triple powerpc64-unknown-unknown -mabi=ieeelongdouble %s + +/// FIXME: This is a version of +/// clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp with the currently +/// supported subset of operations. They should *all* be supported though. + + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define LITTLE_END 1 +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define LITTLE_END 0 +#else +# error "huh?" +#endif + +typedef decltype(nullptr) nullptr_t; + + + +static_assert(sizeof(int) == 4); +static_assert(sizeof(long long) == 8); + +template +constexpr To bit_cast(const From &from) { + static_assert(sizeof(To) == sizeof(From)); + return __builtin_bit_cast(To, from); // ref-note 2{{indeterminate value can only initialize}} \ + // expected-note 2{{indeterminate value can only initialize}} \ + // ref-note {{subexpression not valid}} +} + + +/// Current interpreter does not support this. +/// https://github.com/llvm/llvm-project/issues/63686 +constexpr int FromString = bit_cast("abc"); // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{in call to}} \ + // ref-note {{declared here}} +#if LITTLE_END +static_assert(FromString == 6513249); // ref-error {{is not an integral constant expression}} \ + // ref-note {{initializer of 'FromString' is not a constant expression}} +#else +static_assert(FromString == 1633837824); // ref-error {{is not an integral constant expression}} \ tbaederr wrote: TIL that `constinit` variables aren't usable in constant expressions. But otherwise the test works. https://github.com/llvm/llvm-project/pull/68288 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement bitwise operations for IntegralAP (PR #71807)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/71807 None >From 4d13e7b92c5d6bf08554a2e251ba65b8f433fb87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Thu, 9 Nov 2023 14:29:51 +0100 Subject: [PATCH] [clang][Interp] Implement bitwise operations for IntegralAP --- clang/lib/AST/Interp/IntegralAP.h | 8 +++- clang/test/AST/Interp/intap.cpp | 9 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index 88de1f1392e6813..c8850a4bbb574aa 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -219,21 +219,19 @@ template class IntegralAP final { static bool bitAnd(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { -// FIXME: Implement. -assert(false); +*R = IntegralAP(A.V & B.V); return false; } static bool bitOr(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { -assert(false); +*R = IntegralAP(A.V | B.V); return false; } static bool bitXor(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { -// FIXME: Implement. -assert(false); +*R = IntegralAP(A.V ^ B.V); return false; } diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp index 34c8d0565082994..a8893c8cb4eb9b8 100644 --- a/clang/test/AST/Interp/intap.cpp +++ b/clang/test/AST/Interp/intap.cpp @@ -157,4 +157,13 @@ namespace Bitfields { // expected-warning {{changes value from 100 to 0}} } +namespace BitOps { + constexpr unsigned __int128 UZero = 0; + constexpr unsigned __int128 Max = ~UZero; + static_assert(Max == ~0, ""); + static_assert((Max & 0) == 0, ""); + static_assert((UZero | 0) == 0, ""); + static_assert((Max ^ Max) == 0, ""); +} + #endif ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] add user-level sizeless attribute (PR #71894)
@@ -2400,7 +2402,66 @@ bool Type::isWebAssemblyTableType() const { return false; } -bool Type::isSizelessType() const { return isSizelessBuiltinType(); } +bool Type::isSizelessType() const { + // Check if this type or any of its constituents are sizeless, due to + // being a builtin type or individually having the user attribute. + // As structs can be recursive, we iterate through without repeats. + SmallVector todo = {this}; + llvm::SmallPtrSet done; + + while (todo.size()) { +auto current = todo.pop_back_val(); +if (done.count(current)) + continue; +done.insert(current); + +// If either this is a known sizeless type from being a builtin +// or as marked by the user, this is a sizeless type. +if (current->isSizelessBuiltinType()) + return true; +if (current->hasAttr(attr::SizelessType)) + return true; + +// Otherwise return true if any inner types are sizeless. +switch (current->CanonicalType->getTypeClass()) { +default: + break; +case Record: { + // A struct with sizeless types is itself sizeless. + RecordDecl *Rec = cast(current->CanonicalType)->getDecl(); tbaederr wrote: ```suggestion const auto *Rec = cast(current->CanonicalType)->getDecl(); ``` https://github.com/llvm/llvm-project/pull/71894 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] add user-level sizeless attribute (PR #71894)
@@ -2400,7 +2402,66 @@ bool Type::isWebAssemblyTableType() const { return false; } -bool Type::isSizelessType() const { return isSizelessBuiltinType(); } +bool Type::isSizelessType() const { + // Check if this type or any of its constituents are sizeless, due to + // being a builtin type or individually having the user attribute. + // As structs can be recursive, we iterate through without repeats. + SmallVector todo = {this}; + llvm::SmallPtrSet done; tbaederr wrote: ```suggestion llvm::SmallPtrSet Done; ``` https://github.com/llvm/llvm-project/pull/71894 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] add user-level sizeless attribute (PR #71894)
@@ -2400,7 +2402,66 @@ bool Type::isWebAssemblyTableType() const { return false; } -bool Type::isSizelessType() const { return isSizelessBuiltinType(); } +bool Type::isSizelessType() const { tbaederr wrote: The name of this function sounds like this is a simple getter, but it's quite expensive. Are the other `Type::is*Type()` functions similarly complex or can we rename this? https://github.com/llvm/llvm-project/pull/71894 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] add user-level sizeless attribute (PR #71894)
@@ -2400,7 +2402,66 @@ bool Type::isWebAssemblyTableType() const { return false; } -bool Type::isSizelessType() const { return isSizelessBuiltinType(); } +bool Type::isSizelessType() const { + // Check if this type or any of its constituents are sizeless, due to + // being a builtin type or individually having the user attribute. + // As structs can be recursive, we iterate through without repeats. + SmallVector todo = {this}; + llvm::SmallPtrSet done; + + while (todo.size()) { +auto current = todo.pop_back_val(); +if (done.count(current)) + continue; +done.insert(current); + +// If either this is a known sizeless type from being a builtin +// or as marked by the user, this is a sizeless type. +if (current->isSizelessBuiltinType()) + return true; +if (current->hasAttr(attr::SizelessType)) + return true; + +// Otherwise return true if any inner types are sizeless. +switch (current->CanonicalType->getTypeClass()) { +default: + break; +case Record: { + // A struct with sizeless types is itself sizeless. + RecordDecl *Rec = cast(current->CanonicalType)->getDecl(); + + // skip incomplete structs + if (!Rec->isCompleteDefinition()) +break; + + // a struct marked sizeless explicitly is sizeless + if (Rec->hasAttr()) +return true; + + // A struct is sizeless if it contains a sizeless field + for (auto field : Rec->fields()) +todo.push_back(field->getType().getTypePtr()); + + // A class is sizeless if it contains a sizeless base + if (auto CXXRec = dyn_cast(Rec)) tbaederr wrote: ```suggestion if (const auto *CXXRec = dyn_cast(Rec)) ``` https://github.com/llvm/llvm-project/pull/71894 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] add user-level sizeless attribute (PR #71894)
@@ -2400,7 +2402,66 @@ bool Type::isWebAssemblyTableType() const { return false; } -bool Type::isSizelessType() const { return isSizelessBuiltinType(); } +bool Type::isSizelessType() const { + // Check if this type or any of its constituents are sizeless, due to + // being a builtin type or individually having the user attribute. + // As structs can be recursive, we iterate through without repeats. + SmallVector todo = {this}; tbaederr wrote: ```suggestion SmallVector Todo = {this}; ``` https://github.com/llvm/llvm-project/pull/71894 ___ 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)
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?= , 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: @@ -0,0 +1,187 @@ +//===-- CodeSnippetHighlighter.cpp - 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 +// +//===--===// + +#include "clang/Frontend/CodeSnippetHighlighter.h" +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Lex/Lexer.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Lex/PreprocessorOptions.h" +#include "llvm/Support/raw_ostream.h" +#include + +using namespace clang; + +static constexpr raw_ostream::Colors CommentColor = raw_ostream::GREEN; +static constexpr raw_ostream::Colors LiteralColor = raw_ostream::CYAN; +static constexpr raw_ostream::Colors KeywordColor = raw_ostream::BLUE; + +llvm::SmallVector CodeSnippetHighlighter::highlightLine( +unsigned LineNumber, const Preprocessor *PP, const LangOptions &LangOpts, +FileID FID, const SourceManager &SM, const char *LineStart) { + std::chrono::steady_clock::time_point begin = + std::chrono::steady_clock::now(); + + if (!PP) +return {}; + + // Might cause emission of another diagnostic. + if (PP->getIdentifierTable().getExternalIdentifierLookup()) +return {}; + + size_t NTokens = 0; + // Classify the given token and append it to the given vector. + auto appendStyle = [PP, &LangOpts](llvm::SmallVector &Vec, + const Token &T, unsigned Start, + unsigned Length) -> void { +if (T.is(tok::raw_identifier)) { + StringRef RawIdent = T.getRawIdentifier(); + // Special case true/false/nullptr literals, since they will otherwise be + // treated as keywords. + if (RawIdent == "true" || RawIdent == "false" || RawIdent == "nullptr") { +Vec.push_back(StyleRange{Start, Start + Length, LiteralColor}); + } else { +const IdentifierInfo *II = PP->getIdentifierInfo(RawIdent); +assert(II); +if (II->isKeyword(LangOpts)) + Vec.push_back(StyleRange{Start, Start + Length, KeywordColor}); + } +} else if (tok::isLiteral(T.getKind())) { + Vec.push_back(StyleRange{Start, Start + Length, LiteralColor}); +} else { + assert(T.is(tok::comment)); + Vec.push_back(StyleRange{Start, Start + Length, CommentColor}); +} + }; + + // Figure out where to start lexing from. + auto Buff = SM.getBufferOrNone(FID); + assert(Buff); + Lexer L = Lexer(FID, *Buff, SM, LangOpts); + L.SetKeepWhitespaceMode(true); + + // Seek to the last save point before the start of the line. + if (const char *Save = PP->getSaveFor(LineStart); + Buff->getBufferStart() <= Save && Save < Buff->getBufferEnd()) { +size_t Offset = Save - Buff->getBufferStart(); +assert(Save >= Buff->getBufferStart()); +assert(Save <= Buff->getBufferEnd()); + +L.seek(Offset, /*IsAtStartOfLine=*/true); + } + + llvm::SmallVector LineRanges; + bool Stop = false; + while (!Stop) { +++NTokens; +Token T; +Stop = L.LexFromRawLexer(T); +if (T.is(tok::unknown)) + continue; + +// We are only interested in identifiers, literals and comments. +if (!T.is(tok::raw_identifier) && !T.is(tok::comment) && +!tok::isLiteral(T.getKind())) + continue; + +bool Invalid = false; +unsigned EndLine = SM.getSpellingLineNumber(T.getEndLoc(), &Invalid) - 1; +if (Invalid) + continue; + +if (EndLine < LineNumber) + continue; +unsigned StartLine = +SM.getSpellingLineNumber(T.getLocation(), &Invalid) - 1; +if (Invalid) + continue; +if (StartLine > LineNumber) + break; + +// Must have an intersection at this point +assert(StartLine <= LineNumber && EndLine >= LineNumber); + +unsigned StartCol = +SM.getSpellingColumnNumber(T.getLocation(), &Invalid) - 1; +if (Invalid) + continue; + +// Simple tokens. +if (StartLine == EndLine) { + appendStyle(LineRanges, T, StartCol, T.getLength()); + continue; +} +unsigned NumLines = EndLine - StartLine; +assert(NumLines >= 1); + +// For tokens that span multiple lines (think multiline comments), we +// divide them into multiple StyleRanges. +unsigned EndCol = SM.getSpellingColum
[clang] [clang][Interp] Diagnose reads from non-const global variables (PR #71919)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/71919 This fixes a long-standing FIXME item. Unfortunately it changes the diagnostic output of the tests added in `cxx23.cpp`, but they were wrong before and are wrong after, so no big deal. >From bc71936279a1c669a8fb23c98d880063bd3f6ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Thu, 9 Nov 2023 15:45:05 +0100 Subject: [PATCH] [clang][Interp] Diagnose reads from non-const global variables --- clang/lib/AST/Interp/ByteCodeExprGen.cpp | 2 +- clang/lib/AST/Interp/Interp.cpp | 44 ++-- clang/lib/AST/Interp/Interp.h| 14 clang/lib/AST/Interp/Opcodes.td | 1 + clang/test/AST/Interp/arrays.cpp | 32 + clang/test/AST/Interp/cxx23.cpp | 25 +- clang/test/AST/Interp/literals.cpp | 27 +-- 7 files changed, 122 insertions(+), 23 deletions(-) diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 15a717089660337..eca31efc85272bf 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -2125,7 +2125,7 @@ bool ByteCodeExprGen::visitDecl(const VarDecl *VD) { auto GlobalIndex = P.getGlobal(VD); assert(GlobalIndex); // visitVarDecl() didn't return false. if (VarT) { - if (!this->emitGetGlobal(*VarT, *GlobalIndex, VD)) + if (!this->emitGetGlobalUnchecked(*VarT, *GlobalIndex, VD)) return false; } else { if (!this->emitGetPtrGlobal(*GlobalIndex, VD)) diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index 144b674451e353c..d1d812a591591bf 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -53,6 +53,18 @@ static bool Jf(InterpState &S, CodePtr &PC, int32_t Offset) { return true; } +static void diagnoseNonConstVariable(InterpState &S, CodePtr OpPC, + const ValueDecl *VD) { + const SourceInfo &Loc = S.Current->getSource(OpPC); + S.FFDiag(Loc, + VD->getType()->isIntegralOrEnumerationType() + ? diag::note_constexpr_ltor_non_const_int + : diag::note_constexpr_ltor_non_constexpr, + 1) + << VD; + S.Note(VD->getLocation(), diag::note_declared_at); +} + static bool CheckActive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, AccessKinds AK) { if (Ptr.isActive()) @@ -170,9 +182,7 @@ bool CheckExtern(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { if (!S.checkingPotentialConstantExpression() && S.getLangOpts().CPlusPlus) { const auto *VD = Ptr.getDeclDesc()->asValueDecl(); -const SourceInfo &Loc = S.Current->getSource(OpPC); -S.FFDiag(Loc, diag::note_constexpr_ltor_non_constexpr, 1) << VD; -S.Note(VD->getLocation(), diag::note_declared_at); +diagnoseNonConstVariable(S, OpPC, VD); } return false; } @@ -215,6 +225,24 @@ bool CheckLive(InterpState &S, CodePtr OpPC, const Pointer &Ptr, return true; } +bool CheckConstant(InterpState &S, CodePtr OpPC, const Descriptor *Desc) { + assert(Desc); + if (const auto *D = Desc->asValueDecl()) { +if (const auto *VD = dyn_cast(D); +VD && VD->hasGlobalStorage() && +!(VD->isConstexpr() || VD->getType().isConstQualified())) { + diagnoseNonConstVariable(S, OpPC, VD); + return false; +} + } + + return true; +} + +static bool CheckConstant(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { + return CheckConstant(S, OpPC, Ptr.getDeclDesc()); +} + bool CheckDummy(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { return !Ptr.isZero() && !Ptr.isDummy(); } @@ -303,6 +331,8 @@ bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr, bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { if (!CheckDummy(S, OpPC, Ptr)) return false; + if (!CheckConstant(S, OpPC, Ptr)) +return false; if (!CheckLive(S, OpPC, Ptr, AK_Read)) return false; if (!CheckExtern(S, OpPC, Ptr)) @@ -601,13 +631,7 @@ bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR) { } } else if (const auto *VD = dyn_cast(D)) { if (!VD->getType().isConstQualified()) { - S.FFDiag(E, - VD->getType()->isIntegralOrEnumerationType() - ? diag::note_constexpr_ltor_non_const_int - : diag::note_constexpr_ltor_non_constexpr, - 1) - << VD; - S.Note(VD->getLocation(), diag::note_declared_at) << VD->getSourceRange(); + diagnoseNonConstVariable(S, OpPC, VD); return false; } diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 7dd415d6e460536..5b7bd9916c02b57 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -78,6 +78,9 @@ bool CheckSubobject(InterpState &S, CodePtr OpPC, const Po
[clang] [clang][Interp] Handle SizeOfPackExprs (PR #71929)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/71929 None >From 1fe6815c82c1df26f35edcd64e85d4a2fd584f44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Fri, 10 Nov 2023 13:04:30 +0100 Subject: [PATCH] [clang][Interp] Handle SizeOfPackExprs --- clang/lib/AST/Interp/ByteCodeExprGen.cpp | 5 + clang/lib/AST/Interp/ByteCodeExprGen.h | 1 + clang/test/AST/Interp/functions.cpp | 7 +++ 3 files changed, 13 insertions(+) diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 15a717089660337..c8d3c1243fc1094 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1624,6 +1624,11 @@ bool ByteCodeExprGen::VisitCXXScalarValueInitExpr( return this->visitZeroInitializer(classifyPrim(Ty), Ty, E); } +template +bool ByteCodeExprGen::VisitSizeOfPackExpr(const SizeOfPackExpr *E) { + return this->emitConst(E->getPackLength(), 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 83986d3dd579ed6..ec9b6bb1408453c 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -107,6 +107,7 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, bool VisitSourceLocExpr(const SourceLocExpr *E); bool VisitOffsetOfExpr(const OffsetOfExpr *E); bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E); + bool VisitSizeOfPackExpr(const SizeOfPackExpr *E); protected: bool visitExpr(const Expr *E) override; diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index 4bef9c2f7c0d1fa..ab562e70606b672 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -371,3 +371,10 @@ namespace Variadic { constexpr int (*VFP)(...) = variadic_function2; static_assert(VFP() == 12, ""); } + +namespace Packs { + template + constexpr int foo() { return sizeof...(T); } + static_assert(foo() == 2, ""); + static_assert(foo<>() == 0, ""); +} ___ 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)
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: @@ -1894,6 +1894,8 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, case attr::ArmMveStrictPolymorphism: OS << "__clang_arm_mve_strict_polymorphism"; break; + case attr::RequiresCapability: +OS << "requires_capability(blah)"; tbaederr wrote: >From looking at this some more, it seems like the type doesn't save an actual >`Attr`? 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] Implement __builtin_classify_type (PR #71972)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/71972 This adds some infrastructure for unevaluated builtin calls, but the implementation is almost entirely copied from `ExprConstant.cpp`. I'm open for suggestions on how to share the code. >From 01e541c726de7bd2aca290f51224e2cafcb4494d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Fri, 10 Nov 2023 19:33:21 +0100 Subject: [PATCH] [clang][Interp] Implement __builtin_classify_type --- clang/lib/AST/Interp/ByteCodeEmitter.cpp | 15 +- clang/lib/AST/Interp/ByteCodeExprGen.cpp | 10 +- clang/lib/AST/Interp/Function.cpp| 7 +- clang/lib/AST/Interp/Function.h | 5 +- clang/lib/AST/Interp/Interp.cpp | 3 +- clang/lib/AST/Interp/InterpBuiltin.cpp | 193 +++ clang/test/Sema/builtin-classify-type.c | 1 + clang/test/SemaCXX/builtin-classify-type.cpp | 1 + 8 files changed, 222 insertions(+), 13 deletions(-) diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp b/clang/lib/AST/Interp/ByteCodeEmitter.cpp index c8abb7c17a38ba2..89b7708c0c2a12f 100644 --- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp +++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp @@ -14,6 +14,7 @@ #include "Program.h" #include "clang/AST/ASTLambda.h" #include "clang/AST/DeclCXX.h" +#include "clang/Basic/Builtins.h" #include using namespace clang; @@ -84,10 +85,16 @@ ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) { // Create a handle over the emitted code. Function *Func = P.getFunction(FuncDecl); - if (!Func) -Func = P.createFunction(FuncDecl, ParamOffset, std::move(ParamTypes), -std::move(ParamDescriptors), -std::move(ParamOffsets), HasThisPointer, HasRVO); + if (!Func) { +bool IsUnevaluatedBuiltin = false; +if (unsigned BI = FuncDecl->getBuiltinID()) + IsUnevaluatedBuiltin = Ctx.getASTContext().BuiltinInfo.isUnevaluated(BI); + +Func = +P.createFunction(FuncDecl, ParamOffset, std::move(ParamTypes), + std::move(ParamDescriptors), std::move(ParamOffsets), + HasThisPointer, HasRVO, IsUnevaluatedBuiltin); + } assert(Func); // For not-yet-defined functions, we only create a Function instance and diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 15a717089660337..f1aa1d22315f658 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -2226,10 +2226,12 @@ bool ByteCodeExprGen::VisitBuiltinCallExpr(const CallExpr *E) { if (!Func) return false; - // Put arguments on the stack. - for (const auto *Arg : E->arguments()) { -if (!this->visit(Arg)) - return false; + if (!Func->isUnevaluatedBuiltin()) { +// Put arguments on the stack. +for (const auto *Arg : E->arguments()) { + if (!this->visit(Arg)) +return false; +} } if (!this->emitCallBI(Func, E, E)) diff --git a/clang/lib/AST/Interp/Function.cpp b/clang/lib/AST/Interp/Function.cpp index 357aff7fe6229b9..784e6a2df1d8806 100644 --- a/clang/lib/AST/Interp/Function.cpp +++ b/clang/lib/AST/Interp/Function.cpp @@ -20,11 +20,12 @@ Function::Function(Program &P, const FunctionDecl *F, unsigned ArgSize, llvm::SmallVectorImpl &&ParamTypes, llvm::DenseMap &&Params, llvm::SmallVectorImpl &&ParamOffsets, - bool HasThisPointer, bool HasRVO) + bool HasThisPointer, bool HasRVO, bool UnevaluatedBuiltin) : 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), Variadic(F->isVariadic()) {} + HasRVO(HasRVO), Variadic(F->isVariadic()), + IsUnevaluatedBuiltin(UnevaluatedBuiltin) {} Function::ParamDescriptor Function::getParamDescriptor(unsigned Offset) const { auto It = Params.find(Offset); @@ -50,7 +51,7 @@ bool Function::isVirtual() const { } bool Function::needsRuntimeArgPop(const ASTContext &Ctx) const { - if (!isBuiltin()) + if (!isBuiltin() || isUnevaluatedBuiltin()) return false; return Ctx.BuiltinInfo.hasCustomTypechecking(getBuiltinID()); } diff --git a/clang/lib/AST/Interp/Function.h b/clang/lib/AST/Interp/Function.h index be9b1733635f725..cbd17d90ada3944 100644 --- a/clang/lib/AST/Interp/Function.h +++ b/clang/lib/AST/Interp/Function.h @@ -179,6 +179,8 @@ class Function final { bool isBuiltin() const { return F->getBuiltinID() != 0; } + bool isUnevaluatedBuiltin() const { return IsUnevaluatedBuiltin; } + /// Does this function need its arguments to be classified at runtime /// rather than at bytecode-compile-time? bool needsRuntimeArgPop(const ASTContext &Ctx) const; @@ -195,7 +197,7 @@ class Functi
[clang] [clang] Print static_assert values of arithmetic binary operators (PR #71671)
@@ -17219,10 +17219,10 @@ static bool UsefulToPrintExpr(const Expr *E) { if (const auto *UnaryOp = dyn_cast(E)) return UsefulToPrintExpr(UnaryOp->getSubExpr()); - // Ignore nested binary operators. This could be a FIXME for improvements - // to the diagnostics in the future. - if (isa(E)) -return false; + // Only print nested arithmetic operators. + if (const auto *BO = dyn_cast(E)) +return (BO->isShiftOp() || BO->isAdditiveOp() || BO->isMultiplicativeOp() || +BO->isBitwiseOp()); tbaederr wrote: Those are the ones we don't want to have, because we'd (ideally) have to show multiple comparisons and not just the one https://github.com/llvm/llvm-project/pull/71671 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [clang] Add bitint classification for __builtin_classify_type (PR #72036)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/72036 See #71911 >From 20ec7adfd769b10b74f5104ee308fd9b58b44208 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Sat, 11 Nov 2023 18:44:13 +0100 Subject: [PATCH] [clang] Add bitint classification for __builtin_classify_type See #71911 --- clang/lib/AST/ExprConstant.cpp | 8 +++- clang/test/Sema/builtin-classify-type.c | 5 - clang/test/SemaCXX/builtin-classify-type.cpp | 5 - llvm/cmake/modules/HandleLLVMOptions.cmake | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index e16fec6109e744e..2073679adf790fb 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11486,6 +11486,7 @@ bool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) { /// Values returned by __builtin_classify_type, chosen to match the values /// produced by GCC's builtin. +/// The values can be found in gcc/typeclass.h in the GCC repository. enum class GCCTypeClass { None = -1, Void = 0, @@ -11512,6 +11513,9 @@ enum class GCCTypeClass { // decay to pointer. (Prior to version 6 it was only used in C++ mode). // GCC reserves 15 for strings, but actually uses 5 (pointer) for string // literals. + // Lang = 16, + // OpaqueType = 17, + BitInt = 18 }; /// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way @@ -11644,11 +11648,13 @@ EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts) { case Type::ObjCInterface: case Type::ObjCObjectPointer: case Type::Pipe: - case Type::BitInt: // GCC classifies vectors as None. We follow its lead and classify all // other types that don't fit into the regular classification the same way. return GCCTypeClass::None; + case Type::BitInt: +return GCCTypeClass::BitInt; + case Type::LValueReference: case Type::RValueReference: llvm_unreachable("invalid type for expression"); diff --git a/clang/test/Sema/builtin-classify-type.c b/clang/test/Sema/builtin-classify-type.c index a222ac8af0e32fd..9a4de34e823f231 100644 --- a/clang/test/Sema/builtin-classify-type.c +++ b/clang/test/Sema/builtin-classify-type.c @@ -11,7 +11,8 @@ enum gcc_type_class { function_type_class, method_type_class, record_type_class, union_type_class, array_type_class, string_type_class, - lang_type_class + lang_type_class, opaque_type_class, + bitint_type_class }; void foo(void) { @@ -45,6 +46,7 @@ void foo(void) { vint32_t3 vt5; typedef _BitInt(64) vint64_t3 __attribute__((vector_size(16))); vint64_t3 vt6; + _BitInt(16) bitint; _Atomic int atomic_i; _Atomic double atomic_d; @@ -70,6 +72,7 @@ void foo(void) { int a17[__builtin_classify_type(atomic_d) == real_type_class ? 1 : -1]; int a18[__builtin_classify_type(complex_i) == complex_type_class ? 1 : -1]; int a19[__builtin_classify_type(complex_d) == complex_type_class ? 1 : -1]; + int a20[__builtin_classify_type(bitint) == bitint_type_class ? 1 : -1]; } extern int (^p)(void); diff --git a/clang/test/SemaCXX/builtin-classify-type.cpp b/clang/test/SemaCXX/builtin-classify-type.cpp index ebc81425e401f11..ed5430960001002 100644 --- a/clang/test/SemaCXX/builtin-classify-type.cpp +++ b/clang/test/SemaCXX/builtin-classify-type.cpp @@ -11,7 +11,8 @@ enum gcc_type_class { function_type_class, method_type_class, record_type_class, union_type_class, array_type_class, string_type_class, - lang_type_class + lang_type_class, opaque_type_class, + bitint_type_class }; class cl { @@ -42,6 +43,7 @@ void foo() { _Atomic double atomic_d; _Complex int complex_i; _Complex double complex_d; + _BitInt(32) bitint; int a1[__builtin_classify_type(f()) == void_type_class ? 1 : -1]; int a2[__builtin_classify_type(i) == integer_type_class ? 1 : -1]; @@ -65,5 +67,6 @@ void foo() { int a20[__builtin_classify_type(atomic_d) == real_type_class ? 1 : -1]; int a21[__builtin_classify_type(complex_i) == complex_type_class ? 1 : -1]; int a22[__builtin_classify_type(complex_d) == complex_type_class ? 1 : -1]; + int a23[__builtin_classify_type(bitint) == bitint_type_class ? 1 : -1]; } diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake index 6a3c49edc912ded..087d96550143ee7 100644 --- a/llvm/cmake/modules/HandleLLVMOptions.cmake +++ b/llvm/cmake/modules/HandleLLVMOptions.cmake @@ -1060,7 +1060,7 @@ if (UNIX AND (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9 - append("-fdiagnostics-color" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + append("-fdiagnostics-color=always" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() # lld doesn't print colored diagnostics when invoked from Ninja ___ cfe-
[clang] [clang] Add bitint classification for __builtin_classify_type (PR #72036)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/72036 >From f3cd338335dbbaf89248b6d207379d325166977e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Sat, 11 Nov 2023 18:44:13 +0100 Subject: [PATCH] [clang] Add bitint classification for __builtin_classify_type See #71911 --- clang/lib/AST/ExprConstant.cpp | 8 +++- clang/test/Sema/builtin-classify-type.c | 5 - clang/test/SemaCXX/builtin-classify-type.cpp | 5 - 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index e16fec6109e744e..2073679adf790fb 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11486,6 +11486,7 @@ bool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) { /// Values returned by __builtin_classify_type, chosen to match the values /// produced by GCC's builtin. +/// The values can be found in gcc/typeclass.h in the GCC repository. enum class GCCTypeClass { None = -1, Void = 0, @@ -11512,6 +11513,9 @@ enum class GCCTypeClass { // decay to pointer. (Prior to version 6 it was only used in C++ mode). // GCC reserves 15 for strings, but actually uses 5 (pointer) for string // literals. + // Lang = 16, + // OpaqueType = 17, + BitInt = 18 }; /// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way @@ -11644,11 +11648,13 @@ EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts) { case Type::ObjCInterface: case Type::ObjCObjectPointer: case Type::Pipe: - case Type::BitInt: // GCC classifies vectors as None. We follow its lead and classify all // other types that don't fit into the regular classification the same way. return GCCTypeClass::None; + case Type::BitInt: +return GCCTypeClass::BitInt; + case Type::LValueReference: case Type::RValueReference: llvm_unreachable("invalid type for expression"); diff --git a/clang/test/Sema/builtin-classify-type.c b/clang/test/Sema/builtin-classify-type.c index a222ac8af0e32fd..9a4de34e823f231 100644 --- a/clang/test/Sema/builtin-classify-type.c +++ b/clang/test/Sema/builtin-classify-type.c @@ -11,7 +11,8 @@ enum gcc_type_class { function_type_class, method_type_class, record_type_class, union_type_class, array_type_class, string_type_class, - lang_type_class + lang_type_class, opaque_type_class, + bitint_type_class }; void foo(void) { @@ -45,6 +46,7 @@ void foo(void) { vint32_t3 vt5; typedef _BitInt(64) vint64_t3 __attribute__((vector_size(16))); vint64_t3 vt6; + _BitInt(16) bitint; _Atomic int atomic_i; _Atomic double atomic_d; @@ -70,6 +72,7 @@ void foo(void) { int a17[__builtin_classify_type(atomic_d) == real_type_class ? 1 : -1]; int a18[__builtin_classify_type(complex_i) == complex_type_class ? 1 : -1]; int a19[__builtin_classify_type(complex_d) == complex_type_class ? 1 : -1]; + int a20[__builtin_classify_type(bitint) == bitint_type_class ? 1 : -1]; } extern int (^p)(void); diff --git a/clang/test/SemaCXX/builtin-classify-type.cpp b/clang/test/SemaCXX/builtin-classify-type.cpp index ebc81425e401f11..ed5430960001002 100644 --- a/clang/test/SemaCXX/builtin-classify-type.cpp +++ b/clang/test/SemaCXX/builtin-classify-type.cpp @@ -11,7 +11,8 @@ enum gcc_type_class { function_type_class, method_type_class, record_type_class, union_type_class, array_type_class, string_type_class, - lang_type_class + lang_type_class, opaque_type_class, + bitint_type_class }; class cl { @@ -42,6 +43,7 @@ void foo() { _Atomic double atomic_d; _Complex int complex_i; _Complex double complex_d; + _BitInt(32) bitint; int a1[__builtin_classify_type(f()) == void_type_class ? 1 : -1]; int a2[__builtin_classify_type(i) == integer_type_class ? 1 : -1]; @@ -65,5 +67,6 @@ void foo() { int a20[__builtin_classify_type(atomic_d) == real_type_class ? 1 : -1]; int a21[__builtin_classify_type(complex_i) == complex_type_class ? 1 : -1]; int a22[__builtin_classify_type(complex_d) == complex_type_class ? 1 : -1]; + int a23[__builtin_classify_type(bitint) == bitint_type_class ? 1 : -1]; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add bitint classification for __builtin_classify_type (PR #72036)
@@ -1060,7 +1060,7 @@ if (UNIX AND (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9 - append("-fdiagnostics-color" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + append("-fdiagnostics-color=always" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() tbaederr wrote: Didn't even work :/ https://github.com/llvm/llvm-project/pull/72036 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add bitint classification for __builtin_classify_type (PR #72036)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/72036 >From c7210706c0f45d3f4693e796970c73e3ef6dd48a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Sat, 11 Nov 2023 18:44:13 +0100 Subject: [PATCH] [clang] Add bitint classification for __builtin_classify_type See #71911 --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/AST/ExprConstant.cpp | 8 +++- clang/test/Sema/builtin-classify-type.c | 5 - clang/test/SemaCXX/builtin-classify-type.cpp | 5 - 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7a131cb520aa600..520b4035e001715 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -217,6 +217,8 @@ Non-comprehensive list of changes in this release (e.g., ``uint16x8_t``), this returns the constant number of elements at compile-time. For scalable vectors, e.g., SVE or RISC-V V, the number of elements is not known at compile-time and is determined at runtime. +* ``__builtin_classify_type()`` now classifies ``_BitInt`` values as the return value ``18``, + to match GCC 14's behavior. New Compiler Flags -- diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index e16fec6109e744e..2073679adf790fb 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11486,6 +11486,7 @@ bool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) { /// Values returned by __builtin_classify_type, chosen to match the values /// produced by GCC's builtin. +/// The values can be found in gcc/typeclass.h in the GCC repository. enum class GCCTypeClass { None = -1, Void = 0, @@ -11512,6 +11513,9 @@ enum class GCCTypeClass { // decay to pointer. (Prior to version 6 it was only used in C++ mode). // GCC reserves 15 for strings, but actually uses 5 (pointer) for string // literals. + // Lang = 16, + // OpaqueType = 17, + BitInt = 18 }; /// EvaluateBuiltinClassifyType - Evaluate __builtin_classify_type the same way @@ -11644,11 +11648,13 @@ EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts) { case Type::ObjCInterface: case Type::ObjCObjectPointer: case Type::Pipe: - case Type::BitInt: // GCC classifies vectors as None. We follow its lead and classify all // other types that don't fit into the regular classification the same way. return GCCTypeClass::None; + case Type::BitInt: +return GCCTypeClass::BitInt; + case Type::LValueReference: case Type::RValueReference: llvm_unreachable("invalid type for expression"); diff --git a/clang/test/Sema/builtin-classify-type.c b/clang/test/Sema/builtin-classify-type.c index a222ac8af0e32fd..9a4de34e823f231 100644 --- a/clang/test/Sema/builtin-classify-type.c +++ b/clang/test/Sema/builtin-classify-type.c @@ -11,7 +11,8 @@ enum gcc_type_class { function_type_class, method_type_class, record_type_class, union_type_class, array_type_class, string_type_class, - lang_type_class + lang_type_class, opaque_type_class, + bitint_type_class }; void foo(void) { @@ -45,6 +46,7 @@ void foo(void) { vint32_t3 vt5; typedef _BitInt(64) vint64_t3 __attribute__((vector_size(16))); vint64_t3 vt6; + _BitInt(16) bitint; _Atomic int atomic_i; _Atomic double atomic_d; @@ -70,6 +72,7 @@ void foo(void) { int a17[__builtin_classify_type(atomic_d) == real_type_class ? 1 : -1]; int a18[__builtin_classify_type(complex_i) == complex_type_class ? 1 : -1]; int a19[__builtin_classify_type(complex_d) == complex_type_class ? 1 : -1]; + int a20[__builtin_classify_type(bitint) == bitint_type_class ? 1 : -1]; } extern int (^p)(void); diff --git a/clang/test/SemaCXX/builtin-classify-type.cpp b/clang/test/SemaCXX/builtin-classify-type.cpp index ebc81425e401f11..ed5430960001002 100644 --- a/clang/test/SemaCXX/builtin-classify-type.cpp +++ b/clang/test/SemaCXX/builtin-classify-type.cpp @@ -11,7 +11,8 @@ enum gcc_type_class { function_type_class, method_type_class, record_type_class, union_type_class, array_type_class, string_type_class, - lang_type_class + lang_type_class, opaque_type_class, + bitint_type_class }; class cl { @@ -42,6 +43,7 @@ void foo() { _Atomic double atomic_d; _Complex int complex_i; _Complex double complex_d; + _BitInt(32) bitint; int a1[__builtin_classify_type(f()) == void_type_class ? 1 : -1]; int a2[__builtin_classify_type(i) == integer_type_class ? 1 : -1]; @@ -65,5 +67,6 @@ void foo() { int a20[__builtin_classify_type(atomic_d) == real_type_class ? 1 : -1]; int a21[__builtin_classify_type(complex_i) == complex_type_class ? 1 : -1]; int a22[__builtin_classify_type(complex_d) == complex_type_class ? 1 : -1]; + int a23[__builtin_classify_type(bitint) == bitint_type_class ? 1 : -1]; } ___ cfe-commits m
[clang] [clang][Interp] Handle SizeOfPackExprs (PR #71929)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/71929 ___ 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)
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?= , 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?= , 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 244bd962de82f3a7f65054086546170a88bdac6f 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/22] [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 &LangOpts); + +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 &OS; + CodeSnippetHighlighter SnippetHighlighter; public: TextDiagnostic(raw_ostream &OS, 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"); +
[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)
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?= , 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?= , 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 244bd962de82f3a7f65054086546170a88bdac6f 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/22] [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 &LangOpts); + +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 &OS; + CodeSnippetHighlighter SnippetHighlighter; public: TextDiagnostic(raw_ostream &OS, 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"); +
[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)
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?= , 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?= , 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 244bd962de82f3a7f65054086546170a88bdac6f 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/23] [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 &LangOpts); + +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 &OS; + CodeSnippetHighlighter SnippetHighlighter; public: TextDiagnostic(raw_ostream &OS, 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"); + Keyw
[clang] [clang][Diagnostics] Highlight code snippets (PR #66514)
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?= , 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?= , 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: FYI I think this is ready for proper review now. We could still add some tests of course. It's using a maximum file size now and highlights the entire requested line range in one go. 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][Interp] Fix variables refering to their own address (PR #70587)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/70587 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] IndirectMember initializers (PR #69900)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/69900 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Add an EvaluationResult class (PR #71315)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/71315 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use new interpreter in EvaluateAsConstantExpr if requested (PR #70763)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/70763 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Fix stack peek offset for This ptr (PR #70663)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/70663 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_parity (PR #71662)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/71662 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_bitreverse (PR #71687)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/71687 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)
Timm =?utf-8?q?B=C3=A4der?= Message-ID: In-Reply-To: tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/70772 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Only build static analyzer sources if requested (PR #71653)
@@ -23,7 +23,9 @@ add_subdirectory(Tooling) add_subdirectory(DirectoryWatcher) add_subdirectory(Index) add_subdirectory(IndexSerialization) -add_subdirectory(StaticAnalyzer) +if(CLANG_ENABLE_STATIC_ANALYZER) tbaederr wrote: Well yes, but I'm not introducing the option here, I'm just making it work. https://github.com/llvm/llvm-project/pull/71653 ___ 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)
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?= , 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?= , 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?= , Timm =?utf-8?q?Bäder?= Message-ID: In-Reply-To: @@ -1288,11 +1291,33 @@ void TextDiagnostic::emitSnippet(StringRef SourceLine, // Print the source line one character at a time. bool PrintReversed = false; + bool HighlightingEnabled = DiagOpts->ShowColors; size_t I = 0; while (I < SourceLine.size()) { auto [Str, WasPrintable] = printableTextForNextCharacter(SourceLine, &I, DiagOpts->TabStop); +// Just stop highlighting anything for this line if we found a non-printable +// character. tbaederr wrote: >From some local testing, seems like this just works. 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][Interp] Implement __builtin_clrsb (PR #72243)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/72243 None >From 0a5cc373736f6c9e29f4f8af438d37dd007f09e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Tue, 14 Nov 2023 12:42:03 +0100 Subject: [PATCH] [clang][Interp] Implement __builtin_clrsb --- clang/lib/AST/Interp/InterpBuiltin.cpp | 16 clang/test/AST/Interp/builtin-functions.cpp | 17 - 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index f26d298f5b60045..69383d37440f704 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -439,6 +439,15 @@ static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC, return true; } +static bool interp__builtin_clrsb(InterpState &S, 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.getBitWidth() - Val.getSignificantBits()); + return true; +} + bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *Call) { InterpFrame *Frame = S.Current; @@ -576,6 +585,13 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, return retInt(S, OpPC, Dummy); break; + case Builtin::BI__builtin_clrsb: + case Builtin::BI__builtin_clrsbl: + case Builtin::BI__builtin_clrsbll: +if (interp__builtin_clrsb(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 a78a0fbdf11b1d7..245d775bd366d53 100644 --- a/clang/test/AST/Interp/builtin-functions.cpp +++ b/clang/test/AST/Interp/builtin-functions.cpp @@ -274,6 +274,7 @@ namespace SourceLocation { } } +#define BITSIZE(x) (sizeof(x) * 8) namespace popcount { static_assert(__builtin_popcount(~0u) == __CHAR_BIT__ * sizeof(unsigned int), ""); static_assert(__builtin_popcount(0) == 0, ""); @@ -283,7 +284,6 @@ namespace popcount { 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]; @@ -295,3 +295,18 @@ namespace popcount { char popcount9[__builtin_popcountll(0xF0F0LL) == 8 ? 1 : -1]; char popcount10[__builtin_popcountll(~0LL) == BITSIZE(long long) ? 1 : -1]; } + +namespace clrsb { + char clrsb1[__builtin_clrsb(0) == BITSIZE(int) - 1 ? 1 : -1]; + char clrsb2[__builtin_clrsbl(0L) == BITSIZE(long) - 1 ? 1 : -1]; + char clrsb3[__builtin_clrsbll(0LL) == BITSIZE(long long) - 1 ? 1 : -1]; + char clrsb4[__builtin_clrsb(~0) == BITSIZE(int) - 1 ? 1 : -1]; + char clrsb5[__builtin_clrsbl(~0L) == BITSIZE(long) - 1 ? 1 : -1]; + char clrsb6[__builtin_clrsbll(~0LL) == BITSIZE(long long) - 1 ? 1 : -1]; + char clrsb7[__builtin_clrsb(1) == BITSIZE(int) - 2 ? 1 : -1]; + char clrsb8[__builtin_clrsb(~1) == BITSIZE(int) - 2 ? 1 : -1]; + char clrsb9[__builtin_clrsb(1 << (BITSIZE(int) - 1)) == 0 ? 1 : -1]; + char clrsb10[__builtin_clrsb(~(1 << (BITSIZE(int) - 1))) == 0 ? 1 : -1]; + char clrsb11[__builtin_clrsb(0xf) == BITSIZE(int) - 5 ? 1 : -1]; + char clrsb12[__builtin_clrsb(~0x1f) == BITSIZE(int) - 6 ? 1 : -1]; +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Sema] Check nullness of captured type before use (PR #72230)
@@ -23,3 +23,9 @@ int pr43080(int i) { // expected-note {{declared here}} i; // expected-error {{variable 'i' cannot be implicitly captured in a lambda with no capture-default specified}} }(); } + +void pr72198() { + int [_, b] = {0, 0}; // expected-error{{decomposition declaration cannot be declared with type 'int'; declared type must be 'auto' or reference to 'auto'}} \ + expected-error{{excess elements in scalar initializer}} + [b]{}; // expected-warning{{expression result unused}} tbaederr wrote: ```suggestion int [_, b] = {0, 0}; // expected-error {{decomposition declaration cannot be declared with type 'int'; declared type must be 'auto' or reference to 'auto'}} \ expected-error {{excess elements in scalar initializer}} [b]{}; // expected-warning {{expression result unused}} ``` https://github.com/llvm/llvm-project/pull/72230 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use new interpreter in EvaluateAsConstantExpr if requested (PR #70763)
@@ -129,7 +129,13 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, /// Classifies a type. std::optional classify(const Expr *E) const { -return E->isGLValue() ? PT_Ptr : classify(E->getType()); +if (E->isGLValue()) { + if (E->getType()->isFunctionType()) +return PT_FnPtr; + return PT_Ptr; +} + +return classify(E->getType()); tbaederr wrote: This is basically just an oversight; This should've been added when we added function pointers. This case was just never exercised. I can tell you what test case trips this up as soon as my local build finished. https://github.com/llvm/llvm-project/pull/70763 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Fix classify for glvalues of function type (PR #72269)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/72269 This can't be tested right now but will show up once we use the new interpreter in evaluateAsConstantExpression() as well. Pulled out from https://github.com/llvm/llvm-project/pull/70763 >From 074dd59057f1e1e1f2612ce4603a09420ca0a828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Tue, 14 Nov 2023 16:19:34 +0100 Subject: [PATCH] [clang][Interp] Fix classify for glvalues of function type This can't be tested right now but will show up once we use the new interpreter in evaluateAsConstantExpression() as well. --- clang/lib/AST/Interp/ByteCodeExprGen.h | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index ec9b6bb1408453c..2a75f22e13bed60 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -130,7 +130,13 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, /// Classifies a type. std::optional classify(const Expr *E) const { -return E->isGLValue() ? PT_Ptr : classify(E->getType()); +if (E->isGLValue()) { + if (E->getType()->isFunctionType()) +return PT_FnPtr; + return PT_Ptr; +} + +return classify(E->getType()); } std::optional classify(QualType Ty) const { return Ctx.classify(Ty); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Fix stack peek offset for This ptr (PR #70663)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/70663 ___ 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)
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: @@ -1894,6 +1894,8 @@ void TypePrinter::printAttributedAfter(const AttributedType *T, case attr::ArmMveStrictPolymorphism: OS << "__clang_arm_mve_strict_polymorphism"; break; + case attr::RequiresCapability: +OS << "requires_capability(blah)"; 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] Crash when referencing capture in static lambda (PR #74661)
@@ -8492,14 +8492,24 @@ 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); tbaederr wrote: ```suggestion const auto *MD = cast(Info.CurrentCall->Callee); ``` https://github.com/llvm/llvm-project/pull/74661 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Reject static lambdas with captures (PR #74718)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/74718 A version of #74661 for the new interpreter. It didn't crash before, but we did emit a few non-sensical diagnostics. >From 6ac52b644cbd5e12ad13e6c3c2bf84b96ec5f3b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Thu, 7 Dec 2023 14:19:52 +0100 Subject: [PATCH] [clang][Interp] Reject static lambdas with captures A version of #74661 for the new interpreter. It didn't crash before, but we did emit a few non-sensical diagnostics. --- clang/lib/AST/Interp/ByteCodeEmitter.cpp | 5 + clang/test/AST/Interp/cxx23.cpp | 27 +--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp b/clang/lib/AST/Interp/ByteCodeEmitter.cpp index 89b7708c0c2a1..045263447cbc9 100644 --- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp +++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp @@ -61,6 +61,11 @@ ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) { MD->getParent()->getCaptureFields(LC, LTC); for (auto Cap : LC) { +// Static lambdas cannot have any captures. If this one does, +// it has already been diagnosed and we can only ignore it. +if (MD->isStatic()) + return nullptr; + unsigned Offset = R->getField(Cap.second)->Offset; this->LambdaCaptures[Cap.first] = { Offset, Cap.second->getType()->isReferenceType()}; diff --git a/clang/test/AST/Interp/cxx23.cpp b/clang/test/AST/Interp/cxx23.cpp index e284a66626fb3..bd1cf186d519c 100644 --- a/clang/test/AST/Interp/cxx23.cpp +++ b/clang/test/AST/Interp/cxx23.cpp @@ -4,9 +4,6 @@ // RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=expected23 %s -fexperimental-new-constant-interpreter -// expected23-no-diagnostics - - /// FIXME: The new interpreter is missing all the 'control flows through...' diagnostics. constexpr int f(int n) { // ref20-error {{constexpr function never produces a constant expression}} \ @@ -82,3 +79,27 @@ constexpr int k(int n) { return m; } constexpr int k0 = k(0); + +namespace StaticLambdas { + constexpr auto static_capture_constexpr() { +char n = 'n'; +return [n] static { return n; }(); // expected23-error {{a static lambda cannot have any captures}} \ + // expected20-error {{a static lambda cannot have any captures}} \ + // expected20-warning {{are a C++23 extension}} \ + // expected20-warning {{is a C++23 extension}} \ + // ref23-error {{a static lambda cannot have any captures}} \ + // ref20-error {{a static lambda cannot have any captures}} \ + // ref20-warning {{are a C++23 extension}} \ + // ref20-warning {{is a C++23 extension}} + } + static_assert(static_capture_constexpr()); // expected23-error {{static assertion expression is not an integral constant expression}} \ + // expected20-error {{static assertion expression is not an integral constant expression}} \ + // ref23-error {{static assertion expression is not an integral constant expression}} \ + // ref20-error {{static assertion expression is not an integral constant expression}} + + constexpr auto capture_constexpr() { +char n = 'n'; +return [n] { return n; }(); + } + static_assert(capture_constexpr()); +} ___ 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)
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?= , 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?= , 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?= , Timm =?utf-8?q?Bäder?= , Timm =?utf-8?q?Bäder?= Message-ID: In-Reply-To: @@ -53,6 +53,10 @@ LLVM_READNONE inline bool isASCII(int64_t c) { return 0 <= c && c <= 127; } /// which is [a-zA-Z_]. LLVM_READONLY inline bool isAsciiIdentifierStart(unsigned char c, bool AllowDollar = false) { + if (!AllowDollar) { +return c == '_' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); + } + tbaederr wrote: Ignore this, it's a leftover from a different patch 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][C++20] Implement constexpr std::bit_cast for bit-fields (& [Sema] Print more static_assert exprs) (PR #74775)
tbaederr wrote: I don't have the capacity to review this properly, but the changes to the `static_assert` diagnostics should be split out IMO. https://github.com/llvm/llvm-project/pull/74775 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement builtin_expect (PR #69713)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/69713 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)
@@ -331,3 +331,17 @@ namespace bitreverse { char bitreverse3[__builtin_bitreverse32(0x12345678) == 0x1E6A2C48 ? 1 : -1]; char bitreverse4[__builtin_bitreverse64(0x0123456789ABCDEFULL) == 0xF7B3D591E6A2C480 ? 1 : -1]; } + +namespace rotateleft { + char rotateleft1[__builtin_rotateleft8(0x01, 5) == 0x20 ? 1 : -1]; + char rotateleft2[__builtin_rotateleft16(0x3210, 11) == 0x8190 ? 1 : -1]; + char rotateleft3[__builtin_rotateleft32(0x76543210, 22) == 0x841D950C ? 1 : -1]; + char rotateleft4[__builtin_rotateleft64(0xFEDCBA9876543210ULL, 55) == 0x87F6E5D4C3B2A19ULL ? 1 : -1]; +} + +namespace rotateright { + char rotateright1[__builtin_rotateright8(0x01, 5) == 0x08 ? 1 : -1]; + char rotateright2[__builtin_rotateright16(0x3210, 11) == 0x4206 ? 1 : -1]; + char rotateright3[__builtin_rotateright32(0x76543210, 22) == 0x50C841D9 ? 1 : -1]; + char rotateright4[__builtin_rotateright64(0xFEDCBA9876543210ULL, 55) == 0xB97530ECA86421FDULL ? 1 : -1]; tbaederr wrote: They builtin functions are defined as having unsigned parameters, so does a test like that make sense? https://github.com/llvm/llvm-project/pull/72984 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Add inline descriptor to global variables (PR #72892)
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/72892 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement IntegralAP::{div, rem} (PR #72614)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/72614 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Diagnose reads from non-const global variables (PR #71919)
Timm =?utf-8?q?B=C3=A4der?= Message-ID: In-Reply-To: tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/71919 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Add an EvaluationResult class (PR #71315)
Timm =?utf-8?q?B=C3=A4der?= Message-ID: In-Reply-To: tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/71315 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Fix float->int casts overflowing (PR #72658)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/72658 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement inc/dec for IntegralAP (PR #69597)
Timm =?utf-8?q?B=C3=A4der?= Message-ID: In-Reply-To: tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/69597 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)
Timm =?utf-8?q?B=C3=A4der?= Message-ID: In-Reply-To: tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/70772 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Decay arrays to the first element (PR #72660)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/72660 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] IndirectMember initializers (PR #69900)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/69900 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Use array filler expression (PR #72865)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/72865 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement __builtin_rotate{right, left} (PR #72984)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/72984 >From 71ee39aaf9e962701168290394333654a22ed918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Tue, 21 Nov 2023 13:44:07 +0100 Subject: [PATCH] [clang][Interp] Implement __builtin_rotate{right,left} --- clang/lib/AST/Interp/InterpBuiltin.cpp | 49 + clang/test/AST/Interp/builtin-functions.cpp | 15 +++ 2 files changed, 64 insertions(+) diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index 4384ace6b6be5e..deba38e4e9ddc0 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -579,6 +579,29 @@ static bool interp__builtin_expect(InterpState &S, CodePtr OpPC, return true; } +/// rotateleft(value, amount) +static bool interp__builtin_rotate(InterpState &S, CodePtr OpPC, + const InterpFrame *Frame, + const Function *Func, const CallExpr *Call, + bool Right) { + PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); + assert(ArgT == *S.getContext().classify(Call->getArg(1)->getType())); + + APSInt Amount = peekToAPSInt(S.Stk, ArgT); + APSInt Value = peekToAPSInt(S.Stk, ArgT, align(primSize(ArgT)) * 2); + + APSInt Result; + if (Right) +Result = APSInt(Value.rotr(Amount.urem(Value.getBitWidth())), +/*IsUnsigned=*/true); + else // Left. +Result = APSInt(Value.rotl(Amount.urem(Value.getBitWidth())), +/*IsUnsigned=*/true); + + pushAPSInt(S, Result); + return true; +} + bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *Call) { InterpFrame *Frame = S.Current; @@ -754,6 +777,32 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, return false; break; + case Builtin::BI__builtin_rotateleft8: + case Builtin::BI__builtin_rotateleft16: + case Builtin::BI__builtin_rotateleft32: + case Builtin::BI__builtin_rotateleft64: + case Builtin::BI_rotl8: // Microsoft variants of rotate left + case Builtin::BI_rotl16: + case Builtin::BI_rotl: + case Builtin::BI_lrotl: + case Builtin::BI_rotl64: +if (!interp__builtin_rotate(S, OpPC, Frame, F, Call, /*Right=*/false)) + return false; +break; + + case Builtin::BI__builtin_rotateright8: + case Builtin::BI__builtin_rotateright16: + case Builtin::BI__builtin_rotateright32: + case Builtin::BI__builtin_rotateright64: + case Builtin::BI_rotr8: // Microsoft variants of rotate right + case Builtin::BI_rotr16: + case Builtin::BI_rotr: + case Builtin::BI_lrotr: + case Builtin::BI_rotr64: +if (!interp__builtin_rotate(S, OpPC, Frame, F, Call, /*Right=*/true)) + return false; +break; + default: return false; } diff --git a/clang/test/AST/Interp/builtin-functions.cpp b/clang/test/AST/Interp/builtin-functions.cpp index 35a1f9a75092a0..0e50bfe5d6e30e 100644 --- a/clang/test/AST/Interp/builtin-functions.cpp +++ b/clang/test/AST/Interp/builtin-functions.cpp @@ -332,10 +332,25 @@ namespace bitreverse { char bitreverse4[__builtin_bitreverse64(0x0123456789ABCDEFULL) == 0xF7B3D591E6A2C480 ? 1 : -1]; } +<<< HEAD namespace expect { constexpr int a() { return 12; } static_assert(__builtin_expect(a(),1) == 12, ""); static_assert(__builtin_expect_with_probability(a(), 1, 1.0) == 12, ""); +=== +namespace rotateleft { + char rotateleft1[__builtin_rotateleft8(0x01, 5) == 0x20 ? 1 : -1]; + char rotateleft2[__builtin_rotateleft16(0x3210, 11) == 0x8190 ? 1 : -1]; + char rotateleft3[__builtin_rotateleft32(0x76543210, 22) == 0x841D950C ? 1 : -1]; + char rotateleft4[__builtin_rotateleft64(0xFEDCBA9876543210ULL, 55) == 0x87F6E5D4C3B2A19ULL ? 1 : -1]; +} + +namespace rotateright { + char rotateright1[__builtin_rotateright8(0x01, 5) == 0x08 ? 1 : -1]; + char rotateright2[__builtin_rotateright16(0x3210, 11) == 0x4206 ? 1 : -1]; + char rotateright3[__builtin_rotateright32(0x76543210, 22) == 0x50C841D9 ? 1 : -1]; + char rotateright4[__builtin_rotateright64(0xFEDCBA9876543210ULL, 55) == 0xB97530ECA86421FDULL ? 1 : -1]; +>>> 6417ae298a1a ([clang][Interp] Implement __builtin_rotate{right,left}) } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Don't diagnose undefined functions when checking... (PR #75051)
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/75051 ... for a potential constant expression. They are not defined now, but might be defined later when the function is actually called. >From 74d11ff5c8bd2dbc641e2d602cd3d463f02f59f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Mon, 11 Dec 2023 15:08:32 +0100 Subject: [PATCH] [clang][Interp] Don't diagnose undefined functions when checking... ... for a potential constant expression. They are not defined now, but might be defined later when the function is actually called. --- clang/lib/AST/Interp/Interp.cpp | 19 +++ clang/test/AST/Interp/functions.cpp | 11 +++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index 13b77e9a87725c..29d9dcbf9c3069 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -350,11 +350,6 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { } if (!F->isConstexpr()) { -// Don't emit anything if we're checking for a potential constant -// expression. That will happen later when actually executing. -if (S.checkingPotentialConstantExpression()) - return false; - const SourceLocation &Loc = S.Current->getLocation(OpPC); if (S.getLangOpts().CPlusPlus11) { const FunctionDecl *DiagDecl = F->getDecl(); @@ -371,13 +366,21 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { // FIXME: If DiagDecl is an implicitly-declared special member function // or an inheriting constructor, we should be much more explicit about why // it's not constexpr. - if (CD && CD->isInheritingConstructor()) + if (CD && CD->isInheritingConstructor()) { S.FFDiag(Loc, diag::note_constexpr_invalid_inhctor, 1) << CD->getInheritedConstructor().getConstructor()->getParent(); - else +S.Note(DiagDecl->getLocation(), diag::note_declared_at); + } else { +// Don't emit anything if the function isn't defined and we're checking +// for a constnat expression. It might be defined at the point we're +// actually calling it. +if (!DiagDecl->isDefined() && S.checkingPotentialConstantExpression()) + return false; + S.FFDiag(Loc, diag::note_constexpr_invalid_function, 1) << DiagDecl->isConstexpr() << (bool)CD << DiagDecl; - S.Note(DiagDecl->getLocation(), diag::note_declared_at); +S.Note(DiagDecl->getLocation(), diag::note_declared_at); + } } else { S.FFDiag(Loc, diag::note_invalid_subexpr_in_const_expr); } diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index ab562e70606b67..179a195098b132 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -267,6 +267,17 @@ namespace InvalidCall { // ref-error {{must be initialized by a constant expression}} \ // ref-note {{in call to 'SS()'}} + + /// This should not emit a diagnostic. + constexpr int f(); + constexpr int a() { +return f(); + } + constexpr int f() { +return 5; + } + static_assert(a() == 5, ""); + } namespace CallWithArgs { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Fix float->int casts overflowing (PR #72658)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/72658 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Fix classify for glvalues of function type (PR #72269)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/72269 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use new interpreter in EvaluateAsConstantExpr if requested (PR #70763)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/70763 >From 95db8094955756851e59a377cc13af9c30987221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Mon, 30 Oct 2023 16:14:24 +0100 Subject: [PATCH] [clang] Use new interpreter in EvaluateAsConstantExpr if requested EvaluateAsConstantExpr() uses ::EvaluateInPlace() directly, which does not use the new interpreter if requested. Do it here, which is the same pattern we use in EvaluateAsInitializer. --- clang/lib/AST/ExprConstant.cpp | 16 +--- clang/test/AST/Interp/literals.cpp | 4 +--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 4aa8045bc93be71..373972eb6cab11b 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -15672,12 +15672,14 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, // this doesn't escape. MaterializeTemporaryExpr BaseMTE(T, const_cast(this), true); APValue::LValueBase Base(&BaseMTE); - Info.setEvaluatingDecl(Base, Result.Val); - LValue LVal; - LVal.set(Base); - { + if (Info.EnableNewConstInterp) { +if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, this, Result.Val)) + return false; + } else { +LValue LVal; +LVal.set(Base); // C++23 [intro.execution]/p5 // A full-expression is [...] a constant-expression // So we need to make sure temporary objects are destroyed after having @@ -15686,10 +15688,10 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, if (!::EvaluateInPlace(Result.Val, Info, LVal, this) || Result.HasSideEffects || !Scope.destroy()) return false; - } - if (!Info.discardCleanups()) -llvm_unreachable("Unhandled cleanup; missing full expression marker?"); +if (!Info.discardCleanups()) + llvm_unreachable("Unhandled cleanup; missing full expression marker?"); + } if (!CheckConstantExpression(Info, getExprLoc(), getStorageType(Ctx, this), Result.Val, Kind)) diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index 68833ec2dc48adf..592b5d6243a80aa 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -261,15 +261,13 @@ namespace SizeOf { #if __cplusplus >= 202002L /// FIXME: The following code should be accepted. consteval int foo(int n) { // ref-error {{consteval function never produces a constant expression}} -return sizeof(int[n]); // ref-note 3{{not valid in a constant expression}} \ - // expected-note {{not valid in a constant expression}} +return sizeof(int[n]); // ref-note 3{{not valid in a constant expression}} } constinit int var = foo(5); // ref-error {{not a constant expression}} \ // ref-note 2{{in call to}} \ // ref-error {{does not have a constant initializer}} \ // ref-note {{required by 'constinit' specifier}} \ // expected-error {{is not a constant expression}} \ - // expected-note {{in call to}} \ // expected-error {{does not have a constant initializer}} \ // expected-note {{required by 'constinit' specifier}} \ ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Only build static analyzer sources if requested (PR #71653)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/71653 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Fix variables referring to their own address (PR #70587)
https://github.com/tbaederr edited https://github.com/llvm/llvm-project/pull/70587 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Fix variables referring to their own address (PR #70587)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/70587 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Use new interpreter in EvaluateAsConstantExpr if requested (PR #70763)
https://github.com/tbaederr closed https://github.com/llvm/llvm-project/pull/70763 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement builtin_expect (PR #69713)
Timm =?utf-8?q?B=C3=A4der?= Message-ID: In-Reply-To: tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/69713 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement IntegralAP subtraction (PR #71648)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/71648 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement bitwise operations for IntegralAP (PR #71807)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/71807 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement inc/dec for IntegralAP (PR #69597)
tbaederr wrote: Ping https://github.com/llvm/llvm-project/pull/69597 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Interp] Implement bitwise operations for IntegralAP (PR #71807)
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/71807 >From 72b46d891d34e7c0810bec335221a109cf4fb3a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= Date: Thu, 9 Nov 2023 14:29:51 +0100 Subject: [PATCH] [clang][Interp] Implement bitwise operations for IntegralAP --- clang/lib/AST/Interp/IntegralAP.h | 8 +++- clang/test/AST/Interp/intap.cpp | 12 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/clang/lib/AST/Interp/IntegralAP.h b/clang/lib/AST/Interp/IntegralAP.h index 88de1f1392e6813..c8850a4bbb574aa 100644 --- a/clang/lib/AST/Interp/IntegralAP.h +++ b/clang/lib/AST/Interp/IntegralAP.h @@ -219,21 +219,19 @@ template class IntegralAP final { static bool bitAnd(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { -// FIXME: Implement. -assert(false); +*R = IntegralAP(A.V & B.V); return false; } static bool bitOr(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { -assert(false); +*R = IntegralAP(A.V | B.V); return false; } static bool bitXor(IntegralAP A, IntegralAP B, unsigned OpBits, IntegralAP *R) { -// FIXME: Implement. -assert(false); +*R = IntegralAP(A.V ^ B.V); return false; } diff --git a/clang/test/AST/Interp/intap.cpp b/clang/test/AST/Interp/intap.cpp index 34c8d0565082994..729d144012713fb 100644 --- a/clang/test/AST/Interp/intap.cpp +++ b/clang/test/AST/Interp/intap.cpp @@ -157,4 +157,16 @@ namespace Bitfields { // expected-warning {{changes value from 100 to 0}} } +namespace BitOps { + constexpr unsigned __int128 UZero = 0; + constexpr unsigned __int128 Max = ~UZero; + static_assert(Max == ~0, ""); + static_assert((Max & 0) == 0, ""); + static_assert((UZero | 0) == 0, ""); + static_assert((Max ^ Max) == 0, ""); + static_assert((Max & 1) == 1, ""); + static_assert((UZero | 1) == 1, ""); + static_assert((Max ^ UZero) == Max, ""); +} + #endif ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits