[clang] a0d83c3 - Revert "[clang][Diagnostics] Split source ranges into line ranges before..."
Author: Timm Bäder Date: 2023-06-02T09:02:34+02:00 New Revision: a0d83c3dc364688a223e0031d134e2a1bde4ba78 URL: https://github.com/llvm/llvm-project/commit/a0d83c3dc364688a223e0031d134e2a1bde4ba78 DIFF: https://github.com/llvm/llvm-project/commit/a0d83c3dc364688a223e0031d134e2a1bde4ba78.diff LOG: Revert "[clang][Diagnostics] Split source ranges into line ranges before..." This reverts commit fc1262bd58ac54ad0a0bfa9750254b81c742bbb5. This causes build bot failures because of a parser test case: https://lab.llvm.org/buildbot/#/builders/139/builds/41961 Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp clang/test/Misc/caret-diags-multiline.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index c17508f37c7fd..ad5f1d45cb631 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -945,43 +945,87 @@ maybeAddRange(std::pair A, std::pair B, return A; } -struct LineRange { - unsigned LineNo; - unsigned StartCol; - unsigned EndCol; -}; +/// Highlight a SourceRange (with ~'s) for any characters on LineNo. +static void highlightRange(const CharSourceRange &R, + unsigned LineNo, FileID FID, + const SourceColumnMap &map, + std::string &CaretLine, + const SourceManager &SM, + const LangOptions &LangOpts) { + if (!R.isValid()) return; -/// Highlight \p R (with ~'s) on the current source line. -static void highlightRange(const LineRange &R, const SourceColumnMap &Map, - std::string &CaretLine) { - // Pick the first non-whitespace column. - unsigned StartColNo = R.StartCol; - while (StartColNo < Map.getSourceLine().size() && - (Map.getSourceLine()[StartColNo] == ' ' || - Map.getSourceLine()[StartColNo] == '\t')) -StartColNo = Map.startOfNextColumn(StartColNo); - - // Pick the last non-whitespace column. - unsigned EndColNo = - std::min(static_cast(R.EndCol), Map.getSourceLine().size()); - while (EndColNo && (Map.getSourceLine()[EndColNo - 1] == ' ' || - Map.getSourceLine()[EndColNo - 1] == '\t')) -EndColNo = Map.startOfPreviousColumn(EndColNo); - - // If the start/end passed each other, then we are trying to highlight a - // range that just exists in whitespace. That most likely means we have - // a multi-line highlighting range that covers a blank line. - if (StartColNo > EndColNo) -return; + SourceLocation Begin = R.getBegin(); + SourceLocation End = R.getEnd(); + + unsigned StartLineNo = SM.getExpansionLineNumber(Begin); + if (StartLineNo > LineNo || SM.getFileID(Begin) != FID) +return; // No intersection. + + unsigned EndLineNo = SM.getExpansionLineNumber(End); + if (EndLineNo < LineNo || SM.getFileID(End) != FID) +return; // No intersection. + + // Compute the column number of the start. + unsigned StartColNo = 0; + if (StartLineNo == LineNo) { +StartColNo = SM.getExpansionColumnNumber(Begin); +if (StartColNo) --StartColNo; // Zero base the col #. + } + + // Compute the column number of the end. + unsigned EndColNo = map.getSourceLine().size(); + if (EndLineNo == LineNo) { +EndColNo = SM.getExpansionColumnNumber(End); +if (EndColNo) { + --EndColNo; // Zero base the col #. + + // Add in the length of the token, so that we cover multi-char tokens if + // this is a token range. + if (R.isTokenRange()) +EndColNo += Lexer::MeasureTokenLength(End, SM, LangOpts); +} else { + EndColNo = CaretLine.size(); +} + } + + assert(StartColNo <= EndColNo && "Invalid range!"); + + // Check that a token range does not highlight only whitespace. + if (R.isTokenRange()) { +// Pick the first non-whitespace column. +while (StartColNo < map.getSourceLine().size() && + (map.getSourceLine()[StartColNo] == ' ' || +map.getSourceLine()[StartColNo] == '\t')) + StartColNo = map.startOfNextColumn(StartColNo); + +// Pick the last non-whitespace column. +if (EndColNo > map.getSourceLine().size()) + EndColNo = map.getSourceLine().size(); +while (EndColNo && + (map.getSourceLine()[EndColNo-1] == ' ' || +map.getSourceLine()[EndColNo-1] == '\t')) + EndColNo = map.startOfPreviousColumn(EndColNo); + +// If the start/end passed each other, then we are trying to highlight a +// range that just exists in whitespace. That most likely means we have +// a multi-line highlighting range that covers a blank line. +if (StartColNo > EndColNo) { + assert(StartLineNo != EndLineNo && "trying to highlight whitespace"); + StartColNo = EndColNo; +} + } + + assert(StartColNo <= map.getSourceLine().size() && "Invalid range!"); + assert(EndCo
[clang] fc1262b - [clang][Diagnostics] Split source ranges into line ranges before...
Author: Timm Bäder Date: 2023-06-02T08:52:03+02:00 New Revision: fc1262bd58ac54ad0a0bfa9750254b81c742bbb5 URL: https://github.com/llvm/llvm-project/commit/fc1262bd58ac54ad0a0bfa9750254b81c742bbb5 DIFF: https://github.com/llvm/llvm-project/commit/fc1262bd58ac54ad0a0bfa9750254b81c742bbb5.diff LOG: [clang][Diagnostics] Split source ranges into line ranges before... ... emitting them. This makes later code easier to understand, since we emit the code snippets line by line anyway. It also fixes the weird underlinig of multi-line source ranges. Differential Revision: https://reviews.llvm.org/D151215 Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp clang/test/Misc/caret-diags-multiline.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index ad5f1d45cb631..c17508f37c7fd 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -945,87 +945,43 @@ maybeAddRange(std::pair A, std::pair B, return A; } -/// Highlight a SourceRange (with ~'s) for any characters on LineNo. -static void highlightRange(const CharSourceRange &R, - unsigned LineNo, FileID FID, - const SourceColumnMap &map, - std::string &CaretLine, - const SourceManager &SM, - const LangOptions &LangOpts) { - if (!R.isValid()) return; - - SourceLocation Begin = R.getBegin(); - SourceLocation End = R.getEnd(); - - unsigned StartLineNo = SM.getExpansionLineNumber(Begin); - if (StartLineNo > LineNo || SM.getFileID(Begin) != FID) -return; // No intersection. - - unsigned EndLineNo = SM.getExpansionLineNumber(End); - if (EndLineNo < LineNo || SM.getFileID(End) != FID) -return; // No intersection. - - // Compute the column number of the start. - unsigned StartColNo = 0; - if (StartLineNo == LineNo) { -StartColNo = SM.getExpansionColumnNumber(Begin); -if (StartColNo) --StartColNo; // Zero base the col #. - } - - // Compute the column number of the end. - unsigned EndColNo = map.getSourceLine().size(); - if (EndLineNo == LineNo) { -EndColNo = SM.getExpansionColumnNumber(End); -if (EndColNo) { - --EndColNo; // Zero base the col #. - - // Add in the length of the token, so that we cover multi-char tokens if - // this is a token range. - if (R.isTokenRange()) -EndColNo += Lexer::MeasureTokenLength(End, SM, LangOpts); -} else { - EndColNo = CaretLine.size(); -} - } - - assert(StartColNo <= EndColNo && "Invalid range!"); - - // Check that a token range does not highlight only whitespace. - if (R.isTokenRange()) { -// Pick the first non-whitespace column. -while (StartColNo < map.getSourceLine().size() && - (map.getSourceLine()[StartColNo] == ' ' || -map.getSourceLine()[StartColNo] == '\t')) - StartColNo = map.startOfNextColumn(StartColNo); - -// Pick the last non-whitespace column. -if (EndColNo > map.getSourceLine().size()) - EndColNo = map.getSourceLine().size(); -while (EndColNo && - (map.getSourceLine()[EndColNo-1] == ' ' || -map.getSourceLine()[EndColNo-1] == '\t')) - EndColNo = map.startOfPreviousColumn(EndColNo); - -// If the start/end passed each other, then we are trying to highlight a -// range that just exists in whitespace. That most likely means we have -// a multi-line highlighting range that covers a blank line. -if (StartColNo > EndColNo) { - assert(StartLineNo != EndLineNo && "trying to highlight whitespace"); - StartColNo = EndColNo; -} - } +struct LineRange { + unsigned LineNo; + unsigned StartCol; + unsigned EndCol; +}; - assert(StartColNo <= map.getSourceLine().size() && "Invalid range!"); - assert(EndColNo <= map.getSourceLine().size() && "Invalid range!"); +/// Highlight \p R (with ~'s) on the current source line. +static void highlightRange(const LineRange &R, const SourceColumnMap &Map, + std::string &CaretLine) { + // Pick the first non-whitespace column. + unsigned StartColNo = R.StartCol; + while (StartColNo < Map.getSourceLine().size() && + (Map.getSourceLine()[StartColNo] == ' ' || + Map.getSourceLine()[StartColNo] == '\t')) +StartColNo = Map.startOfNextColumn(StartColNo); + + // Pick the last non-whitespace column. + unsigned EndColNo = + std::min(static_cast(R.EndCol), Map.getSourceLine().size()); + while (EndColNo && (Map.getSourceLine()[EndColNo - 1] == ' ' || + Map.getSourceLine()[EndColNo - 1] == '\t')) +EndColNo = Map.startOfPreviousColumn(EndColNo); + + // If the start/end passed each other, then we are trying to highlight a + // range that just exists in whitespace. That most likely means we have + //
[clang] cc69bc4 - [clang][Interp][NFC] Print Function name in unreachable type failures
Author: Timm Bäder Date: 2023-06-02T08:38:13+02:00 New Revision: cc69bc4254ba9cb4316ca2b304fbb3230e38ed63 URL: https://github.com/llvm/llvm-project/commit/cc69bc4254ba9cb4316ca2b304fbb3230e38ed63 DIFF: https://github.com/llvm/llvm-project/commit/cc69bc4254ba9cb4316ca2b304fbb3230e38ed63.diff LOG: [clang][Interp][NFC] Print Function name in unreachable type failures and pass Record* pointers around as const. Added: Modified: clang/utils/TableGen/ClangOpcodesEmitter.cpp Removed: diff --git a/clang/utils/TableGen/ClangOpcodesEmitter.cpp b/clang/utils/TableGen/ClangOpcodesEmitter.cpp index aa012233c46ee..db88c990d5f9b 100644 --- a/clang/utils/TableGen/ClangOpcodesEmitter.cpp +++ b/clang/utils/TableGen/ClangOpcodesEmitter.cpp @@ -21,7 +21,7 @@ using namespace llvm; namespace { class ClangOpcodesEmitter { RecordKeeper &Records; - Record Root; + const Record Root; unsigned NumTypes; public: @@ -34,33 +34,32 @@ class ClangOpcodesEmitter { private: /// Emits the opcode name for the opcode enum. /// The name is obtained by concatenating the name with the list of types. - void EmitEnum(raw_ostream &OS, StringRef N, Record *R); + void EmitEnum(raw_ostream &OS, StringRef N, const Record *R); /// Emits the switch case and the invocation in the interpreter. - void EmitInterp(raw_ostream &OS, StringRef N, Record *R); + void EmitInterp(raw_ostream &OS, StringRef N, const Record *R); /// Emits the disassembler. - void EmitDisasm(raw_ostream &OS, StringRef N, Record *R); + void EmitDisasm(raw_ostream &OS, StringRef N, const Record *R); /// Emits the byte code emitter method. - void EmitEmitter(raw_ostream &OS, StringRef N, Record *R); + void EmitEmitter(raw_ostream &OS, StringRef N, const Record *R); /// Emits the prototype. - void EmitProto(raw_ostream &OS, StringRef N, Record *R); + void EmitProto(raw_ostream &OS, StringRef N, const Record *R); /// Emits the prototype to dispatch from a type. - void EmitGroup(raw_ostream &OS, StringRef N, Record *R); + void EmitGroup(raw_ostream &OS, StringRef N, const Record *R); /// Emits the evaluator method. - void EmitEval(raw_ostream &OS, StringRef N, Record *R); + void EmitEval(raw_ostream &OS, StringRef N, const Record *R); - void PrintTypes(raw_ostream &OS, ArrayRef Types); + void PrintTypes(raw_ostream &OS, ArrayRef Types); }; -void Enumerate(const Record *R, - StringRef N, - std::function, Twine)> &&F) { - llvm::SmallVector TypePath; +void Enumerate(const Record *R, StringRef N, + std::function, Twine)> &&F) { + llvm::SmallVector TypePath; auto *Types = R->getValueAsListInit("Types"); std::function Rec; @@ -102,67 +101,72 @@ void ClangOpcodesEmitter::run(raw_ostream &OS) { } } -void ClangOpcodesEmitter::EmitEnum(raw_ostream &OS, StringRef N, Record *R) { +void ClangOpcodesEmitter::EmitEnum(raw_ostream &OS, StringRef N, + const Record *R) { OS << "#ifdef GET_OPCODE_NAMES\n"; - Enumerate(R, N, [&OS](ArrayRef, const Twine &ID) { + Enumerate(R, N, [&OS](ArrayRef, const Twine &ID) { OS << "OP_" << ID << ",\n"; }); OS << "#endif\n"; } -void ClangOpcodesEmitter::EmitInterp(raw_ostream &OS, StringRef N, Record *R) { +void ClangOpcodesEmitter::EmitInterp(raw_ostream &OS, StringRef N, + const Record *R) { OS << "#ifdef GET_INTERP\n"; - Enumerate(R, N, [this, R, &OS, &N](ArrayRef TS, const Twine &ID) { -bool CanReturn = R->getValueAsBit("CanReturn"); -bool ChangesPC = R->getValueAsBit("ChangesPC"); -auto Args = R->getValueAsListOfDefs("Args"); - -OS << "case OP_" << ID << ": {\n"; - -if (CanReturn) - OS << " bool DoReturn = (S.Current == StartFrame);\n"; - -// Emit calls to read arguments. -for (size_t I = 0, N = Args.size(); I < N; ++I) { - OS << " auto V" << I; - OS << " = "; - OS << "ReadArg<" << Args[I]->getValueAsString("Name") << ">(S, PC);\n"; -} - -// Emit a call to the template method and pass arguments. -OS << " if (!" << N; -PrintTypes(OS, TS); -OS << "(S"; -if (ChangesPC) - OS << ", PC"; -else - OS << ", OpPC"; -if (CanReturn) - OS << ", Result"; -for (size_t I = 0, N = Args.size(); I < N; ++I) - OS << ", V" << I; -OS << "))\n"; -OS << "return false;\n"; - -// Bail out if interpreter returned. -if (CanReturn) { - OS << " if (!S.Current || S.Current->isRoot())\n"; - OS << "return true;\n"; - - OS << " if (DoReturn)\n"; - OS << "return true;\n"; -} - -OS << " continue;\n"; -OS << "}\n"; - }); + Enumerate(R, N, +[this, R, &OS, &N](ArrayRef TS, const Twine &ID) { + bool CanReturn = R->getValueAsBit("CanReturn"); + bool ChangesPC = R->getValueAsBit(
[clang] f1a318b - [clang][Interp][NFC] Add FunctionPointer.h header comment
Author: Timm Bäder Date: 2023-06-02T08:38:13+02:00 New Revision: f1a318b3ddd2d224ab37fa397d63c767f516085d URL: https://github.com/llvm/llvm-project/commit/f1a318b3ddd2d224ab37fa397d63c767f516085d DIFF: https://github.com/llvm/llvm-project/commit/f1a318b3ddd2d224ab37fa397d63c767f516085d.diff LOG: [clang][Interp][NFC] Add FunctionPointer.h header comment Added: Modified: clang/lib/AST/Interp/FunctionPointer.h Removed: diff --git a/clang/lib/AST/Interp/FunctionPointer.h b/clang/lib/AST/Interp/FunctionPointer.h index 20d4d7793185c..4a3f993d4882e 100644 --- a/clang/lib/AST/Interp/FunctionPointer.h +++ b/clang/lib/AST/Interp/FunctionPointer.h @@ -1,4 +1,10 @@ - +//===--- FunctionPointer.h - Types for the constexpr VM --*- 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_AST_INTERP_FUNCTION_POINTER_H #define LLVM_CLANG_AST_INTERP_FUNCTION_POINTER_H ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 710749f - [clang][Interp] Optionally cast comparison result to non-bool
Author: Timm Bäder Date: 2023-06-01T10:36:33+02:00 New Revision: 710749f78695b0e00026e5ff7c9f94e08e7b482a URL: https://github.com/llvm/llvm-project/commit/710749f78695b0e00026e5ff7c9f94e08e7b482a DIFF: https://github.com/llvm/llvm-project/commit/710749f78695b0e00026e5ff7c9f94e08e7b482a.diff LOG: [clang][Interp] Optionally cast comparison result to non-bool Our comparison opcodes always produce a Boolean value and push it on the stack. However, the result of such a comparison in C is int, so the later code expects an integer value on the stack. Work around this problem by casting the boolean value to int in those cases. This is not ideal for C however. The comparison is usually wrapped in a IntegerToBool cast anyway. Differential Revision: https://reviews.llvm.org/D149645 Added: clang/test/AST/Interp/c.c Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index df7c4a72f21a7..1be131be66e3b 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -237,19 +237,31 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { if (!visit(LHS) || !visit(RHS)) return false; + // For languages such as C, cast the result of one + // of our comparision opcodes to T (which is usually int). + auto MaybeCastToBool = [this, T, BO](bool Result) { +if (!Result) + return false; +if (DiscardResult) + return this->emitPop(*T, BO); +if (T != PT_Bool) + return this->emitCast(PT_Bool, *T, BO); +return true; + }; + switch (BO->getOpcode()) { case BO_EQ: -return Discard(this->emitEQ(*LT, BO)); +return MaybeCastToBool(this->emitEQ(*LT, BO)); case BO_NE: -return Discard(this->emitNE(*LT, BO)); +return MaybeCastToBool(this->emitNE(*LT, BO)); case BO_LT: -return Discard(this->emitLT(*LT, BO)); +return MaybeCastToBool(this->emitLT(*LT, BO)); case BO_LE: -return Discard(this->emitLE(*LT, BO)); +return MaybeCastToBool(this->emitLE(*LT, BO)); case BO_GT: -return Discard(this->emitGT(*LT, BO)); +return MaybeCastToBool(this->emitGT(*LT, BO)); case BO_GE: -return Discard(this->emitGE(*LT, BO)); +return MaybeCastToBool(this->emitGE(*LT, BO)); case BO_Sub: if (BO->getType()->isFloatingType()) return Discard(this->emitSubf(getRoundingMode(BO), BO)); @@ -925,6 +937,15 @@ bool ByteCodeExprGen::visitConditional( if (!this->visit(Condition)) return false; + + // C special case: Convert to bool because our jump ops need that. + // TODO: We probably want this to be done in visitBool(). + if (std::optional CondT = classify(Condition->getType()); + CondT && CondT != PT_Bool) { +if (!this->emitCast(*CondT, PT_Bool, E)) + return false; + } + if (!this->jumpFalse(LabelFalse)) return false; diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c new file mode 100644 index 0..fe794bb014e7c --- /dev/null +++ b/clang/test/AST/Interp/c.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s +// RUN: %clang_cc1 -verify=ref %s + +/// expected-no-diagnostics +/// ref-no-diagnostics + +_Static_assert(1, ""); +_Static_assert(0 != 1, ""); +_Static_assert(1.0 == 1.0, ""); +_Static_assert( (5 > 4) + (3 > 2) == 2, ""); + +int a = (1 == 1 ? 5 : 3); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 2e676fa - Revert "[clang][Interp] Optionally cast comparison result to non-bool"
Author: Timm Bäder Date: 2023-05-31T13:07:40+02:00 New Revision: 2e676fad2620a2ee41b7a00b27770fcfcb16f912 URL: https://github.com/llvm/llvm-project/commit/2e676fad2620a2ee41b7a00b27770fcfcb16f912 DIFF: https://github.com/llvm/llvm-project/commit/2e676fad2620a2ee41b7a00b27770fcfcb16f912.diff LOG: Revert "[clang][Interp] Optionally cast comparison result to non-bool" This reverts commit 81522a012accfcc6bbf4dfa21a793aea6e4e532a. Looks like we're not ready for this yet: https://lab.llvm.org/buildbot/#/builders/139/builds/41797 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp Removed: clang/test/AST/Interp/c.c diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 24663a15bcd0..df7c4a72f21a 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -237,31 +237,19 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { if (!visit(LHS) || !visit(RHS)) return false; - // For languages such as C, cast the result of one - // of our comparision opcodes to T (which is usually int). - auto MaybeCastToBool = [this, T, BO](bool Result) { -if (!Result) - return false; -if (DiscardResult) - return this->emitPop(*T, BO); -if (T != PT_Bool) - return this->emitCast(PT_Bool, *T, BO); -return true; - }; - switch (BO->getOpcode()) { case BO_EQ: -return MaybeCastToBool(this->emitEQ(*LT, BO)); +return Discard(this->emitEQ(*LT, BO)); case BO_NE: -return MaybeCastToBool(this->emitNE(*LT, BO)); +return Discard(this->emitNE(*LT, BO)); case BO_LT: -return MaybeCastToBool(this->emitLT(*LT, BO)); +return Discard(this->emitLT(*LT, BO)); case BO_LE: -return MaybeCastToBool(this->emitLE(*LT, BO)); +return Discard(this->emitLE(*LT, BO)); case BO_GT: -return MaybeCastToBool(this->emitGT(*LT, BO)); +return Discard(this->emitGT(*LT, BO)); case BO_GE: -return MaybeCastToBool(this->emitGE(*LT, BO)); +return Discard(this->emitGE(*LT, BO)); case BO_Sub: if (BO->getType()->isFloatingType()) return Discard(this->emitSubf(getRoundingMode(BO), BO)); diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c deleted file mode 100644 index 248494c95f5e.. --- a/clang/test/AST/Interp/c.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s -// RUN: %clang_cc1 -verify=ref %s - -/// expected-no-diagnostics -/// ref-no-diagnostics - -_Static_assert(1, ""); -_Static_assert(0 != 1, ""); -_Static_assert(1.0 == 1.0, ""); -_Static_assert( (5 > 4) + (3 > 2) == 2, ""); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 81522a0 - [clang][Interp] Optionally cast comparison result to non-bool
Author: Timm Bäder Date: 2023-05-31T13:01:01+02:00 New Revision: 81522a012accfcc6bbf4dfa21a793aea6e4e532a URL: https://github.com/llvm/llvm-project/commit/81522a012accfcc6bbf4dfa21a793aea6e4e532a DIFF: https://github.com/llvm/llvm-project/commit/81522a012accfcc6bbf4dfa21a793aea6e4e532a.diff LOG: [clang][Interp] Optionally cast comparison result to non-bool Our comparison opcodes always produce a Boolean value and push it on the stack. However, the result of such a comparison in C is int, so the later code expects an integer value on the stack. Work around this problem by casting the boolean value to int in those cases. This is not ideal for C however. The comparison is usually wrapped in a IntegerToBool cast anyway. Differential Revision: https://reviews.llvm.org/D149645 Added: clang/test/AST/Interp/c.c Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index df7c4a72f21a..24663a15bcd0 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -237,19 +237,31 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { if (!visit(LHS) || !visit(RHS)) return false; + // For languages such as C, cast the result of one + // of our comparision opcodes to T (which is usually int). + auto MaybeCastToBool = [this, T, BO](bool Result) { +if (!Result) + return false; +if (DiscardResult) + return this->emitPop(*T, BO); +if (T != PT_Bool) + return this->emitCast(PT_Bool, *T, BO); +return true; + }; + switch (BO->getOpcode()) { case BO_EQ: -return Discard(this->emitEQ(*LT, BO)); +return MaybeCastToBool(this->emitEQ(*LT, BO)); case BO_NE: -return Discard(this->emitNE(*LT, BO)); +return MaybeCastToBool(this->emitNE(*LT, BO)); case BO_LT: -return Discard(this->emitLT(*LT, BO)); +return MaybeCastToBool(this->emitLT(*LT, BO)); case BO_LE: -return Discard(this->emitLE(*LT, BO)); +return MaybeCastToBool(this->emitLE(*LT, BO)); case BO_GT: -return Discard(this->emitGT(*LT, BO)); +return MaybeCastToBool(this->emitGT(*LT, BO)); case BO_GE: -return Discard(this->emitGE(*LT, BO)); +return MaybeCastToBool(this->emitGE(*LT, BO)); case BO_Sub: if (BO->getType()->isFloatingType()) return Discard(this->emitSubf(getRoundingMode(BO), BO)); diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c new file mode 100644 index ..248494c95f5e --- /dev/null +++ b/clang/test/AST/Interp/c.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s +// RUN: %clang_cc1 -verify=ref %s + +/// expected-no-diagnostics +/// ref-no-diagnostics + +_Static_assert(1, ""); +_Static_assert(0 != 1, ""); +_Static_assert(1.0 == 1.0, ""); +_Static_assert( (5 > 4) + (3 > 2) == 2, ""); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 722fc7e - [clang][Interp] Add missing static_assert messages
Author: Timm Bäder Date: 2023-05-31T12:28:22+02:00 New Revision: 722fc7e7ff8672d9b6b1493a28b850775082948e URL: https://github.com/llvm/llvm-project/commit/722fc7e7ff8672d9b6b1493a28b850775082948e DIFF: https://github.com/llvm/llvm-project/commit/722fc7e7ff8672d9b6b1493a28b850775082948e.diff LOG: [clang][Interp] Add missing static_assert messages Added: Modified: clang/test/AST/Interp/depth-limit.cpp clang/test/AST/Interp/depth-limit2.cpp Removed: diff --git a/clang/test/AST/Interp/depth-limit.cpp b/clang/test/AST/Interp/depth-limit.cpp index 3e8a29c569ce..a6d5e56b141c 100644 --- a/clang/test/AST/Interp/depth-limit.cpp +++ b/clang/test/AST/Interp/depth-limit.cpp @@ -29,7 +29,7 @@ constexpr int f(int a) { // expected-note {{in call to 'f(2)'}} \ // expected-note {{in call to 'f(1)'}} } -static_assert(f(0) == 100); // ref-error {{not an integral constant expression}} \ -// ref-note {{in call to 'f(0)'}} \ -// expected-error {{not an integral constant expression}} \ -// expected-note {{in call to 'f(0)'}} +static_assert(f(0) == 100, ""); // ref-error {{not an integral constant expression}} \ +// ref-note {{in call to 'f(0)'}} \ +// expected-error {{not an integral constant expression}} \ +// expected-note {{in call to 'f(0)'}} diff --git a/clang/test/AST/Interp/depth-limit2.cpp b/clang/test/AST/Interp/depth-limit2.cpp index 614472c68ba9..3f6e64a5cf67 100644 --- a/clang/test/AST/Interp/depth-limit2.cpp +++ b/clang/test/AST/Interp/depth-limit2.cpp @@ -16,8 +16,8 @@ constexpr int bar() { // ref-note {{in call to 'foo()'}} } -static_assert(bar() == 12); // expected-error {{not an integral constant expression}} \ -// expected-note {{in call to 'bar()'}} \ -// ref-error {{not an integral constant expression}} \ -// ref-note {{in call to 'bar()'}} +static_assert(bar() == 12, ""); // expected-error {{not an integral constant expression}} \ +// expected-note {{in call to 'bar()'}} \ +// ref-error {{not an integral constant expression}} \ +// ref-note {{in call to 'bar()'}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] da836b3 - [clang][Interp] Track frame depth
Author: Timm Bäder Date: 2023-05-31T12:08:03+02:00 New Revision: da836b36bc3540d21c947a95474d2bb6cc458951 URL: https://github.com/llvm/llvm-project/commit/da836b36bc3540d21c947a95474d2bb6cc458951 DIFF: https://github.com/llvm/llvm-project/commit/da836b36bc3540d21c947a95474d2bb6cc458951.diff LOG: [clang][Interp] Track frame depth Save the depth of each InterpFrame and bail out if we're too deep. Differential Revision: https://reviews.llvm.org/D148614 Added: clang/test/AST/Interp/depth-limit.cpp clang/test/AST/Interp/depth-limit2.cpp Modified: clang/lib/AST/Interp/Interp.cpp clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/InterpFrame.cpp clang/lib/AST/Interp/InterpFrame.h clang/lib/AST/Interp/InterpState.cpp clang/lib/AST/Interp/InterpState.h Removed: diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index 0479f4c60c16..3798146b32d1 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -341,6 +341,17 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { return true; } +bool CheckCallDepth(InterpState &S, CodePtr OpPC) { + if ((S.Current->getDepth() + 1) > S.getLangOpts().ConstexprCallDepth) { +S.FFDiag(S.Current->getSource(OpPC), + diag::note_constexpr_depth_limit_exceeded) +<< S.getLangOpts().ConstexprCallDepth; +return false; + } + + return true; +} + bool CheckThis(InterpState &S, CodePtr OpPC, const Pointer &This) { if (!This.isZero()) return true; diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 64bdd872221a..fd5ce3c32596 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -88,6 +88,10 @@ bool CheckInit(InterpState &S, CodePtr OpPC, const Pointer &Ptr); /// Checks if a method can be called. bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F); +/// Checks if calling the currently active function would exceed +/// the allowed call depth. +bool CheckCallDepth(InterpState &S, CodePtr OpPC); + /// Checks the 'this' pointer. bool CheckThis(InterpState &S, CodePtr OpPC, const Pointer &This); @@ -158,7 +162,6 @@ enum class ArithOp { Add, Sub }; template ::T> bool Ret(InterpState &S, CodePtr &PC, APValue &Result) { - S.CallStackDepth--; const T &Ret = S.Stk.pop(); assert(S.Current->getFrameOffset() == S.Stk.size() && "Invalid frame"); @@ -181,8 +184,6 @@ bool Ret(InterpState &S, CodePtr &PC, APValue &Result) { template inline bool RetVoid(InterpState &S, CodePtr &PC, APValue &Result) { - S.CallStackDepth--; - assert(S.Current->getFrameOffset() == S.Stk.size() && "Invalid frame"); if (Builtin || !S.checkingPotentialConstantExpression()) S.Current->popArgs(); @@ -1598,6 +1599,9 @@ inline bool Call(InterpState &S, CodePtr OpPC, const Function *Func) { if (!CheckCallable(S, OpPC, Func)) return false; + if (!CheckCallDepth(S, OpPC)) +return false; + auto NewFrame = std::make_unique(S, Func, OpPC); InterpFrame *FrameBefore = S.Current; S.Current = NewFrame.get(); diff --git a/clang/lib/AST/Interp/InterpFrame.cpp b/clang/lib/AST/Interp/InterpFrame.cpp index e20f283c2855..14b55bea8820 100644 --- a/clang/lib/AST/Interp/InterpFrame.cpp +++ b/clang/lib/AST/Interp/InterpFrame.cpp @@ -23,8 +23,8 @@ using namespace clang::interp; InterpFrame::InterpFrame(InterpState &S, const Function *Func, InterpFrame *Caller, CodePtr RetPC) -: Caller(Caller), S(S), Func(Func), RetPC(RetPC), - ArgSize(Func ? Func->getArgSize() : 0), +: Caller(Caller), S(S), Depth(Caller ? Caller->Depth + 1 : 0), Func(Func), + RetPC(RetPC), ArgSize(Func ? Func->getArgSize() : 0), Args(static_cast(S.Stk.top())), FrameOffset(S.Stk.size()) { if (!Func) return; diff --git a/clang/lib/AST/Interp/InterpFrame.h b/clang/lib/AST/Interp/InterpFrame.h index c0f4825096be..7988e74a61fe 100644 --- a/clang/lib/AST/Interp/InterpFrame.h +++ b/clang/lib/AST/Interp/InterpFrame.h @@ -15,7 +15,6 @@ #include "Frame.h" #include "Program.h" -#include "State.h" #include #include @@ -120,6 +119,8 @@ class InterpFrame final : public Frame { const Expr *getExpr(CodePtr PC) const; SourceLocation getLocation(CodePtr PC) const; + unsigned getDepth() const { return Depth; } + private: /// Returns an original argument from the stack. template const T &stackRef(unsigned Offset) const { @@ -145,6 +146,8 @@ class InterpFrame final : public Frame { private: /// Reference to the interpreter state. InterpState &S; + /// Depth of this frame. + unsigned Depth; /// Reference to the function being executed. const Function *Func; /// Current object pointer for methods. diff --git a/clang/lib/AST/Interp/InterpState.cpp b/clang/lib/AST/Interp/InterpState.cpp index 6ae4ecd78c0f..bd7daf38796c
[clang] 40c26ec - [clang][Interp] Fix diagnosing uninitialized ctor record arrays
Author: Timm Bäder Date: 2023-05-31T11:39:40+02:00 New Revision: 40c26ec48c8a8ec3c72dde912d3d7118917c8e71 URL: https://github.com/llvm/llvm-project/commit/40c26ec48c8a8ec3c72dde912d3d7118917c8e71 DIFF: https://github.com/llvm/llvm-project/commit/40c26ec48c8a8ec3c72dde912d3d7118917c8e71.diff LOG: [clang][Interp] Fix diagnosing uninitialized ctor record arrays Differential Revision: https://reviews.llvm.org/D143334 Added: Modified: clang/lib/AST/Interp/Interp.cpp clang/test/AST/Interp/cxx20.cpp Removed: diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index 4d331467f8f2e..0479f4c60c16c 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -386,7 +386,7 @@ static bool CheckArrayInitialized(InterpState &S, CodePtr OpPC, size_t NumElems = CAT->getSize().getZExtValue(); QualType ElemType = CAT->getElementType(); - if (isa(ElemType.getTypePtr())) { + if (ElemType->isRecordType()) { const Record *R = BasePtr.getElemRecord(); for (size_t I = 0; I != NumElems; ++I) { Pointer ElemPtr = BasePtr.atIndex(I).narrow(); diff --git a/clang/test/AST/Interp/cxx20.cpp b/clang/test/AST/Interp/cxx20.cpp index 2bf935ef2375b..5d9fa90b482ea 100644 --- a/clang/test/AST/Interp/cxx20.cpp +++ b/clang/test/AST/Interp/cxx20.cpp @@ -138,8 +138,8 @@ static_assert(!b4); // ref-error {{not an integral constant expression}} \ namespace UninitializedFields { class A { public: -int a; // expected-note 2{{subobject declared here}} \ - // ref-note 2{{subobject declared here}} +int a; // expected-note 3{{subobject declared here}} \ + // ref-note 3{{subobject declared here}} constexpr A() {} }; constexpr A a; // expected-error {{must be initialized by a constant expression}} \ @@ -174,19 +174,15 @@ namespace UninitializedFields { // ref-error {{must be initialized by a constant expression}} \ // ref-note {{subobject 'a' is not initialized}} - - // FIXME: These two are currently disabled because the array fields - // cannot be initialized. -#if 0 class C3 { public: A a[2]; constexpr C3() {} }; constexpr C3 c3; // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{subobject of type 'int' is not initialized}} \ + // expected-note {{subobject 'a' is not initialized}} \ // ref-error {{must be initialized by a constant expression}} \ - // ref-note {{subobject of type 'int' is not initialized}} + // ref-note {{subobject 'a' is not initialized}} class C4 { public: @@ -195,10 +191,9 @@ namespace UninitializedFields { constexpr C4(){} }; constexpr C4 c4; // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{subobject of type 'bool' is not initialized}} \ + // expected-note {{subobject 'B' is not initialized}} \ // ref-error {{must be initialized by a constant expression}} \ - // ref-note {{subobject of type 'bool' is not initialized}} -#endif + // ref-note {{subobject 'B' is not initialized}} }; namespace ConstThis { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 895b555 - [clang][Diagnostics][NFC] Move variable decl into if statement
Author: Timm Bäder Date: 2023-05-31T10:49:06+02:00 New Revision: 895b55537870cdaf6e4c304a09f4bf01954ccbd6 URL: https://github.com/llvm/llvm-project/commit/895b55537870cdaf6e4c304a09f4bf01954ccbd6 DIFF: https://github.com/llvm/llvm-project/commit/895b55537870cdaf6e4c304a09f4bf01954ccbd6.diff LOG: [clang][Diagnostics][NFC] Move variable decl into if statement Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index 11ae2667dfa8..ad5f1d45cb63 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -773,8 +773,7 @@ void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc, ArrayRef Ranges) { if (PLoc.isInvalid()) { // At least print the file name if available: -FileID FID = Loc.getFileID(); -if (FID.isValid()) { +if (FileID FID = Loc.getFileID(); FID.isValid()) { if (const FileEntry *FE = Loc.getFileEntry()) { emitFilename(FE->getName(), Loc.getManager()); OS << ": "; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] b5c7892 - [clang][Diagnostics][NFC] Move Buf{Start,End} out of the loop
Author: Timm Bäder Date: 2023-05-31T10:21:24+02:00 New Revision: b5c7892d54f8d415e3e0198e067886c825f26e0c URL: https://github.com/llvm/llvm-project/commit/b5c7892d54f8d415e3e0198e067886c825f26e0c DIFF: https://github.com/llvm/llvm-project/commit/b5c7892d54f8d415e3e0198e067886c825f26e0c.diff LOG: [clang][Diagnostics][NFC] Move Buf{Start,End} out of the loop They don't change inside the loop. Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index f817ab7d3613..11ae2667dfa8 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -1134,6 +1134,8 @@ void TextDiagnostic::emitSnippetAndCaret( StringRef BufData = Loc.getBufferData(&Invalid); if (Invalid) return; + const char *BufStart = BufData.data(); + const char *BufEnd = BufStart + BufData.size(); unsigned CaretLineNo = Loc.getLineNumber(); unsigned CaretColNo = Loc.getColumnNumber(); @@ -1167,9 +1169,6 @@ void TextDiagnostic::emitSnippetAndCaret( for (unsigned LineNo = Lines.first; LineNo != Lines.second + 1; ++LineNo, ++DisplayLineNo) { -const char *BufStart = BufData.data(); -const char *BufEnd = BufStart + BufData.size(); - // Rewind from the current position to the start of the line. const char *LineStart = BufStart + ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] a806b3f - [clang][Diagnostics][NFC] Remove unnecessary StringRef
Author: Timm Bäder Date: 2023-05-31T10:21:24+02:00 New Revision: a806b3f49667f3aa0800572b84f91b77654e29fd URL: https://github.com/llvm/llvm-project/commit/a806b3f49667f3aa0800572b84f91b77654e29fd DIFF: https://github.com/llvm/llvm-project/commit/a806b3f49667f3aa0800572b84f91b77654e29fd.diff LOG: [clang][Diagnostics][NFC] Remove unnecessary StringRef Seems unnecessary to create a StringRef here just so we can drop the trailing null bytes. We can do that with the std::string we create anyway. Differential Revision: https://reviews.llvm.org/D151300 Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index d2cbb55dea87..f817ab7d3613 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -1187,14 +1187,12 @@ void TextDiagnostic::emitSnippetAndCaret( if (size_t(LineEnd - LineStart) > MaxLineLengthToPrint) return; -// Trim trailing null-bytes. -StringRef Line(LineStart, LineEnd - LineStart); -while (!Line.empty() && Line.back() == '\0' && - (LineNo != CaretLineNo || Line.size() > CaretColNo)) - Line = Line.drop_back(); - // Copy the line of code into an std::string for ease of manipulation. -std::string SourceLine(Line.begin(), Line.end()); +std::string SourceLine(LineStart, LineEnd); +// Remove trailing null bytes. +while (!SourceLine.empty() && SourceLine.back() == '\0' && + (LineNo != CaretLineNo || SourceLine.size() > CaretColNo)) + SourceLine.pop_back(); // Build the byte to column map. const SourceColumnMap sourceColMap(SourceLine, DiagOpts->TabStop); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3184fb9 - [clang][Diagnostics] Print empty lines in multiline snippets
Author: Timm Bäder Date: 2023-05-31T10:21:24+02:00 New Revision: 3184fb958091f6b119c878e2eab894d799432686 URL: https://github.com/llvm/llvm-project/commit/3184fb958091f6b119c878e2eab894d799432686 DIFF: https://github.com/llvm/llvm-project/commit/3184fb958091f6b119c878e2eab894d799432686.diff LOG: [clang][Diagnostics] Print empty lines in multiline snippets We should preserve empty lines in output snippets. Differential Revision: https://reviews.llvm.org/D151301 Added: clang/test/Misc/diag-style.cpp Modified: clang/lib/Frontend/TextDiagnostic.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index d285b8873977..d2cbb55dea87 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -1225,7 +1225,7 @@ void TextDiagnostic::emitSnippetAndCaret( // to produce easily machine parsable output. Add a space before the // source line and the caret to make it trivial to tell the main diagnostic // line from what the user is intended to see. -if (DiagOpts->ShowSourceRanges) { +if (DiagOpts->ShowSourceRanges && !SourceLine.empty()) { SourceLine = ' ' + SourceLine; CaretLine = ' ' + CaretLine; } @@ -1262,9 +1262,6 @@ void TextDiagnostic::emitSnippetAndCaret( void TextDiagnostic::emitSnippet(StringRef SourceLine, unsigned MaxLineNoDisplayWidth, unsigned LineNo) { - if (SourceLine.empty()) -return; - // Emit line number. if (MaxLineNoDisplayWidth > 0) { unsigned LineNoDisplayWidth = getNumDisplayWidth(LineNo); diff --git a/clang/test/Misc/diag-style.cpp b/clang/test/Misc/diag-style.cpp new file mode 100644 index ..b12afb2cd923 --- /dev/null +++ b/clang/test/Misc/diag-style.cpp @@ -0,0 +1,12 @@ +// RUN: not %clang_cc1 -fsyntax-only %s 2>&1 | FileCheck -strict-whitespace %s + +/// empty lines in multi-line diagnostic snippets are preserved. +static_assert(false && + + true, ""); +// CHECK: static assertion failed +// CHECK-NEXT: {{^}}4 | static_assert(false &&{{$}} +// CHECK-NEXT: {{^}} | ^~~~{{$}} +// CHECK-NEXT: {{^}}5 | {{$}} +// CHECK-NEXT: {{^}}6 | true, "");{{$}} +// CHECK-NEXT: {{^}} | {{$}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 0157815 - [clang][Diagnostics][NFC] Don't create oversized CaretLine
Author: Timm Bäder Date: 2023-05-31T10:21:24+02:00 New Revision: 01578153ee8228562d0f64d3847e7fc91573da36 URL: https://github.com/llvm/llvm-project/commit/01578153ee8228562d0f64d3847e7fc91573da36 DIFF: https://github.com/llvm/llvm-project/commit/01578153ee8228562d0f64d3847e7fc91573da36.diff LOG: [clang][Diagnostics][NFC] Don't create oversized CaretLine Instead of creating a CaretLine the size of the SourceLine, just leave it empty at first, let HighlightRange resize it to fit all the ~, then resize it to fit the ^. Then we can save ourselves the work to remove the trailing whitespace again. Differential Revision: https://reviews.llvm.org/D151286 Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index 74c555e30689..d285b8873977 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -1199,20 +1199,16 @@ void TextDiagnostic::emitSnippetAndCaret( // Build the byte to column map. const SourceColumnMap sourceColMap(SourceLine, DiagOpts->TabStop); -// Create a line for the caret that is filled with spaces that is the same -// number of columns as the line of source code. -std::string CaretLine(sourceColMap.columns(), ' '); - +std::string CaretLine; // Highlight all of the characters covered by Ranges with ~ characters. for (const auto &I : Ranges) highlightRange(I, LineNo, FID, sourceColMap, CaretLine, SM, LangOpts); // Next, insert the caret itself. if (CaretLineNo == LineNo) { - CaretColNo = sourceColMap.byteToContainingColumn(CaretColNo - 1); - if (CaretLine.size() < CaretColNo + 1) -CaretLine.resize(CaretColNo + 1, ' '); - CaretLine[CaretColNo] = '^'; + size_t Col = sourceColMap.byteToContainingColumn(CaretColNo - 1); + CaretLine.resize(std::max(Col + 1, CaretLine.size()), ' '); + CaretLine[Col] = '^'; } std::string FixItInsertionLine = buildFixItInsertionLine( @@ -1234,10 +1230,6 @@ void TextDiagnostic::emitSnippetAndCaret( CaretLine = ' ' + CaretLine; } -// Finally, remove any blank spaces from the end of CaretLine. -while (!CaretLine.empty() && CaretLine[CaretLine.size() - 1] == ' ') - CaretLine.erase(CaretLine.end() - 1); - // Emit what we have computed. emitSnippet(SourceLine, MaxLineNoDisplayWidth, DisplayLineNo); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 543c929 - [clang][Diagnostics][NFC] Remove unused Indentation parameter
Author: Timm Bäder Date: 2023-05-31T10:17:03+02:00 New Revision: 543c92969ba867434af6688808998b82496e9dc1 URL: https://github.com/llvm/llvm-project/commit/543c92969ba867434af6688808998b82496e9dc1 DIFF: https://github.com/llvm/llvm-project/commit/543c92969ba867434af6688808998b82496e9dc1.diff LOG: [clang][Diagnostics][NFC] Remove unused Indentation parameter printWordWrapped() is only called in one place, which passes all parameters except `Indentation`. So, remove that parameter and use its default value instead. Also remove the other default parameter values, since those are unneeded. Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index 7a2d78b504f8..74c555e30689 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -590,15 +590,10 @@ static unsigned findEndOfWord(unsigned Start, StringRef Str, /// Str will be printed. This will be non-zero when part of the first /// line has already been printed. /// \param Bold if the current text should be bold -/// \param Indentation the number of spaces to indent any lines beyond -/// the first line. /// \returns true if word-wrapping was required, or false if the /// string fit on the first line. -static bool printWordWrapped(raw_ostream &OS, StringRef Str, - unsigned Columns, - unsigned Column = 0, - bool Bold = false, - unsigned Indentation = WordWrapIndentation) { +static bool printWordWrapped(raw_ostream &OS, StringRef Str, unsigned Columns, + unsigned Column, bool Bold) { const unsigned Length = std::min(Str.find('\n'), Str.size()); bool TextNormal = true; @@ -630,10 +625,10 @@ static bool printWordWrapped(raw_ostream &OS, StringRef Str, // This word does not fit on the current line, so wrap to the next // line. OS << '\n'; -OS.indent(Indentation); +OS.indent(WordWrapIndentation); applyTemplateHighlighting(OS, Str.substr(WordStart, WordLength), TextNormal, Bold); -Column = Indentation + WordLength; +Column = WordWrapIndentation + WordLength; Wrapped = true; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 50f0b8d - [clang][Diagnostics][NFC] Merge byte/column mapping functions into one.
Author: Timm Bäder Date: 2023-05-31T10:00:08+02:00 New Revision: 50f0b8d219cb1557625ce768ea78670d13671e1d URL: https://github.com/llvm/llvm-project/commit/50f0b8d219cb1557625ce768ea78670d13671e1d DIFF: https://github.com/llvm/llvm-project/commit/50f0b8d219cb1557625ce768ea78670d13671e1d.diff LOG: [clang][Diagnostics][NFC] Merge byte/column mapping functions into one. They were both only called from one place and did very similar things. Merge them into one, so we only have to iterate the source line once to generate the SourceMap. Differential Revision: https://reviews.llvm.org/D151100 Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index a03c1856eaeb..7a2d78b504f8 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -173,7 +173,21 @@ static void expandTabs(std::string &SourceLine, unsigned TabStop) { } } -/// This function takes a raw source line and produces a mapping from the bytes +/// \p BytesOut: +/// A mapping from columns to the byte of the source line that produced the +/// character displaying at that column. This is the inverse of \p ColumnsOut. +/// +/// The last element in the array is the number of bytes in the source string. +/// +/// example: (given a tabstop of 8) +/// +///"a \t \u3042" -> {0,1,2,-1,-1,-1,-1,-1,3,4,-1,7} +/// +/// (\\u3042 is represented in UTF-8 by three bytes and takes two columns to +/// display) +/// +/// \p ColumnsOut: +/// A mapping from the bytes /// of the printable representation of the line to the columns those printable /// characters will appear at (numbering the first column as 0). /// @@ -195,60 +209,34 @@ static void expandTabs(std::string &SourceLine, unsigned TabStop) { /// /// (\\u3042 is represented in UTF-8 by three bytes and takes two columns to /// display) -static void byteToColumn(StringRef SourceLine, unsigned TabStop, - SmallVectorImpl &out) { - out.clear(); +static void genColumnByteMapping(StringRef SourceLine, unsigned TabStop, + SmallVectorImpl &BytesOut, + SmallVectorImpl &ColumnsOut) { + assert(BytesOut.empty()); + assert(ColumnsOut.empty()); if (SourceLine.empty()) { -out.resize(1u,0); +BytesOut.resize(1u, 0); +ColumnsOut.resize(1u, 0); return; } - out.resize(SourceLine.size()+1, -1); - - int columns = 0; - size_t i = 0; - while (i,bool> res - = printableTextForNextCharacter(SourceLine, &i, TabStop); -columns += llvm::sys::locale::columnWidth(res.first); - } - out.back() = columns; -} - -/// This function takes a raw source line and produces a mapping from columns -/// to the byte of the source line that produced the character displaying at -/// that column. This is the inverse of the mapping produced by byteToColumn() -/// -/// The last element in the array is the number of bytes in the source string -/// -/// example: (given a tabstop of 8) -/// -///"a \t \u3042" -> {0,1,2,-1,-1,-1,-1,-1,3,4,-1,7} -/// -/// (\\u3042 is represented in UTF-8 by three bytes and takes two columns to -/// display) -static void columnToByte(StringRef SourceLine, unsigned TabStop, - SmallVectorImpl &out) { - out.clear(); + ColumnsOut.resize(SourceLine.size() + 1, -1); - if (SourceLine.empty()) { -out.resize(1u, 0); -return; + int Columns = 0; + size_t I = 0; + while (I < SourceLine.size()) { +ColumnsOut[I] = Columns; +BytesOut.resize(Columns + 1, -1); +BytesOut.back() = I; +auto [Str, Printable] = +printableTextForNextCharacter(SourceLine, &I, TabStop); +Columns += llvm::sys::locale::columnWidth(Str); } - int columns = 0; - size_t i = 0; - while (i,bool> res - = printableTextForNextCharacter(SourceLine, &i, TabStop); -columns += llvm::sys::locale::columnWidth(res.first); - } - out.resize(columns+1, -1); - out.back() = i; + ColumnsOut.back() = Columns; + BytesOut.resize(Columns + 1, -1); + BytesOut.back() = I; } namespace { @@ -256,8 +244,7 @@ struct SourceColumnMap { SourceColumnMap(StringRef SourceLine, unsigned TabStop) : m_SourceLine(SourceLine) { -::byteToColumn(SourceLine, TabStop, m_byteToColumn); -::columnToByte(SourceLine, TabStop, m_columnToByte); +genColumnByteMapping(SourceLine, TabStop, m_columnToByte, m_byteToColumn); assert(m_byteToColumn.size()==SourceLine.size()+1); assert(0 < m_byteToColumn.size() && 0 < m_columnToByte.size()); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] bb6c036 - [clang][Diagnostics][NFC] Use getFileID() directly
Author: Timm Bäder Date: 2023-05-31T09:57:16+02:00 New Revision: bb6c036ef378de321d5b7fc0ada317f91c88570d URL: https://github.com/llvm/llvm-project/commit/bb6c036ef378de321d5b7fc0ada317f91c88570d DIFF: https://github.com/llvm/llvm-project/commit/bb6c036ef378de321d5b7fc0ada317f91c88570d.diff LOG: [clang][Diagnostics][NFC] Use getFileID() directly Instead of calling getDecomposedLoc() and then only using the FileID. Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index 83f254f7de83..a03c1856eaeb 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -1144,9 +1144,7 @@ void TextDiagnostic::emitSnippetAndCaret( (LastLevel != DiagnosticsEngine::Note || Level == LastLevel)) return; - // Decompose the location into a FID/Offset pair. - std::pair LocInfo = Loc.getDecomposedLoc(); - FileID FID = LocInfo.first; + FileID FID = Loc.getFileID(); const SourceManager &SM = Loc.getManager(); // Get information about the buffer it points into. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] c113cbb - [clang][Diagnostic][NFC] Simplify emitDiagnosticLoc
Author: Timm Bäder Date: 2023-05-31T09:40:24+02:00 New Revision: c113cbb51005108d1380a4b9d501ddeb1366a406 URL: https://github.com/llvm/llvm-project/commit/c113cbb51005108d1380a4b9d501ddeb1366a406 DIFF: https://github.com/llvm/llvm-project/commit/c113cbb51005108d1380a4b9d501ddeb1366a406.diff LOG: [clang][Diagnostic][NFC] Simplify emitDiagnosticLoc We don't use the offset returned from SourceManager::getDecomposedLoc here, so we might as well just use getFileID(). Differential Revision: https://reviews.llvm.org/D151093 Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index 930033a7d552..83f254f7de83 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -850,30 +850,26 @@ void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc, if (DiagOpts->ShowSourceRanges && !Ranges.empty()) { FileID CaretFileID = Loc.getExpansionLoc().getFileID(); bool PrintedRange = false; +const SourceManager &SM = Loc.getManager(); for (const auto &R : Ranges) { // Ignore invalid ranges. if (!R.isValid()) continue; - auto &SM = Loc.getManager(); SourceLocation B = SM.getExpansionLoc(R.getBegin()); CharSourceRange ERange = SM.getExpansionRange(R.getEnd()); SourceLocation E = ERange.getEnd(); - bool IsTokenRange = ERange.isTokenRange(); - std::pair BInfo = SM.getDecomposedLoc(B); - std::pair EInfo = SM.getDecomposedLoc(E); - - // If the start or end of the range is in another file, just discard - // it. - if (BInfo.first != CaretFileID || EInfo.first != CaretFileID) + // If the start or end of the range is in another file, just + // discard it. + if (SM.getFileID(B) != CaretFileID || SM.getFileID(E) != CaretFileID) continue; // Add in the length of the token, so that we cover multi-char // tokens. unsigned TokSize = 0; - if (IsTokenRange) + if (ERange.isTokenRange()) TokSize = Lexer::MeasureTokenLength(E, SM, LangOpts); FullSourceLoc BF(B, SM), EF(E, SM); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 1c76548 - [clang][Diagnostics] Use llvm::raw_ostream::indent()
Author: Timm Bäder Date: 2023-05-31T09:40:24+02:00 New Revision: 1c765483fd34efe3ff7f71a9d2d5781bdf3d4517 URL: https://github.com/llvm/llvm-project/commit/1c765483fd34efe3ff7f71a9d2d5781bdf3d4517 DIFF: https://github.com/llvm/llvm-project/commit/1c765483fd34efe3ff7f71a9d2d5781bdf3d4517.diff LOG: [clang][Diagnostics] Use llvm::raw_ostream::indent() Differential Revision: https://reviews.llvm.org/D151078 Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index 9b11294224ed..930033a7d552 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -615,9 +615,6 @@ static bool printWordWrapped(raw_ostream &OS, StringRef Str, const unsigned Length = std::min(Str.find('\n'), Str.size()); bool TextNormal = true; - // The string used to indent each line. - SmallString<16> IndentStr; - IndentStr.assign(Indentation, ' '); bool Wrapped = false; for (unsigned WordStart = 0, WordEnd; WordStart < Length; WordStart = WordEnd) { @@ -646,7 +643,7 @@ static bool printWordWrapped(raw_ostream &OS, StringRef Str, // This word does not fit on the current line, so wrap to the next // line. OS << '\n'; -OS.write(&IndentStr[0], Indentation); +OS.indent(Indentation); applyTemplateHighlighting(OS, Str.substr(WordStart, WordLength), TextNormal, Bold); Column = Indentation + WordLength; @@ -1188,12 +1185,8 @@ void TextDiagnostic::emitSnippetAndCaret( ? std::max(4u, getNumDisplayWidth(DisplayLineNo + MaxLines)) : 0; auto indentForLineNumbers = [&] { -if (MaxLineNoDisplayWidth > 0) { - OS << ' '; - for (unsigned I = 0; I != MaxLineNoDisplayWidth; ++I) -OS << ' '; - OS << " | "; -} +if (MaxLineNoDisplayWidth > 0) + OS.indent(MaxLineNoDisplayWidth + 2) << "| "; }; for (unsigned LineNo = Lines.first; LineNo != Lines.second + 1; @@ -1307,11 +1300,8 @@ void TextDiagnostic::emitSnippet(StringRef SourceLine, // Emit line number. if (MaxLineNoDisplayWidth > 0) { unsigned LineNoDisplayWidth = getNumDisplayWidth(LineNo); -OS << ' '; -for (unsigned I = LineNoDisplayWidth; I < MaxLineNoDisplayWidth; ++I) - OS << ' '; -OS << LineNo; -OS << " | "; +OS.indent(MaxLineNoDisplayWidth - LineNoDisplayWidth + 1) +<< LineNo << " | "; } // Print the source line one character at a time. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 49843c5 - [clang][Diagnostics] Simplify emitSnippet()
Author: Timm Bäder Date: 2023-05-31T09:40:24+02:00 New Revision: 49843c5036847a8e2f83852c8a515c2784a1645e URL: https://github.com/llvm/llvm-project/commit/49843c5036847a8e2f83852c8a515c2784a1645e DIFF: https://github.com/llvm/llvm-project/commit/49843c5036847a8e2f83852c8a515c2784a1645e.diff LOG: [clang][Diagnostics] Simplify emitSnippet() Don't try to minimize the times we invoke operator<< on the output stream by keeping a ToPrint string around. Instead, just print the characters as we iterate over them. Differential Revision: https://reviews.llvm.org/D151075 Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index 51b901180ee5..9b11294224ed 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -1314,30 +1314,27 @@ void TextDiagnostic::emitSnippet(StringRef SourceLine, OS << " | "; } + // Print the source line one character at a time. bool PrintReversed = false; - std::string ToPrint; size_t I = 0; while (I < SourceLine.size()) { auto [Str, WasPrintable] = printableTextForNextCharacter(SourceLine, &I, DiagOpts->TabStop); -if (DiagOpts->ShowColors && WasPrintable == PrintReversed) { - if (PrintReversed) -OS.reverseColor(); - OS << ToPrint; - ToPrint.clear(); - if (DiagOpts->ShowColors) -OS.resetColor(); +// Toggle inverted colors on or off for this character. +if (DiagOpts->ShowColors) { + if (WasPrintable == PrintReversed) { +PrintReversed = !PrintReversed; +if (PrintReversed) + OS.reverseColor(); +else + OS.resetColor(); + } } - -PrintReversed = !WasPrintable; -ToPrint += Str; +OS << Str; } - if (PrintReversed && DiagOpts->ShowColors) -OS.reverseColor(); - OS << ToPrint; - if (PrintReversed && DiagOpts->ShowColors) + if (DiagOpts->ShowColors) OS.resetColor(); OS << '\n'; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] b7e5cb1 - [clang][NFC] Refactor emitSnippet()
Author: Timm Bäder Date: 2023-05-31T09:21:23+02:00 New Revision: b7e5cb1f9a3a5226f22bb81c865214be81dce940 URL: https://github.com/llvm/llvm-project/commit/b7e5cb1f9a3a5226f22bb81c865214be81dce940 DIFF: https://github.com/llvm/llvm-project/commit/b7e5cb1f9a3a5226f22bb81c865214be81dce940.diff LOG: [clang][NFC] Refactor emitSnippet() Rename parameters and local variables and reorder things a bit to be closer to their first point of use. Differential Revision: https://reviews.llvm.org/D150840 Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index baf9b017fc83..51b901180ee5 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -1298,16 +1298,12 @@ void TextDiagnostic::emitSnippetAndCaret( emitParseableFixits(Hints, SM); } -void TextDiagnostic::emitSnippet(StringRef line, unsigned MaxLineNoDisplayWidth, +void TextDiagnostic::emitSnippet(StringRef SourceLine, + unsigned MaxLineNoDisplayWidth, unsigned LineNo) { - if (line.empty()) + if (SourceLine.empty()) return; - size_t i = 0; - - std::string to_print; - bool print_reversed = false; - // Emit line number. if (MaxLineNoDisplayWidth > 0) { unsigned LineNoDisplayWidth = getNumDisplayWidth(LineNo); @@ -1318,28 +1314,30 @@ void TextDiagnostic::emitSnippet(StringRef line, unsigned MaxLineNoDisplayWidth, OS << " | "; } - while (i,bool> res -= printableTextForNextCharacter(line, &i, DiagOpts->TabStop); -bool was_printable = res.second; + bool PrintReversed = false; + std::string ToPrint; + size_t I = 0; + while (I < SourceLine.size()) { +auto [Str, WasPrintable] = +printableTextForNextCharacter(SourceLine, &I, DiagOpts->TabStop); -if (DiagOpts->ShowColors && was_printable == print_reversed) { - if (print_reversed) +if (DiagOpts->ShowColors && WasPrintable == PrintReversed) { + if (PrintReversed) OS.reverseColor(); - OS << to_print; - to_print.clear(); + OS << ToPrint; + ToPrint.clear(); if (DiagOpts->ShowColors) OS.resetColor(); } -print_reversed = !was_printable; -to_print += res.first.str(); +PrintReversed = !WasPrintable; +ToPrint += Str; } - if (print_reversed && DiagOpts->ShowColors) + if (PrintReversed && DiagOpts->ShowColors) OS.reverseColor(); - OS << to_print; - if (print_reversed && DiagOpts->ShowColors) + OS << ToPrint; + if (PrintReversed && DiagOpts->ShowColors) OS.resetColor(); OS << '\n'; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] a0ea9f6 - [clang] Fix 39f4bd214f1be248283fb7e35bc2610c19169252 on win builders
Author: Timm Bäder Date: 2023-05-31T09:13:48+02:00 New Revision: a0ea9f63c25b1cd4cb7747ea611596bb5e2db8a3 URL: https://github.com/llvm/llvm-project/commit/a0ea9f63c25b1cd4cb7747ea611596bb5e2db8a3 DIFF: https://github.com/llvm/llvm-project/commit/a0ea9f63c25b1cd4cb7747ea611596bb5e2db8a3.diff LOG: [clang] Fix 39f4bd214f1be248283fb7e35bc2610c19169252 on win builders Added: Modified: clang/lib/AST/Interp/Disasm.cpp Removed: diff --git a/clang/lib/AST/Interp/Disasm.cpp b/clang/lib/AST/Interp/Disasm.cpp index f4a6cb85470f..35ed5d128697 100644 --- a/clang/lib/AST/Interp/Disasm.cpp +++ b/clang/lib/AST/Interp/Disasm.cpp @@ -42,7 +42,9 @@ LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const { auto PrintName = [&OS](const char *Name) { OS << Name; -OS.indent(std::max(30l - strlen(Name), 0ul)); +long N = 30 - strlen(Name); +if (N > 0) + OS.indent(N); }; for (CodePtr Start = getCodeBegin(), PC = Start; PC != getCodeEnd();) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] ddff70c - [clang][Interp][NFC] Make InterpFrame::describe() more const-correct
Author: Timm Bäder Date: 2023-05-31T09:01:57+02:00 New Revision: ddff70cb4b0017489d98bf301a5bcc4f9fa4afab URL: https://github.com/llvm/llvm-project/commit/ddff70cb4b0017489d98bf301a5bcc4f9fa4afab DIFF: https://github.com/llvm/llvm-project/commit/ddff70cb4b0017489d98bf301a5bcc4f9fa4afab.diff LOG: [clang][Interp][NFC] Make InterpFrame::describe() more const-correct Added: Modified: clang/lib/AST/Interp/InterpFrame.cpp Removed: diff --git a/clang/lib/AST/Interp/InterpFrame.cpp b/clang/lib/AST/Interp/InterpFrame.cpp index 6acfbd3fa614..e20f283c2855 100644 --- a/clang/lib/AST/Interp/InterpFrame.cpp +++ b/clang/lib/AST/Interp/InterpFrame.cpp @@ -98,20 +98,19 @@ void print(llvm::raw_ostream &OS, const Pointer &P, ASTContext &Ctx, return; } - auto printDesc = [&OS, &Ctx](Descriptor *Desc) { -if (auto *D = Desc->asDecl()) { + auto printDesc = [&OS, &Ctx](const Descriptor *Desc) { +if (const auto *D = Desc->asDecl()) { // Subfields or named values. - if (auto *VD = dyn_cast(D)) { + if (const auto *VD = dyn_cast(D)) { OS << *VD; return; } // Base classes. - if (isa(D)) { + if (isa(D)) return; - } } // Temporary expression. -if (auto *E = Desc->asExpr()) { +if (const auto *E = Desc->asExpr()) { E->printPretty(OS, nullptr, Ctx.getPrintingPolicy()); return; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 39f4bd2 - [clang][Interp][NFC] Simplify dump() indentation
Author: Timm Bäder Date: 2023-05-31T09:01:57+02:00 New Revision: 39f4bd214f1be248283fb7e35bc2610c19169252 URL: https://github.com/llvm/llvm-project/commit/39f4bd214f1be248283fb7e35bc2610c19169252 DIFF: https://github.com/llvm/llvm-project/commit/39f4bd214f1be248283fb7e35bc2610c19169252.diff LOG: [clang][Interp][NFC] Simplify dump() indentation Use llvm::raw_ostream::indent(). Added: Modified: clang/lib/AST/Interp/Disasm.cpp Removed: diff --git a/clang/lib/AST/Interp/Disasm.cpp b/clang/lib/AST/Interp/Disasm.cpp index 7a5da90cd9002..f4a6cb85470fb 100644 --- a/clang/lib/AST/Interp/Disasm.cpp +++ b/clang/lib/AST/Interp/Disasm.cpp @@ -42,9 +42,7 @@ LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const { auto PrintName = [&OS](const char *Name) { OS << Name; -for (long I = 0, N = strlen(Name); I < 30 - N; ++I) { - OS << ' '; -} +OS.indent(std::max(30l - strlen(Name), 0ul)); }; for (CodePtr Start = getCodeBegin(), PC = Start; PC != getCodeEnd();) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] f63155a - [clang] Show line numbers in diagnostic code snippets
Author: Timm Bäder Date: 2023-05-31T07:26:03+02:00 New Revision: f63155aaa6467bd2610820dfd1996af3bb6029a7 URL: https://github.com/llvm/llvm-project/commit/f63155aaa6467bd2610820dfd1996af3bb6029a7 DIFF: https://github.com/llvm/llvm-project/commit/f63155aaa6467bd2610820dfd1996af3bb6029a7.diff LOG: [clang] Show line numbers in diagnostic code snippets Show line numbers to the left of diagnostic code snippets and increase the numbers of lines shown from 1 to 16. Differential Revision: https://reviews.llvm.org/D147875 Added: Modified: clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-float16.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-floating-point-opencl-half.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-floating-point.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-hexadecimal-floating-point.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-custom-list.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-ms.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer.cpp clang/docs/ReleaseNotes.rst clang/docs/UsersManual.rst clang/include/clang/Basic/DiagnosticOptions.def clang/include/clang/Basic/DiagnosticOptions.h clang/include/clang/Driver/Options.td clang/include/clang/Frontend/TextDiagnostic.h clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/TextDiagnostic.cpp clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp clang/test/FixIt/fixit-function-call.cpp clang/test/FixIt/fixit-newline-style.c clang/test/FixIt/fixit-unicode-with-utf8-output.c clang/test/FixIt/fixit-unicode.c clang/test/Frontend/source-col-map.c clang/test/Lexer/header.cpp clang/test/Lexer/string-literal-errors.cpp clang/test/Misc/caret-diags-macros.c clang/test/Misc/caret-diags-multiline.cpp clang/test/Misc/diag-macro-backtrace.c clang/test/Misc/message-length.c clang/test/Misc/tabstop.c clang/test/Misc/unnecessary-elipses.cpp clang/test/Misc/unprintable.c clang/test/Misc/wrong-encoding.c clang/test/Parser/brackets.c clang/test/Parser/brackets.cpp clang/test/Preprocessor/ucn-pp-identifier.c clang/test/Sema/caret-diags-complex-init.cpp clang/test/SemaCXX/struct-class-redecl.cpp lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py Removed: diff --git a/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp b/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp index 0dc06df4f18b4..6fa700bf06d4f 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp @@ -31,7 +31,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'l', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v5 = 1l; // CHECK-MESSAGES-NEXT: ^~ - // CHECK-MESSAGES-NEXT: {{^ *}}L{{$}} + // CHECK-MESSAGES-NEXT: {{^ *| *}}L{{$}} // CHECK-FIXES: static constexpr auto v5 = 1L; static_assert(is_same::value, ""); static_assert(v5 == 1, ""); @@ -46,7 +46,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'll', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v7 = 1ll; // CHECK-MESSAGES-NEXT: ^~~ - // CHECK-MESSAGES-NEXT: {{^ *}}LL{{$}} + // CHECK-MESSAGES-NEXT: {{^ *| *}}LL{{$}} // CHECK-FIXES: static constexpr auto v7 = 1LL; static_assert(is_same::value, ""); static_assert(v7 == 1, ""); @@ -79,7 +79,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lu', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v13 = 1lu; // CHECK-MESSAGES-NEXT: ^~~ - // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}} + // CHECK-MESSAGES-NEXT: {{^ *| *}}LU{{$}} // CHECK-FIXES: static constexpr auto v13 = 1LU; static_assert(is_same::value, ""); static_assert(v13 == 1, ""); @@ -88,7 +88,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Lu', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1Lu; // CHECK-MESSAGES-NEXT: ^~~ - // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}} + // CHECK-MESSAGES-NEXT: {{^ *| *}}LU{{$}} // CHECK-FIXES: static constexpr auto v14 = 1LU; static_assert(is_same::value, ""); static_assert(v14 == 1, ""); @@ -97,7 +97,7 @@ voi
[clang-tools-extra] f63155a - [clang] Show line numbers in diagnostic code snippets
Author: Timm Bäder Date: 2023-05-31T07:26:03+02:00 New Revision: f63155aaa6467bd2610820dfd1996af3bb6029a7 URL: https://github.com/llvm/llvm-project/commit/f63155aaa6467bd2610820dfd1996af3bb6029a7 DIFF: https://github.com/llvm/llvm-project/commit/f63155aaa6467bd2610820dfd1996af3bb6029a7.diff LOG: [clang] Show line numbers in diagnostic code snippets Show line numbers to the left of diagnostic code snippets and increase the numbers of lines shown from 1 to 16. Differential Revision: https://reviews.llvm.org/D147875 Added: Modified: clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-float16.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-floating-point-opencl-half.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-floating-point.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-hexadecimal-floating-point.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-custom-list.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-ms.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer.cpp clang/docs/ReleaseNotes.rst clang/docs/UsersManual.rst clang/include/clang/Basic/DiagnosticOptions.def clang/include/clang/Basic/DiagnosticOptions.h clang/include/clang/Driver/Options.td clang/include/clang/Frontend/TextDiagnostic.h clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/TextDiagnostic.cpp clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp clang/test/FixIt/fixit-function-call.cpp clang/test/FixIt/fixit-newline-style.c clang/test/FixIt/fixit-unicode-with-utf8-output.c clang/test/FixIt/fixit-unicode.c clang/test/Frontend/source-col-map.c clang/test/Lexer/header.cpp clang/test/Lexer/string-literal-errors.cpp clang/test/Misc/caret-diags-macros.c clang/test/Misc/caret-diags-multiline.cpp clang/test/Misc/diag-macro-backtrace.c clang/test/Misc/message-length.c clang/test/Misc/tabstop.c clang/test/Misc/unnecessary-elipses.cpp clang/test/Misc/unprintable.c clang/test/Misc/wrong-encoding.c clang/test/Parser/brackets.c clang/test/Parser/brackets.cpp clang/test/Preprocessor/ucn-pp-identifier.c clang/test/Sema/caret-diags-complex-init.cpp clang/test/SemaCXX/struct-class-redecl.cpp lldb/test/API/commands/expression/diagnostics/TestExprDiagnostics.py Removed: diff --git a/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp b/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp index 0dc06df4f18b4..6fa700bf06d4f 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp @@ -31,7 +31,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'l', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v5 = 1l; // CHECK-MESSAGES-NEXT: ^~ - // CHECK-MESSAGES-NEXT: {{^ *}}L{{$}} + // CHECK-MESSAGES-NEXT: {{^ *| *}}L{{$}} // CHECK-FIXES: static constexpr auto v5 = 1L; static_assert(is_same::value, ""); static_assert(v5 == 1, ""); @@ -46,7 +46,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'll', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v7 = 1ll; // CHECK-MESSAGES-NEXT: ^~~ - // CHECK-MESSAGES-NEXT: {{^ *}}LL{{$}} + // CHECK-MESSAGES-NEXT: {{^ *| *}}LL{{$}} // CHECK-FIXES: static constexpr auto v7 = 1LL; static_assert(is_same::value, ""); static_assert(v7 == 1, ""); @@ -79,7 +79,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lu', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v13 = 1lu; // CHECK-MESSAGES-NEXT: ^~~ - // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}} + // CHECK-MESSAGES-NEXT: {{^ *| *}}LU{{$}} // CHECK-FIXES: static constexpr auto v13 = 1LU; static_assert(is_same::value, ""); static_assert(v13 == 1, ""); @@ -88,7 +88,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Lu', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1Lu; // CHECK-MESSAGES-NEXT: ^~~ - // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}} + // CHECK-MESSAGES-NEXT: {{^ *| *}}LU{{$}} // CHECK-FIXES: static constexpr auto v14 = 1LU; static_assert(is_same::value, ""); static_assert(v14 == 1, ""); @@ -97,7 +97,7 @@ voi
[clang] f8c9947 - [clang][Interp][NFC] Move dyn_cast check into if condition
Author: Timm Bäder Date: 2023-05-17T10:27:44+02:00 New Revision: f8c99477d4b3e8c9faf0f316178e8ab92e281602 URL: https://github.com/llvm/llvm-project/commit/f8c99477d4b3e8c9faf0f316178e8ab92e281602 DIFF: https://github.com/llvm/llvm-project/commit/f8c99477d4b3e8c9faf0f316178e8ab92e281602.diff LOG: [clang][Interp][NFC] Move dyn_cast check into if condition M is not used anywhere else. Added: Modified: clang/lib/AST/Interp/InterpFrame.cpp Removed: diff --git a/clang/lib/AST/Interp/InterpFrame.cpp b/clang/lib/AST/Interp/InterpFrame.cpp index a8c4aab84ef8d..6acfbd3fa6143 100644 --- a/clang/lib/AST/Interp/InterpFrame.cpp +++ b/clang/lib/AST/Interp/InterpFrame.cpp @@ -147,8 +147,8 @@ void print(llvm::raw_ostream &OS, const Pointer &P, ASTContext &Ctx, void InterpFrame::describe(llvm::raw_ostream &OS) { const FunctionDecl *F = getCallee(); - auto *M = dyn_cast(F); - if (M && M->isInstance() && !isa(F)) { + if (const auto *M = dyn_cast(F); + M && M->isInstance() && !isa(F)) { print(OS, This, S.getCtx(), S.getCtx().getRecordType(M->getParent())); OS << "->"; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 5fd35c3 - Revert "[clang] Show line numbers in diagnostic code snippets"
Author: Timm Bäder Date: 2023-05-16T17:26:48+02:00 New Revision: 5fd35c326a1bc96d1c2a8ed67d0e1f61ed10ea0e URL: https://github.com/llvm/llvm-project/commit/5fd35c326a1bc96d1c2a8ed67d0e1f61ed10ea0e DIFF: https://github.com/llvm/llvm-project/commit/5fd35c326a1bc96d1c2a8ed67d0e1f61ed10ea0e.diff LOG: Revert "[clang] Show line numbers in diagnostic code snippets" This reverts commit e2917311f026cc445fa8aeefa0457b0c7a60824a. This caused some problems with lldb testing the diagnostic output: https://lab.llvm.org/buildbot/#/builders/68/builds/52754 Added: Modified: clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-float16.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-floating-point-opencl-half.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-floating-point.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-hexadecimal-floating-point.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-custom-list.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-ms.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer.cpp clang/docs/ReleaseNotes.rst clang/docs/UsersManual.rst clang/include/clang/Basic/DiagnosticOptions.def clang/include/clang/Basic/DiagnosticOptions.h clang/include/clang/Driver/Options.td clang/include/clang/Frontend/TextDiagnostic.h clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/TextDiagnostic.cpp clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp clang/test/FixIt/fixit-function-call.cpp clang/test/FixIt/fixit-newline-style.c clang/test/FixIt/fixit-unicode-with-utf8-output.c clang/test/FixIt/fixit-unicode.c clang/test/Frontend/source-col-map.c clang/test/Lexer/header.cpp clang/test/Lexer/string-literal-errors.cpp clang/test/Misc/caret-diags-macros.c clang/test/Misc/caret-diags-multiline.cpp clang/test/Misc/diag-macro-backtrace.c clang/test/Misc/message-length.c clang/test/Misc/tabstop.c clang/test/Misc/unnecessary-elipses.cpp clang/test/Misc/unprintable.c clang/test/Misc/wrong-encoding.c clang/test/Parser/brackets.c clang/test/Parser/brackets.cpp clang/test/Preprocessor/ucn-pp-identifier.c clang/test/Sema/caret-diags-complex-init.cpp clang/test/SemaCXX/struct-class-redecl.cpp Removed: diff --git a/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp b/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp index 6fa700bf06d4f..0dc06df4f18b4 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp @@ -31,7 +31,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'l', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v5 = 1l; // CHECK-MESSAGES-NEXT: ^~ - // CHECK-MESSAGES-NEXT: {{^ *| *}}L{{$}} + // CHECK-MESSAGES-NEXT: {{^ *}}L{{$}} // CHECK-FIXES: static constexpr auto v5 = 1L; static_assert(is_same::value, ""); static_assert(v5 == 1, ""); @@ -46,7 +46,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'll', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v7 = 1ll; // CHECK-MESSAGES-NEXT: ^~~ - // CHECK-MESSAGES-NEXT: {{^ *| *}}LL{{$}} + // CHECK-MESSAGES-NEXT: {{^ *}}LL{{$}} // CHECK-FIXES: static constexpr auto v7 = 1LL; static_assert(is_same::value, ""); static_assert(v7 == 1, ""); @@ -79,7 +79,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lu', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v13 = 1lu; // CHECK-MESSAGES-NEXT: ^~~ - // CHECK-MESSAGES-NEXT: {{^ *| *}}LU{{$}} + // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}} // CHECK-FIXES: static constexpr auto v13 = 1LU; static_assert(is_same::value, ""); static_assert(v13 == 1, ""); @@ -88,7 +88,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Lu', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1Lu; // CHECK-MESSAGES-NEXT: ^~~ - // CHECK-MESSAGES-NEXT: {{^ *| *}}LU{{$}} + // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}} // CHECK-FIXES: static constexpr auto v14 = 1LU; static_assert(is_same::value, ""); static_assert(v14 == 1, ""); @@ -97,7 +97,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[
[clang] 8bc0a29 - [clang][docs] Fix sphinx bot
Author: Timm Bäder Date: 2023-05-16T17:20:40+02:00 New Revision: 8bc0a29f01050935bbeac6f1c3a5987e45eb3144 URL: https://github.com/llvm/llvm-project/commit/8bc0a29f01050935bbeac6f1c3a5987e45eb3144 DIFF: https://github.com/llvm/llvm-project/commit/8bc0a29f01050935bbeac6f1c3a5987e45eb3144.diff LOG: [clang][docs] Fix sphinx bot Breakage: https://lab.llvm.org/buildbot/#/builders/92/builds/44222 Added: Modified: clang/docs/UsersManual.rst Removed: diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 27728c697bdf..46260c4e0757 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -596,7 +596,7 @@ output format of the diagnostics that it generates. | int - With :option:`-fno-diagnostics-show-line-numbers`: + With -fno-diagnostics-show-line-numbers: :: ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e291731 - [clang] Show line numbers in diagnostic code snippets
Author: Timm Bäder Date: 2023-05-16T17:12:47+02:00 New Revision: e2917311f026cc445fa8aeefa0457b0c7a60824a URL: https://github.com/llvm/llvm-project/commit/e2917311f026cc445fa8aeefa0457b0c7a60824a DIFF: https://github.com/llvm/llvm-project/commit/e2917311f026cc445fa8aeefa0457b0c7a60824a.diff LOG: [clang] Show line numbers in diagnostic code snippets Show line numbers to the left of diagnostic code snippets and increase the numbers of lines shown from 1 to 16. Differential Revision: https://reviews.llvm.org/D147875 Added: Modified: clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-float16.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-floating-point-opencl-half.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-floating-point.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-hexadecimal-floating-point.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-custom-list.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer-ms.cpp clang-tools-extra/test/clang-tidy/checkers/readability/uppercase-literal-suffix-integer.cpp clang/docs/ReleaseNotes.rst clang/docs/UsersManual.rst clang/include/clang/Basic/DiagnosticOptions.def clang/include/clang/Basic/DiagnosticOptions.h clang/include/clang/Driver/Options.td clang/include/clang/Frontend/TextDiagnostic.h clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/TextDiagnostic.cpp clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp clang/test/FixIt/fixit-function-call.cpp clang/test/FixIt/fixit-newline-style.c clang/test/FixIt/fixit-unicode-with-utf8-output.c clang/test/FixIt/fixit-unicode.c clang/test/Frontend/source-col-map.c clang/test/Lexer/header.cpp clang/test/Lexer/string-literal-errors.cpp clang/test/Misc/caret-diags-macros.c clang/test/Misc/caret-diags-multiline.cpp clang/test/Misc/diag-macro-backtrace.c clang/test/Misc/message-length.c clang/test/Misc/tabstop.c clang/test/Misc/unnecessary-elipses.cpp clang/test/Misc/unprintable.c clang/test/Misc/wrong-encoding.c clang/test/Parser/brackets.c clang/test/Parser/brackets.cpp clang/test/Preprocessor/ucn-pp-identifier.c clang/test/Sema/caret-diags-complex-init.cpp clang/test/SemaCXX/struct-class-redecl.cpp Removed: diff --git a/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp b/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp index 0dc06df4f18b4..6fa700bf06d4f 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cert/uppercase-literal-suffix-integer.cpp @@ -31,7 +31,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'l', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v5 = 1l; // CHECK-MESSAGES-NEXT: ^~ - // CHECK-MESSAGES-NEXT: {{^ *}}L{{$}} + // CHECK-MESSAGES-NEXT: {{^ *| *}}L{{$}} // CHECK-FIXES: static constexpr auto v5 = 1L; static_assert(is_same::value, ""); static_assert(v5 == 1, ""); @@ -46,7 +46,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'll', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v7 = 1ll; // CHECK-MESSAGES-NEXT: ^~~ - // CHECK-MESSAGES-NEXT: {{^ *}}LL{{$}} + // CHECK-MESSAGES-NEXT: {{^ *| *}}LL{{$}} // CHECK-FIXES: static constexpr auto v7 = 1LL; static_assert(is_same::value, ""); static_assert(v7 == 1, ""); @@ -79,7 +79,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lu', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v13 = 1lu; // CHECK-MESSAGES-NEXT: ^~~ - // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}} + // CHECK-MESSAGES-NEXT: {{^ *| *}}LU{{$}} // CHECK-FIXES: static constexpr auto v13 = 1LU; static_assert(is_same::value, ""); static_assert(v13 == 1, ""); @@ -88,7 +88,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Lu', which is not uppercase // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1Lu; // CHECK-MESSAGES-NEXT: ^~~ - // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}} + // CHECK-MESSAGES-NEXT: {{^ *| *}}LU{{$}} // CHECK-FIXES: static constexpr auto v14 = 1LU; static_assert(is_same::value, ""); static_assert(v14 == 1, ""); @@ -97,7 +97,7 @@ void integer_suffix() { // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: inte
[clang] 2dc435a - [clang][NFC] Use llvm::count_if instead of manual loop
Author: Timm Bäder Date: 2023-05-16T15:35:05+02:00 New Revision: 2dc435a59d565849ef62ae3c63dd4fc79a3e16f3 URL: https://github.com/llvm/llvm-project/commit/2dc435a59d565849ef62ae3c63dd4fc79a3e16f3 DIFF: https://github.com/llvm/llvm-project/commit/2dc435a59d565849ef62ae3c63dd4fc79a3e16f3.diff LOG: [clang][NFC] Use llvm::count_if instead of manual loop Added: Modified: clang/lib/Frontend/DiagnosticRenderer.cpp Removed: diff --git a/clang/lib/Frontend/DiagnosticRenderer.cpp b/clang/lib/Frontend/DiagnosticRenderer.cpp index 4cd7d982ed0e..18c8be7a7293 100644 --- a/clang/lib/Frontend/DiagnosticRenderer.cpp +++ b/clang/lib/Frontend/DiagnosticRenderer.cpp @@ -494,10 +494,8 @@ static bool checkRangesForMacroArgExpansion(FullSourceLoc Loc, mapDiagnosticRanges(Loc, Ranges, SpellingRanges); // Count all valid ranges. - unsigned ValidCount = 0; - for (const auto &Range : Ranges) -if (Range.isValid()) - ValidCount++; + unsigned ValidCount = + llvm::count_if(Ranges, [](const auto &R) { return R.isValid(); }); if (ValidCount > SpellingRanges.size()) return false; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] dce89fe - [clang][NFC] Fix a doc comment mixup
Author: Timm Bäder Date: 2023-05-16T08:12:48+02:00 New Revision: dce89fe7212255b5f76fff3b8d55929920f0eb34 URL: https://github.com/llvm/llvm-project/commit/dce89fe7212255b5f76fff3b8d55929920f0eb34 DIFF: https://github.com/llvm/llvm-project/commit/dce89fe7212255b5f76fff3b8d55929920f0eb34.diff LOG: [clang][NFC] Fix a doc comment mixup These are regular comments, use double slashes. Added: Modified: clang/lib/Frontend/DiagnosticRenderer.cpp Removed: diff --git a/clang/lib/Frontend/DiagnosticRenderer.cpp b/clang/lib/Frontend/DiagnosticRenderer.cpp index 9177ba9f4f068..4cd7d982ed0ec 100644 --- a/clang/lib/Frontend/DiagnosticRenderer.cpp +++ b/clang/lib/Frontend/DiagnosticRenderer.cpp @@ -493,7 +493,7 @@ static bool checkRangesForMacroArgExpansion(FullSourceLoc Loc, SmallVector SpellingRanges; mapDiagnosticRanges(Loc, Ranges, SpellingRanges); - /// Count all valid ranges. + // Count all valid ranges. unsigned ValidCount = 0; for (const auto &Range : Ranges) if (Range.isValid()) @@ -502,11 +502,11 @@ static bool checkRangesForMacroArgExpansion(FullSourceLoc Loc, if (ValidCount > SpellingRanges.size()) return false; - /// To store the source location of the argument location. + // To store the source location of the argument location. FullSourceLoc ArgumentLoc; - /// Set the ArgumentLoc to the beginning location of the expansion of Loc - /// so to check if the ranges expands to the same beginning location. + // Set the ArgumentLoc to the beginning location of the expansion of Loc + // so to check if the ranges expands to the same beginning location. if (!Loc.isMacroArgExpansion(&ArgumentLoc)) return false; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e8fb478 - [clang][Interp] Don't call getSource() on functions without a body
Author: Timm Bäder Date: 2023-05-05T11:59:42+02:00 New Revision: e8fb478f2df863c744b4eed5a5aa07a36fba737d URL: https://github.com/llvm/llvm-project/commit/e8fb478f2df863c744b4eed5a5aa07a36fba737d DIFF: https://github.com/llvm/llvm-project/commit/e8fb478f2df863c744b4eed5a5aa07a36fba737d.diff LOG: [clang][Interp] Don't call getSource() on functions without a body For builtin functions, we create a Function instance without a body or code. When emitting diagnostics from them, we need a proper SourceInfo to point to, but the only thing we can use is the call site of the builtin function. Differential Revision: https://reviews.llvm.org/D149824 Added: Modified: clang/lib/AST/Interp/EvalEmitter.h clang/lib/AST/Interp/Function.cpp Removed: diff --git a/clang/lib/AST/Interp/EvalEmitter.h b/clang/lib/AST/Interp/EvalEmitter.h index 22d7b7c68d104..99933900f2921 100644 --- a/clang/lib/AST/Interp/EvalEmitter.h +++ b/clang/lib/AST/Interp/EvalEmitter.h @@ -71,7 +71,7 @@ class EvalEmitter : public SourceMapper { /// Returns the source location of the current opcode. SourceInfo getSource(const Function *F, CodePtr PC) const override { -return F ? F->getSource(PC) : CurrentSource; +return (F && F->hasBody()) ? F->getSource(PC) : CurrentSource; } /// Parameter indices. diff --git a/clang/lib/AST/Interp/Function.cpp b/clang/lib/AST/Interp/Function.cpp index 40001faad4116..4e6d175c41b26 100644 --- a/clang/lib/AST/Interp/Function.cpp +++ b/clang/lib/AST/Interp/Function.cpp @@ -32,6 +32,7 @@ Function::ParamDescriptor Function::getParamDescriptor(unsigned Offset) const { SourceInfo Function::getSource(CodePtr PC) const { assert(PC >= getCodeBegin() && "PC does not belong to this function"); assert(PC <= getCodeEnd() && "PC Does not belong to this function"); + assert(hasBody() && "Function has no body"); unsigned Offset = PC - getCodeBegin(); using Elem = std::pair; auto It = llvm::lower_bound(SrcMap, Elem{Offset, {}}, llvm::less_first()); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] c3f1faf - [clang][Interp][NFC] Fix allocateLocalPrimitive parameter name
Author: Timm Bäder Date: 2023-05-04T13:45:14+02:00 New Revision: c3f1faf96f18ca2162aff96b0adaf4cd22689ad4 URL: https://github.com/llvm/llvm-project/commit/c3f1faf96f18ca2162aff96b0adaf4cd22689ad4 DIFF: https://github.com/llvm/llvm-project/commit/c3f1faf96f18ca2162aff96b0adaf4cd22689ad4.diff LOG: [clang][Interp][NFC] Fix allocateLocalPrimitive parameter name This is passed on to Program::createDescriptor, where it is used as a value for IsConst. Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/ByteCodeExprGen.h Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index ca9d345c2e86..df7c4a72f21a 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -831,7 +831,7 @@ bool ByteCodeExprGen::VisitMaterializeTemporaryExpr( // For everyhing else, use local variables. if (SubExprT) { if (std::optional LocalIndex = allocateLocalPrimitive( -SubExpr, *SubExprT, /*IsMutable=*/true, /*IsExtended=*/true)) { +SubExpr, *SubExprT, /*IsConst=*/true, /*IsExtended=*/true)) { if (!this->visitInitializer(SubExpr)) return false; this->emitSetLocal(*SubExprT, *LocalIndex, E); diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index a3aab16c4a08..52a8eca593c2 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -185,7 +185,7 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, llvm::function_ref V); /// Creates a local primitive value. - unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsMutable, + unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst, bool IsExtended = false); /// Allocates a space storing a local given its type. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] eadf6db - [docs] Hide collaboration and include graphs in doxygen docs
Author: Timm Bäder Date: 2023-05-04T12:26:51+02:00 New Revision: eadf6db585e1f018e30d9c8de4b32c5d78468e19 URL: https://github.com/llvm/llvm-project/commit/eadf6db585e1f018e30d9c8de4b32c5d78468e19 DIFF: https://github.com/llvm/llvm-project/commit/eadf6db585e1f018e30d9c8de4b32c5d78468e19.diff LOG: [docs] Hide collaboration and include graphs in doxygen docs They don't convey any useful information and make the documentation unnecessarily hard to read. Differential Revision: https://reviews.llvm.org/D149641 Added: Modified: bolt/docs/doxygen.cfg.in clang-tools-extra/docs/doxygen.cfg.in clang/docs/doxygen.cfg.in flang/docs/doxygen.cfg.in lldb/docs/doxygen.cfg.in llvm/docs/doxygen.cfg.in mlir/docs/doxygen.cfg.in openmp/docs/doxygen.cfg.in openmp/runtime/doc/doxygen/config polly/docs/doxygen.cfg.in Removed: diff --git a/bolt/docs/doxygen.cfg.in b/bolt/docs/doxygen.cfg.in index acdf6f66842b6..421ef4760aa37 100644 --- a/bolt/docs/doxygen.cfg.in +++ b/bolt/docs/doxygen.cfg.in @@ -2107,7 +2107,7 @@ CLASS_GRAPH= YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -COLLABORATION_GRAPH= YES +COLLABORATION_GRAPH= NO # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for # groups, showing the direct groups dependencies. @@ -2152,7 +2152,7 @@ TEMPLATE_RELATIONS = NO # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDE_GRAPH = YES +INCLUDE_GRAPH = NO # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are # set to YES then doxygen will generate a graph for each documented file showing @@ -2161,7 +2161,7 @@ INCLUDE_GRAPH = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDED_BY_GRAPH = YES +INCLUDED_BY_GRAPH = NO # If the CALL_GRAPH tag is set to YES then doxygen will generate a call # dependency graph for every global function or class method. diff --git a/clang-tools-extra/docs/doxygen.cfg.in b/clang-tools-extra/docs/doxygen.cfg.in index 7e1d47a7a95a5..df33a63906389 100644 --- a/clang-tools-extra/docs/doxygen.cfg.in +++ b/clang-tools-extra/docs/doxygen.cfg.in @@ -2102,7 +2102,7 @@ CLASS_GRAPH= YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -COLLABORATION_GRAPH= YES +COLLABORATION_GRAPH= NO # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for # groups, showing the direct groups dependencies. @@ -2147,7 +2147,7 @@ TEMPLATE_RELATIONS = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDE_GRAPH = YES +INCLUDE_GRAPH = NO # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are # set to YES then doxygen will generate a graph for each documented file showing @@ -2156,7 +2156,7 @@ INCLUDE_GRAPH = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDED_BY_GRAPH = YES +INCLUDED_BY_GRAPH = NO # If the CALL_GRAPH tag is set to YES then doxygen will generate a call # dependency graph for every global function or class method. diff --git a/clang/docs/doxygen.cfg.in b/clang/docs/doxygen.cfg.in index 39a346409b935..251afb179b205 100644 --- a/clang/docs/doxygen.cfg.in +++ b/clang/docs/doxygen.cfg.in @@ -2090,7 +2090,7 @@ CLASS_GRAPH= YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -COLLABORATION_GRAPH= YES +COLLABORATION_GRAPH= NO # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for # groups, showing the direct groups dependencies. @@ -2135,7 +2135,7 @@ TEMPLATE_RELATIONS = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDE_GRAPH = YES +INCLUDE_GRAPH = NO # If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are # set to YES then doxygen will generate a graph for each documented file showing @@ -2144,7 +2144,7 @@ INCLUDE_GRAPH = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDED_BY_GRAPH = YES +INCLUDED_BY_GRAPH = NO # If the CALL_GRAPH tag is set to YES then doxygen will generate a call # dependency graph for every global function or class method. diff --git a/flang/docs/doxygen.cfg.in b/flang/docs/doxygen.cfg.in index 6ee771c23d2b6..2782ded84aa00 100644 --- a/flang/docs/doxygen.cfg.in +++ b/flang/docs/doxygen.cfg.in @@ -2105,7 +2105,7 @@ CLASS_GRAPH= YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -COLLABORATION_GRAPH= YES +COLLABORATION_GRAPH
[clang] d3c0165 - [clang][Interp][NFC] Remove unnecessary include from State.h
Author: Timm Bäder Date: 2023-05-04T10:21:01+02:00 New Revision: d3c01652448231ad24eb9abfc6af95f58f865f07 URL: https://github.com/llvm/llvm-project/commit/d3c01652448231ad24eb9abfc6af95f58f865f07 DIFF: https://github.com/llvm/llvm-project/commit/d3c01652448231ad24eb9abfc6af95f58f865f07.diff LOG: [clang][Interp][NFC] Remove unnecessary include from State.h Forward-declare OptionalDiagnostic instead. And turn a few comments in to doc comments. Added: Modified: clang/lib/AST/Interp/State.cpp clang/lib/AST/Interp/State.h Removed: diff --git a/clang/lib/AST/Interp/State.cpp b/clang/lib/AST/Interp/State.cpp index 251297925760..f67bde1082fa 100644 --- a/clang/lib/AST/Interp/State.cpp +++ b/clang/lib/AST/Interp/State.cpp @@ -11,6 +11,7 @@ #include "Program.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CXXInheritance.h" +#include "clang/AST/OptionalDiagnostic.h" using namespace clang; using namespace clang::interp; diff --git a/clang/lib/AST/Interp/State.h b/clang/lib/AST/Interp/State.h index 131fbcf3cffc..d897b7c20275 100644 --- a/clang/lib/AST/Interp/State.h +++ b/clang/lib/AST/Interp/State.h @@ -15,9 +15,9 @@ #include "clang/AST/ASTDiagnostic.h" #include "clang/AST/Expr.h" -#include "clang/AST/OptionalDiagnostic.h" namespace clang { +class OptionalDiagnostic; /// Kinds of access we can perform on an object, for diagnostics. Note that /// we consider a member function call to be a kind of access, even though @@ -36,7 +36,7 @@ enum AccessKinds { AK_Destroy, }; -// The order of this enum is important for diagnostics. +/// The order of this enum is important for diagnostics. enum CheckSubobjectKind { CSK_Base, CSK_Derived, @@ -72,7 +72,7 @@ class State { public: State() : InConstantContext(false) {} - // Diagnose that the evaluation could not be folded (FF => FoldFailure) + /// Diagnose that the evaluation could not be folded (FF => FoldFailure) OptionalDiagnostic FFDiag(SourceLocation Loc, diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr, ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 5c9a849 - [clang][Interp][NFC] Use const references to Floating
Author: Timm Bäder Date: 2023-05-04T10:03:40+02:00 New Revision: 5c9a84960de2260f149ee15313998593255a78df URL: https://github.com/llvm/llvm-project/commit/5c9a84960de2260f149ee15313998593255a78df DIFF: https://github.com/llvm/llvm-project/commit/5c9a84960de2260f149ee15313998593255a78df.diff LOG: [clang][Interp][NFC] Use const references to Floating in the static functions. Since a Floating is backed by an APFloat, we don't want to copy that around if it's not necessary. Added: Modified: clang/lib/AST/Interp/Floating.h Removed: diff --git a/clang/lib/AST/Interp/Floating.h b/clang/lib/AST/Interp/Floating.h index 90f8c1f8d4ad..85876236a999 100644 --- a/clang/lib/AST/Interp/Floating.h +++ b/clang/lib/AST/Interp/Floating.h @@ -105,8 +105,8 @@ class Floating final { // --- - static APFloat::opStatus add(Floating A, Floating B, llvm::RoundingMode RM, - Floating *R) { + static APFloat::opStatus add(const Floating &A, const Floating &B, + llvm::RoundingMode RM, Floating *R) { *R = Floating(A.F); return R->F.add(B.F, RM); } @@ -118,8 +118,8 @@ class Floating final { return R->F.add(One, RM); } - static APFloat::opStatus sub(Floating A, Floating B, llvm::RoundingMode RM, - Floating *R) { + static APFloat::opStatus sub(const Floating &A, const Floating &B, + llvm::RoundingMode RM, Floating *R) { *R = Floating(A.F); return R->F.subtract(B.F, RM); } @@ -131,19 +131,19 @@ class Floating final { return R->F.subtract(One, RM); } - static APFloat::opStatus mul(Floating A, Floating B, llvm::RoundingMode RM, - Floating *R) { + static APFloat::opStatus mul(const Floating &A, const Floating &B, + llvm::RoundingMode RM, Floating *R) { *R = Floating(A.F); return R->F.multiply(B.F, RM); } - static APFloat::opStatus div(Floating A, Floating B, llvm::RoundingMode RM, - Floating *R) { + static APFloat::opStatus div(const Floating &A, const Floating &B, + llvm::RoundingMode RM, Floating *R) { *R = Floating(A.F); return R->F.divide(B.F, RM); } - static bool neg(Floating A, Floating *R) { + static bool neg(const Floating &A, Floating *R) { *R = -A; return false; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 0354f31 - [clang][Interp][NFC] Don't cast primitive types to the same type
Author: Timm Bäder Date: 2023-05-04T09:53:15+02:00 New Revision: 0354f31b513991d936e8a9af0a50890c48ea01b0 URL: https://github.com/llvm/llvm-project/commit/0354f31b513991d936e8a9af0a50890c48ea01b0 DIFF: https://github.com/llvm/llvm-project/commit/0354f31b513991d936e8a9af0a50890c48ea01b0.diff LOG: [clang][Interp][NFC] Don't cast primitive types to the same type We might classify different clang types to the same interp types, so skip the cast in that case. No test attached since this is already exercised a few times in the existing tests. Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 7686a2eb71ec..ca9d345c2e86 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -146,7 +146,9 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { if (!this->visit(SubExpr)) return false; -// TODO: Emit this only if FromT != ToT. +if (FromT == ToT) + return true; + return this->emitCast(*FromT, *ToT, CE); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 67c9fd7 - [clang][Interp][NFC] Make Pointer::block() const
Author: Timm Bäder Date: 2023-05-04T09:36:40+02:00 New Revision: 67c9fd7a184a138a690cae1bef4073fddba07151 URL: https://github.com/llvm/llvm-project/commit/67c9fd7a184a138a690cae1bef4073fddba07151 DIFF: https://github.com/llvm/llvm-project/commit/67c9fd7a184a138a690cae1bef4073fddba07151.diff LOG: [clang][Interp][NFC] Make Pointer::block() const Added: Modified: clang/lib/AST/Interp/Pointer.h Removed: diff --git a/clang/lib/AST/Interp/Pointer.h b/clang/lib/AST/Interp/Pointer.h index 5895c61295e0..10d21a27167f 100644 --- a/clang/lib/AST/Interp/Pointer.h +++ b/clang/lib/AST/Interp/Pointer.h @@ -290,7 +290,7 @@ class Pointer { /// Returns the number of elements. unsigned getNumElems() const { return getSize() / elemSize(); } - Block *block() const { return Pointee; } + const Block *block() const { return Pointee; } /// Returns the index into an array. int64_t getIndex() const { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 6ccf330 - [clang][Interp] Add missing static_assert messages
Author: Timm Bäder Date: 2023-05-04T09:10:21+02:00 New Revision: 6ccf3307f49fe8265802320be837a9b4210ebf05 URL: https://github.com/llvm/llvm-project/commit/6ccf3307f49fe8265802320be837a9b4210ebf05 DIFF: https://github.com/llvm/llvm-project/commit/6ccf3307f49fe8265802320be837a9b4210ebf05.diff LOG: [clang][Interp] Add missing static_assert messages Added: Modified: clang/test/AST/Interp/floats.cpp Removed: diff --git a/clang/test/AST/Interp/floats.cpp b/clang/test/AST/Interp/floats.cpp index 7d45999a997c..ab75a537d0ce 100644 --- a/clang/test/AST/Interp/floats.cpp +++ b/clang/test/AST/Interp/floats.cpp @@ -101,14 +101,14 @@ namespace unary { assert(f == 1.0); return 1.0; } - static_assert(a() == 1.0); + static_assert(a() == 1.0, ""); constexpr float b() { float f = __FLT_MAX__; f++; return f; } - static_assert(b() == __FLT_MAX__); + static_assert(b() == __FLT_MAX__, ""); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 338c248 - [clang][Interp] Implement inc/dec operators for floats
Author: Timm Bäder Date: 2023-05-04T08:52:53+02:00 New Revision: 338c2489f63e1c34db047ac8e45efeeb88c8a067 URL: https://github.com/llvm/llvm-project/commit/338c2489f63e1c34db047ac8e45efeeb88c8a067 DIFF: https://github.com/llvm/llvm-project/commit/338c2489f63e1c34db047ac8e45efeeb88c8a067.diff LOG: [clang][Interp] Implement inc/dec operators for floats Differential Revision: https://reviews.llvm.org/D149634 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/Floating.h clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/Opcodes.td clang/test/AST/Interp/floats.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index ba6356136cab..7686a2eb71ec 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1776,6 +1776,11 @@ bool ByteCodeExprGen::VisitUnaryOperator(const UnaryOperator *E) { return DiscardResult ? this->emitPopPtr(E) : true; } +if (T == PT_Float) { + return DiscardResult ? this->emitIncfPop(getRoundingMode(E), E) + : this->emitIncf(getRoundingMode(E), E); +} + return DiscardResult ? this->emitIncPop(*T, E) : this->emitInc(*T, E); } case UO_PostDec: { // x-- @@ -1789,6 +1794,11 @@ bool ByteCodeExprGen::VisitUnaryOperator(const UnaryOperator *E) { return DiscardResult ? this->emitPopPtr(E) : true; } +if (T == PT_Float) { + return DiscardResult ? this->emitDecfPop(getRoundingMode(E), E) + : this->emitDecf(getRoundingMode(E), E); +} + return DiscardResult ? this->emitDecPop(*T, E) : this->emitDec(*T, E); } case UO_PreInc: { // ++x @@ -1803,9 +1813,19 @@ bool ByteCodeExprGen::VisitUnaryOperator(const UnaryOperator *E) { } // Post-inc and pre-inc are the same if the value is to be discarded. -if (DiscardResult) +if (DiscardResult) { + if (T == PT_Float) +return this->emitIncfPop(getRoundingMode(E), E); return this->emitIncPop(*T, E); +} +if (T == PT_Float) { + const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType()); + this->emitLoadFloat(E); + this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E); + this->emitAddf(getRoundingMode(E), E); + return this->emitStoreFloat(E); +} this->emitLoad(*T, E); this->emitConst(1, E); this->emitAdd(*T, E); @@ -1823,9 +1843,19 @@ bool ByteCodeExprGen::VisitUnaryOperator(const UnaryOperator *E) { } // Post-dec and pre-dec are the same if the value is to be discarded. -if (DiscardResult) +if (DiscardResult) { + if (T == PT_Float) +return this->emitDecfPop(getRoundingMode(E), E); return this->emitDecPop(*T, E); +} +if (T == PT_Float) { + const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType()); + this->emitLoadFloat(E); + this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E); + this->emitSubf(getRoundingMode(E), E); + return this->emitStoreFloat(E); +} this->emitLoad(*T, E); this->emitConst(1, E); this->emitSub(*T, E); diff --git a/clang/lib/AST/Interp/Floating.h b/clang/lib/AST/Interp/Floating.h index fb0884bb3b60..90f8c1f8d4ad 100644 --- a/clang/lib/AST/Interp/Floating.h +++ b/clang/lib/AST/Interp/Floating.h @@ -111,12 +111,26 @@ class Floating final { return R->F.add(B.F, RM); } + static APFloat::opStatus increment(const Floating &A, llvm::RoundingMode RM, + Floating *R) { +APFloat One(A.F.getSemantics(), 1); +*R = Floating(A.F); +return R->F.add(One, RM); + } + static APFloat::opStatus sub(Floating A, Floating B, llvm::RoundingMode RM, Floating *R) { *R = Floating(A.F); return R->F.subtract(B.F, RM); } + static APFloat::opStatus decrement(const Floating &A, llvm::RoundingMode RM, + Floating *R) { +APFloat One(A.F.getSemantics(), 1); +*R = Floating(A.F); +return R->F.subtract(One, RM); + } + static APFloat::opStatus mul(Floating A, Floating B, llvm::RoundingMode RM, Floating *R) { *R = Floating(A.F); diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 2baef4293d51..64bdd872221a 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -540,6 +540,50 @@ bool DecPop(InterpState &S, CodePtr OpPC) { return IncDecHelper(S, OpPC, Ptr); } +template +bool IncDecFloatHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr, + llvm::RoundingMode RM) { + Floating Value = Ptr.deref(); + Floating Result; + + if constexpr (DoPush == PushVal::Yes) +S.Stk.push(Value); + + llvm::APFloat::opStatus Status; +
[clang] fd4c302 - [clang][Interp][NFC] Call discard() when discarding ExprWithCleanups
Author: Timm Bäder Date: 2023-05-04T08:45:14+02:00 New Revision: fd4c302c4119ac946138c11494f15544bd4cc2de URL: https://github.com/llvm/llvm-project/commit/fd4c302c4119ac946138c11494f15544bd4cc2de DIFF: https://github.com/llvm/llvm-project/commit/fd4c302c4119ac946138c11494f15544bd4cc2de.diff LOG: [clang][Interp][NFC] Call discard() when discarding ExprWithCleanups Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index c3939996919e..ba6356136cab 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -798,12 +798,10 @@ bool ByteCodeExprGen::VisitExprWithCleanups( const Expr *SubExpr = E->getSubExpr(); assert(E->getNumObjects() == 0 && "TODO: Implement cleanups"); - if (!this->visit(SubExpr)) -return false; - if (DiscardResult) -return this->emitPopPtr(E); - return true; +return this->discard(SubExpr); + + return this->visit(SubExpr); } template ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 92f67dc - [clang][Interp] Handle DiscardResult for DeclRef- and ParenExprs
Author: Timm Bäder Date: 2023-05-04T08:22:06+02:00 New Revision: 92f67dc27f41b555fa4b93f3d679fb895e51d795 URL: https://github.com/llvm/llvm-project/commit/92f67dc27f41b555fa4b93f3d679fb895e51d795 DIFF: https://github.com/llvm/llvm-project/commit/92f67dc27f41b555fa4b93f3d679fb895e51d795.diff LOG: [clang][Interp] Handle DiscardResult for DeclRef- and ParenExprs Fixes https://github.com/llvm/llvm-project/issues/62004 Differential Revision: https://reviews.llvm.org/D147840 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/test/AST/Interp/literals.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index ee59fc372a8b5..c3939996919e2 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -188,7 +188,12 @@ bool ByteCodeExprGen::VisitFloatingLiteral(const FloatingLiteral *E) { template bool ByteCodeExprGen::VisitParenExpr(const ParenExpr *PE) { - return this->visit(PE->getSubExpr()); + const Expr *SubExpr = PE->getSubExpr(); + + if (DiscardResult) +return this->discard(SubExpr); + + return this->visit(SubExpr); } template @@ -1872,6 +1877,9 @@ bool ByteCodeExprGen::VisitUnaryOperator(const UnaryOperator *E) { template bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) { + if (DiscardResult) +return true; + const auto *D = E->getDecl(); if (const auto *ECD = dyn_cast(D)) { diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index acad760bc43ee..5f4c0485ba772 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -814,4 +814,18 @@ constexpr int ignoredDecls() { return F{12}.a; } static_assert(ignoredDecls() == 12, ""); + +struct A{}; +constexpr int ignoredExprs() { + (void)(1 / 2); + A a; + a; // expected-warning {{unused}} \ + // ref-warning {{unused}} + (void)a; + (a); // expected-warning {{unused}} \ + // ref-warning {{unused}} + + return 0; +} + #endif ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 9ec5423 - [clang][Interp][NFC] Add documentation for SetLocal
Author: Timm Bäder Date: 2023-05-02T06:16:49+02:00 New Revision: 9ec5423b90c888d9ec4206c18b728946be5f1368 URL: https://github.com/llvm/llvm-project/commit/9ec5423b90c888d9ec4206c18b728946be5f1368 DIFF: https://github.com/llvm/llvm-project/commit/9ec5423b90c888d9ec4206c18b728946be5f1368.diff LOG: [clang][Interp][NFC] Add documentation for SetLocal Added: Modified: clang/lib/AST/Interp/Interp.h Removed: diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index d751ba021b11..2baef4293d51 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -744,6 +744,9 @@ bool GetLocal(InterpState &S, CodePtr OpPC, uint32_t I) { return true; } +/// 1) Pops the value from the stack. +/// 2) Writes the value to the local variable with the +///given offset. template ::T> bool SetLocal(InterpState &S, CodePtr OpPC, uint32_t I) { S.Current->setLocal(I, S.Stk.pop()); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 7d0938b - [clang][Interp][NFC] Make OptionScope final
Author: Timm Bäder Date: 2023-05-02T06:16:49+02:00 New Revision: 7d0938bf2c2a35d4eb4b8c4c728aaa85d1dd428e URL: https://github.com/llvm/llvm-project/commit/7d0938bf2c2a35d4eb4b8c4c728aaa85d1dd428e DIFF: https://github.com/llvm/llvm-project/commit/7d0938bf2c2a35d4eb4b8c4c728aaa85d1dd428e.diff LOG: [clang][Interp][NFC] Make OptionScope final Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 9f79a7bcf9d3..ee59fc372a8b 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -40,7 +40,7 @@ template class DeclScope final : public VariableScope { }; /// Scope used to handle initialization methods. -template class OptionScope { +template class OptionScope final { public: /// Root constructor, compiling or discarding primitives. OptionScope(ByteCodeExprGen *Ctx, bool NewDiscardResult) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] f8a9c55 - [clang][Interp] Emit diagnostic when comparing function pointers
Author: Timm Bäder Date: 2023-04-27T12:33:28+02:00 New Revision: f8a9c55bef380a592c4588025f8b6ca4dfc94c47 URL: https://github.com/llvm/llvm-project/commit/f8a9c55bef380a592c4588025f8b6ca4dfc94c47 DIFF: https://github.com/llvm/llvm-project/commit/f8a9c55bef380a592c4588025f8b6ca4dfc94c47.diff LOG: [clang][Interp] Emit diagnostic when comparing function pointers Function pointers can be compared for (in)equality but, but LE, GE, LT, and GT opcodes should emit an error and abort. Differential Revision: https://reviews.llvm.org/D149154 Added: Modified: clang/lib/AST/Interp/FunctionPointer.h clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/Opcodes.td clang/test/AST/Interp/functions.cpp Removed: diff --git a/clang/lib/AST/Interp/FunctionPointer.h b/clang/lib/AST/Interp/FunctionPointer.h index 2d449bdb031d..20d4d7793185 100644 --- a/clang/lib/AST/Interp/FunctionPointer.h +++ b/clang/lib/AST/Interp/FunctionPointer.h @@ -8,6 +8,7 @@ #include "clang/AST/APValue.h" namespace clang { +class ASTContext; namespace interp { class FunctionPointer final { @@ -38,6 +39,13 @@ class FunctionPointer final { OS << ")"; } + std::string toDiagnosticString(const ASTContext &Ctx) const { +if (!Func) + return "nullptr"; + +return toAPValue().getAsString(Ctx, Func->getDecl()->getType()); + } + ComparisonCategoryResult compare(const FunctionPointer &RHS) const { if (Func == RHS.Func) return ComparisonCategoryResult::Equal; diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 7b80bb964991..d751ba021b11 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -574,6 +574,29 @@ bool CmpHelperEQ(InterpState &S, CodePtr OpPC, CompareFn Fn) { return CmpHelper(S, OpPC, Fn); } +/// Function pointers cannot be compared in an ordered way. +template <> +inline bool CmpHelper(InterpState &S, CodePtr OpPC, + CompareFn Fn) { + const auto &RHS = S.Stk.pop(); + const auto &LHS = S.Stk.pop(); + + const SourceInfo &Loc = S.Current->getSource(OpPC); + S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_unspecified) + << LHS.toDiagnosticString(S.getCtx()) + << RHS.toDiagnosticString(S.getCtx()); + return false; +} + +template <> +inline bool CmpHelperEQ(InterpState &S, CodePtr OpPC, + CompareFn Fn) { + const auto &RHS = S.Stk.pop(); + const auto &LHS = S.Stk.pop(); + S.Stk.push(Boolean::from(Fn(LHS.compare(RHS; + return true; +} + template <> inline bool CmpHelper(InterpState &S, CodePtr OpPC, CompareFn Fn) { using BoolT = PrimConv::T; diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index ed0774a78833..717c4629fcc3 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -94,7 +94,7 @@ def AllTypeClass : TypeClass { } def ComparableTypeClass : TypeClass { - let Types = !listconcat(AluTypeClass.Types, [Ptr], [Float]); + let Types = !listconcat(AluTypeClass.Types, [Ptr], [Float], [FnPtr]); } class SingletonTypeClass : TypeClass { diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index a8681aae0d58..5bb48ffc54dd 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -178,6 +178,31 @@ namespace FunctionReturnType { static_assert(s.fp == nullptr, ""); // zero-initialized function pointer. } +namespace Comparison { + void f(), g(); + constexpr void (*pf)() = &f, (*pg)() = &g; + + constexpr bool u13 = pf < pg; // ref-warning {{ordered comparison of function pointers}} \ +// ref-error {{must be initialized by a constant expression}} \ +// ref-note {{comparison between '&f' and '&g' has unspecified value}} \ +// expected-warning {{ordered comparison of function pointers}} \ +// expected-error {{must be initialized by a constant expression}} \ +// expected-note {{comparison between '&f' and '&g' has unspecified value}} + + constexpr bool u14 = pf < (void(*)())nullptr; // ref-warning {{ordered comparison of function pointers}} \ +// ref-error {{must be initialized by a constant expression}} \ +// ref-note {{comparison between '&f' and 'nullptr' has unspecified value}} \ +// expected-warning {{ordered comparison of function pointers}} \ +// expected-error {{must be initialized by a constant expression}} \ +// expected-note {{comparison between '&f' and 'nullptr' has u
[clang] 6cf14a7 - [clang][Interp] Check Neg ops for errors
Author: Timm Bäder Date: 2023-04-27T12:05:23+02:00 New Revision: 6cf14a72390f0914b18f30f2f357b783ff84533c URL: https://github.com/llvm/llvm-project/commit/6cf14a72390f0914b18f30f2f357b783ff84533c DIFF: https://github.com/llvm/llvm-project/commit/6cf14a72390f0914b18f30f2f357b783ff84533c.diff LOG: [clang][Interp] Check Neg ops for errors This should fail when negating __INT_MIN__. Differential Revision: https://reviews.llvm.org/D148987 Added: Modified: clang/lib/AST/Interp/Integral.h clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/PrimType.h clang/test/AST/Interp/literals.cpp Removed: diff --git a/clang/lib/AST/Interp/Integral.h b/clang/lib/AST/Interp/Integral.h index 932caca29b9f0..cc7c7a9d2430e 100644 --- a/clang/lib/AST/Interp/Integral.h +++ b/clang/lib/AST/Interp/Integral.h @@ -223,6 +223,9 @@ template class Integral final { } static bool neg(Integral A, Integral *R) { +if (Signed && A.isMin()) + return true; + *R = -A; return false; } diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 152a876a42964..7b80bb9649916 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -413,12 +413,32 @@ bool Inv(InterpState &S, CodePtr OpPC) { template ::T> bool Neg(InterpState &S, CodePtr OpPC) { - const T &Val = S.Stk.pop(); + const T &Value = S.Stk.pop(); T Result; - T::neg(Val, &Result); + if (!T::neg(Value, &Result)) { +S.Stk.push(Result); +return true; + } + + assert(isIntegralType(Name) && + "don't expect other types to fail at constexpr negation"); S.Stk.push(Result); - return true; + + APSInt NegatedValue = -Value.toAPSInt(Value.bitWidth() + 1); + const Expr *E = S.Current->getExpr(OpPC); + QualType Type = E->getType(); + + if (S.checkingForUndefinedBehavior()) { +SmallString<32> Trunc; +NegatedValue.trunc(Result.bitWidth()).toString(Trunc, 10); +auto Loc = E->getExprLoc(); +S.report(Loc, diag::warn_integer_constant_overflow) << Trunc << Type; +return true; + } + + S.CCEDiag(E, diag::note_constexpr_overflow) << NegatedValue << Type; + return S.noteUndefinedBehavior(); } enum class PushVal : bool { diff --git a/clang/lib/AST/Interp/PrimType.h b/clang/lib/AST/Interp/PrimType.h index 30bec3f2a17cf..693e57210608d 100644 --- a/clang/lib/AST/Interp/PrimType.h +++ b/clang/lib/AST/Interp/PrimType.h @@ -42,6 +42,8 @@ enum PrimType : unsigned { PT_FnPtr, }; +constexpr bool isIntegralType(PrimType T) { return T <= PT_Uint64; } + /// Mapping from primitive types to their representation. template struct PrimConv; template <> struct PrimConv { using T = Integral<8, true>; }; diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index 598d748c266b4..acad760bc43ee 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -80,6 +80,12 @@ static_assert(~255 == -256, ""); static_assert(~INT_MIN == INT_MAX, ""); static_assert(~INT_MAX == INT_MIN, ""); +static_assert(-(1 << 31), ""); // expected-error {{not an integral constant expression}} \ + // expected-note {{outside the range of representable values}} \ + // ref-error {{not an integral constant expression}} \ + // ref-note {{outside the range of representable values}} \ + + enum E {}; constexpr E e = static_cast(0); static_assert(~e == -1, ""); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] a31b3a1 - [clang[[Interp][NFC] Make some Descriptor pointers const
Author: Timm Bäder Date: 2023-04-26T10:57:43+02:00 New Revision: a31b3a1a6d60cbb2ca9a110e70f0592aac574f1f URL: https://github.com/llvm/llvm-project/commit/a31b3a1a6d60cbb2ca9a110e70f0592aac574f1f DIFF: https://github.com/llvm/llvm-project/commit/a31b3a1a6d60cbb2ca9a110e70f0592aac574f1f.diff LOG: [clang[[Interp][NFC] Make some Descriptor pointers const Added: Modified: clang/lib/AST/Interp/Pointer.cpp Removed: diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp index 8f1dfa346c63..7f127143a99d 100644 --- a/clang/lib/AST/Interp/Pointer.cpp +++ b/clang/lib/AST/Interp/Pointer.cpp @@ -147,7 +147,7 @@ APValue Pointer::toAPValue() const { bool Pointer::isInitialized() const { assert(Pointee && "Cannot check if null pointer was initialized"); - Descriptor *Desc = getFieldDesc(); + const Descriptor *Desc = getFieldDesc(); assert(Desc); if (Desc->isPrimitiveArray()) { if (isStatic() && Base == 0) @@ -167,7 +167,7 @@ bool Pointer::isInitialized() const { void Pointer::initialize() const { assert(Pointee && "Cannot initialize null pointer"); - Descriptor *Desc = getFieldDesc(); + const Descriptor *Desc = getFieldDesc(); assert(Desc); if (Desc->isPrimitiveArray()) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3185e47 - [clang][Interp] Fix post-inc/dec operator result
Author: Timm Bäder Date: 2023-04-26T09:36:08+02:00 New Revision: 3185e47b5a8444e9fd70b746a7ad679dd131ffe4 URL: https://github.com/llvm/llvm-project/commit/3185e47b5a8444e9fd70b746a7ad679dd131ffe4 DIFF: https://github.com/llvm/llvm-project/commit/3185e47b5a8444e9fd70b746a7ad679dd131ffe4.diff LOG: [clang][Interp] Fix post-inc/dec operator result We pushed the wrong value on the stack, always leaving a 0 behind. Differential Revision: https://reviews.llvm.org/D148901 Added: Modified: clang/lib/AST/Interp/Interp.h clang/test/AST/Interp/literals.cpp Removed: diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 1eda38e9fa5b1..152a876a42964 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -436,7 +436,7 @@ bool IncDecHelper(InterpState &S, CodePtr OpPC, const Pointer &Ptr) { T Result; if constexpr (DoPush == PushVal::Yes) -S.Stk.push(Result); +S.Stk.push(Value); if constexpr (Op == IncDecOp::Inc) { if (!T::increment(Value, &Result)) { diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index 54f3aefcef2b1..598d748c266b4 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -719,6 +719,23 @@ namespace IncDec { // ref-note {{cannot refer to element -1 of array of 3 elements}} return *p; } + + /// This used to leave a 0 on the stack instead of the previous + /// value of a. + constexpr int bug1Inc() { +int a = 3; +int b = a++; +return b; + } + static_assert(bug1Inc() == 3); + + constexpr int bug1Dec() { +int a = 3; +int b = a--; +return b; + } + static_assert(bug1Dec() == 3); + }; #endif ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] c9e403d - [clang][Interp] Fix zero-init of float and pointer arrays
Author: Timm Bäder Date: 2023-04-25T09:00:47+02:00 New Revision: c9e403d1992b064e9cd5b94749fb3f00fa0c0910 URL: https://github.com/llvm/llvm-project/commit/c9e403d1992b064e9cd5b94749fb3f00fa0c0910 DIFF: https://github.com/llvm/llvm-project/commit/c9e403d1992b064e9cd5b94749fb3f00fa0c0910.diff LOG: [clang][Interp] Fix zero-init of float and pointer arrays Our Zero opcode only exists for integer types. Use visitZeroInitializer() here as well so it works for floats and pointers. Differential Revision: https://reviews.llvm.org/D149059 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/test/AST/Interp/arrays.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 536438b347a20..9f79a7bcf9d34 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1291,7 +1291,7 @@ bool ByteCodeExprGen::visitArrayInitializer(const Expr *Initializer) { // since we memset our Block*s to 0 and so we have the desired value // without this. for (size_t I = 0; I != NumElems; ++I) { -if (!this->emitZero(*ElemT, Initializer)) +if (!this->visitZeroInitializer(CAT->getElementType(), Initializer)) return false; if (!this->emitInitElem(*ElemT, I, Initializer)) return false; diff --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp index 413ab2fa45d84..22ccafd579241 100644 --- a/clang/test/AST/Interp/arrays.cpp +++ b/clang/test/AST/Interp/arrays.cpp @@ -334,3 +334,19 @@ namespace IncDec { // ref-error {{not an integral constant expression}} \ // ref-note {{in call to}} }; + +namespace ZeroInit { + struct A { +int *p[2]; + }; + constexpr A a = {}; + static_assert(a.p[0] == nullptr, ""); + static_assert(a.p[1] == nullptr, ""); + + struct B { +double f[2]; + }; + constexpr B b = {}; + static_assert(b.f[0] == 0.0, ""); + static_assert(b.f[1] == 0.0, ""); +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 7766648 - [clang][Interp] PointerToBoolean casts
Author: Timm Bäder Date: 2023-04-25T08:04:08+02:00 New Revision: 7766648c3aff43408b5d17214fc67c8521952558 URL: https://github.com/llvm/llvm-project/commit/7766648c3aff43408b5d17214fc67c8521952558 DIFF: https://github.com/llvm/llvm-project/commit/7766648c3aff43408b5d17214fc67c8521952558.diff LOG: [clang][Interp] PointerToBoolean casts Just emit e != nullptr for these. Differential Revision: https://reviews.llvm.org/D148981 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/test/AST/Interp/literals.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index e28532b288871..536438b347a20 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -150,6 +150,17 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { return this->emitCast(*FromT, *ToT, CE); } + case CK_PointerToBoolean: { +// Just emit p != nullptr for this. +if (!this->visit(SubExpr)) + return false; + +if (!this->emitNullPtr(CE)) + return false; + +return this->emitNEPtr(CE); + } + case CK_ToVoid: return discard(SubExpr); diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index f31a49088dc6c..54f3aefcef2b1 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -101,6 +101,19 @@ constexpr int gimme(int k) { } static_assert(gimme(5) == 5, ""); +namespace PointerToBool { + + constexpr void *N = nullptr; + constexpr bool B = N; + static_assert(!B, ""); + static_assert(!N, ""); + + constexpr float F = 1.0; + constexpr const float *FP = &F; + static_assert(FP, ""); + static_assert(!!FP, ""); +} + namespace SizeOf { constexpr int soint = sizeof(int); constexpr int souint = sizeof(unsigned int); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] bdbc6c6 - [clang][AST][NFC] Turn some single-line comments into doc comments
Author: Timm Bäder Date: 2023-04-25T07:17:58+02:00 New Revision: bdbc6c6c325adb6fc55b1e6228fef7c52b3d6731 URL: https://github.com/llvm/llvm-project/commit/bdbc6c6c325adb6fc55b1e6228fef7c52b3d6731 DIFF: https://github.com/llvm/llvm-project/commit/bdbc6c6c325adb6fc55b1e6228fef7c52b3d6731.diff LOG: [clang][AST][NFC] Turn some single-line comments into doc comments Added: Modified: clang/include/clang/AST/Expr.h Removed: diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index d9b17f8eaf936..0ab778e5d8cd3 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -2233,14 +2233,14 @@ class UnaryOperator final bool canOverflow() const { return UnaryOperatorBits.CanOverflow; } void setCanOverflow(bool C) { UnaryOperatorBits.CanOverflow = C; } - // Get the FP contractability status of this operator. Only meaningful for - // operations on floating point types. + /// Get the FP contractability status of this operator. Only meaningful for + /// operations on floating point types. bool isFPContractableWithinStatement(const LangOptions &LO) const { return getFPFeaturesInEffect(LO).allowFPContractWithinStatement(); } - // Get the FENV_ACCESS status of this operator. Only meaningful for - // operations on floating point types. + /// Get the FENV_ACCESS status of this operator. Only meaningful for + /// operations on floating point types. bool isFEnvAccessOn(const LangOptions &LO) const { return getFPFeaturesInEffect(LO).getAllowFEnvAccess(); } @@ -2325,8 +2325,8 @@ class UnaryOperator final void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; } public: - // Get the FP features status of this operator. Only meaningful for - // operations on floating point types. + /// Get the FP features status of this operator. Only meaningful for + /// operations on floating point types. FPOptions getFPFeaturesInEffect(const LangOptions &LO) const { if (UnaryOperatorBits.HasFPFeatures) return getStoredFPFeatures().applyOverrides(LO); @@ -3082,8 +3082,8 @@ class CallExpr : public Expr { *getTrailingFPFeatures() = F; } - // Get the FP features status of this operator. Only meaningful for - // operations on floating point types. + /// Get the FP features status of this operator. Only meaningful for + /// operations on floating point types. FPOptions getFPFeaturesInEffect(const LangOptions &LO) const { if (hasStoredFPFeatures()) return getStoredFPFeatures().applyOverrides(LO); @@ -3573,8 +3573,8 @@ class CastExpr : public Expr { return *getTrailingFPFeatures(); } - // Get the FP features status of this operation. Only meaningful for - // operations on floating point types. + /// Get the FP features status of this operation. Only meaningful for + /// operations on floating point types. FPOptions getFPFeaturesInEffect(const LangOptions &LO) const { if (hasStoredFPFeatures()) return getStoredFPFeatures().applyOverrides(LO); @@ -3971,9 +3971,9 @@ class BinaryOperator : public Expr { return isShiftAssignOp(getOpcode()); } - // Return true if a binary operator using the specified opcode and operands - // would match the 'p = (i8*)nullptr + n' idiom for casting a pointer-sized - // integer to a pointer. + /// Return true if a binary operator using the specified opcode and operands + /// would match the 'p = (i8*)nullptr + n' idiom for casting a pointer-sized + /// integer to a pointer. static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, const Expr *LHS, const Expr *RHS); @@ -4007,8 +4007,8 @@ class BinaryOperator : public Expr { *getTrailingFPFeatures() = F; } - // Get the FP features status of this operator. Only meaningful for - // operations on floating point types. + /// Get the FP features status of this operator. Only meaningful for + /// operations on floating point types. FPOptions getFPFeaturesInEffect(const LangOptions &LO) const { if (BinaryOperatorBits.HasFPFeatures) return getStoredFPFeatures().applyOverrides(LO); @@ -4022,14 +4022,14 @@ class BinaryOperator : public Expr { return FPOptionsOverride(); } - // Get the FP contractability status of this operator. Only meaningful for - // operations on floating point types. + /// Get the FP contractability status of this operator. Only meaningful for + /// operations on floating point types. bool isFPContractableWithinStatement(const LangOptions &LO) const { return getFPFeaturesInEffect(LO).allowFPContractWithinStatement(); } - // Get the FENV_ACCESS status of this operator. Only meaningful for - // operations on floating point types. + /// Get the FENV_ACCESS status of this operator. Only mean
[clang] 8aea6e0 - [clang][Interp][NFC] Take a QualType in visitZeroInitializer()
Author: Timm Bäder Date: 2023-04-24T17:58:15+02:00 New Revision: 8aea6e004fd2edafbdee2d3d13571ab5eace004e URL: https://github.com/llvm/llvm-project/commit/8aea6e004fd2edafbdee2d3d13571ab5eace004e DIFF: https://github.com/llvm/llvm-project/commit/8aea6e004fd2edafbdee2d3d13571ab5eace004e.diff LOG: [clang][Interp][NFC] Take a QualType in visitZeroInitializer() The given expression is not necessarily usable to obtain a type for, so we can't use it to get the floating point semantics. Pass a QualType instead, which we can use--and classify() that here. Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/ByteCodeExprGen.h Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index a8e8b2997ddef..e28532b288871 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -390,7 +390,7 @@ bool ByteCodeExprGen::VisitImplicitValueInitExpr(const ImplicitValueIni if (!T) return false; - return this->visitZeroInitializer(*T, E); + return this->visitZeroInitializer(E->getType(), E); } template @@ -929,7 +929,12 @@ bool ByteCodeExprGen::visitConditional( } template -bool ByteCodeExprGen::visitZeroInitializer(PrimType T, const Expr *E) { +bool ByteCodeExprGen::visitZeroInitializer(QualType QT, +const Expr *E) { + // FIXME: We need the QualType to get the float semantics, but that means we + // classify it over and over again in array situations. + PrimType T = classifyPrim(QT); + switch (T) { case PT_Bool: return this->emitZeroBool(E); @@ -954,8 +959,7 @@ bool ByteCodeExprGen::visitZeroInitializer(PrimType T, const Expr *E) { case PT_FnPtr: return this->emitNullFnPtr(E); case PT_Float: { -return this->emitConstFloat( -APFloat::getZero(Ctx.getFloatSemantics(E->getType())), E); +return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E); } } llvm_unreachable("unknown primitive type"); diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index 85588c6ecd3c1..a3aab16c4a083 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -201,7 +201,7 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, friend class ArrayIndexScope; /// Emits a zero initializer. - bool visitZeroInitializer(PrimType T, const Expr *E); + bool visitZeroInitializer(QualType QT, const Expr *E); enum class DerefKind { /// Value is read and pushed to stack. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 57304bb - [clang][Sema][NFC] Add const where appropriate
Author: Timm Bäder Date: 2023-04-22T08:28:27+02:00 New Revision: 57304bbda20014b23d5c706f99fefec7b5f6a31c URL: https://github.com/llvm/llvm-project/commit/57304bbda20014b23d5c706f99fefec7b5f6a31c DIFF: https://github.com/llvm/llvm-project/commit/57304bbda20014b23d5c706f99fefec7b5f6a31c.diff LOG: [clang][Sema][NFC] Add const where appropriate Added: Modified: clang/include/clang/AST/Expr.h clang/include/clang/Sema/Sema.h clang/lib/AST/Expr.cpp clang/lib/Sema/SemaLookup.cpp Removed: diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index a7e28c852d6ec..d9b17f8eaf936 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -3975,7 +3975,8 @@ class BinaryOperator : public Expr { // would match the 'p = (i8*)nullptr + n' idiom for casting a pointer-sized // integer to a pointer. static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, - Expr *LHS, Expr *RHS); + const Expr *LHS, + const Expr *RHS); static bool classof(const Stmt *S) { return S->getStmtClass() >= firstBinaryOperatorConstant && diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index fd0b89eaec87c..0ab5dd9e8bb64 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2403,8 +2403,8 @@ class Sema final { bool hasReachableDeclarationSlow( const NamedDecl *D, llvm::SmallVectorImpl *Modules = nullptr); - bool hasVisibleMergedDefinition(NamedDecl *Def); - bool hasMergedDefinitionInCurrentModule(NamedDecl *Def); + bool hasVisibleMergedDefinition(const NamedDecl *Def); + bool hasMergedDefinitionInCurrentModule(const NamedDecl *Def); /// Determine if \p D and \p Suggested have a structurally compatible /// layout as described in C11 6.2.7/1. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 756acc37d569e..0ff10a511ef44 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1529,19 +1529,17 @@ unsigned CallExpr::offsetToTrailingObjects(StmtClass SC) { Decl *Expr::getReferencedDeclOfCallee() { Expr *CEE = IgnoreParenImpCasts(); - while (SubstNonTypeTemplateParmExpr *NTTP = - dyn_cast(CEE)) { + while (auto *NTTP = dyn_cast(CEE)) CEE = NTTP->getReplacement()->IgnoreParenImpCasts(); - } // If we're calling a dereference, look at the pointer instead. while (true) { -if (BinaryOperator *BO = dyn_cast(CEE)) { +if (auto *BO = dyn_cast(CEE)) { if (BO->isPtrMemOp()) { CEE = BO->getRHS()->IgnoreParenImpCasts(); continue; } -} else if (UnaryOperator *UO = dyn_cast(CEE)) { +} else if (auto *UO = dyn_cast(CEE)) { if (UO->getOpcode() == UO_Deref || UO->getOpcode() == UO_AddrOf || UO->getOpcode() == UO_Plus) { CEE = UO->getSubExpr()->IgnoreParenImpCasts(); @@ -1551,9 +1549,9 @@ Decl *Expr::getReferencedDeclOfCallee() { break; } - if (DeclRefExpr *DRE = dyn_cast(CEE)) + if (auto *DRE = dyn_cast(CEE)) return DRE->getDecl(); - if (MemberExpr *ME = dyn_cast(CEE)) + if (auto *ME = dyn_cast(CEE)) return ME->getMemberDecl(); if (auto *BE = dyn_cast(CEE)) return BE->getBlockDecl(); @@ -1563,7 +1561,7 @@ Decl *Expr::getReferencedDeclOfCallee() { /// If this is a call to a builtin, return the builtin ID. If not, return 0. unsigned CallExpr::getBuiltinCallee() const { - auto *FDecl = getDirectCallee(); + const auto *FDecl = getDirectCallee(); return FDecl ? FDecl->getBuiltinID() : 0; } @@ -1618,8 +1616,8 @@ const Attr *CallExpr::getUnusedResultAttr(const ASTContext &Ctx) const { } SourceLocation CallExpr::getBeginLoc() const { - if (isa(this)) -return cast(this)->getBeginLoc(); + if (const auto *OCE = dyn_cast(this)) +return OCE->getBeginLoc(); SourceLocation begin = getCallee()->getBeginLoc(); if (begin.isInvalid() && getNumArgs() > 0 && getArg(0)) @@ -1627,8 +1625,8 @@ SourceLocation CallExpr::getBeginLoc() const { return begin; } SourceLocation CallExpr::getEndLoc() const { - if (isa(this)) -return cast(this)->getEndLoc(); + if (const auto *OCE = dyn_cast(this)) +return OCE->getEndLoc(); SourceLocation end = getRParenLoc(); if (end.isInvalid() && getNumArgs() > 0 && getArg(getNumArgs() - 1)) @@ -1953,7 +1951,7 @@ const char *CastExpr::getCastKindName(CastKind CK) { namespace { // Skip over implicit nodes produced as part of semantic analysis. // Designed for use with IgnoreExprNodes. -Expr *ignoreImplicitSemaNodes(Expr *E) { +static Expr *ignoreImplicitSemaNodes(Expr *E) { if (auto *Materialize = dyn_cast(E)) return Materialize->getSubExpr(); @@ -2198,12 +2196,13 @@ OverloadedOperatorKind BinaryOperator::getOver
[clang] 80fda7a - [clang][Sema][NFC] Make a bunch of things const if possible
Author: Timm Bäder Date: 2023-04-20T12:23:51+02:00 New Revision: 80fda7a346630e490e8bc3a9cc0d5e0d35526ecb URL: https://github.com/llvm/llvm-project/commit/80fda7a346630e490e8bc3a9cc0d5e0d35526ecb DIFF: https://github.com/llvm/llvm-project/commit/80fda7a346630e490e8bc3a9cc0d5e0d35526ecb.diff LOG: [clang][Sema][NFC] Make a bunch of things const if possible And some general code style cleanup. Differential Revision: https://reviews.llvm.org/D148696 Added: Modified: clang/include/clang/AST/DeclarationName.h clang/include/clang/Sema/Sema.h clang/lib/AST/DeclarationName.cpp clang/lib/Sema/Sema.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaLookup.cpp clang/lib/Sema/SemaOpenMP.cpp Removed: diff --git a/clang/include/clang/AST/DeclarationName.h b/clang/include/clang/AST/DeclarationName.h index b682a75e65764..b06931ea3e418 100644 --- a/clang/include/clang/AST/DeclarationName.h +++ b/clang/include/clang/AST/DeclarationName.h @@ -118,14 +118,14 @@ class alignas(IdentifierInfoAlignment) CXXLiteralOperatorIdName friend class clang::DeclarationName; friend class clang::DeclarationNameTable; - IdentifierInfo *ID; + const IdentifierInfo *ID; /// Extra information associated with this operator name that /// can be used by the front end. All bits are really needed /// so it is not possible to stash something in the low order bits. void *FETokenInfo; - CXXLiteralOperatorIdName(IdentifierInfo *II) + CXXLiteralOperatorIdName(const IdentifierInfo *II) : DeclarationNameExtra(CXXLiteralOperatorName), ID(II), FETokenInfo(nullptr) {} @@ -478,7 +478,7 @@ class DeclarationName { /// If this name is the name of a literal operator, /// retrieve the identifier associated with it. - IdentifierInfo *getCXXLiteralIdentifier() const { + const IdentifierInfo *getCXXLiteralIdentifier() const { if (getNameKind() == CXXLiteralOperatorName) { assert(getPtr() && "getCXXLiteralIdentifier on a null DeclarationName!"); return castAsCXXLiteralOperatorIdName()->ID; @@ -650,7 +650,7 @@ class DeclarationNameTable { } /// Get the name of the literal operator function with II as the identifier. - DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II); + DeclarationName getCXXLiteralOperatorName(const IdentifierInfo *II); }; /// DeclarationNameLoc - Additional source/type location info diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index b05238d0352e6..fd0b89eaec87c 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -840,7 +840,7 @@ class Sema final { /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes. std::unique_ptr FieldCollector; - typedef llvm::SmallSetVector NamedDeclSetType; + typedef llvm::SmallSetVector NamedDeclSetType; /// Set containing all declared private fields that are not used. NamedDeclSetType UnusedPrivateFields; @@ -1489,7 +1489,7 @@ class Sema final { /// Determine if VD, which must be a variable or function, is an external /// symbol that nonetheless can't be referenced from outside this translation /// unit because its type has no linkage and it's not extern "C". - bool isExternalWithNoLinkageType(ValueDecl *VD) const; + bool isExternalWithNoLinkageType(const ValueDecl *VD) const; /// Obtain a sorted list of functions that are undefined but ODR-used. void getUndefinedButUsed( @@ -1778,7 +1778,7 @@ class Sema final { }; SemaDiagnosticBuilder(Kind K, SourceLocation Loc, unsigned DiagID, - FunctionDecl *Fn, Sema &S); + const FunctionDecl *Fn, Sema &S); SemaDiagnosticBuilder(SemaDiagnosticBuilder &&D); SemaDiagnosticBuilder(const SemaDiagnosticBuilder &) = default; ~SemaDiagnosticBuilder(); @@ -1853,7 +1853,7 @@ class Sema final { Sema &S; SourceLocation Loc; unsigned DiagID; -FunctionDecl *Fn; +const FunctionDecl *Fn; bool ShowCallStack; // Invariant: At most one of these Optionals has a value. @@ -3242,9 +3242,9 @@ class Sema final { /// Diagnose that the specified declaration needs to be visible but /// isn't, and suggest a module import that would resolve the problem. - void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl, + void diagnoseMissingImport(SourceLocation Loc, const NamedDecl *Decl, MissingImportKind MIK, bool Recover = true); - void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl, + void diagnoseMissingImport(SourceLocation Loc, const NamedDecl *Decl, SourceLocation DeclLoc, ArrayRef Modules, MissingImportKind MIK, bool Recover); @@ -4510,7 +4510,7 @@ class Sema final { TemplateDiscarded, // Di
[clang] 9bbe25e - [clang][Lex][NFC] Use a range for loop in StringLiteralParser
Author: Timm Bäder Date: 2023-04-20T11:51:05+02:00 New Revision: 9bbe25eca534b0627e03749437713183452ec8c5 URL: https://github.com/llvm/llvm-project/commit/9bbe25eca534b0627e03749437713183452ec8c5 DIFF: https://github.com/llvm/llvm-project/commit/9bbe25eca534b0627e03749437713183452ec8c5.diff LOG: [clang][Lex][NFC] Use a range for loop in StringLiteralParser Added: Modified: clang/lib/Lex/LiteralSupport.cpp Removed: diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 3efecc709334c..9cc0215fb6250 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1867,28 +1867,27 @@ void StringLiteralParser::init(ArrayRef StringToks){ // Implement Translation Phase #6: concatenation of string literals /// (C99 5.1.1.2p1). The common case is only one string fragment. - for (unsigned i = 1; i != StringToks.size(); ++i) { -if (StringToks[i].getLength() < 2) - return DiagnoseLexingError(StringToks[i].getLocation()); + for (const Token &Tok : StringToks) { +if (Tok.getLength() < 2) + return DiagnoseLexingError(Tok.getLocation()); // The string could be shorter than this if it needs cleaning, but this is a // reasonable bound, which is all we need. -assert(StringToks[i].getLength() >= 2 && "literal token is invalid!"); -SizeBound += StringToks[i].getLength()-2; // -2 for "". +assert(Tok.getLength() >= 2 && "literal token is invalid!"); +SizeBound += Tok.getLength() - 2; // -2 for "". // Remember maximum string piece length. -if (StringToks[i].getLength() > MaxTokenLength) - MaxTokenLength = StringToks[i].getLength(); +if (Tok.getLength() > MaxTokenLength) + MaxTokenLength = Tok.getLength(); // Remember if we see any wide or utf-8/16/32 strings. // Also check for illegal concatenations. -if (StringToks[i].isNot(Kind) && StringToks[i].isNot(tok::string_literal)) { +if (Tok.isNot(Kind) && Tok.isNot(tok::string_literal)) { if (isOrdinary()) { -Kind = StringToks[i].getKind(); +Kind = Tok.getKind(); } else { if (Diags) - Diags->Report(StringToks[i].getLocation(), -diag::err_unsupported_string_concat); + Diags->Report(Tok.getLocation(), diag::err_unsupported_string_concat); hadError = true; } } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 30aea03 - [clang][Sema][NFC] Use existing TargetInfo local variable
Author: Timm Bäder Date: 2023-04-20T11:25:46+02:00 New Revision: 30aea0320271502796b0afeed43c1ba2e8059e15 URL: https://github.com/llvm/llvm-project/commit/30aea0320271502796b0afeed43c1ba2e8059e15 DIFF: https://github.com/llvm/llvm-project/commit/30aea0320271502796b0afeed43c1ba2e8059e15.diff LOG: [clang][Sema][NFC] Use existing TargetInfo local variable Added: Modified: clang/lib/Sema/Sema.cpp Removed: diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 76dc77d17092b..b709f920f236c 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -2008,7 +2008,7 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) { if (Diag(Loc, PD, FD) << false /*show bit size*/ << 0 << Ty << false /*return*/ - << Context.getTargetInfo().getTriple().str()) { + << TI.getTriple().str()) { if (D) D->setInvalidDecl(); } @@ -2027,7 +2027,7 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) { if (Diag(Loc, PD, FD) << false /*show bit size*/ << 0 << Ty << true /*return*/ - << Context.getTargetInfo().getTriple().str()) { + << TI.getTriple().str()) { if (D) D->setInvalidDecl(); } @@ -2037,17 +2037,17 @@ void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) { // RISC-V vector builtin types (RISCVVTypes.def) if (Ty->isRVVType(/* Bitwidth */ 64, /* IsFloat */ false) && -!Context.getTargetInfo().hasFeature("zve64x")) +!TI.hasFeature("zve64x")) Diag(Loc, diag::err_riscv_type_requires_extension, FD) << Ty << "zve64x"; if (Ty->isRVVType(/* Bitwidth */ 16, /* IsFloat */ true) && -!Context.getTargetInfo().hasFeature("experimental-zvfh")) +!TI.hasFeature("experimental-zvfh")) Diag(Loc, diag::err_riscv_type_requires_extension, FD) << Ty << "zvfh"; if (Ty->isRVVType(/* Bitwidth */ 32, /* IsFloat */ true) && -!Context.getTargetInfo().hasFeature("zve32f")) +!TI.hasFeature("zve32f")) Diag(Loc, diag::err_riscv_type_requires_extension, FD) << Ty << "zve32f"; if (Ty->isRVVType(/* Bitwidth */ 64, /* IsFloat */ true) && -!Context.getTargetInfo().hasFeature("zve64d")) +!TI.hasFeature("zve64d")) Diag(Loc, diag::err_riscv_type_requires_extension, FD) << Ty << "zve64d"; // Don't allow SVE types in functions without a SVE target. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 70ba243 - [clang][Interp][NFC] Small State.cpp refactoring
Author: Timm Bäder Date: 2023-04-19T08:13:16+02:00 New Revision: 70ba243c6a6ed645efa20443026c520c2d62ff72 URL: https://github.com/llvm/llvm-project/commit/70ba243c6a6ed645efa20443026c520c2d62ff72 DIFF: https://github.com/llvm/llvm-project/commit/70ba243c6a6ed645efa20443026c520c2d62ff72.diff LOG: [clang][Interp][NFC] Small State.cpp refactoring Added: Modified: clang/lib/AST/Interp/State.cpp Removed: diff --git a/clang/lib/AST/Interp/State.cpp b/clang/lib/AST/Interp/State.cpp index f0eed85054ce9..2512979257605 100644 --- a/clang/lib/AST/Interp/State.cpp +++ b/clang/lib/AST/Interp/State.cpp @@ -142,12 +142,12 @@ void State::addCallStack(unsigned Limit) { // Use a diff erent note for an inheriting constructor, because from the // user's perspective it's not really a function at all. -if (auto *CD = dyn_cast_if_present(F->getCallee())) { - if (CD->isInheritingConstructor()) { -addDiag(CallLocation, diag::note_constexpr_inherited_ctor_call_here) -<< CD->getParent(); -continue; - } +if (const auto *CD = +dyn_cast_if_present(F->getCallee()); +CD && CD->isInheritingConstructor()) { + addDiag(CallLocation, diag::note_constexpr_inherited_ctor_call_here) + << CD->getParent(); + continue; } SmallString<128> Buffer; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 455c9ef - [clang][NFC] Use range-for loop in SemaLookup.cpp
Author: Timm Bäder Date: 2023-04-17T09:49:04+02:00 New Revision: 455c9efb41de101eaf5e3d4d521097428b5c75d3 URL: https://github.com/llvm/llvm-project/commit/455c9efb41de101eaf5e3d4d521097428b5c75d3 DIFF: https://github.com/llvm/llvm-project/commit/455c9efb41de101eaf5e3d4d521097428b5c75d3.diff LOG: [clang][NFC] Use range-for loop in SemaLookup.cpp Added: Modified: clang/lib/Sema/SemaLookup.cpp Removed: diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 2413f31744c5..a495d3ca1989 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -3761,8 +3761,8 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R, // operator template, but not both. if (FoundRaw && FoundTemplate) { Diag(R.getNameLoc(), diag::err_ovl_ambiguous_call) << R.getLookupName(); -for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) - NoteOverloadCandidate(*I, (*I)->getUnderlyingDecl()->getAsFunction()); +for (const NamedDecl *D : R) + NoteOverloadCandidate(D, D->getUnderlyingDecl()->getAsFunction()); return LOLR_Error; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 82fdd5b - [clang][NFC] Make parameters to NoteOverloadCandidate const
Author: Timm Bäder Date: 2023-04-17T09:27:51+02:00 New Revision: 82fdd5b5123ee8528267a5bed1c443a30f3f93d7 URL: https://github.com/llvm/llvm-project/commit/82fdd5b5123ee8528267a5bed1c443a30f3f93d7 DIFF: https://github.com/llvm/llvm-project/commit/82fdd5b5123ee8528267a5bed1c443a30f3f93d7.diff LOG: [clang][NFC] Make parameters to NoteOverloadCandidate const Added: Modified: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaOverload.cpp Removed: diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 33d6c40f157fe..c12660081e7c4 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -4076,7 +4076,7 @@ class Sema final { // Emit as a 'note' the specific overload candidate void NoteOverloadCandidate( - NamedDecl *Found, FunctionDecl *Fn, + const NamedDecl *Found, const FunctionDecl *Fn, OverloadCandidateRewriteKind RewriteKind = OverloadCandidateRewriteKind(), QualType DestType = QualType(), bool TakingAddress = false); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index ab4300518ecf1..5a8544e3739fe 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -10385,7 +10385,8 @@ enum OverloadCandidateSelect { }; static std::pair -ClassifyOverloadCandidate(Sema &S, NamedDecl *Found, FunctionDecl *Fn, +ClassifyOverloadCandidate(Sema &S, const NamedDecl *Found, + const FunctionDecl *Fn, OverloadCandidateRewriteKind CRK, std::string &Description) { @@ -10409,7 +10410,7 @@ ClassifyOverloadCandidate(Sema &S, NamedDecl *Found, FunctionDecl *Fn, if (CRK & CRK_Reversed) return oc_reversed_binary_operator; -if (CXXConstructorDecl *Ctor = dyn_cast(Fn)) { +if (const auto *Ctor = dyn_cast(Fn)) { if (!Ctor->isImplicit()) { if (isa(Found)) return oc_inherited_constructor; @@ -10428,7 +10429,7 @@ ClassifyOverloadCandidate(Sema &S, NamedDecl *Found, FunctionDecl *Fn, return oc_implicit_copy_constructor; } -if (CXXMethodDecl *Meth = dyn_cast(Fn)) { +if (const auto *Meth = dyn_cast(Fn)) { // This actually gets spelled 'candidate function' for now, but // it doesn't hurt to split it out. if (!Meth->isImplicit()) @@ -10450,10 +10451,10 @@ ClassifyOverloadCandidate(Sema &S, NamedDecl *Found, FunctionDecl *Fn, return std::make_pair(Kind, Select); } -void MaybeEmitInheritedConstructorNote(Sema &S, Decl *FoundDecl) { +void MaybeEmitInheritedConstructorNote(Sema &S, const Decl *FoundDecl) { // FIXME: It'd be nice to only emit a note once per using-decl per overload // set. - if (auto *Shadow = dyn_cast(FoundDecl)) + if (const auto *Shadow = dyn_cast(FoundDecl)) S.Diag(FoundDecl->getLocation(), diag::note_ovl_candidate_inherited_constructor) << Shadow->getNominatedBaseClass(); @@ -10560,7 +10561,7 @@ bool Sema::checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, // Don't print candidates other than the one that matches the calling // convention of the call operator, since that is guaranteed to exist. -static bool shouldSkipNotingLambdaConversionDecl(FunctionDecl *Fn) { +static bool shouldSkipNotingLambdaConversionDecl(const FunctionDecl *Fn) { const auto *ConvD = dyn_cast(Fn); if (!ConvD) @@ -10580,7 +10581,7 @@ static bool shouldSkipNotingLambdaConversionDecl(FunctionDecl *Fn) { } // Notes the location of an overload candidate. -void Sema::NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn, +void Sema::NoteOverloadCandidate(const NamedDecl *Found, const FunctionDecl *Fn, OverloadCandidateRewriteKind RewriteKind, QualType DestType, bool TakingAddress) { if (TakingAddress && !checkAddressOfCandidateIsAvailable(*this, Fn)) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 4a6a4f8 - [clang][Interp] Add a failing test case
Author: Timm Bäder Date: 2023-04-13T15:55:57+02:00 New Revision: 4a6a4f84a7af7212d36aea9c34a1a8b9bb05d733 URL: https://github.com/llvm/llvm-project/commit/4a6a4f84a7af7212d36aea9c34a1a8b9bb05d733 DIFF: https://github.com/llvm/llvm-project/commit/4a6a4f84a7af7212d36aea9c34a1a8b9bb05d733.diff LOG: [clang][Interp] Add a failing test case Added: Modified: clang/test/AST/Interp/records.cpp Removed: diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 745a30bec33b..a874bf378150 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -451,3 +451,40 @@ namespace ConditionalInit { static_assert(getS(true).a == 12, ""); static_assert(getS(false).a == 13, ""); }; +/// FIXME: The following tests are broken. +/// They are using CXXDefaultInitExprs which contain a CXXThisExpr. The This pointer +/// in those refers to the declaration we are currently initializing, *not* the +/// This pointer of the current stack frame. This is something we haven't +/// implemented in the new interpreter yet. +namespace DeclRefs { + struct A{ int m; const int &f = m; }; // expected-note {{implicit use of 'this'}} + + constexpr A a{10}; // expected-error {{must be initialized by a constant expression}} + static_assert(a.m == 10, ""); + static_assert(a.f == 10, ""); // expected-error {{not an integral constant expression}} \ +// expected-note {{read of object outside its lifetime}} + + class Foo { + public: +int z = 1337; +constexpr int a() const { + A b{this->z}; + + return b.f; +} + }; + constexpr Foo f; + static_assert(f.a() == 1337, ""); + + + struct B { +A a = A{100}; + }; + constexpr B b; + /// FIXME: The following two lines don't work because we don't get the + /// pointers on the LHS correct. They make us run into an assertion + /// in CheckEvaluationResult. However, this may just be caused by the + /// problems in the previous examples. + //static_assert(b.a.m == 100, ""); + //static_assert(b.a.f == 100, ""); +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] f508d9b - [clang][Interp] Don't create global variables more than once
Author: Timm Bäder Date: 2023-04-13T15:41:43+02:00 New Revision: f508d9b1d4fa48e7586b9587a22be23c976297a7 URL: https://github.com/llvm/llvm-project/commit/f508d9b1d4fa48e7586b9587a22be23c976297a7 DIFF: https://github.com/llvm/llvm-project/commit/f508d9b1d4fa48e7586b9587a22be23c976297a7.diff LOG: [clang][Interp] Don't create global variables more than once just because we're being told to evaluate it twice. This sometimes happens when a variable is evaluated again during codegen. Differential Revision: https://reviews.llvm.org/D147535 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 6ced8ca4d07f..a8e8b2997dde 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1562,7 +1562,11 @@ bool ByteCodeExprGen::visitVarDecl(const VarDecl *VD) { std::optional VarT = classify(VD->getType()); if (shouldBeGloballyIndexed(VD)) { -std::optional GlobalIndex = P.getOrCreateGlobal(VD, Init); +// We've already seen and initialized this global. +if (P.getGlobal(VD)) + return true; + +std::optional GlobalIndex = P.createGlobal(VD, Init); if (!GlobalIndex) return this->bail(VD); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 25d6123 - [clang][Interp] Make sure we have a variable scope for initializers
Author: Timm Bäder Date: 2023-04-13T15:35:30+02:00 New Revision: 25d6123854d16370463ba884e750f303d09e9001 URL: https://github.com/llvm/llvm-project/commit/25d6123854d16370463ba884e750f303d09e9001 DIFF: https://github.com/llvm/llvm-project/commit/25d6123854d16370463ba884e750f303d09e9001.diff LOG: [clang][Interp] Make sure we have a variable scope for initializers Otherwise, we run into an assertion when trying to use the current variable scope while creating temporaries for constructor initializers. Differential Revision: https://reviews.llvm.org/D147534 Added: Modified: clang/lib/AST/Interp/ByteCodeStmtGen.cpp clang/test/AST/Interp/records.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp index 2c53900111d9b..e20b714120e8d 100644 --- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp @@ -102,6 +102,9 @@ bool ByteCodeStmtGen::visitFunc(const FunctionDecl *F) { return false; for (const auto *Init : Ctor->inits()) { + // Scope needed for the initializers. + BlockScope Scope(this); + const Expr *InitExpr = Init->getInit(); if (const FieldDecl *Member = Init->getMember()) { const Record::Field *F = R->getField(Member); diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 39eb65c13342f..745a30bec33bd 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -250,6 +250,78 @@ struct S { constexpr S s; static_assert(s.m() == 1, ""); +namespace InitializerTemporaries { + class Bar { + private: +int a; + + public: +constexpr Bar() : a(10) {} +constexpr int getA() const { return a; } + }; + + class Foo { + public: +int a; + +constexpr Foo() : a(Bar().getA()) {} + }; + constexpr Foo F; + static_assert(F.a == 10, ""); + + + /// Needs constexpr destructors. +#if __cplusplus >= 202002L + /// Does + ///Arr[Pos] = Value; + ///++Pos; + /// in its destructor. + class BitSetter { + private: +int *Arr; +int &Pos; +int Value; + + public: +constexpr BitSetter(int *Arr, int &Pos, int Value) : + Arr(Arr), Pos(Pos), Value(Value) {} + +constexpr int getValue() const { return 0; } +constexpr ~BitSetter() { + Arr[Pos] = Value; + ++Pos; +} + }; + + class Test { +int a, b, c; + public: +constexpr Test(int *Arr, int &Pos) : + a(BitSetter(Arr, Pos, 1).getValue()), + b(BitSetter(Arr, Pos, 2).getValue()), + c(BitSetter(Arr, Pos, 3).getValue()) +{} + }; + + + constexpr int T(int Index) { +int Arr[] = {0, 0, 0}; +int Pos = 0; + +{ + auto T = Test(Arr, Pos); + // End of scope, should destroy Test. +} + +return Arr[Index]; + } + + static_assert(T(0) == 1); + static_assert(T(1) == 2); + static_assert(T(2) == 3); +#endif +} + #if __cplusplus >= 201703L namespace BaseInit { class _A {public: int a;}; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] dfafb7f - [clang][NFC] More range for loops in TextDiagnostic.cpp
Author: Timm Bäder Date: 2023-04-13T13:43:57+02:00 New Revision: dfafb7fe5af3e55ff35fb5dbc685a4337af5b29c URL: https://github.com/llvm/llvm-project/commit/dfafb7fe5af3e55ff35fb5dbc685a4337af5b29c DIFF: https://github.com/llvm/llvm-project/commit/dfafb7fe5af3e55ff35fb5dbc685a4337af5b29c.diff LOG: [clang][NFC] More range for loops in TextDiagnostic.cpp Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index 6dbf7f4ce6f1..08f84d28bb85 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -856,15 +856,14 @@ void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc, FileID CaretFileID = Loc.getExpansionLoc().getFileID(); bool PrintedRange = false; -for (ArrayRef::const_iterator RI = Ranges.begin(), - RE = Ranges.end(); - RI != RE; ++RI) { +for (const auto &R : Ranges) { // Ignore invalid ranges. - if (!RI->isValid()) continue; + if (!R.isValid()) +continue; auto &SM = Loc.getManager(); - SourceLocation B = SM.getExpansionLoc(RI->getBegin()); - CharSourceRange ERange = SM.getExpansionRange(RI->getEnd()); + SourceLocation B = SM.getExpansionLoc(R.getBegin()); + CharSourceRange ERange = SM.getExpansionRange(R.getEnd()); SourceLocation E = ERange.getEnd(); bool IsTokenRange = ERange.isTokenRange(); @@ -1068,51 +1067,51 @@ static std::string buildFixItInsertionLine(FileID FID, return FixItInsertionLine; unsigned PrevHintEndCol = 0; - for (ArrayRef::iterator I = Hints.begin(), E = Hints.end(); - I != E; ++I) { -if (!I->CodeToInsert.empty()) { - // We have an insertion hint. Determine whether the inserted - // code contains no newlines and is on the same line as the caret. - std::pair HintLocInfo -= SM.getDecomposedExpansionLoc(I->RemoveRange.getBegin()); - if (FID == HintLocInfo.first && - LineNo == SM.getLineNumber(HintLocInfo.first, HintLocInfo.second) && - StringRef(I->CodeToInsert).find_first_of("\n\r") == StringRef::npos) { -// Insert the new code into the line just below the code -// that the user wrote. -// Note: When modifying this function, be very careful about what is a -// "column" (printed width, platform-dependent) and what is a -// "byte offset" (SourceManager "column"). -unsigned HintByteOffset - = SM.getColumnNumber(HintLocInfo.first, HintLocInfo.second) - 1; - -// The hint must start inside the source or right at the end -assert(HintByteOffset < static_cast(map.bytes())+1); -unsigned HintCol = map.byteToContainingColumn(HintByteOffset); - -// If we inserted a long previous hint, push this one forwards, and add -// an extra space to show that this is not part of the previous -// completion. This is sort of the best we can do when two hints appear -// to overlap. -// -// Note that if this hint is located immediately after the previous -// hint, no space will be added, since the location is more important. -if (HintCol < PrevHintEndCol) - HintCol = PrevHintEndCol + 1; - -// This should NOT use HintByteOffset, because the source might have -// Unicode characters in earlier columns. -unsigned NewFixItLineSize = FixItInsertionLine.size() + - (HintCol - PrevHintEndCol) + I->CodeToInsert.size(); -if (NewFixItLineSize > FixItInsertionLine.size()) - FixItInsertionLine.resize(NewFixItLineSize, ' '); - -std::copy(I->CodeToInsert.begin(), I->CodeToInsert.end(), - FixItInsertionLine.end() - I->CodeToInsert.size()); - -PrevHintEndCol = - HintCol + llvm::sys::locale::columnWidth(I->CodeToInsert); - } + for (const auto &H : Hints) { +if (H.CodeToInsert.empty()) + continue; + +// We have an insertion hint. Determine whether the inserted +// code contains no newlines and is on the same line as the caret. +std::pair HintLocInfo = +SM.getDecomposedExpansionLoc(H.RemoveRange.getBegin()); +if (FID == HintLocInfo.first && +LineNo == SM.getLineNumber(HintLocInfo.first, HintLocInfo.second) && +StringRef(H.CodeToInsert).find_first_of("\n\r") == StringRef::npos) { + // Insert the new code into the line just below the code + // that the user wrote. + // Note: When modifying this function, be very careful about what is a + // "column" (printed width, platform-dependent) and what is a + // "byte offset" (SourceManager "column"). + unsigned HintByteOffset = + SM.getColumnNumber(HintLocInfo.first, HintLocInfo.second) - 1; + + // The hint must start in
[clang] 650d69f - [clang][NFC] Fix comment typo
Author: Timm Bäder Date: 2023-04-13T13:42:58+02:00 New Revision: 650d69ffe4d0ff2d2c84b8bf19555a8a9b10aae8 URL: https://github.com/llvm/llvm-project/commit/650d69ffe4d0ff2d2c84b8bf19555a8a9b10aae8 DIFF: https://github.com/llvm/llvm-project/commit/650d69ffe4d0ff2d2c84b8bf19555a8a9b10aae8.diff LOG: [clang][NFC] Fix comment typo Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index 95b5f257c63d4..6dbf7f4ce6f14 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -787,7 +787,7 @@ void TextDiagnostic::emitFilename(StringRef Filename, const SourceManager &SM) { /// Print out the file/line/column information and include trace. /// -/// This method handlen the emission of the diagnostic location information. +/// This method handles the emission of the diagnostic location information. /// This includes extracting as much location information as is present for /// the diagnostic and printing it, as well as any include stack or source /// ranges necessary. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3704752 - [clang][NFC] Use range-for loop in TextDiagnostic.cpp
Author: Timm Bäder Date: 2023-04-12T18:50:37+02:00 New Revision: 37047523a9fb5ffa74eaf94d9d52db831f99c062 URL: https://github.com/llvm/llvm-project/commit/37047523a9fb5ffa74eaf94d9d52db831f99c062 DIFF: https://github.com/llvm/llvm-project/commit/37047523a9fb5ffa74eaf94d9d52db831f99c062.diff LOG: [clang][NFC] Use range-for loop in TextDiagnostic.cpp Added: Modified: clang/lib/Frontend/TextDiagnostic.cpp Removed: diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index 809d5309d1af..95b5f257c63d 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -1168,11 +1168,10 @@ void TextDiagnostic::emitSnippetAndCaret( // Find the set of lines to include. const unsigned MaxLines = DiagOpts->SnippetLineLimit; std::pair Lines = {CaretLineNo, CaretLineNo}; - for (SmallVectorImpl::iterator I = Ranges.begin(), - E = Ranges.end(); - I != E; ++I) -if (auto OptionalRange = findLinesForRange(*I, FID, SM)) + for (auto &I : Ranges) { +if (auto OptionalRange = findLinesForRange(I, FID, SM)) Lines = maybeAddRange(Lines, *OptionalRange, MaxLines); + } for (unsigned LineNo = Lines.first; LineNo != Lines.second + 1; ++LineNo) { const char *BufStart = BufData.data(); @@ -1212,10 +1211,8 @@ void TextDiagnostic::emitSnippetAndCaret( std::string CaretLine(sourceColMap.columns(), ' '); // Highlight all of the characters covered by Ranges with ~ characters. -for (SmallVectorImpl::iterator I = Ranges.begin(), -E = Ranges.end(); - I != E; ++I) - highlightRange(*I, LineNo, FID, sourceColMap, CaretLine, SM, LangOpts); +for (auto &I : Ranges) + highlightRange(I, LineNo, FID, sourceColMap, CaretLine, SM, LangOpts); // Next, insert the caret itself. if (CaretLineNo == LineNo) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] f43adc4 - [clang][Interp] Add missing static_assert message
Author: Timm Bäder Date: 2023-04-08T15:44:11+02:00 New Revision: f43adc498065fdfa120bd1aeea02c64f7ecea8f9 URL: https://github.com/llvm/llvm-project/commit/f43adc498065fdfa120bd1aeea02c64f7ecea8f9 DIFF: https://github.com/llvm/llvm-project/commit/f43adc498065fdfa120bd1aeea02c64f7ecea8f9.diff LOG: [clang][Interp] Add missing static_assert message Added: Modified: clang/test/AST/Interp/functions.cpp Removed: diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index 933cc860577e..a8681aae0d58 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -214,10 +214,10 @@ namespace InvalidCall { } }; constexpr S s; - static_assert(s.a() == 1); // expected-error {{not an integral constant expression}} \ - // expected-note {{in call to}} \ - // ref-error {{not an integral constant expression}} \ - // ref-note {{in call to}} + static_assert(s.a() == 1, ""); // expected-error {{not an integral constant expression}} \ + // expected-note {{in call to}} \ + // ref-error {{not an integral constant expression}} \ + // ref-note {{in call to}} /// This used to cause an assertion failure in the new constant interpreter. constexpr void func(); // expected-note {{declared here}} \ ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 0260ea3 - [clang][Interp][NFC] Add test for e7f55bb
Author: Timm Bäder Date: 2023-04-08T15:28:47+02:00 New Revision: 0260ea3a5b1cfa0b0dbb9852742da7480fda620c URL: https://github.com/llvm/llvm-project/commit/0260ea3a5b1cfa0b0dbb9852742da7480fda620c DIFF: https://github.com/llvm/llvm-project/commit/0260ea3a5b1cfa0b0dbb9852742da7480fda620c.diff LOG: [clang][Interp][NFC] Add test for e7f55bb Added: Modified: clang/test/AST/Interp/functions.cpp Removed: diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index 8b6b1bcd6f5c..933cc860577e 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -218,4 +218,17 @@ namespace InvalidCall { // expected-note {{in call to}} \ // ref-error {{not an integral constant expression}} \ // ref-note {{in call to}} + + /// This used to cause an assertion failure in the new constant interpreter. + constexpr void func(); // expected-note {{declared here}} \ + // ref-note {{declared here}} + struct SS { +constexpr SS() { func(); } // expected-note {{undefined function }} \ + // ref-note {{undefined function}} + }; + constexpr SS ss; // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{in call to 'SS()'}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{in call to 'SS()'}} + } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 1c818b0 - [clang][Interp] Fix a crash when calling invalid constexpr functions
Author: Timm Bäder Date: 2023-04-08T15:28:47+02:00 New Revision: 1c818b0a4f92abd6a450841ebca37f3ef5dac0bc URL: https://github.com/llvm/llvm-project/commit/1c818b0a4f92abd6a450841ebca37f3ef5dac0bc DIFF: https://github.com/llvm/llvm-project/commit/1c818b0a4f92abd6a450841ebca37f3ef5dac0bc.diff LOG: [clang][Interp] Fix a crash when calling invalid constexpr functions Differential Revision: https://reviews.llvm.org/D147845 Added: Modified: clang/lib/AST/Interp/InterpFrame.cpp clang/test/AST/Interp/functions.cpp Removed: diff --git a/clang/lib/AST/Interp/InterpFrame.cpp b/clang/lib/AST/Interp/InterpFrame.cpp index 897d420e91a3a..a8c4aab84ef8d 100644 --- a/clang/lib/AST/Interp/InterpFrame.cpp +++ b/clang/lib/AST/Interp/InterpFrame.cpp @@ -127,7 +127,8 @@ void print(llvm::raw_ostream &OS, const Pointer &P, ASTContext &Ctx, } // Drop the first pointer since we print it unconditionally anyway. - Levels.erase(Levels.begin()); + if (!Levels.empty()) +Levels.erase(Levels.begin()); printDesc(P.getDeclDesc()); for (const auto &It : Levels) { diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index 06edcdeffa705..8b6b1bcd6f5c3 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -202,3 +202,20 @@ constexpr int nyd(int m); constexpr int doit() { return nyd(10); } constexpr int nyd(int m) { return m; } static_assert(doit() == 10, ""); + +namespace InvalidCall { + struct S { +constexpr int a() const { // expected-error {{never produces a constant expression}} \ + // ref-error {{never produces a constant expression}} + return 1 / 0; // expected-note 2{{division by zero}} \ +// expected-warning {{is undefined}} \ +// ref-note 2{{division by zero}} \ +// ref-warning {{is undefined}} +} + }; + constexpr S s; + static_assert(s.a() == 1); // expected-error {{not an integral constant expression}} \ + // expected-note {{in call to}} \ + // ref-error {{not an integral constant expression}} \ + // ref-note {{in call to}} +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 11ad7d2 - [clang][Sema][NFC] Save token name instead of the full token
Author: Timm Bäder Date: 2023-04-08T09:02:19+02:00 New Revision: 11ad7d2935afe965c9e8c7ba4732215b404ff57f URL: https://github.com/llvm/llvm-project/commit/11ad7d2935afe965c9e8c7ba4732215b404ff57f DIFF: https://github.com/llvm/llvm-project/commit/11ad7d2935afe965c9e8c7ba4732215b404ff57f.diff LOG: [clang][Sema][NFC] Save token name instead of the full token Differential Revision: https://reviews.llvm.org/D147615 Added: Modified: clang/lib/Parse/ParseDeclCXX.cpp Removed: diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 037bc869c5a1..1530d824c345 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -958,8 +958,8 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) { assert(Tok.isOneOf(tok::kw_static_assert, tok::kw__Static_assert) && "Not a static_assert declaration"); - // Save the token used for static assertion. - Token SavedTok = Tok; + // Save the token name used for static assertion. + const char *TokName = Tok.getName(); if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11) Diag(Tok, diag::ext_c11_feature) << Tok.getName(); @@ -1027,9 +1027,7 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) { T.consumeClose(); DeclEnd = Tok.getLocation(); - // Passing the token used to the error message. - ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, - SavedTok.getName()); + ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, TokName); return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, AssertExpr.get(), AssertMessage.get(), ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e7f55bb - [clang][Interp][NFCI] Call* ops don't modify the PC
Author: Timm Bäder Date: 2023-04-08T08:49:22+02:00 New Revision: e7f55bbdb880eb0c096b05d915ee920fe1f2fb98 URL: https://github.com/llvm/llvm-project/commit/e7f55bbdb880eb0c096b05d915ee920fe1f2fb98 DIFF: https://github.com/llvm/llvm-project/commit/e7f55bbdb880eb0c096b05d915ee920fe1f2fb98.diff LOG: [clang][Interp][NFCI] Call* ops don't modify the PC This caused the reported errors from the Call*() handlers to report the wrong source location. Fixes: https://github.com/llvm/llvm-project/issues/62002 Added: Modified: clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/Opcodes.td Removed: diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index afc5f24baf73..1eda38e9fa5b 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -1486,28 +1486,29 @@ inline bool ArrayElemPtrPop(InterpState &S, CodePtr OpPC) { return NarrowPtr(S, OpPC); } -inline bool CheckGlobalCtor(InterpState &S, CodePtr &PC) { +inline bool CheckGlobalCtor(InterpState &S, CodePtr OpPC) { const Pointer &Obj = S.Stk.peek(); - return CheckCtorCall(S, PC, Obj); + return CheckCtorCall(S, OpPC, Obj); } -inline bool Call(InterpState &S, CodePtr &PC, const Function *Func) { +inline bool Call(InterpState &S, CodePtr OpPC, const Function *Func) { if (Func->hasThisPointer()) { size_t ThisOffset = Func->getArgSize() + (Func->hasRVO() ? primSize(PT_Ptr) : 0); + const Pointer &ThisPtr = S.Stk.peek(ThisOffset); -if (!CheckInvoke(S, PC, ThisPtr)) +if (!CheckInvoke(S, OpPC, ThisPtr)) return false; if (S.checkingPotentialConstantExpression()) return false; } - if (!CheckCallable(S, PC, Func)) + if (!CheckCallable(S, OpPC, Func)) return false; - auto NewFrame = std::make_unique(S, Func, PC); + auto NewFrame = std::make_unique(S, Func, OpPC); InterpFrame *FrameBefore = S.Current; S.Current = NewFrame.get(); @@ -1541,14 +1542,14 @@ inline bool CallBI(InterpState &S, CodePtr &PC, const Function *Func) { return false; } -inline bool CallPtr(InterpState &S, CodePtr &PC) { +inline bool CallPtr(InterpState &S, CodePtr OpPC) { const FunctionPointer &FuncPtr = S.Stk.pop(); const Function *F = FuncPtr.getFunction(); if (!F || !F->isConstexpr()) return false; - return Call(S, PC, F); + return Call(S, OpPC, F); } inline bool GetFnPtr(InterpState &S, CodePtr &PC, const Function *Func) { diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index f3662dcd6f43..ed0774a78833 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -179,19 +179,16 @@ def NoRet : Opcode {} def Call : Opcode { let Args = [ArgFunction]; let Types = []; - let ChangesPC = 1; } def CallBI : Opcode { let Args = [ArgFunction]; let Types = []; - let ChangesPC = 1; } def CallPtr : Opcode { let Args = []; let Types = []; - let ChangesPC = 1; } //===--===// ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 7d9511b - [clang][Interp] Add missing static_assert messages
Author: Timm Bäder Date: 2023-04-06T12:03:45+02:00 New Revision: 7d9511b2e33f1981cd846dd2493c6d96ece2c77e URL: https://github.com/llvm/llvm-project/commit/7d9511b2e33f1981cd846dd2493c6d96ece2c77e DIFF: https://github.com/llvm/llvm-project/commit/7d9511b2e33f1981cd846dd2493c6d96ece2c77e.diff LOG: [clang][Interp] Add missing static_assert messages This broke build bots, e.g: https://lab.llvm.org/buildbot/#/builders/139/builds/38697 Added: Modified: clang/test/AST/Interp/floats.cpp Removed: diff --git a/clang/test/AST/Interp/floats.cpp b/clang/test/AST/Interp/floats.cpp index 3b392d3b6727b..71f585ee70a9c 100644 --- a/clang/test/AST/Interp/floats.cpp +++ b/clang/test/AST/Interp/floats.cpp @@ -87,8 +87,8 @@ namespace ZeroInit { }; constexpr A a{12}; - static_assert(a.f == 0.0f); + static_assert(a.f == 0.0f, ""); constexpr A b{12}; - static_assert(a.f == 0.0); + static_assert(a.f == 0.0, ""); }; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 70e5a2a - [clang][Interp] Fix zero-initializing of floating types
Author: Timm Bäder Date: 2023-04-06T10:52:01+02:00 New Revision: 70e5a2a94354fd7cec577d3e0c3892cc5e7ef07a URL: https://github.com/llvm/llvm-project/commit/70e5a2a94354fd7cec577d3e0c3892cc5e7ef07a DIFF: https://github.com/llvm/llvm-project/commit/70e5a2a94354fd7cec577d3e0c3892cc5e7ef07a.diff LOG: [clang][Interp] Fix zero-initializing of floating types Differential Revision: https://reviews.llvm.org/D146788 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/test/AST/Interp/floats.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 3c0992e4fee0..6ced8ca4d07f 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -953,8 +953,10 @@ bool ByteCodeExprGen::visitZeroInitializer(PrimType T, const Expr *E) { return this->emitNullPtr(E); case PT_FnPtr: return this->emitNullFnPtr(E); - case PT_Float: -assert(false); + case PT_Float: { +return this->emitConstFloat( +APFloat::getZero(Ctx.getFloatSemantics(E->getType())), E); + } } llvm_unreachable("unknown primitive type"); } diff --git a/clang/test/AST/Interp/floats.cpp b/clang/test/AST/Interp/floats.cpp index 7b9328c4d118..3b392d3b6727 100644 --- a/clang/test/AST/Interp/floats.cpp +++ b/clang/test/AST/Interp/floats.cpp @@ -78,3 +78,17 @@ namespace compound { } static_assert(f2() == __FLT_MAX__, ""); } + +namespace ZeroInit { + template + struct A { +int a; +FloatT f; + }; + + constexpr A a{12}; + static_assert(a.f == 0.0f); + + constexpr A b{12}; + static_assert(a.f == 0.0); +}; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 47ee851 - [clang][Interp][NFC] Context: Add getFloatSemantics()
Author: Timm Bäder Date: 2023-04-06T10:39:49+02:00 New Revision: 47ee8519ec2620ffe376d9b28cba8a2a0a73214a URL: https://github.com/llvm/llvm-project/commit/47ee8519ec2620ffe376d9b28cba8a2a0a73214a DIFF: https://github.com/llvm/llvm-project/commit/47ee8519ec2620ffe376d9b28cba8a2a0a73214a.diff LOG: [clang][Interp][NFC] Context: Add getFloatSemantics() We use this quite a bit, so add some convenience API for it. Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/Context.cpp clang/lib/AST/Interp/Context.h Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index a1f6f72c9bfc..3c0992e4fee0 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -92,8 +92,7 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { case CK_FloatingCast: { if (!this->visit(SubExpr)) return false; -const auto *TargetSemantics = -&Ctx.getASTContext().getFloatTypeSemantics(CE->getType()); +const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType()); return this->emitCastFP(TargetSemantics, getRoundingMode(CE), CE); } @@ -105,8 +104,7 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { if (!this->visit(SubExpr)) return false; -const auto *TargetSemantics = -&Ctx.getASTContext().getFloatTypeSemantics(CE->getType()); +const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType()); llvm::RoundingMode RM = getRoundingMode(CE); return this->emitCastIntegralFloating(*FromT, TargetSemantics, RM, CE); } @@ -601,8 +599,7 @@ bool ByteCodeExprGen::VisitFloatCompoundAssignOperator( // If necessary, convert LHS to its computation type. if (LHS->getType() != LHSComputationType) { -const auto *TargetSemantics = -&Ctx.getASTContext().getFloatTypeSemantics(LHSComputationType); +const auto *TargetSemantics = &Ctx.getFloatSemantics(LHSComputationType); if (!this->emitCastFP(TargetSemantics, RM, E)) return false; @@ -635,8 +632,7 @@ bool ByteCodeExprGen::VisitFloatCompoundAssignOperator( // If necessary, convert result to LHS's type. if (LHS->getType() != ResultType) { -const auto *TargetSemantics = -&Ctx.getASTContext().getFloatTypeSemantics(LHS->getType()); +const auto *TargetSemantics = &Ctx.getFloatSemantics(LHS->getType()); if (!this->emitCastFP(TargetSemantics, RM, E)) return false; diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp index 6ede05e0f4c4..ed7ed41b1b24 100644 --- a/clang/lib/AST/Interp/Context.cpp +++ b/clang/lib/AST/Interp/Context.cpp @@ -133,6 +133,12 @@ unsigned Context::getCharBit() const { return Ctx.getTargetInfo().getCharWidth(); } +/// Simple wrapper around getFloatTypeSemantics() to make code a +/// little shorter. +const llvm::fltSemantics &Context::getFloatSemantics(QualType T) const { + return Ctx.getFloatTypeSemantics(T); +} + bool Context::Run(State &Parent, Function *Func, APValue &Result) { InterpState State(Parent, *P, Stk, *this); State.Current = new InterpFrame(State, Func, /*Caller=*/nullptr, {}); diff --git a/clang/lib/AST/Interp/Context.h b/clang/lib/AST/Interp/Context.h index e49422e64b87..cbae7fcf2860 100644 --- a/clang/lib/AST/Interp/Context.h +++ b/clang/lib/AST/Interp/Context.h @@ -57,6 +57,8 @@ class Context final { InterpStack &getStack() { return Stk; } /// Returns CHAR_BIT. unsigned getCharBit() const; + /// Return the floating-point semantics for T. + const llvm::fltSemantics &getFloatSemantics(QualType T) const; /// Classifies an expression. std::optional classify(QualType T) const; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 4016e5d - [clang][Interp][NFC] Call emit*Ptr directly
Author: Timm Bäder Date: 2023-04-06T10:25:57+02:00 New Revision: 4016e5d9499e3cbcde32dbfe1d0a5085a9b16c96 URL: https://github.com/llvm/llvm-project/commit/4016e5d9499e3cbcde32dbfe1d0a5085a9b16c96 DIFF: https://github.com/llvm/llvm-project/commit/4016e5d9499e3cbcde32dbfe1d0a5085a9b16c96.diff LOG: [clang][Interp][NFC] Call emit*Ptr directly Instead of the version that uses a switch statement to figure this out. Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 2f9f99cc0648..a1f6f72c9bfc 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1881,13 +1881,13 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) { return this->emitGetPtrLocal(Offset, E); } else if (auto GlobalIndex = P.getGlobal(D)) { if (IsReference) - return this->emitGetGlobal(PT_Ptr, *GlobalIndex, E); + return this->emitGetGlobalPtr(*GlobalIndex, E); return this->emitGetPtrGlobal(*GlobalIndex, E); } else if (const auto *PVD = dyn_cast(D)) { if (auto It = this->Params.find(PVD); It != this->Params.end()) { if (IsReference) -return this->emitGetParam(PT_Ptr, It->second, E); +return this->emitGetParamPtr(It->second, E); return this->emitGetPtrParam(It->second, E); } } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 92417f2 - [clang][Interp] Record initialization via conditional operator
Author: Timm Bäder Date: 2023-04-06T09:44:02+02:00 New Revision: 92417f2d4b1706326717cc5e782f3aa77a7157bb URL: https://github.com/llvm/llvm-project/commit/92417f2d4b1706326717cc5e782f3aa77a7157bb DIFF: https://github.com/llvm/llvm-project/commit/92417f2d4b1706326717cc5e782f3aa77a7157bb.diff LOG: [clang][Interp] Record initialization via conditional operator Differential Revision: https://reviews.llvm.org/D141497 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/ByteCodeExprGen.h clang/test/AST/Interp/constexpr-nqueens.cpp clang/test/AST/Interp/records.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index e620b4f9b2f63..2f9f99cc06489 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -560,32 +560,8 @@ bool ByteCodeExprGen::VisitOpaqueValueExpr(const OpaqueValueExpr *E) { template bool ByteCodeExprGen::VisitAbstractConditionalOperator( const AbstractConditionalOperator *E) { - const Expr *Condition = E->getCond(); - const Expr *TrueExpr = E->getTrueExpr(); - const Expr *FalseExpr = E->getFalseExpr(); - - LabelTy LabelEnd = this->getLabel(); // Label after the operator. - LabelTy LabelFalse = this->getLabel(); // Label for the false expr. - - if (!this->visit(Condition)) -return false; - if (!this->jumpFalse(LabelFalse)) -return false; - - if (!this->visit(TrueExpr)) -return false; - if (!this->jump(LabelEnd)) -return false; - - this->emitLabel(LabelFalse); - - if (!this->visit(FalseExpr)) -return false; - - this->fallthrough(LabelEnd); - this->emitLabel(LabelEnd); - - return true; + return this->visitConditional( + E, [this](const Expr *E) { return this->visit(E); }); } template @@ -921,6 +897,41 @@ bool ByteCodeExprGen::visitBool(const Expr *E) { } } +/// Visit a conditional operator, i.e. `A ? B : C`. +/// \V determines what function to call for the B and C expressions. +template +bool ByteCodeExprGen::visitConditional( +const AbstractConditionalOperator *E, +llvm::function_ref V) { + + const Expr *Condition = E->getCond(); + const Expr *TrueExpr = E->getTrueExpr(); + const Expr *FalseExpr = E->getFalseExpr(); + + LabelTy LabelEnd = this->getLabel(); // Label after the operator. + LabelTy LabelFalse = this->getLabel(); // Label for the false expr. + + if (!this->visit(Condition)) +return false; + if (!this->jumpFalse(LabelFalse)) +return false; + + if (!V(TrueExpr)) +return false; + if (!this->jump(LabelEnd)) +return false; + + this->emitLabel(LabelFalse); + + if (!V(FalseExpr)) +return false; + + this->fallthrough(LabelEnd); + this->emitLabel(LabelEnd); + + return true; +} + template bool ByteCodeExprGen::visitZeroInitializer(PrimType T, const Expr *E) { switch (T) { @@ -1429,6 +1440,10 @@ bool ByteCodeExprGen::visitRecordInitializer(const Expr *Initializer) { return this->visitInitializer(CE->getSubExpr()); } else if (const auto *CE = dyn_cast(Initializer)) { return this->visitInitializer(CE->getSubExpr()); + } else if (const auto *ACO = + dyn_cast(Initializer)) { +return this->visitConditional( +ACO, [this](const Expr *E) { return this->visitRecordInitializer(E); }); } return false; diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index 46a926bfb5f01..85588c6ecd3c1 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -181,6 +181,9 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, return this->emitPopPtr(I); } + bool visitConditional(const AbstractConditionalOperator *E, +llvm::function_ref V); + /// Creates a local primitive value. unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsMutable, bool IsExtended = false); diff --git a/clang/test/AST/Interp/constexpr-nqueens.cpp b/clang/test/AST/Interp/constexpr-nqueens.cpp index 5aeb7afcd79ce..c71092af069bb 100644 --- a/clang/test/AST/Interp/constexpr-nqueens.cpp +++ b/clang/test/AST/Interp/constexpr-nqueens.cpp @@ -17,7 +17,8 @@ struct Board { constexpr Board(uint64_t State, bool Failed = false) : Failed(Failed) {} constexpr Board addQueen(int Row, int Col) const { -return Board(State | ((uint64_t)Row << (Col * 4))); // ref-note {{read of uninitialized object}} +return Board(State | ((uint64_t)Row << (Col * 4))); // ref-note {{read of uninitialized object}} \ +// expected-note {{read of object outside its lifetime}} } constexpr int getQueenRow(int Col) const { return (State >> (Col * 4)) & 0xf; @@ -47,17 +48,22 @@ constexpr Board tryBoard(const Board
[clang] 626b7e5 - [clang][Interp][NFC] Remove Integral.h include from PrimType.h
Author: Timm Bäder Date: 2023-04-04T10:44:56+02:00 New Revision: 626b7e5dd249f569203e024141c1a2a0f618df9c URL: https://github.com/llvm/llvm-project/commit/626b7e5dd249f569203e024141c1a2a0f618df9c DIFF: https://github.com/llvm/llvm-project/commit/626b7e5dd249f569203e024141c1a2a0f618df9c.diff LOG: [clang][Interp][NFC] Remove Integral.h include from PrimType.h Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.h clang/lib/AST/Interp/PrimType.h clang/lib/AST/Interp/Program.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index af5b4678b070..46a926bfb5f0 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -224,9 +224,9 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, llvm::function_ref Indirect); /// Emits an APSInt constant. - bool emitConst(const APSInt &Value, const Expr *E); - bool emitConst(const APInt &Value, const Expr *E) { -return emitConst(static_cast(Value), E); + bool emitConst(const llvm::APSInt &Value, const Expr *E); + bool emitConst(const llvm::APInt &Value, const Expr *E) { +return emitConst(static_cast(Value), E); } /// Emits an integer constant. diff --git a/clang/lib/AST/Interp/PrimType.h b/clang/lib/AST/Interp/PrimType.h index 91311cf7030a..30bec3f2a17c 100644 --- a/clang/lib/AST/Interp/PrimType.h +++ b/clang/lib/AST/Interp/PrimType.h @@ -13,7 +13,6 @@ #ifndef LLVM_CLANG_AST_INTERP_TYPE_H #define LLVM_CLANG_AST_INTERP_TYPE_H -#include "Integral.h" #include #include #include @@ -25,6 +24,7 @@ class Pointer; class Boolean; class Floating; class FunctionPointer; +template class Integral; /// Enumeration of the primitive types of the VM. enum PrimType : unsigned { diff --git a/clang/lib/AST/Interp/Program.cpp b/clang/lib/AST/Interp/Program.cpp index 106c59463e2b..f6f378dd49f1 100644 --- a/clang/lib/AST/Interp/Program.cpp +++ b/clang/lib/AST/Interp/Program.cpp @@ -10,6 +10,7 @@ #include "ByteCodeStmtGen.h" #include "Context.h" #include "Function.h" +#include "Integral.h" #include "Opcode.h" #include "PrimType.h" #include "clang/AST/Decl.h" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] ee71cbd - [clang][Interp] Ignore more non-VarDecl declarations
Author: Timm Bäder Date: 2023-04-04T10:41:46+02:00 New Revision: ee71cbddb77f8da9285657cac248b431928143b9 URL: https://github.com/llvm/llvm-project/commit/ee71cbddb77f8da9285657cac248b431928143b9 DIFF: https://github.com/llvm/llvm-project/commit/ee71cbddb77f8da9285657cac248b431928143b9.diff LOG: [clang][Interp] Ignore more non-VarDecl declarations They are harmless and handled by other means, but we used to return false from visitDeclStmt. Differential Revision: https://reviews.llvm.org/D145861 Added: Modified: clang/lib/AST/Interp/ByteCodeStmtGen.cpp clang/test/AST/Interp/literals.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp index 6faa3f9a47a9b..2c53900111d9b 100644 --- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp @@ -224,7 +224,7 @@ bool ByteCodeStmtGen::visitCompoundStmt( template bool ByteCodeStmtGen::visitDeclStmt(const DeclStmt *DS) { for (auto *D : DS->decls()) { -if (isa(D)) +if (isa(D)) continue; const auto *VD = dyn_cast(D); diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index 5883c1879b925..f31a49088dc6c 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -766,3 +766,16 @@ namespace TypeTraits { static_assert(S3{}.foo(), ""); static_assert(!S3{}.foo(), ""); } + +#if __cplusplus >= 201402L +constexpr int ignoredDecls() { + static_assert(true, ""); + struct F { int a; }; + enum E { b }; + using A = int; + typedef int Z; + + return F{12}.a; +} +static_assert(ignoredDecls() == 12, ""); +#endif ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 82facc2 - [clang][Interp] Add missing static_assert message
Author: Timm Bäder Date: 2023-04-03T17:12:05+02:00 New Revision: 82facc2b2462441a83ca35d2d6ef1ab28244a1b3 URL: https://github.com/llvm/llvm-project/commit/82facc2b2462441a83ca35d2d6ef1ab28244a1b3 DIFF: https://github.com/llvm/llvm-project/commit/82facc2b2462441a83ca35d2d6ef1ab28244a1b3.diff LOG: [clang][Interp] Add missing static_assert message This broke builders, e.g: https://lab.llvm.org/buildbot/#builders/139/builds/38457 Added: Modified: clang/test/AST/Interp/functions.cpp Removed: diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index 4b81e7d6be3b..06edcdeffa70 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -10,7 +10,7 @@ static_assert(gimme5() == 5, ""); template constexpr T identity(T t) { - static_assert(true); + static_assert(true, ""); return t; } static_assert(identity(true), ""); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 192c2c5 - [clang][Interp] Ignore StaticAssertDecls
Author: Timm Bäder Date: 2023-04-03T16:56:58+02:00 New Revision: 192c2c5c89477e28d0129f37a7d262112585b353 URL: https://github.com/llvm/llvm-project/commit/192c2c5c89477e28d0129f37a7d262112585b353 DIFF: https://github.com/llvm/llvm-project/commit/192c2c5c89477e28d0129f37a7d262112585b353.diff LOG: [clang][Interp] Ignore StaticAssertDecls They have already been handled before, but we can't just return false when we encounter one. Differential Revision: https://reviews.llvm.org/D144272 Added: Modified: clang/lib/AST/Interp/ByteCodeStmtGen.cpp clang/test/AST/Interp/functions.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp index 1735b9b0272b..6faa3f9a47a9 100644 --- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp @@ -224,6 +224,9 @@ bool ByteCodeStmtGen::visitCompoundStmt( template bool ByteCodeStmtGen::visitDeclStmt(const DeclStmt *DS) { for (auto *D : DS->decls()) { +if (isa(D)) + continue; + const auto *VD = dyn_cast(D); if (!VD) return false; diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index 2b44f42486d3..4b81e7d6be3b 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -9,11 +9,28 @@ constexpr int gimme5() { static_assert(gimme5() == 5, ""); -template constexpr T identity(T t) { return t; } +template constexpr T identity(T t) { + static_assert(true); + return t; +} static_assert(identity(true), ""); static_assert(identity(true), ""); /// Compiled bytecode should be cached static_assert(!identity(false), ""); +template +constexpr bool sameSize() { + static_assert(sizeof(A) == sizeof(B), ""); // expected-error {{static assertion failed}} \ + // ref-error {{static assertion failed}} \ + // expected-note {{evaluates to}} \ + // ref-note {{evaluates to}} + return true; +} +static_assert(sameSize(), ""); +static_assert(sameSize(), ""); +static_assert(sameSize(), ""); // expected-note {{in instantiation of function template specialization}} \ + // ref-note {{in instantiation of function template specialization}} + + constexpr auto add(int a, int b) -> int { return identity(a) + identity(b); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] b15a946 - [clang][Interp][NFC] Refactor VisitDeclRefExpr
Author: Timm Bäder Date: 2023-04-03T16:42:25+02:00 New Revision: b15a946b9f59f91518ae5e2cb6125592d9c1bf3c URL: https://github.com/llvm/llvm-project/commit/b15a946b9f59f91518ae5e2cb6125592d9c1bf3c DIFF: https://github.com/llvm/llvm-project/commit/b15a946b9f59f91518ae5e2cb6125592d9c1bf3c.diff LOG: [clang][Interp][NFC] Refactor VisitDeclRefExpr Make it clearer that we only need to check for variables and parameters if we don't have the easy case. Also only do the IsReference check if necessary. Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index ee5dd73159a6..e620b4f9b2f6 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1840,37 +1840,41 @@ bool ByteCodeExprGen::VisitUnaryOperator(const UnaryOperator *E) { template bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) { - const auto *Decl = E->getDecl(); + const auto *D = E->getDecl(); + + if (const auto *ECD = dyn_cast(D)) { +return this->emitConst(ECD->getInitVal(), E); + } else if (const auto *BD = dyn_cast(D)) { +return this->visit(BD->getBinding()); + } else if (const auto *FuncDecl = dyn_cast(D)) { +const Function *F = getFunction(FuncDecl); +return F && this->emitGetFnPtr(F, E); + } + // References are implemented via pointers, so when we see a DeclRefExpr // pointing to a reference, we need to get its value directly (i.e. the // pointer to the actual value) instead of a pointer to the pointer to the // value. - bool IsReference = Decl->getType()->isReferenceType(); + bool IsReference = D->getType()->isReferenceType(); - if (auto It = Locals.find(Decl); It != Locals.end()) { + // Check for local/global variables and parameters. + if (auto It = Locals.find(D); It != Locals.end()) { const unsigned Offset = It->second.Offset; if (IsReference) return this->emitGetLocal(PT_Ptr, Offset, E); return this->emitGetPtrLocal(Offset, E); - } else if (auto GlobalIndex = P.getGlobal(Decl)) { + } else if (auto GlobalIndex = P.getGlobal(D)) { if (IsReference) return this->emitGetGlobal(PT_Ptr, *GlobalIndex, E); return this->emitGetPtrGlobal(*GlobalIndex, E); - } else if (const auto *PVD = dyn_cast(Decl)) { + } else if (const auto *PVD = dyn_cast(D)) { if (auto It = this->Params.find(PVD); It != this->Params.end()) { if (IsReference) return this->emitGetParam(PT_Ptr, It->second, E); return this->emitGetPtrParam(It->second, E); } - } else if (const auto *ECD = dyn_cast(Decl)) { -return this->emitConst(ECD->getInitVal(), E); - } else if (const auto *BD = dyn_cast(Decl)) { -return this->visit(BD->getBinding()); - } else if (const auto *FuncDecl = dyn_cast(Decl)) { -const Function *F = getFunction(FuncDecl); -return F && this->emitGetFnPtr(F, E); } return false; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 056042d - [clang][Interp] Fix initializing fields after base class members
Author: Timm Bäder Date: 2023-04-03T15:55:11+02:00 New Revision: 056042d21b72a86653f88719c0b54b07e35d2144 URL: https://github.com/llvm/llvm-project/commit/056042d21b72a86653f88719c0b54b07e35d2144 DIFF: https://github.com/llvm/llvm-project/commit/056042d21b72a86653f88719c0b54b07e35d2144.diff LOG: [clang][Interp] Fix initializing fields after base class members Differential Revision: https://reviews.llvm.org/D145860 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/test/AST/Interp/cxx20.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index e5c9b2637b85..ee5dd73159a6 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1384,6 +1384,7 @@ bool ByteCodeExprGen::visitRecordInitializer(const Expr *Initializer) { if (!this->emitPopPtr(Initializer)) return false; +++InitIndex; } else { // Initializer for a direct base class. if (const Record::Base *B = R->getBase(Init->getType())) { @@ -1395,6 +1396,8 @@ bool ByteCodeExprGen::visitRecordInitializer(const Expr *Initializer) { if (!this->emitPopPtr(Initializer)) return false; + // Base initializers don't increase InitIndex, since they don't count + // into the Record's fields. } else { const Record::Field *FieldToInit = R->getField(InitIndex); // Non-primitive case. Get a pointer to the field-to-initialize @@ -1407,9 +1410,9 @@ bool ByteCodeExprGen::visitRecordInitializer(const Expr *Initializer) { if (!this->emitPopPtr(Initializer)) return false; + ++InitIndex; } } - ++InitIndex; } return true; diff --git a/clang/test/AST/Interp/cxx20.cpp b/clang/test/AST/Interp/cxx20.cpp index 6cb106adf59c..37be7a41bf75 100644 --- a/clang/test/AST/Interp/cxx20.cpp +++ b/clang/test/AST/Interp/cxx20.cpp @@ -583,3 +583,20 @@ namespace Destructors { constexpr Outer O; static_assert(O.bar() == 12); } + +namespace BaseAndFieldInit { + struct A { +int a; + }; + + struct B : A { +int b; + }; + + struct C : B { +int c; + }; + + constexpr C c = {1,2,3}; + static_assert(c.a == 1 && c.b == 2 && c.c == 3); +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 58cf70b - [clang][Interp] Fix diagnostics for calling non-constexpr constructors
Author: Timm Bäder Date: 2023-04-03T15:42:08+02:00 New Revision: 58cf70b2cdc17a905f7db2ec5a6f9d497f9bd133 URL: https://github.com/llvm/llvm-project/commit/58cf70b2cdc17a905f7db2ec5a6f9d497f9bd133 DIFF: https://github.com/llvm/llvm-project/commit/58cf70b2cdc17a905f7db2ec5a6f9d497f9bd133.diff LOG: [clang][Interp] Fix diagnostics for calling non-constexpr constructors Differential Revision: https://reviews.llvm.org/D145841 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/test/AST/Interp/cxx20.cpp clang/test/AST/Interp/records.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 665f60d572ea..e5c9b2637b85 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1350,7 +1350,7 @@ bool ByteCodeExprGen::visitRecordInitializer(const Expr *Initializer) { if (const auto CtorExpr = dyn_cast(Initializer)) { const Function *Func = getFunction(CtorExpr->getConstructor()); -if (!Func || !Func->isConstexpr()) +if (!Func) return false; // The This pointer is already on the stack because this is an initializer, diff --git a/clang/test/AST/Interp/cxx20.cpp b/clang/test/AST/Interp/cxx20.cpp index cfa9729f4b03..6cb106adf59c 100644 --- a/clang/test/AST/Interp/cxx20.cpp +++ b/clang/test/AST/Interp/cxx20.cpp @@ -207,13 +207,15 @@ namespace ConstThis { // ref-note {{declared const here}} int a; public: -constexpr Foo() { +constexpr Foo() { // expected-note {{declared here}} this->a = 10; T = 13; // expected-error {{cannot assign to non-static data member 'T' with const-qualified type}} \ // ref-error {{cannot assign to non-static data member 'T' with const-qualified type}} } }; constexpr Foo F; // expected-error {{must be initialized by a constant expression}} \ + // FIXME: The following note is wrong. \ + // expected-note {{undefined constructor 'Foo' cannot be used in a constant expression}} \ // ref-error {{must be initialized by a constant expression}} diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 37cdf341fbd7..a7085e45ca33 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -308,7 +308,7 @@ namespace MI { }; namespace DeriveFailures { - struct Base { // ref-note 2{{declared here}} + struct Base { // ref-note 2{{declared here}} expected-note {{declared here}} int Val; }; @@ -316,13 +316,15 @@ namespace DeriveFailures { int OtherVal; constexpr Derived(int i) : OtherVal(i) {} // ref-error {{never produces a constant expression}} \ - // ref-note 2{{non-constexpr constructor 'Base' cannot be used in a constant expression}} + // ref-note 2{{non-constexpr constructor 'Base' cannot be used in a constant expression}} \ + // expected-note {{non-constexpr constructor 'Base' cannot be used in a constant expression}} }; constexpr Derived D(12); // ref-error {{must be initialized by a constant expression}} \ // ref-note {{in call to 'Derived(12)'}} \ // ref-note {{declared here}} \ - // expected-error {{must be initialized by a constant expression}} + // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{in call to 'Derived(12)'}} static_assert(D.Val == 0, ""); // ref-error {{not an integral constant expression}} \ // ref-note {{initializer of 'D' is not a constant expression}} \ // expected-error {{not an integral constant expression}} \ @@ -348,7 +350,8 @@ namespace DeriveFailures { }; struct YetAnotherDerived : YetAnotherBase { -using YetAnotherBase::YetAnotherBase; //ref-note {{declared here}} +using YetAnotherBase::YetAnotherBase; // ref-note {{declared here}} \ + // expected-note {{declared here}} int OtherVal; constexpr bool doit() const { return Val == OtherVal; } @@ -356,8 +359,8 @@ namespace DeriveFailures { constexpr YetAnotherDerived Oops(0); // ref-error {{must be initialized by a constant expression}} \ // ref-note {{constructor inherited from base class 'YetAnotherBase' cannot be used in a constant expression}} \ - // expected-error {{must be initialized by a constant expression}} - // FIXME: Missing reason for rejection. +
[clang] db3dcdc - [clang][Interp] Fix initializing base class members
Author: Timm Bäder Date: 2023-04-03T13:51:04+02:00 New Revision: db3dcdc08ce06e301cdcc75e2849315a47d7a28d URL: https://github.com/llvm/llvm-project/commit/db3dcdc08ce06e301cdcc75e2849315a47d7a28d DIFF: https://github.com/llvm/llvm-project/commit/db3dcdc08ce06e301cdcc75e2849315a47d7a28d.diff LOG: [clang][Interp] Fix initializing base class members For the given test case, we were trying to initialize a member of C, which doesn't have any. Get the proper base pointer instead and initialize the members there. Differential Revision: https://reviews.llvm.org/D143466 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/Interp.cpp clang/lib/AST/Interp/Record.cpp clang/lib/AST/Interp/Record.h clang/test/AST/Interp/cxx20.cpp clang/test/AST/Interp/records.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index ad802f72aad4c..665f60d572ea7 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1370,12 +1370,12 @@ bool ByteCodeExprGen::visitRecordInitializer(const Expr *Initializer) { unsigned InitIndex = 0; for (const Expr *Init : InitList->inits()) { - const Record::Field *FieldToInit = R->getField(InitIndex); if (!this->emitDupPtr(Initializer)) return false; if (std::optional T = classify(Init)) { +const Record::Field *FieldToInit = R->getField(InitIndex); if (!this->visit(Init)) return false; @@ -1385,16 +1385,29 @@ bool ByteCodeExprGen::visitRecordInitializer(const Expr *Initializer) { if (!this->emitPopPtr(Initializer)) return false; } else { -// Non-primitive case. Get a pointer to the field-to-initialize -// on the stack and recurse into visitInitializer(). -if (!this->emitGetPtrField(FieldToInit->Offset, Init)) - return false; +// Initializer for a direct base class. +if (const Record::Base *B = R->getBase(Init->getType())) { + if (!this->emitGetPtrBasePop(B->Offset, Init)) +return false; -if (!this->visitInitializer(Init)) - return false; + if (!this->visitInitializer(Init)) +return false; -if (!this->emitPopPtr(Initializer)) - return false; + if (!this->emitPopPtr(Initializer)) +return false; +} else { + const Record::Field *FieldToInit = R->getField(InitIndex); + // Non-primitive case. Get a pointer to the field-to-initialize + // on the stack and recurse into visitInitializer(). + if (!this->emitGetPtrField(FieldToInit->Offset, Init)) +return false; + + if (!this->visitInitializer(Init)) +return false; + + if (!this->emitPopPtr(Initializer)) +return false; +} } ++InitIndex; } diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index 554e9a8e2d204..3af8027ddeb53 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -434,7 +434,7 @@ static bool CheckFieldsInitialized(InterpState &S, CodePtr OpPC, // Check Fields in all bases for (const Record::Base &B : R->bases()) { -Pointer P = Pointer(BasePtr.block(), B.Offset); +Pointer P = BasePtr.atField(B.Offset); Result &= CheckFieldsInitialized(S, OpPC, P, B.R); } diff --git a/clang/lib/AST/Interp/Record.cpp b/clang/lib/AST/Interp/Record.cpp index f440c4705051e..c8cbdb314f512 100644 --- a/clang/lib/AST/Interp/Record.cpp +++ b/clang/lib/AST/Interp/Record.cpp @@ -39,6 +39,16 @@ const Record::Base *Record::getBase(const RecordDecl *FD) const { return It->second; } +const Record::Base *Record::getBase(QualType T) const { + if (!T->isRecordType()) +return nullptr; + + const RecordDecl *RD = T->getAs()->getDecl(); + if (auto It = BaseMap.find(RD); It != BaseMap.end()) +return It->second; + return nullptr; +} + const Record::Base *Record::getVirtualBase(const RecordDecl *FD) const { auto It = VirtualBaseMap.find(FD); assert(It != VirtualBaseMap.end() && "Missing virtual base"); diff --git a/clang/lib/AST/Interp/Record.h b/clang/lib/AST/Interp/Record.h index 1742cb1cc4ee6..52173fffa5447 100644 --- a/clang/lib/AST/Interp/Record.h +++ b/clang/lib/AST/Interp/Record.h @@ -61,6 +61,8 @@ class Record final { const Field *getField(const FieldDecl *FD) const; /// Returns a base descriptor. const Base *getBase(const RecordDecl *FD) const; + /// Returns a base descriptor. + const Base *getBase(QualType T) const; /// Returns a virtual base descriptor. const Base *getVirtualBase(const RecordDecl *RD) const; // Returns the destructor of the record, if any. diff --git a/clang/test/AST/Interp/cxx20.cpp b/clang/test/A
[clang] 968b417 - [clang][Interp] Fix derived-to-base casts for >1 levels
Author: Timm Bäder Date: 2023-04-03T11:35:55+02:00 New Revision: 968b4172f6a9878e56dc911f3f9df089d2a9134f URL: https://github.com/llvm/llvm-project/commit/968b4172f6a9878e56dc911f3f9df089d2a9134f DIFF: https://github.com/llvm/llvm-project/commit/968b4172f6a9878e56dc911f3f9df089d2a9134f.diff LOG: [clang][Interp] Fix derived-to-base casts for >1 levels The GetPtrBasePop op we were using only works for direct base classes. Differential Revision: https://reviews.llvm.org/D143480 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/ByteCodeExprGen.h clang/test/AST/Interp/records.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 733247787d760..ad802f72aad4c 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -85,15 +85,8 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { if (!this->visit(SubExpr)) return false; -const CXXRecordDecl *FromDecl = getRecordDecl(SubExpr); -assert(FromDecl); -const CXXRecordDecl *ToDecl = getRecordDecl(CE); -assert(ToDecl); -const Record *R = getRecord(FromDecl); -const Record::Base *ToBase = R->getBase(ToDecl); -assert(ToBase); - -return this->emitGetPtrBasePop(ToBase->Offset, CE); +return this->emitDerivedToBaseCasts(getRecordTy(SubExpr->getType()), +getRecordTy(CE->getType()), CE); } case CK_FloatingCast: { @@ -1873,6 +1866,38 @@ void ByteCodeExprGen::emitCleanup() { C->emitDestruction(); } +template +bool ByteCodeExprGen::emitDerivedToBaseCasts( +const RecordType *DerivedType, const RecordType *BaseType, const Expr *E) { + // Pointer of derived type is already on the stack. + const auto *FinalDecl = cast(BaseType->getDecl()); + const RecordDecl *CurDecl = DerivedType->getDecl(); + const Record *CurRecord = getRecord(CurDecl); + assert(CurDecl && FinalDecl); + for (;;) { +assert(CurRecord->getNumBases() > 0); +// One level up +for (const Record::Base &B : CurRecord->bases()) { + const auto *BaseDecl = cast(B.Decl); + + if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(FinalDecl)) { +// This decl will lead us to the final decl, so emit a base cast. +if (!this->emitGetPtrBasePop(B.Offset, E)) + return false; + +CurRecord = B.R; +CurDecl = BaseDecl; +break; + } +} +if (CurDecl == FinalDecl) + return true; + } + + llvm_unreachable("Couldn't find the base class?"); + return false; +} + /// When calling this, we have a pointer of the local-to-destroy /// on the stack. /// Emit destruction of record types (or arrays of record types). diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index 4baf5d433c9e0..af5b4678b0703 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -260,6 +260,8 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, } bool emitRecordDestruction(const Descriptor *Desc); + bool emitDerivedToBaseCasts(const RecordType *DerivedType, + const RecordType *BaseType, const Expr *E); protected: /// Variable to storage mapping. diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 448e1c0eb7223..188db827fe08b 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -250,6 +250,21 @@ struct S { constexpr S s; static_assert(s.m() == 1, ""); +#if __cplusplus >= 201703L +namespace BaseInit { + class A {public: int a;}; + class B : public A {}; + class C : public A {}; + class D : public B, public C {}; + + // FIXME: Enable this once we support the initialization. + // This initializes D::B::A::a and not D::C::A::a. + //constexpr D d{12}; + //static_assert(d.B::a == 12); + //static_assert(d.C::a == 0); +}; +#endif + namespace MI { class A { public: ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 943ef06 - [clang][Interp] Check This pointer without creating InterpFrame
Author: Timm Bäder Date: 2023-03-31T16:18:15+02:00 New Revision: 943ef06420105cad23e3caea24d6a274cdb0316f URL: https://github.com/llvm/llvm-project/commit/943ef06420105cad23e3caea24d6a274cdb0316f DIFF: https://github.com/llvm/llvm-project/commit/943ef06420105cad23e3caea24d6a274cdb0316f.diff LOG: [clang][Interp] Check This pointer without creating InterpFrame The InterpFrame was only created so early so we could use getThis(). However, we need to know the Function when creating the InterpFrame and in the case of virtual functions, we need to determine what function to call at interpretation time. Get the This pointer ourselves and just create the InterpFrame later. Differential Revision: https://reviews.llvm.org/D142617 Added: Modified: clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/InterpStack.cpp clang/lib/AST/Interp/InterpStack.h Removed: diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index bb34737e018b..afc5f24baf73 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -1492,10 +1492,11 @@ inline bool CheckGlobalCtor(InterpState &S, CodePtr &PC) { } inline bool Call(InterpState &S, CodePtr &PC, const Function *Func) { - auto NewFrame = std::make_unique(S, Func, PC); - Pointer ThisPtr; if (Func->hasThisPointer()) { -ThisPtr = NewFrame->getThis(); +size_t ThisOffset = +Func->getArgSize() + (Func->hasRVO() ? primSize(PT_Ptr) : 0); +const Pointer &ThisPtr = S.Stk.peek(ThisOffset); + if (!CheckInvoke(S, PC, ThisPtr)) return false; @@ -1506,6 +1507,7 @@ inline bool Call(InterpState &S, CodePtr &PC, const Function *Func) { if (!CheckCallable(S, PC, Func)) return false; + auto NewFrame = std::make_unique(S, Func, PC); InterpFrame *FrameBefore = S.Current; S.Current = NewFrame.get(); diff --git a/clang/lib/AST/Interp/InterpStack.cpp b/clang/lib/AST/Interp/InterpStack.cpp index 7fe678e62192..63a088be6705 100644 --- a/clang/lib/AST/Interp/InterpStack.cpp +++ b/clang/lib/AST/Interp/InterpStack.cpp @@ -46,7 +46,7 @@ void *InterpStack::grow(size_t Size) { return Object; } -void *InterpStack::peek(size_t Size) const { +void *InterpStack::peekData(size_t Size) const { assert(Chunk && "Stack is empty!"); StackChunk *Ptr = Chunk; diff --git a/clang/lib/AST/Interp/InterpStack.h b/clang/lib/AST/Interp/InterpStack.h index e625ffd8e421..435120d0e441 100644 --- a/clang/lib/AST/Interp/InterpStack.h +++ b/clang/lib/AST/Interp/InterpStack.h @@ -64,11 +64,16 @@ class InterpStack final { /// Returns a reference to the value on the top of the stack. template T &peek() const { -return *reinterpret_cast(peek(aligned_size())); +return *reinterpret_cast(peekData(aligned_size())); + } + + template T &peek(size_t Offset) const { +assert(aligned(Offset)); +return *reinterpret_cast(peekData(Offset)); } /// Returns a pointer to the top object. - void *top() const { return Chunk ? peek(0) : nullptr; } + void *top() const { return Chunk ? peekData(0) : nullptr; } /// Returns the size of the stack in bytes. size_t size() const { return StackSize; } @@ -90,7 +95,7 @@ class InterpStack final { /// Grows the stack to accommodate a value and returns a pointer to it. void *grow(size_t Size); /// Returns a pointer from the top of the stack. - void *peek(size_t Size) const; + void *peekData(size_t Size) const; /// Shrinks the stack. void shrink(size_t Size); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 8d2899a - [clang][Interp] Handle TypeTraitExprs
Author: Timm Bäder Date: 2023-03-31T15:54:44+02:00 New Revision: 8d2899acbcf1b8ce120bc219aeb30207d4422042 URL: https://github.com/llvm/llvm-project/commit/8d2899acbcf1b8ce120bc219aeb30207d4422042 DIFF: https://github.com/llvm/llvm-project/commit/8d2899acbcf1b8ce120bc219aeb30207d4422042.diff LOG: [clang][Interp] Handle TypeTraitExprs Differential Revision: https://reviews.llvm.org/D142448 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/ByteCodeExprGen.h clang/test/AST/Interp/literals.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 1b605a9e0927..733247787d76 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -897,6 +897,11 @@ bool ByteCodeExprGen::VisitCompoundLiteralExpr( return false; } +template +bool ByteCodeExprGen::VisitTypeTraitExpr(const TypeTraitExpr *E) { + return this->emitConstBool(E->getValue(), 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 03d2eb87b5e1..4baf5d433c9e 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -92,6 +92,7 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, bool VisitExprWithCleanups(const ExprWithCleanups *E); bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E); bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); + bool VisitTypeTraitExpr(const TypeTraitExpr *E); protected: bool visitExpr(const Expr *E) override; diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index fc36c13ed07b..5883c1879b92 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -743,3 +743,26 @@ namespace CompoundLiterals { static_assert(get3() == 3, ""); #endif }; + +namespace TypeTraits { + static_assert(__is_trivial(int), ""); + static_assert(__is_trivial(float), ""); + static_assert(__is_trivial(E), ""); + struct S{}; + static_assert(__is_trivial(S), ""); + struct S2 { +S2() {} + }; + static_assert(!__is_trivial(S2), ""); + + template + struct S3 { +constexpr bool foo() const { return __is_trivial(T); } + }; + struct T { +~T() {} + }; + struct U {}; + static_assert(S3{}.foo(), ""); + static_assert(!S3{}.foo(), ""); +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] d472c55 - [clang][Interp] Fix double-printing InterpFrame::describe()
Author: Timm Bäder Date: 2023-03-31T15:25:30+02:00 New Revision: d472c55fa28a249e1845908b47a1be6f2e05a1cd URL: https://github.com/llvm/llvm-project/commit/d472c55fa28a249e1845908b47a1be6f2e05a1cd DIFF: https://github.com/llvm/llvm-project/commit/d472c55fa28a249e1845908b47a1be6f2e05a1cd.diff LOG: [clang][Interp] Fix double-printing InterpFrame::describe() Differential Revision: https://reviews.llvm.org/D141831 Added: Modified: clang/lib/AST/Interp/InterpFrame.cpp clang/test/AST/Interp/constexpr-nqueens.cpp Removed: diff --git a/clang/lib/AST/Interp/InterpFrame.cpp b/clang/lib/AST/Interp/InterpFrame.cpp index 584cf1a9a69e6..897d420e91a3a 100644 --- a/clang/lib/AST/Interp/InterpFrame.cpp +++ b/clang/lib/AST/Interp/InterpFrame.cpp @@ -126,6 +126,9 @@ void print(llvm::raw_ostream &OS, const Pointer &P, ASTContext &Ctx, F = F.isArrayElement() ? F.getArray().expand() : F.getBase(); } + // Drop the first pointer since we print it unconditionally anyway. + Levels.erase(Levels.begin()); + printDesc(P.getDeclDesc()); for (const auto &It : Levels) { if (It.inArray()) { diff --git a/clang/test/AST/Interp/constexpr-nqueens.cpp b/clang/test/AST/Interp/constexpr-nqueens.cpp index ffe8553a944b0..5aeb7afcd79ce 100644 --- a/clang/test/AST/Interp/constexpr-nqueens.cpp +++ b/clang/test/AST/Interp/constexpr-nqueens.cpp @@ -6,9 +6,6 @@ /// Board constructors. /// This tests that InterpFrame::describe(). -// FIXME: With the new interpreter, most of the described frames are -// currently broken in one way or another. - typedef unsigned long uint64_t; struct Board { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] d29f706 - [clang][Interp] Fix binary comma operators
Author: Timm Bäder Date: 2023-03-31T14:54:51+02:00 New Revision: d29f70670db8ca43a49b6df9112035dc4b646182 URL: https://github.com/llvm/llvm-project/commit/d29f70670db8ca43a49b6df9112035dc4b646182 DIFF: https://github.com/llvm/llvm-project/commit/d29f70670db8ca43a49b6df9112035dc4b646182.diff LOG: [clang][Interp] Fix binary comma operators We left the result of RHS on the stack in case DiscardResult was true. Differential Revision: https://reviews.llvm.org/D141784 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/test/SemaCXX/constexpr-duffs-device.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index afa5372a5112c..1b605a9e09278 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -198,18 +198,6 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { const Expr *LHS = BO->getLHS(); const Expr *RHS = BO->getRHS(); - // Deal with operations which have composite or void types. - switch (BO->getOpcode()) { - case BO_Comma: -if (!discard(LHS)) - return false; -if (!this->visit(RHS)) - return false; -return true; - default: -break; - } - // Typecheck the args. std::optional LT = classify(LHS->getType()); std::optional RT = classify(RHS->getType()); @@ -224,6 +212,13 @@ bool ByteCodeExprGen::VisitBinaryOperator(const BinaryOperator *BO) { return DiscardResult ? this->emitPop(*T, BO) : true; }; + // Deal with operations which have composite or void types. + if (BO->isCommaOp()) { +if (!discard(LHS)) + return false; +return Discard(this->visit(RHS)); + } + // Pointer arithmetic special case. if (BO->getOpcode() == BO_Add || BO->getOpcode() == BO_Sub) { if (*T == PT_Ptr || (*LT == PT_Ptr && *RT == PT_Ptr)) diff --git a/clang/test/SemaCXX/constexpr-duffs-device.cpp b/clang/test/SemaCXX/constexpr-duffs-device.cpp index f77d989b9d36f..3c643cbb2af4b 100644 --- a/clang/test/SemaCXX/constexpr-duffs-device.cpp +++ b/clang/test/SemaCXX/constexpr-duffs-device.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -std=c++1y -verify %s +// RUN: %clang_cc1 -std=c++1y -verify -fexperimental-new-constant-interpreter %s // expected-no-diagnostics constexpr void copy(const char *from, unsigned long count, char *to) { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] cef69ce - [clang][Interp] Fix record initialization via CallExpr subclasses
Author: Timm Bäder Date: 2023-03-31T13:16:49+02:00 New Revision: cef69ce7791f2b6415ef3991347904381717a1ec URL: https://github.com/llvm/llvm-project/commit/cef69ce7791f2b6415ef3991347904381717a1ec DIFF: https://github.com/llvm/llvm-project/commit/cef69ce7791f2b6415ef3991347904381717a1ec.diff LOG: [clang][Interp] Fix record initialization via CallExpr subclasses We can't just use VisitCallExpr() here, as that doesn't handle CallExpr subclasses such as CXXMemberCallExpr. Differential Revision: https://reviews.llvm.org/D141772 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/test/AST/Interp/records.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 1e61bc992448..afa5372a5112 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1413,7 +1413,7 @@ bool ByteCodeExprGen::visitRecordInitializer(const Expr *Initializer) { if (!this->emitDupPtr(Initializer)) return false; -return this->VisitCallExpr(CE); +return this->visit(CE); } else if (const auto *DIE = dyn_cast(Initializer)) { return this->visitInitializer(DIE->getExpr()); } else if (const auto *CE = dyn_cast(Initializer)) { diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index c0bfdeb090eb..448e1c0eb722 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -98,12 +98,20 @@ class C { int b; constexpr C() : a(100), b(200) {} + + constexpr C get() const { +return *this; + } }; constexpr C c; static_assert(c.a == 100, ""); static_assert(c.b == 200, ""); +constexpr C c2 = C().get(); +static_assert(c.a == 100, ""); +static_assert(c.b == 200, ""); + constexpr int getB() { C c; int &j = c.b; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 068e0e0 - [clang][Interp][NFC] Add failing test case for InterpFrame::describe()
Author: Timm Bäder Date: 2023-03-31T08:32:42+02:00 New Revision: 068e0e001d63a76fcec0cb585ffe8832794115eb URL: https://github.com/llvm/llvm-project/commit/068e0e001d63a76fcec0cb585ffe8832794115eb DIFF: https://github.com/llvm/llvm-project/commit/068e0e001d63a76fcec0cb585ffe8832794115eb.diff LOG: [clang][Interp][NFC] Add failing test case for InterpFrame::describe() Added: clang/test/AST/Interp/constexpr-nqueens.cpp Modified: Removed: diff --git a/clang/test/AST/Interp/constexpr-nqueens.cpp b/clang/test/AST/Interp/constexpr-nqueens.cpp new file mode 100644 index ..ffe8553a944b --- /dev/null +++ b/clang/test/AST/Interp/constexpr-nqueens.cpp @@ -0,0 +1,66 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=ref %s +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fexperimental-new-constant-interpreter -verify %s + +/// This is a version of the nqueens.cpp from SemaCXX/, +/// but we don't initialize the State variable in the +/// Board constructors. +/// This tests that InterpFrame::describe(). + +// FIXME: With the new interpreter, most of the described frames are +// currently broken in one way or another. + +typedef unsigned long uint64_t; + +struct Board { + uint64_t State; + bool Failed; + + constexpr Board() : Failed(false) {} + constexpr Board(const Board &O) : Failed(O.Failed) {} + constexpr Board(uint64_t State, bool Failed = false) : +Failed(Failed) {} + constexpr Board addQueen(int Row, int Col) const { +return Board(State | ((uint64_t)Row << (Col * 4))); // ref-note {{read of uninitialized object}} + } + constexpr int getQueenRow(int Col) const { +return (State >> (Col * 4)) & 0xf; + } + constexpr bool ok(int Row, int Col) const { +return okRecurse(Row, Col, 0); + } + constexpr bool okRecurse(int Row, int Col, int CheckCol) const { +return Col == CheckCol ? true : + getQueenRow(CheckCol) == Row ? false : + getQueenRow(CheckCol) == Row + (Col - CheckCol) ? false : + getQueenRow(CheckCol) == Row + (CheckCol - Col) ? false : + okRecurse(Row, Col, CheckCol + 1); + } + constexpr bool at(int Row, int Col) const { +return getQueenRow(Col) == Row; + } + constexpr bool check(const char *, int=0, int=0) const; +}; + +constexpr Board buildBoardRecurse(int N, int Col, const Board &B); +constexpr Board buildBoardScan(int N, int Col, int Row, const Board &B); +constexpr Board tryBoard(const Board &Try, + int N, int Col, int Row, const Board &B) { + return Try.Failed ? buildBoardScan(N, Col, Row, B) : Try; +} +constexpr Board buildBoardScan(int N, int Col, int Row, const Board &B) { + return Row == N ? Board(0, true) : + B.ok(Row, Col) ? + tryBoard(buildBoardRecurse(N, Col + 1, B.addQueen(Row, Col)), // ref-note {{in call to '&Board()->addQueen(0, 0)}} + N, Col, Row+1, B) : + buildBoardScan(N, Col, Row + 1, B); +} +constexpr Board buildBoardRecurse(int N, int Col, const Board &B) { + return Col == N ? B : buildBoardScan(N, Col, 0, B); // ref-note {{in call to 'buildBoardScan(8, 0, 0, Board())'}} +} +constexpr Board buildBoard(int N) { + return buildBoardRecurse(N, 0, Board()); // ref-note {{in call to 'buildBoardRecurse(8, 0, Board())'}} +} + +constexpr Board q8 = buildBoard(8); // ref-error {{must be initialized by a constant expression}} \ +// ref-note {{in call to 'buildBoard(8)'}} \ +// expected-error {{must be initialized by a constant expression}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] e9b150c - [clang][Interp][NFC] Add missing static_assert message
Author: Timm Bäder Date: 2023-03-31T08:22:34+02:00 New Revision: e9b150c2d9bb856f371d201d9968b504e12d98a3 URL: https://github.com/llvm/llvm-project/commit/e9b150c2d9bb856f371d201d9968b504e12d98a3 DIFF: https://github.com/llvm/llvm-project/commit/e9b150c2d9bb856f371d201d9968b504e12d98a3.diff LOG: [clang][Interp][NFC] Add missing static_assert message This broke builders, e.g. https://lab.llvm.org/buildbot#builders/139/builds/38298 Added: Modified: clang/test/AST/Interp/functions.cpp Removed: diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index 1abdb2db97ff..2b44f42486d3 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -184,4 +184,4 @@ struct BodylessMemberFunction { constexpr int nyd(int m); constexpr int doit() { return nyd(10); } constexpr int nyd(int m) { return m; } -static_assert(doit() == 10); +static_assert(doit() == 10, ""); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] fce093c - [clang][Interp] Fix parameter map when re-visiting function
Author: Timm Bäder Date: 2023-03-31T08:06:06+02:00 New Revision: fce093ccb1c56b57bc26c47b47e2a0388953a27f URL: https://github.com/llvm/llvm-project/commit/fce093ccb1c56b57bc26c47b47e2a0388953a27f DIFF: https://github.com/llvm/llvm-project/commit/fce093ccb1c56b57bc26c47b47e2a0388953a27f.diff LOG: [clang][Interp] Fix parameter map when re-visiting function 'Params' is a member of the ByteCodeEmitter. We only added the parameters the first time we saw the function, so subsequent visits didn't work if they had (and used) parameters. Just do the work everytime we see a function. Differential Revision: https://reviews.llvm.org/D141681 Added: Modified: clang/lib/AST/Interp/ByteCodeEmitter.cpp clang/test/AST/Interp/functions.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp b/clang/lib/AST/Interp/ByteCodeEmitter.cpp index 7453b60118ea..34ad9bf2b326 100644 --- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp +++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp @@ -22,51 +22,50 @@ using Error = llvm::Error; Expected ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) { - // Create a handle over the emitted code. - Function *Func = P.getFunction(FuncDecl); - if (!Func) { -// Set up argument indices. -unsigned ParamOffset = 0; -SmallVector ParamTypes; -llvm::DenseMap ParamDescriptors; - -// If the return is not a primitive, a pointer to the storage where the -// value is initialized in is passed as the first argument. See 'RVO' -// elsewhere in the code. -QualType Ty = FuncDecl->getReturnType(); -bool HasRVO = false; -if (!Ty->isVoidType() && !Ctx.classify(Ty)) { - HasRVO = true; - ParamTypes.push_back(PT_Ptr); - ParamOffset += align(primSize(PT_Ptr)); -} + // Set up argument indices. + unsigned ParamOffset = 0; + SmallVector ParamTypes; + llvm::DenseMap ParamDescriptors; + + // If the return is not a primitive, a pointer to the storage where the + // value is initialized in is passed as the first argument. See 'RVO' + // elsewhere in the code. + QualType Ty = FuncDecl->getReturnType(); + bool HasRVO = false; + if (!Ty->isVoidType() && !Ctx.classify(Ty)) { +HasRVO = true; +ParamTypes.push_back(PT_Ptr); +ParamOffset += align(primSize(PT_Ptr)); + } -// If the function decl is a member decl, the next parameter is -// the 'this' pointer. This parameter is pop()ed from the -// InterpStack when calling the function. -bool HasThisPointer = false; -if (const auto *MD = dyn_cast(FuncDecl); -MD && MD->isInstance()) { - HasThisPointer = true; - ParamTypes.push_back(PT_Ptr); - ParamOffset += align(primSize(PT_Ptr)); -} + // If the function decl is a member decl, the next parameter is + // the 'this' pointer. This parameter is pop()ed from the + // InterpStack when calling the function. + bool HasThisPointer = false; + if (const auto *MD = dyn_cast(FuncDecl); + MD && MD->isInstance()) { +HasThisPointer = true; +ParamTypes.push_back(PT_Ptr); +ParamOffset += align(primSize(PT_Ptr)); + } -// Assign descriptors to all parameters. -// Composite objects are lowered to pointers. -for (const ParmVarDecl *PD : FuncDecl->parameters()) { - PrimType Ty = Ctx.classify(PD->getType()).value_or(PT_Ptr); - Descriptor *Desc = P.createDescriptor(PD, Ty); - ParamDescriptors.insert({ParamOffset, {Ty, Desc}}); - Params.insert({PD, ParamOffset}); - ParamOffset += align(primSize(Ty)); - ParamTypes.push_back(Ty); -} + // Assign descriptors to all parameters. + // Composite objects are lowered to pointers. + for (const ParmVarDecl *PD : FuncDecl->parameters()) { +PrimType Ty = Ctx.classify(PD->getType()).value_or(PT_Ptr); +Descriptor *Desc = P.createDescriptor(PD, Ty); +ParamDescriptors.insert({ParamOffset, {Ty, Desc}}); +Params.insert({PD, ParamOffset}); +ParamOffset += align(primSize(Ty)); +ParamTypes.push_back(Ty); + } + // 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), HasThisPointer, HasRVO); - } assert(Func); // For not-yet-defined functions, we only create a Function instance and diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index 5113593d8d11..1abdb2db97ff 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -180,3 +180,8 @@ struct BodylessMemberFunction { return 1; } }; + +constexpr int nyd(int m); +constexpr int doit() { return nyd(10); } +constexpr int nyd(int m) { return m; } +static_assert(doit() == 10); ___ cfe-commits mailing list cfe-co
[clang] 30f96a8 - [clang][Interp] Properly identify not-yet-defined functions
Author: Timm Bäder Date: 2023-03-31T07:27:04+02:00 New Revision: 30f96a8fb4511bed31a75863d4abec51c3d967a8 URL: https://github.com/llvm/llvm-project/commit/30f96a8fb4511bed31a75863d4abec51c3d967a8 DIFF: https://github.com/llvm/llvm-project/commit/30f96a8fb4511bed31a75863d4abec51c3d967a8.diff LOG: [clang][Interp] Properly identify not-yet-defined functions Since we now handle functions without a body as well, we can't just use getHasBody() anymore. Funtions that haven't been defined yet are those that don't have a body *and* aren't valid. Also, just pass the information about whether the Function has a body or not along from the FunctionDecl. Differential Revision: https://reviews.llvm.org/D141591 Added: Modified: clang/lib/AST/Interp/ByteCodeEmitter.cpp clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/Function.h clang/test/AST/Interp/functions.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp b/clang/lib/AST/Interp/ByteCodeEmitter.cpp index f56e0d1ba32b..7453b60118ea 100644 --- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp +++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp @@ -92,7 +92,7 @@ ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) { // Set the function's code. Func->setCode(NextLocalOffset, std::move(Code), std::move(SrcMap), - std::move(Scopes)); + std::move(Scopes), FuncDecl->hasBody()); Func->setIsFullyCompiled(true); return Func; } diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index c6cf7f7c99a5..1e61bc992448 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1465,7 +1465,7 @@ const Function *ByteCodeExprGen::getFunction(const FunctionDecl *FD) { assert(FD); const Function *Func = P.getFunction(FD); bool IsBeingCompiled = Func && !Func->isFullyCompiled(); - bool WasNotDefined = Func && !Func->hasBody(); + bool WasNotDefined = Func && !Func->isConstexpr() && !Func->hasBody(); if (IsBeingCompiled) return Func; diff --git a/clang/lib/AST/Interp/Function.h b/clang/lib/AST/Interp/Function.h index 422211708a77..005cda7379c2 100644 --- a/clang/lib/AST/Interp/Function.h +++ b/clang/lib/AST/Interp/Function.h @@ -157,14 +157,15 @@ class Function final { bool HasThisPointer, bool HasRVO); /// Sets the code of a function. - void setCode(unsigned NewFrameSize, std::vector &&NewCode, SourceMap &&NewSrcMap, - llvm::SmallVector &&NewScopes) { + void setCode(unsigned NewFrameSize, std::vector &&NewCode, + SourceMap &&NewSrcMap, llvm::SmallVector &&NewScopes, + bool NewHasBody) { FrameSize = NewFrameSize; Code = std::move(NewCode); SrcMap = std::move(NewSrcMap); Scopes = std::move(NewScopes); IsValid = true; -HasBody = true; +HasBody = NewHasBody; } void setIsFullyCompiled(bool FC) { IsFullyCompiled = FC; } diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index 9c0d51686581..5113593d8d11 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -162,3 +162,21 @@ namespace FunctionReturnType { } } + +struct F { + constexpr bool ok() const { +return okRecurse(); + } + constexpr bool okRecurse() const { +return true; + } +}; + +struct BodylessMemberFunction { + constexpr int first() const { +return second(); + } + constexpr int second() const { +return 1; + } +}; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3930e33 - [clang][Interp] Add missing static_assert messages
Author: Timm Bäder Date: 2023-03-30T15:43:43+02:00 New Revision: 3930e3331e7173bbacb7181015d8f7ca93f4aaef URL: https://github.com/llvm/llvm-project/commit/3930e3331e7173bbacb7181015d8f7ca93f4aaef DIFF: https://github.com/llvm/llvm-project/commit/3930e3331e7173bbacb7181015d8f7ca93f4aaef.diff LOG: [clang][Interp] Add missing static_assert messages This broke builders, e.g. https://lab.llvm.org/buildbot/#builders/139/builds/38250 Added: Modified: clang/test/AST/Interp/functions.cpp Removed: diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index 48862d399722..9c0d51686581 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -150,7 +150,7 @@ namespace FunctionReturnType { return m; } - static_assert(foo() == 10); + static_assert(foo() == 10, ""); struct S { int i; @@ -158,7 +158,7 @@ namespace FunctionReturnType { }; constexpr S s{ 12 }; - static_assert(s.fp == nullptr); // zero-initialized function pointer. + static_assert(s.fp == nullptr, ""); // zero-initialized function pointer. } } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3ad1673 - [clang][Interp] Implement function pointers
Author: Timm Bäder Date: 2023-03-30T15:37:49+02:00 New Revision: 3ad167329aafde02e70b0327c0488602111a81ee URL: https://github.com/llvm/llvm-project/commit/3ad167329aafde02e70b0327c0488602111a81ee DIFF: https://github.com/llvm/llvm-project/commit/3ad167329aafde02e70b0327c0488602111a81ee.diff LOG: [clang][Interp] Implement function pointers Differential Revision: https://reviews.llvm.org/D141472 Added: clang/lib/AST/Interp/FunctionPointer.h Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/Context.cpp clang/lib/AST/Interp/Descriptor.cpp clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/InterpStack.h clang/lib/AST/Interp/Opcodes.td clang/lib/AST/Interp/PrimType.cpp clang/lib/AST/Interp/PrimType.h clang/test/AST/Interp/functions.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index fff2425bedf42..c6cf7f7c99a59 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -131,6 +131,11 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { return this->emitCastFloatingIntegral(*ToT, CE); } + case CK_NullToPointer: +if (DiscardResult) + return true; +return this->emitNull(classifyPrim(CE->getType()), CE); + case CK_ArrayToPointerDecay: case CK_AtomicToNonAtomic: case CK_ConstructorConversion: @@ -138,7 +143,6 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { case CK_NonAtomicToAtomic: case CK_NoOp: case CK_UserDefinedConversion: - case CK_NullToPointer: return this->visit(SubExpr); case CK_IntegralToBoolean: @@ -400,10 +404,7 @@ bool ByteCodeExprGen::VisitImplicitValueInitExpr(const ImplicitValueIni if (!T) return false; - if (E->getType()->isPointerType()) -return this->emitNullPtr(E); - - return this->emitZero(*T, E); + return this->visitZeroInitializer(*T, E); } template @@ -950,6 +951,8 @@ bool ByteCodeExprGen::visitZeroInitializer(PrimType T, const Expr *E) { return this->emitZeroUint64(E); case PT_Ptr: return this->emitNullPtr(E); + case PT_FnPtr: +return this->emitNullFnPtr(E); case PT_Float: assert(false); } @@ -1116,6 +1119,7 @@ bool ByteCodeExprGen::emitConst(T Value, const Expr *E) { case PT_Bool: return this->emitConstBool(Value, E); case PT_Ptr: + case PT_FnPtr: case PT_Float: llvm_unreachable("Invalid integral type"); break; @@ -1606,8 +1610,27 @@ bool ByteCodeExprGen::VisitCallExpr(const CallExpr *E) { if (E->getBuiltinCallee()) return VisitBuiltinCallExpr(E); - const Decl *Callee = E->getCalleeDecl(); - if (const auto *FuncDecl = dyn_cast_if_present(Callee)) { + QualType ReturnType = E->getCallReturnType(Ctx.getASTContext()); + std::optional T = classify(ReturnType); + bool HasRVO = !ReturnType->isVoidType() && !T; + + if (HasRVO && DiscardResult) { +// If we need to discard the return value but the function returns its +// value via an RVO pointer, we need to create one such pointer just +// for this call. +if (std::optional LocalIndex = allocateLocal(E)) { + if (!this->emitGetPtrLocal(*LocalIndex, E)) +return false; +} + } + + // Put arguments on the stack. + for (const auto *Arg : E->arguments()) { +if (!this->visit(Arg)) + return false; + } + + if (const FunctionDecl *FuncDecl = E->getDirectCallee()) { const Function *Func = getFunction(FuncDecl); if (!Func) return false; @@ -1619,24 +1642,7 @@ bool ByteCodeExprGen::VisitCallExpr(const CallExpr *E) { if (Func->isFullyCompiled() && !Func->isConstexpr()) return false; -QualType ReturnType = E->getCallReturnType(Ctx.getASTContext()); -std::optional T = classify(ReturnType); - -if (Func->hasRVO() && DiscardResult) { - // If we need to discard the return value but the function returns its - // value via an RVO pointer, we need to create one such pointer just - // for this call. - if (std::optional LocalIndex = allocateLocal(E)) { -if (!this->emitGetPtrLocal(*LocalIndex, E)) - return false; - } -} - -// Put arguments on the stack. -for (const auto *Arg : E->arguments()) { - if (!this->visit(Arg)) -return false; -} +assert(HasRVO == Func->hasRVO()); // In any case call the function. The return value will end up on the stack // and if the function has RVO, we already have the pointer on the stack to @@ -1644,15 +1650,22 @@ bool ByteCodeExprGen::VisitCallExpr(const CallExpr *E) { if (!this->emitCall(Func, E)) return false; -if (DiscardResult && !ReturnType->isVoidType() && T) - return this->emitPop(*T, E); - -return true; } else { -assert(false && "We don't support non-FunctionDecl callees right now."); +// I
[clang] 243b355 - [clang][Interp] Support destructors
Author: Timm Bäder Date: 2023-03-30T13:17:04+02:00 New Revision: 243b355ee0f063cff4988f061215839020c2175b URL: https://github.com/llvm/llvm-project/commit/243b355ee0f063cff4988f061215839020c2175b DIFF: https://github.com/llvm/llvm-project/commit/243b355ee0f063cff4988f061215839020c2175b.diff LOG: [clang][Interp] Support destructors Emit destructors for non-primitive (array) variables on scope ends. Differential Revision: https://reviews.llvm.org/D145545 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/ByteCodeExprGen.h clang/lib/AST/Interp/ByteCodeStmtGen.cpp clang/lib/AST/Interp/ByteCodeStmtGen.h clang/test/AST/Interp/cxx20.cpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 0056da191765b..fff2425bedf42 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -26,10 +26,10 @@ namespace clang { namespace interp { /// Scope used to handle temporaries in toplevel variable declarations. -template class DeclScope final : public LocalScope { +template class DeclScope final : public VariableScope { public: DeclScope(ByteCodeExprGen *Ctx, const ValueDecl *VD) - : LocalScope(Ctx), Scope(Ctx->P, VD) {} + : VariableScope(Ctx), Scope(Ctx->P, VD) {} void addExtended(const Scope::Local &Local) override { return this->addLocal(Local); @@ -1857,6 +1857,80 @@ void ByteCodeExprGen::emitCleanup() { C->emitDestruction(); } +/// When calling this, we have a pointer of the local-to-destroy +/// on the stack. +/// Emit destruction of record types (or arrays of record types). +/// FIXME: Handle virtual destructors. +template +bool ByteCodeExprGen::emitRecordDestruction(const Descriptor *Desc) { + assert(Desc); + assert(!Desc->isPrimitive()); + assert(!Desc->isPrimitiveArray()); + + // Arrays. + if (Desc->isArray()) { +const Descriptor *ElemDesc = Desc->ElemDesc; +const Record *ElemRecord = ElemDesc->ElemRecord; +assert(ElemRecord); // This is not a primitive array. + +if (const CXXDestructorDecl *Dtor = ElemRecord->getDestructor(); +Dtor && !Dtor->isTrivial()) { + for (ssize_t I = Desc->getNumElems() - 1; I >= 0; --I) { +if (!this->emitConstUint64(I, SourceInfo{})) + return false; +if (!this->emitArrayElemPtrUint64(SourceInfo{})) + return false; +if (!this->emitRecordDestruction(Desc->ElemDesc)) + return false; + } +} +return this->emitPopPtr(SourceInfo{}); + } + + const Record *R = Desc->ElemRecord; + assert(R); + // First, destroy all fields. + for (const Record::Field &Field : llvm::reverse(R->fields())) { +const Descriptor *D = Field.Desc; +if (!D->isPrimitive() && !D->isPrimitiveArray()) { + if (!this->emitDupPtr(SourceInfo{})) +return false; + if (!this->emitGetPtrField(Field.Offset, SourceInfo{})) +return false; + if (!this->emitRecordDestruction(D)) +return false; +} + } + + // FIXME: Unions need to be handled diff erently here. We don't want to + // call the destructor of its members. + + // Now emit the destructor and recurse into base classes. + if (const CXXDestructorDecl *Dtor = R->getDestructor(); + Dtor && !Dtor->isTrivial()) { +const Function *DtorFunc = getFunction(Dtor); +if (DtorFunc && DtorFunc->isConstexpr()) { + assert(DtorFunc->hasThisPointer()); + assert(DtorFunc->getNumParams() == 1); + if (!this->emitDupPtr(SourceInfo{})) +return false; + if (!this->emitCall(DtorFunc, SourceInfo{})) +return false; +} + } + + for (const Record::Base &Base : llvm::reverse(R->bases())) { +if (!this->emitGetPtrBase(Base.Offset, SourceInfo{})) + return false; +if (!this->emitRecordDestruction(Base.Desc)) + return false; + } + // FIXME: Virtual bases. + + // Remove the instance pointer. + return this->emitPopPtr(SourceInfo{}); +} + namespace clang { namespace interp { diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index 231f39ff8bd6d..03d2eb87b5e1c 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -29,6 +29,7 @@ class QualType; namespace interp { template class LocalScope; +template class DestructorScope; template class RecordScope; template class VariableScope; template class DeclScope; @@ -189,6 +190,7 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, private: friend class VariableScope; friend class LocalScope; + friend class DestructorScope; friend class RecordScope; friend class DeclScope; friend class OptionScope; @@ -256,6 +258,8 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, return FPO.getRoundingMode(); } + bool emitR
[clang] 814177e - Revert "[clang][Interp][NFC] Add tests for __fp16"
Author: Timm Bäder Date: 2023-03-23T10:33:51+01:00 New Revision: 814177e434d8daf70a3d67345c166d40457f68f1 URL: https://github.com/llvm/llvm-project/commit/814177e434d8daf70a3d67345c166d40457f68f1 DIFF: https://github.com/llvm/llvm-project/commit/814177e434d8daf70a3d67345c166d40457f68f1.diff LOG: Revert "[clang][Interp][NFC] Add tests for __fp16" This reverts commit 0691bcb18024a28e82e8dd9a08ab0820b40c9a37. Looks like this breaks builders, e.g. https://lab.llvm.org/buildbot#builders/231/builds/9790 Added: Modified: clang/test/AST/Interp/floats.cpp Removed: diff --git a/clang/test/AST/Interp/floats.cpp b/clang/test/AST/Interp/floats.cpp index b3c4dd4c19a84..7b9328c4d1182 100644 --- a/clang/test/AST/Interp/floats.cpp +++ b/clang/test/AST/Interp/floats.cpp @@ -78,94 +78,3 @@ namespace compound { } static_assert(f2() == __FLT_MAX__, ""); } - - -namespace FP16 { - constexpr int i = 2; - constexpr __fp16 f = 1.0f; - static_assert(f == 1.0f, ""); - - constexpr __fp16 f2 = 1u * f; - static_assert(f2 == 1.0f, ""); - - constexpr __fp16 f3 = 1.5; - constexpr int i3 = f3; - static_assert(i3 == 1, ""); - - constexpr bool b3 = f3; - static_assert(b3, ""); - - - static_assert(1.0f16 + 3u == 4, ""); - static_assert(4.0f16 / 1.0f16 == 4, ""); - static_assert(10.0f16 * false == 0, ""); - - constexpr __fp16 __fp16s[] = {1.0f16, 2.0f16, 3.0f16, 4.0f16}; - - constexpr __fp16 m = 5.0f16 / 0.0f16; // ref-error {{must be initialized by a constant expression}} \ - // ref-note {{division by zero}} \ - // expected-error {{must be initialized by a constant expression}} \ - // expected-note {{division by zero}} - - static_assert(~2.0f16 == 3, ""); // ref-error {{invalid argument type '_Float16' to unary expression}} \ - // expected-error {{invalid argument type '_Float16' to unary expression}} - - /// Initialized by a double. - constexpr __fp16 df = 0.0; - /// The other way around. - constexpr double fd = 0.0f16; - - static_assert(0.0f == -0.0f, ""); - - const int k = 3 * (1.0f16 / 3.0f16); - static_assert(k == 1, ""); - - constexpr bool b = 1.0f16; - static_assert(b, ""); - - constexpr double db = true; - static_assert(db == 1.0f16, ""); - - constexpr __fp16 fa[] = {1.0f, 2.0, 1, false}; - constexpr double da[] = {1.0f, 2.0, 1, false}; - - constexpr __fp16 fm = __FLT16_MAX__; - constexpr int someInt = fm; - - constexpr float SomeFloat = __FLT_MAX__; - constexpr __fp16 halfFloat = SomeFloat; - - constexpr float fp16ptr() { -__fp16 f1 = 1.0f16; -__fp16 *f2 = &f1; - -*f2 = 3.0; -return f1; - } - static_assert(fp16ptr() == 3.0, ""); - - namespace compound { -constexpr float f1() { - __fp16 f = 0; - f += 3.0; - f -= 3.0f; - - f += 1; - f /= 1; - f /= 1.0; - f *= f; - - f *= 2.0; - return f; -} -static_assert(f1() == 2, ""); - -constexpr float f2() { - __fp16 f = __FLT16_MAX__; - f += 1.0; - return f; -} -static_assert(f2() == __FLT16_MAX__, ""); - } - -} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 0691bcb - [clang][Interp][NFC] Add tests for __fp16
Author: Timm Bäder Date: 2023-03-23T10:08:34+01:00 New Revision: 0691bcb18024a28e82e8dd9a08ab0820b40c9a37 URL: https://github.com/llvm/llvm-project/commit/0691bcb18024a28e82e8dd9a08ab0820b40c9a37 DIFF: https://github.com/llvm/llvm-project/commit/0691bcb18024a28e82e8dd9a08ab0820b40c9a37.diff LOG: [clang][Interp][NFC] Add tests for __fp16 Differential Revision: https://reviews.llvm.org/D146436 Added: Modified: clang/test/AST/Interp/floats.cpp Removed: diff --git a/clang/test/AST/Interp/floats.cpp b/clang/test/AST/Interp/floats.cpp index 7b9328c4d1182..b3c4dd4c19a84 100644 --- a/clang/test/AST/Interp/floats.cpp +++ b/clang/test/AST/Interp/floats.cpp @@ -78,3 +78,94 @@ namespace compound { } static_assert(f2() == __FLT_MAX__, ""); } + + +namespace FP16 { + constexpr int i = 2; + constexpr __fp16 f = 1.0f; + static_assert(f == 1.0f, ""); + + constexpr __fp16 f2 = 1u * f; + static_assert(f2 == 1.0f, ""); + + constexpr __fp16 f3 = 1.5; + constexpr int i3 = f3; + static_assert(i3 == 1, ""); + + constexpr bool b3 = f3; + static_assert(b3, ""); + + + static_assert(1.0f16 + 3u == 4, ""); + static_assert(4.0f16 / 1.0f16 == 4, ""); + static_assert(10.0f16 * false == 0, ""); + + constexpr __fp16 __fp16s[] = {1.0f16, 2.0f16, 3.0f16, 4.0f16}; + + constexpr __fp16 m = 5.0f16 / 0.0f16; // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{division by zero}} \ + // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{division by zero}} + + static_assert(~2.0f16 == 3, ""); // ref-error {{invalid argument type '_Float16' to unary expression}} \ + // expected-error {{invalid argument type '_Float16' to unary expression}} + + /// Initialized by a double. + constexpr __fp16 df = 0.0; + /// The other way around. + constexpr double fd = 0.0f16; + + static_assert(0.0f == -0.0f, ""); + + const int k = 3 * (1.0f16 / 3.0f16); + static_assert(k == 1, ""); + + constexpr bool b = 1.0f16; + static_assert(b, ""); + + constexpr double db = true; + static_assert(db == 1.0f16, ""); + + constexpr __fp16 fa[] = {1.0f, 2.0, 1, false}; + constexpr double da[] = {1.0f, 2.0, 1, false}; + + constexpr __fp16 fm = __FLT16_MAX__; + constexpr int someInt = fm; + + constexpr float SomeFloat = __FLT_MAX__; + constexpr __fp16 halfFloat = SomeFloat; + + constexpr float fp16ptr() { +__fp16 f1 = 1.0f16; +__fp16 *f2 = &f1; + +*f2 = 3.0; +return f1; + } + static_assert(fp16ptr() == 3.0, ""); + + namespace compound { +constexpr float f1() { + __fp16 f = 0; + f += 3.0; + f -= 3.0f; + + f += 1; + f /= 1; + f /= 1.0; + f *= f; + + f *= 2.0; + return f; +} +static_assert(f1() == 2, ""); + +constexpr float f2() { + __fp16 f = __FLT16_MAX__; + f += 1.0; + return f; +} +static_assert(f2() == __FLT16_MAX__, ""); + } + +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits