[clang] [Debug Info] Fix debug info ptr to ptr test (PR #95637)
https://github.com/huangjd created https://github.com/llvm/llvm-project/pull/95637 Fix test case in #95298 because another recent submitted patch removed llvm.dbg intrinsics, updated test case accordingly >From 5fafbda01e5bf10b898f71b38305485e57e5b13f Mon Sep 17 00:00:00 2001 From: William Huang Date: Sat, 15 Jun 2024 03:08:12 -0400 Subject: [PATCH] [Debug Info] Fix debug info ptr to ptr test Fix test case in #95298 because another recent submitted patch removed llvm.dbg intrinsics, updated test case accordingly --- .../test/CodeGenCXX/debug-info-ptr-to-ptr.cpp | 28 +-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp b/clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp index 51ce0f107b5e3..6975eae1fb122 100644 --- a/clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp +++ b/clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp @@ -25,7 +25,7 @@ class C { // CHECK-LABEL: define dso_local noundef i32 @{{.*}}func1{{.*}}( // CHECK: [[A_ADDR:%.*]] = getelementptr inbounds %class.B, ptr {{%.*}}, i32 0, i32 0, !dbg [[DBG1:![0-9]+]] // CHECK-NEXT:[[A:%.*]] = load ptr, ptr [[A_ADDR]], align {{.*}}, !dbg [[DBG1]] -// CHECK-NEXT:call void @llvm.dbg.value(metadata ptr [[A]], metadata [[META1:![0-9]+]], metadata !DIExpression()), !dbg [[DBG1]] +// CHECK-NEXT: #dbg_value(ptr [[A]], [[META1:![0-9]+]], !DIExpression(), [[DBG1]]) // CHECK-NEXT:{{%.*}} = getelementptr inbounds %class.A, ptr [[A]], i32 0, i32 0, int func1(B *b) { return b->a->i; @@ -33,9 +33,9 @@ int func1(B *b) { // Should generate a pseudo variable when pointer is type-casted. // CHECK-LABEL: define dso_local noundef ptr @{{.*}}func2{{.*}}( -// CHECK: call void @llvm.dbg.declare(metadata ptr [[B_ADDR:%.*]], metadata [[META2:![0-9]+]], metadata !DIExpression()) +// CHECK: #dbg_declare(ptr [[B_ADDR:%.*]], [[META2:![0-9]+]], !DIExpression(), // CHECK-NEXT:[[B:%.*]] = load ptr, ptr [[B_ADDR]], -// CHECK-NEXT:call void @llvm.dbg.value(metadata ptr [[B]], metadata [[META3:![0-9]+]], metadata !DIExpression()) +// CHECK-NEXT: #dbg_value(ptr [[B]], [[META3:![0-9]+]], !DIExpression(), // CHECK-NEXT:{{%.*}} = getelementptr inbounds %class.B, ptr [[B]], i32 0, A* func2(void *b) { return ((B*)b)->a; @@ -43,9 +43,9 @@ A* func2(void *b) { // Should not generate pseudo variable in this case. // CHECK-LABEL: define dso_local noundef i32 @{{.*}}func3{{.*}}( -// CHECK:call void @llvm.dbg.declare(metadata ptr [[B_ADDR:%.*]], metadata [[META4:![0-9]+]], metadata !DIExpression()) -// CHECK:call void @llvm.dbg.declare(metadata ptr [[LOCAL1:%.*]], metadata [[META5:![0-9]+]], metadata !DIExpression()) -// CHECK-NOT: call void @llvm.dbg.value(metadata ptr +// CHECK: #dbg_declare(ptr [[B_ADDR:%.*]], [[META4:![0-9]+]], !DIExpression(), +// CHECK: #dbg_declare(ptr [[LOCAL1:%.*]], [[META5:![0-9]+]], !DIExpression(), +// CHECK-NOT: #dbg_value(ptr int func3(B *b) { A *local1 = b->a; return local1->i; @@ -54,10 +54,10 @@ int func3(B *b) { // CHECK-LABEL: define dso_local noundef signext i8 @{{.*}}func4{{.*}}( // CHECK: [[A_ADDR:%.*]] = getelementptr inbounds %class.C, ptr {{%.*}}, i32 0, i32 1 // CHECK-NEXT:[[A:%.*]] = load ptr, ptr [[A_ADDR]], -// CHECK-NEXT:call void @llvm.dbg.value(metadata ptr [[A]], metadata [[META6:![0-9]+]], metadata !DIExpression()) +// CHECK-NEXT: #dbg_value(ptr [[A]], [[META6:![0-9]+]], !DIExpression(), // CHECK-NEXT:{{%.*}} = getelementptr inbounds %class.A, ptr [[A]], i32 0, i32 0, // CHECK: [[CALL:%.*]] = call noundef ptr @{{.*}}foo{{.*}}( -// CHECK-NEXT:call void @llvm.dbg.value(metadata ptr [[CALL]], metadata [[META6]], metadata !DIExpression()) +// CHECK-NEXT: #dbg_value(ptr [[CALL]], [[META6]], !DIExpression(), // CHECK-NEXT:[[I1:%.*]] = getelementptr inbounds %class.A, ptr [[CALL]], i32 0, i32 1 char func4(C *c) { extern A* foo(int x); @@ -65,25 +65,25 @@ char func4(C *c) { } // CHECK-LABEL: define dso_local noundef signext i8 @{{.*}}func5{{.*}}( -// CHECK: call void @llvm.dbg.declare(metadata ptr {{%.*}}, metadata [[META7:![0-9]+]], metadata !DIExpression()) -// CHECK: call void @llvm.dbg.declare(metadata ptr {{%.*}}, metadata [[META8:![0-9]+]], metadata !DIExpression()) +// CHECK: #dbg_declare(ptr {{%.*}}, [[META7:![0-9]+]], !DIExpression(), +// CHECK: #dbg_declare(ptr {{%.*}}, [[META8:![0-9]+]], !DIExpression(), // CHECK: [[A_ADDR:%.*]] = getelementptr inbounds %class.A, ptr {{%.*}}, i64 {{%.*}}, -// CHECK-NEXT:call void @llvm.dbg.value(metadata ptr [[A_ADDR]], metadata [[META9:![0-9]+]], metadata !DIExpression()) +// CHECK-NEXT: #dbg_value(ptr [[A_ADDR]], [[META9:![0-9]+]], !DIExpression(), // CHECK-NEXT:{{%.*}} = getelementptr inbounds %class.A, ptr [[A_ADDR]], i32 0, i32 1, char func5(void *arr, int n) { return ((A*)arr)[n
[clang] [Debug Info] Fix debug info ptr to ptr test (PR #95637)
llvmbot wrote: @llvm/pr-subscribers-clang Author: William Junda Huang (huangjd) Changes Fix test case in #95298 because another recent submitted patch removed llvm.dbg intrinsics, updated test case accordingly --- Full diff: https://github.com/llvm/llvm-project/pull/95637.diff 1 Files Affected: - (modified) clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp (+14-14) ``diff diff --git a/clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp b/clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp index 51ce0f107b5e3..6975eae1fb122 100644 --- a/clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp +++ b/clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp @@ -25,7 +25,7 @@ class C { // CHECK-LABEL: define dso_local noundef i32 @{{.*}}func1{{.*}}( // CHECK: [[A_ADDR:%.*]] = getelementptr inbounds %class.B, ptr {{%.*}}, i32 0, i32 0, !dbg [[DBG1:![0-9]+]] // CHECK-NEXT:[[A:%.*]] = load ptr, ptr [[A_ADDR]], align {{.*}}, !dbg [[DBG1]] -// CHECK-NEXT:call void @llvm.dbg.value(metadata ptr [[A]], metadata [[META1:![0-9]+]], metadata !DIExpression()), !dbg [[DBG1]] +// CHECK-NEXT: #dbg_value(ptr [[A]], [[META1:![0-9]+]], !DIExpression(), [[DBG1]]) // CHECK-NEXT:{{%.*}} = getelementptr inbounds %class.A, ptr [[A]], i32 0, i32 0, int func1(B *b) { return b->a->i; @@ -33,9 +33,9 @@ int func1(B *b) { // Should generate a pseudo variable when pointer is type-casted. // CHECK-LABEL: define dso_local noundef ptr @{{.*}}func2{{.*}}( -// CHECK: call void @llvm.dbg.declare(metadata ptr [[B_ADDR:%.*]], metadata [[META2:![0-9]+]], metadata !DIExpression()) +// CHECK: #dbg_declare(ptr [[B_ADDR:%.*]], [[META2:![0-9]+]], !DIExpression(), // CHECK-NEXT:[[B:%.*]] = load ptr, ptr [[B_ADDR]], -// CHECK-NEXT:call void @llvm.dbg.value(metadata ptr [[B]], metadata [[META3:![0-9]+]], metadata !DIExpression()) +// CHECK-NEXT: #dbg_value(ptr [[B]], [[META3:![0-9]+]], !DIExpression(), // CHECK-NEXT:{{%.*}} = getelementptr inbounds %class.B, ptr [[B]], i32 0, A* func2(void *b) { return ((B*)b)->a; @@ -43,9 +43,9 @@ A* func2(void *b) { // Should not generate pseudo variable in this case. // CHECK-LABEL: define dso_local noundef i32 @{{.*}}func3{{.*}}( -// CHECK:call void @llvm.dbg.declare(metadata ptr [[B_ADDR:%.*]], metadata [[META4:![0-9]+]], metadata !DIExpression()) -// CHECK:call void @llvm.dbg.declare(metadata ptr [[LOCAL1:%.*]], metadata [[META5:![0-9]+]], metadata !DIExpression()) -// CHECK-NOT: call void @llvm.dbg.value(metadata ptr +// CHECK: #dbg_declare(ptr [[B_ADDR:%.*]], [[META4:![0-9]+]], !DIExpression(), +// CHECK: #dbg_declare(ptr [[LOCAL1:%.*]], [[META5:![0-9]+]], !DIExpression(), +// CHECK-NOT: #dbg_value(ptr int func3(B *b) { A *local1 = b->a; return local1->i; @@ -54,10 +54,10 @@ int func3(B *b) { // CHECK-LABEL: define dso_local noundef signext i8 @{{.*}}func4{{.*}}( // CHECK: [[A_ADDR:%.*]] = getelementptr inbounds %class.C, ptr {{%.*}}, i32 0, i32 1 // CHECK-NEXT:[[A:%.*]] = load ptr, ptr [[A_ADDR]], -// CHECK-NEXT:call void @llvm.dbg.value(metadata ptr [[A]], metadata [[META6:![0-9]+]], metadata !DIExpression()) +// CHECK-NEXT: #dbg_value(ptr [[A]], [[META6:![0-9]+]], !DIExpression(), // CHECK-NEXT:{{%.*}} = getelementptr inbounds %class.A, ptr [[A]], i32 0, i32 0, // CHECK: [[CALL:%.*]] = call noundef ptr @{{.*}}foo{{.*}}( -// CHECK-NEXT:call void @llvm.dbg.value(metadata ptr [[CALL]], metadata [[META6]], metadata !DIExpression()) +// CHECK-NEXT: #dbg_value(ptr [[CALL]], [[META6]], !DIExpression(), // CHECK-NEXT:[[I1:%.*]] = getelementptr inbounds %class.A, ptr [[CALL]], i32 0, i32 1 char func4(C *c) { extern A* foo(int x); @@ -65,25 +65,25 @@ char func4(C *c) { } // CHECK-LABEL: define dso_local noundef signext i8 @{{.*}}func5{{.*}}( -// CHECK: call void @llvm.dbg.declare(metadata ptr {{%.*}}, metadata [[META7:![0-9]+]], metadata !DIExpression()) -// CHECK: call void @llvm.dbg.declare(metadata ptr {{%.*}}, metadata [[META8:![0-9]+]], metadata !DIExpression()) +// CHECK: #dbg_declare(ptr {{%.*}}, [[META7:![0-9]+]], !DIExpression(), +// CHECK: #dbg_declare(ptr {{%.*}}, [[META8:![0-9]+]], !DIExpression(), // CHECK: [[A_ADDR:%.*]] = getelementptr inbounds %class.A, ptr {{%.*}}, i64 {{%.*}}, -// CHECK-NEXT:call void @llvm.dbg.value(metadata ptr [[A_ADDR]], metadata [[META9:![0-9]+]], metadata !DIExpression()) +// CHECK-NEXT: #dbg_value(ptr [[A_ADDR]], [[META9:![0-9]+]], !DIExpression(), // CHECK-NEXT:{{%.*}} = getelementptr inbounds %class.A, ptr [[A_ADDR]], i32 0, i32 1, char func5(void *arr, int n) { return ((A*)arr)[n].c; } // CHECK-LABEL: define dso_local noundef i32 @{{.*}}func6{{.*}}( -// CHECK: call void @llvm.dbg.declare(metadata ptr {{%.*}}, metadata [[META10:![0-9]+]], metadata !DIExpression()) -// CHECK: call void @llvm.dbg.value(metadata
[clang] (New) Add option to generate additional debug info for expression dereferencing pointer to pointers (PR #95298)
huangjd wrote: > @huangjd, I'm not sure the buildbot emails on failure are working, but the > test you added seems to be failing on many bots. Can you take a look and > revert if you need time to investigate? > > * https://lab.llvm.org/buildbot/#/builders/144/builds/163 > * https://lab.llvm.org/buildbot/#/builders/46/builds/93 > * https://lab.llvm.org/buildbot/#/builders/174/builds/92 > * https://lab.llvm.org/buildbot/#/builders/190/builds/108 > * https://lab.llvm.org/buildbot/#/builders/23/builds/56 Test updated https://github.com/llvm/llvm-project/pull/95637 https://github.com/llvm/llvm-project/pull/95298 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Comments] Support for parsing headers in Doxygen \par commands (PR #91100)
https://github.com/hdoc updated https://github.com/llvm/llvm-project/pull/91100 >From 926abee4c34bc23a92e0c71551348bf74e39ff56 Mon Sep 17 00:00:00 2001 From: hdoc Date: Sat, 4 May 2024 18:50:16 -0700 Subject: [PATCH 1/3] Support for parsing headers in Doxygen \par commands --- .../include/clang/AST/CommentCommandTraits.h | 4 + clang/include/clang/AST/CommentCommands.td| 3 +- clang/include/clang/AST/CommentParser.h | 4 +- clang/lib/AST/CommentParser.cpp | 77 ++ clang/test/Index/comment-misc-tags.m | 8 +- clang/unittests/AST/CommentParser.cpp | 137 ++ .../ClangCommentCommandInfoEmitter.cpp| 1 + 7 files changed, 227 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/AST/CommentCommandTraits.h b/clang/include/clang/AST/CommentCommandTraits.h index 0c3254d84eb00..78c484fff3aed 100644 --- a/clang/include/clang/AST/CommentCommandTraits.h +++ b/clang/include/clang/AST/CommentCommandTraits.h @@ -88,6 +88,10 @@ struct CommandInfo { LLVM_PREFERRED_TYPE(bool) unsigned IsHeaderfileCommand : 1; + /// True if this is a \\par command. + LLVM_PREFERRED_TYPE(bool) + unsigned IsParCommand : 1; + /// True if we don't want to warn about this command being passed an empty /// paragraph. Meaningful only for block commands. LLVM_PREFERRED_TYPE(bool) diff --git a/clang/include/clang/AST/CommentCommands.td b/clang/include/clang/AST/CommentCommands.td index 06b2fa9b5531c..a410cd4039bee 100644 --- a/clang/include/clang/AST/CommentCommands.td +++ b/clang/include/clang/AST/CommentCommands.td @@ -18,6 +18,7 @@ class Command { bit IsThrowsCommand = 0; bit IsDeprecatedCommand = 0; bit IsHeaderfileCommand = 0; + bit IsParCommand = 0; bit IsEmptyParagraphAllowed = 0; @@ -156,7 +157,7 @@ def Date : BlockCommand<"date">; def Invariant : BlockCommand<"invariant">; def Li : BlockCommand<"li">; def Note : BlockCommand<"note">; -def Par: BlockCommand<"par">; +def Par: BlockCommand<"par"> { let IsParCommand = 1; let NumArgs = 1; } def Post : BlockCommand<"post">; def Pre: BlockCommand<"pre">; def Remark : BlockCommand<"remark">; diff --git a/clang/include/clang/AST/CommentParser.h b/clang/include/clang/AST/CommentParser.h index a2d0e30835e2c..289f0b2c066b9 100644 --- a/clang/include/clang/AST/CommentParser.h +++ b/clang/include/clang/AST/CommentParser.h @@ -105,6 +105,9 @@ class Parser { ArrayRef parseThrowCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs); + ArrayRef + parseParCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs); + BlockCommandComment *parseBlockCommand(); InlineCommandComment *parseInlineCommand(); @@ -123,4 +126,3 @@ class Parser { } // end namespace clang #endif - diff --git a/clang/lib/AST/CommentParser.cpp b/clang/lib/AST/CommentParser.cpp index 5baf81a509fb6..bbe93ebc37d13 100644 --- a/clang/lib/AST/CommentParser.cpp +++ b/clang/lib/AST/CommentParser.cpp @@ -222,6 +222,63 @@ class TextTokenRetokenizer { return true; } + /// Check if this line starts with @par or \par + bool startsWithParCommand() { +unsigned Offset = 1; + +/// Skip all whitespace characters at the beginning. +/// This needs to backtrack because Pos has already advanced past the +/// actual \par or @par command by the time this function is called. +while (isWhitespace(*(Pos.BufferPtr - Offset))) + Offset++; + +/// Check if next four characters are \par or @par +llvm::StringRef LineStart(Pos.BufferPtr - 5, 4); +return LineStart.starts_with("\\par") || LineStart.starts_with("@par"); + } + + /// Extract a par command argument-header. + bool lexParHeading(Token &Tok) { +if (isEnd()) + return false; + +Position SavedPos = Pos; + +consumeWhitespace(); +SmallString<32> WordText; +const char *WordBegin = Pos.BufferPtr; +SourceLocation Loc = getSourceLocation(); + +if (!startsWithParCommand()) + return false; + +// Read until the end of this token, which is effectively the end of the +// line This gets us the content of the par header, if there is one. +while (!isEnd()) { + WordText.push_back(peek()); + if (Pos.BufferPtr + 1 == Pos.BufferEnd) { +consumeChar(); +break; + } else { +consumeChar(); + } +} + +const unsigned Length = WordText.size(); +if (Length == 0) { + Pos = SavedPos; + return false; +} + +char *TextPtr = Allocator.Allocate(Length + 1); + +memcpy(TextPtr, WordText.c_str(), Length + 1); +StringRef Text = StringRef(TextPtr, Length); + +formTokenWithChars(Tok, Loc, WordBegin, Length, Text); +return true; + } + /// Extract a word -- sequence of non-whitespace characters. bool lexWord(Token &Tok) { if (isEnd()) @@ -394,6 +451,23 @@ Parser::parseThrowCommandArgs(TextTokenRetokenizer &Retokenizer, ret
[clang] [Clang][Comments] Support for parsing headers in Doxygen \par commands (PR #91100)
hdoc wrote: Ping. This is rebased on latest main (which integrates the other comment parser changes we've made) and should be ready to go. https://github.com/llvm/llvm-project/pull/91100 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Comments] Support for parsing headers in Doxygen \par commands (PR #91100)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 8cc6a2469c95f0815487c442495a829c337913c4 362080b5ab4e0401b24e85a9c28ece3a9b0e0286 -- clang/include/clang/AST/CommentCommandTraits.h clang/include/clang/AST/CommentParser.h clang/lib/AST/CommentParser.cpp clang/unittests/AST/CommentParser.cpp clang/utils/TableGen/ClangCommentCommandInfoEmitter.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/lib/AST/CommentParser.cpp b/clang/lib/AST/CommentParser.cpp index 24aa1ab8fc..d5e5bb27ce 100644 --- a/clang/lib/AST/CommentParser.cpp +++ b/clang/lib/AST/CommentParser.cpp @@ -232,8 +232,8 @@ public: while (isWhitespace(*(Pos.BufferPtr - Offset))) Offset++; -// Once we've reached the whitespace, backtrack and check if the previous four -// characters are \par or @par. +// Once we've reached the whitespace, backtrack and check if the previous +// four characters are \par or @par. llvm::StringRef LineStart(Pos.BufferPtr - Offset - 3, 4); return LineStart.starts_with("\\par") || LineStart.starts_with("@par"); } diff --git a/clang/utils/TableGen/ClangCommentCommandInfoEmitter.cpp b/clang/utils/TableGen/ClangCommentCommandInfoEmitter.cpp index 07b26dc2f6..f90ebc4630 100644 --- a/clang/utils/TableGen/ClangCommentCommandInfoEmitter.cpp +++ b/clang/utils/TableGen/ClangCommentCommandInfoEmitter.cpp @@ -32,8 +32,7 @@ void clang::EmitClangCommentCommandInfo(RecordKeeper &Records, Record &Tag = *Tags[i]; OS << " { " << "\"" << Tag.getValueAsString("Name") << "\", " - << "\"" << Tag.getValueAsString("EndCommandName") << "\", " - << i << ", " + << "\"" << Tag.getValueAsString("EndCommandName") << "\", " << i << ", " << Tag.getValueAsInt("NumArgs") << ", " << Tag.getValueAsBit("IsInlineCommand") << ", " << Tag.getValueAsBit("IsBlockCommand") << ", " `` https://github.com/llvm/llvm-project/pull/91100 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Comments] Support for parsing headers in Doxygen \par commands (PR #91100)
https://github.com/hdoc updated https://github.com/llvm/llvm-project/pull/91100 >From 926abee4c34bc23a92e0c71551348bf74e39ff56 Mon Sep 17 00:00:00 2001 From: hdoc Date: Sat, 4 May 2024 18:50:16 -0700 Subject: [PATCH 1/4] Support for parsing headers in Doxygen \par commands --- .../include/clang/AST/CommentCommandTraits.h | 4 + clang/include/clang/AST/CommentCommands.td| 3 +- clang/include/clang/AST/CommentParser.h | 4 +- clang/lib/AST/CommentParser.cpp | 77 ++ clang/test/Index/comment-misc-tags.m | 8 +- clang/unittests/AST/CommentParser.cpp | 137 ++ .../ClangCommentCommandInfoEmitter.cpp| 1 + 7 files changed, 227 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/AST/CommentCommandTraits.h b/clang/include/clang/AST/CommentCommandTraits.h index 0c3254d84eb00..78c484fff3aed 100644 --- a/clang/include/clang/AST/CommentCommandTraits.h +++ b/clang/include/clang/AST/CommentCommandTraits.h @@ -88,6 +88,10 @@ struct CommandInfo { LLVM_PREFERRED_TYPE(bool) unsigned IsHeaderfileCommand : 1; + /// True if this is a \\par command. + LLVM_PREFERRED_TYPE(bool) + unsigned IsParCommand : 1; + /// True if we don't want to warn about this command being passed an empty /// paragraph. Meaningful only for block commands. LLVM_PREFERRED_TYPE(bool) diff --git a/clang/include/clang/AST/CommentCommands.td b/clang/include/clang/AST/CommentCommands.td index 06b2fa9b5531c..a410cd4039bee 100644 --- a/clang/include/clang/AST/CommentCommands.td +++ b/clang/include/clang/AST/CommentCommands.td @@ -18,6 +18,7 @@ class Command { bit IsThrowsCommand = 0; bit IsDeprecatedCommand = 0; bit IsHeaderfileCommand = 0; + bit IsParCommand = 0; bit IsEmptyParagraphAllowed = 0; @@ -156,7 +157,7 @@ def Date : BlockCommand<"date">; def Invariant : BlockCommand<"invariant">; def Li : BlockCommand<"li">; def Note : BlockCommand<"note">; -def Par: BlockCommand<"par">; +def Par: BlockCommand<"par"> { let IsParCommand = 1; let NumArgs = 1; } def Post : BlockCommand<"post">; def Pre: BlockCommand<"pre">; def Remark : BlockCommand<"remark">; diff --git a/clang/include/clang/AST/CommentParser.h b/clang/include/clang/AST/CommentParser.h index a2d0e30835e2c..289f0b2c066b9 100644 --- a/clang/include/clang/AST/CommentParser.h +++ b/clang/include/clang/AST/CommentParser.h @@ -105,6 +105,9 @@ class Parser { ArrayRef parseThrowCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs); + ArrayRef + parseParCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs); + BlockCommandComment *parseBlockCommand(); InlineCommandComment *parseInlineCommand(); @@ -123,4 +126,3 @@ class Parser { } // end namespace clang #endif - diff --git a/clang/lib/AST/CommentParser.cpp b/clang/lib/AST/CommentParser.cpp index 5baf81a509fb6..bbe93ebc37d13 100644 --- a/clang/lib/AST/CommentParser.cpp +++ b/clang/lib/AST/CommentParser.cpp @@ -222,6 +222,63 @@ class TextTokenRetokenizer { return true; } + /// Check if this line starts with @par or \par + bool startsWithParCommand() { +unsigned Offset = 1; + +/// Skip all whitespace characters at the beginning. +/// This needs to backtrack because Pos has already advanced past the +/// actual \par or @par command by the time this function is called. +while (isWhitespace(*(Pos.BufferPtr - Offset))) + Offset++; + +/// Check if next four characters are \par or @par +llvm::StringRef LineStart(Pos.BufferPtr - 5, 4); +return LineStart.starts_with("\\par") || LineStart.starts_with("@par"); + } + + /// Extract a par command argument-header. + bool lexParHeading(Token &Tok) { +if (isEnd()) + return false; + +Position SavedPos = Pos; + +consumeWhitespace(); +SmallString<32> WordText; +const char *WordBegin = Pos.BufferPtr; +SourceLocation Loc = getSourceLocation(); + +if (!startsWithParCommand()) + return false; + +// Read until the end of this token, which is effectively the end of the +// line This gets us the content of the par header, if there is one. +while (!isEnd()) { + WordText.push_back(peek()); + if (Pos.BufferPtr + 1 == Pos.BufferEnd) { +consumeChar(); +break; + } else { +consumeChar(); + } +} + +const unsigned Length = WordText.size(); +if (Length == 0) { + Pos = SavedPos; + return false; +} + +char *TextPtr = Allocator.Allocate(Length + 1); + +memcpy(TextPtr, WordText.c_str(), Length + 1); +StringRef Text = StringRef(TextPtr, Length); + +formTokenWithChars(Tok, Loc, WordBegin, Length, Text); +return true; + } + /// Extract a word -- sequence of non-whitespace characters. bool lexWord(Token &Tok) { if (isEnd()) @@ -394,6 +451,23 @@ Parser::parseThrowCommandArgs(TextTokenRetokenizer &Retokenizer, ret
[clang] [Clang][Comments] Support for parsing headers in Doxygen \par commands (PR #91100)
https://github.com/hdoc updated https://github.com/llvm/llvm-project/pull/91100 >From 926abee4c34bc23a92e0c71551348bf74e39ff56 Mon Sep 17 00:00:00 2001 From: hdoc Date: Sat, 4 May 2024 18:50:16 -0700 Subject: [PATCH 1/5] Support for parsing headers in Doxygen \par commands --- .../include/clang/AST/CommentCommandTraits.h | 4 + clang/include/clang/AST/CommentCommands.td| 3 +- clang/include/clang/AST/CommentParser.h | 4 +- clang/lib/AST/CommentParser.cpp | 77 ++ clang/test/Index/comment-misc-tags.m | 8 +- clang/unittests/AST/CommentParser.cpp | 137 ++ .../ClangCommentCommandInfoEmitter.cpp| 1 + 7 files changed, 227 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/AST/CommentCommandTraits.h b/clang/include/clang/AST/CommentCommandTraits.h index 0c3254d84eb00..78c484fff3aed 100644 --- a/clang/include/clang/AST/CommentCommandTraits.h +++ b/clang/include/clang/AST/CommentCommandTraits.h @@ -88,6 +88,10 @@ struct CommandInfo { LLVM_PREFERRED_TYPE(bool) unsigned IsHeaderfileCommand : 1; + /// True if this is a \\par command. + LLVM_PREFERRED_TYPE(bool) + unsigned IsParCommand : 1; + /// True if we don't want to warn about this command being passed an empty /// paragraph. Meaningful only for block commands. LLVM_PREFERRED_TYPE(bool) diff --git a/clang/include/clang/AST/CommentCommands.td b/clang/include/clang/AST/CommentCommands.td index 06b2fa9b5531c..a410cd4039bee 100644 --- a/clang/include/clang/AST/CommentCommands.td +++ b/clang/include/clang/AST/CommentCommands.td @@ -18,6 +18,7 @@ class Command { bit IsThrowsCommand = 0; bit IsDeprecatedCommand = 0; bit IsHeaderfileCommand = 0; + bit IsParCommand = 0; bit IsEmptyParagraphAllowed = 0; @@ -156,7 +157,7 @@ def Date : BlockCommand<"date">; def Invariant : BlockCommand<"invariant">; def Li : BlockCommand<"li">; def Note : BlockCommand<"note">; -def Par: BlockCommand<"par">; +def Par: BlockCommand<"par"> { let IsParCommand = 1; let NumArgs = 1; } def Post : BlockCommand<"post">; def Pre: BlockCommand<"pre">; def Remark : BlockCommand<"remark">; diff --git a/clang/include/clang/AST/CommentParser.h b/clang/include/clang/AST/CommentParser.h index a2d0e30835e2c..289f0b2c066b9 100644 --- a/clang/include/clang/AST/CommentParser.h +++ b/clang/include/clang/AST/CommentParser.h @@ -105,6 +105,9 @@ class Parser { ArrayRef parseThrowCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs); + ArrayRef + parseParCommandArgs(TextTokenRetokenizer &Retokenizer, unsigned NumArgs); + BlockCommandComment *parseBlockCommand(); InlineCommandComment *parseInlineCommand(); @@ -123,4 +126,3 @@ class Parser { } // end namespace clang #endif - diff --git a/clang/lib/AST/CommentParser.cpp b/clang/lib/AST/CommentParser.cpp index 5baf81a509fb6..bbe93ebc37d13 100644 --- a/clang/lib/AST/CommentParser.cpp +++ b/clang/lib/AST/CommentParser.cpp @@ -222,6 +222,63 @@ class TextTokenRetokenizer { return true; } + /// Check if this line starts with @par or \par + bool startsWithParCommand() { +unsigned Offset = 1; + +/// Skip all whitespace characters at the beginning. +/// This needs to backtrack because Pos has already advanced past the +/// actual \par or @par command by the time this function is called. +while (isWhitespace(*(Pos.BufferPtr - Offset))) + Offset++; + +/// Check if next four characters are \par or @par +llvm::StringRef LineStart(Pos.BufferPtr - 5, 4); +return LineStart.starts_with("\\par") || LineStart.starts_with("@par"); + } + + /// Extract a par command argument-header. + bool lexParHeading(Token &Tok) { +if (isEnd()) + return false; + +Position SavedPos = Pos; + +consumeWhitespace(); +SmallString<32> WordText; +const char *WordBegin = Pos.BufferPtr; +SourceLocation Loc = getSourceLocation(); + +if (!startsWithParCommand()) + return false; + +// Read until the end of this token, which is effectively the end of the +// line This gets us the content of the par header, if there is one. +while (!isEnd()) { + WordText.push_back(peek()); + if (Pos.BufferPtr + 1 == Pos.BufferEnd) { +consumeChar(); +break; + } else { +consumeChar(); + } +} + +const unsigned Length = WordText.size(); +if (Length == 0) { + Pos = SavedPos; + return false; +} + +char *TextPtr = Allocator.Allocate(Length + 1); + +memcpy(TextPtr, WordText.c_str(), Length + 1); +StringRef Text = StringRef(TextPtr, Length); + +formTokenWithChars(Tok, Loc, WordBegin, Length, Text); +return true; + } + /// Extract a word -- sequence of non-whitespace characters. bool lexWord(Token &Tok) { if (isEnd()) @@ -394,6 +451,23 @@ Parser::parseThrowCommandArgs(TextTokenRetokenizer &Retokenizer, ret
[clang] [llvm] clang/AMDGPU: Emit atomicrmw from ds_fadd builtins (PR #95395)
https://github.com/arsenm edited https://github.com/llvm/llvm-project/pull/95395 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy]fix false positives of the result of std::move() is used as rvalue for performance-move-const-arg (PR #95633)
https://github.com/PiotrZSL approved this pull request. https://github.com/llvm/llvm-project/pull/95633 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Skip checking anonymous enum in using enum declaration (PR #87144)
vabridgers wrote: This change has caused a regression in one of our systems integration tests that test static analysis for the bstring lib project (https://github.com/websnarf/bstrlib) with cross translation unit analysis enabled. Unfortunately I do not have a simple reproducer that stands alone just using clang, but I do have a reproducer that uses CodeChecker and can paste in the crash signature here. Please consider reverting the change until a proper fix can be made and this issue is addressed. bstrwrap.cpp 1 #include "bstrwrap.h" 2 #include 3 4 Bstrlib::CBString::CBString () { 5 } bstrwrap.h 1 #include 2 3 namespace Bstrlib { 4 struct CBString { 5CBString (); 6 }; 7 8 extern std::istream& getline (std::istream& sin, CBString& b, char terminator='\n'); 9 10 } // namespace Bstrlib test.cpp 1 #include "bstrwrap.h" 2 3 int test0 (void) { 4 Bstrlib::CBString c0; 5 return 0; 6 } Using CodeChecker from https://github.com/Ericsson/codechecker, Log the build ``CodeChecker log -b "g++ -c test.cpp bstrwrap.cpp" -o comp.json`` Repro step ``env PATH=:$PATH CC_ANALYZERS_FROM_PATH=1 CodeChecker analyze comp.json --clean --ctu -o report --analyzers clangsa`` The crash signature, appears to be crashing in AST Import. 1. parser at end of file 2. While analyzing stack: #0 Calling test0() 3. test.cpp:4:21: Error evaluating statement 4. test.cpp:4:21: Error evaluating statement #0 0x03cb7248 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (clang-19+0x3cb7248) #1 0x03cb4f2c llvm::sys::CleanupOnSignal(unsigned long) (clang-19+0x3cb4f2c) #2 0x03bfd308 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0 #3 0x7f9e5d53d630 __restore_rt sigaction.c:0:0 #4 0x7f9e5af39387 raise (/lib64/libc.so.6+0x36387) #5 0x7f9e5af3aa78 abort (/lib64/libc.so.6+0x37a78) #6 0x7f9e5af321a6 __assert_fail_base (/lib64/libc.so.6+0x2f1a6) #7 0x7f9e5af32252 (/lib64/libc.so.6+0x2f252) #8 0x072ada26 clang::FunctionDecl::setDescribedFunctionTemplate(clang::FunctionTemplateDecl*) (clang-19+0x72ada26) #9 0x07190a56 clang::ASTNodeImporter::VisitFunctionTemplateDecl(clang::FunctionTemplateDecl*) (clang-19+0x7190a56) #10 0x0716e998 clang::declvisitor::Base>::Visit(clang::Decl*) crtstuff.c:0:0 #11 0x0716eedb clang::ASTImporter::Import(clang::Decl*) (clang-19+0x716eedb) #12 0x07172108 std::conditional, llvm::Expected, llvm::Expected>::type clang::ASTNodeImporter::import(clang::Decl*) crtstuff.c:0:0 #13 0x0717d072 clang::ASTNodeImporter::ImportDeclContext(clang::DeclContext*, bool) (clang-19+0x717d072) #14 0x0718677b clang::ASTNodeImporter::VisitNamespaceDecl(clang::NamespaceDecl*) (clang-19+0x718677b) #15 0x0716ea38 clang::declvisitor::Base>::Visit(clang::Decl*) crtstuff.c:0:0 #16 0x0716eedb clang::ASTImporter::Import(clang::Decl*) (clang-19+0x716eedb) #17 0x07175146 clang::ASTImporter::Import(clang::NestedNameSpecifier*) (clang-19+0x7175146) #18 0x0717a0bb clang::ASTNodeImporter::VisitElaboratedType(clang::ElaboratedType const*) (clang-19+0x717a0bb) #19 0x07174945 clang::TypeVisitor>::Visit(clang::Type const*) crtstuff.c:0:0 #20 0x07174c07 clang::ASTImporter::Import(clang::Type const*) (clang-19+0x7174c07) #21 0x07175bd7 clang::ASTImporter::Import(clang::QualType) (clang-19+0x7175bd7) #22 0x07177e20 clang::ASTNodeImporter::VisitLValueReferenceType(clang::LValueReferenceType const*) (clang-19+0x7177e20) https://github.com/llvm/llvm-project/pull/87144 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Sema] Skip checking anonymous enum in using enum declaration (PR #87144)
vabridgers wrote: @dkrupp , @balazske https://github.com/llvm/llvm-project/pull/87144 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [compiler-rt] [compiler-rt] adding safestack support for sunos platforms. (PR #95648)
https://github.com/devnexen created https://github.com/llvm/llvm-project/pull/95648 None >From e7b7e784e4f36b76d1dd8ddfa8ea296859443a10 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 15 Jun 2024 09:48:58 + Subject: [PATCH] [compiler-rt] adding safestack support for sunos platforms. --- clang/lib/Driver/ToolChains/Solaris.cpp| 1 + compiler-rt/cmake/config-ix.cmake | 2 +- compiler-rt/lib/safestack/safestack_platform.h | 10 +- compiler-rt/test/safestack/lit.cfg.py | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp index 7126e018ca5b6..e82ed2ca79ffd 100644 --- a/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/clang/lib/Driver/ToolChains/Solaris.cpp @@ -341,6 +341,7 @@ SanitizerMask Solaris::getSupportedSanitizers() const { Res |= SanitizerKind::PointerCompare; Res |= SanitizerKind::PointerSubtract; } + Res |= SanitizerKind::SafeStack; Res |= SanitizerKind::Vptr; return Res; } diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index bddaa37579fd7..c05bdd58519fb 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -833,7 +833,7 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND SAFESTACK_SUPPORTED_ARCH AND -OS_NAME MATCHES "Linux|FreeBSD|NetBSD") +OS_NAME MATCHES "Linux|FreeBSD|NetBSD|SunOS") set(COMPILER_RT_HAS_SAFESTACK TRUE) else() set(COMPILER_RT_HAS_SAFESTACK FALSE) diff --git a/compiler-rt/lib/safestack/safestack_platform.h b/compiler-rt/lib/safestack/safestack_platform.h index 2b1fc139baa90..df2f05b84f1aa 100644 --- a/compiler-rt/lib/safestack/safestack_platform.h +++ b/compiler-rt/lib/safestack/safestack_platform.h @@ -25,7 +25,7 @@ #include #include -#if !(SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX) +#if !(SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS) #error "Support for your platform has not been implemented" #endif @@ -39,6 +39,10 @@ extern "C" void *__mmap(void *, size_t, int, int, int, int, off_t); #include #endif +#if SANITIZER_SOLARIS +#include +#endif + namespace safestack { #if SANITIZER_NETBSD @@ -73,6 +77,8 @@ inline ThreadId GetTid() { long Tid; thr_self(&Tid); return Tid; +#elif SANITIZER_SOLARIS + return thr_self(); #else return syscall(SYS_gettid); #endif @@ -83,6 +89,8 @@ inline int TgKill(pid_t pid, ThreadId tid, int sig) { DEFINE__REAL(int, _lwp_kill, int a, int b); (void)pid; return _REAL(_lwp_kill, tid, sig); +#elif SANITIZER_SOLARIS + return syscall(SYS_lwp_kill, tid, sig); #elif SANITIZER_FREEBSD return syscall(SYS_thr_kill2, pid, tid, sig); #else diff --git a/compiler-rt/test/safestack/lit.cfg.py b/compiler-rt/test/safestack/lit.cfg.py index aadb8bf0d5c77..17dfae46a412b 100644 --- a/compiler-rt/test/safestack/lit.cfg.py +++ b/compiler-rt/test/safestack/lit.cfg.py @@ -33,5 +33,5 @@ ) ) -if config.host_os not in ["Linux", "FreeBSD", "NetBSD"]: +if config.host_os not in ["Linux", "FreeBSD", "NetBSD", "SunOS"]: config.unsupported = True ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [compiler-rt] [compiler-rt] adding safestack support for sunos platforms. (PR #95648)
llvmbot wrote: @llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-driver Author: David CARLIER (devnexen) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/95648.diff 4 Files Affected: - (modified) clang/lib/Driver/ToolChains/Solaris.cpp (+1) - (modified) compiler-rt/cmake/config-ix.cmake (+1-1) - (modified) compiler-rt/lib/safestack/safestack_platform.h (+9-1) - (modified) compiler-rt/test/safestack/lit.cfg.py (+1-1) ``diff diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp index 7126e018ca5b6..e82ed2ca79ffd 100644 --- a/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/clang/lib/Driver/ToolChains/Solaris.cpp @@ -341,6 +341,7 @@ SanitizerMask Solaris::getSupportedSanitizers() const { Res |= SanitizerKind::PointerCompare; Res |= SanitizerKind::PointerSubtract; } + Res |= SanitizerKind::SafeStack; Res |= SanitizerKind::Vptr; return Res; } diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index bddaa37579fd7..c05bdd58519fb 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -833,7 +833,7 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND SAFESTACK_SUPPORTED_ARCH AND -OS_NAME MATCHES "Linux|FreeBSD|NetBSD") +OS_NAME MATCHES "Linux|FreeBSD|NetBSD|SunOS") set(COMPILER_RT_HAS_SAFESTACK TRUE) else() set(COMPILER_RT_HAS_SAFESTACK FALSE) diff --git a/compiler-rt/lib/safestack/safestack_platform.h b/compiler-rt/lib/safestack/safestack_platform.h index 2b1fc139baa90..df2f05b84f1aa 100644 --- a/compiler-rt/lib/safestack/safestack_platform.h +++ b/compiler-rt/lib/safestack/safestack_platform.h @@ -25,7 +25,7 @@ #include #include -#if !(SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX) +#if !(SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS) #error "Support for your platform has not been implemented" #endif @@ -39,6 +39,10 @@ extern "C" void *__mmap(void *, size_t, int, int, int, int, off_t); #include #endif +#if SANITIZER_SOLARIS +#include +#endif + namespace safestack { #if SANITIZER_NETBSD @@ -73,6 +77,8 @@ inline ThreadId GetTid() { long Tid; thr_self(&Tid); return Tid; +#elif SANITIZER_SOLARIS + return thr_self(); #else return syscall(SYS_gettid); #endif @@ -83,6 +89,8 @@ inline int TgKill(pid_t pid, ThreadId tid, int sig) { DEFINE__REAL(int, _lwp_kill, int a, int b); (void)pid; return _REAL(_lwp_kill, tid, sig); +#elif SANITIZER_SOLARIS + return syscall(SYS_lwp_kill, tid, sig); #elif SANITIZER_FREEBSD return syscall(SYS_thr_kill2, pid, tid, sig); #else diff --git a/compiler-rt/test/safestack/lit.cfg.py b/compiler-rt/test/safestack/lit.cfg.py index aadb8bf0d5c77..17dfae46a412b 100644 --- a/compiler-rt/test/safestack/lit.cfg.py +++ b/compiler-rt/test/safestack/lit.cfg.py @@ -33,5 +33,5 @@ ) ) -if config.host_os not in ["Linux", "FreeBSD", "NetBSD"]: +if config.host_os not in ["Linux", "FreeBSD", "NetBSD", "SunOS"]: config.unsupported = True `` https://github.com/llvm/llvm-project/pull/95648 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [compiler-rt] [compiler-rt] adding safestack support for sunos platforms. (PR #95648)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 8cc6a2469c95f0815487c442495a829c337913c4 e7b7e784e4f36b76d1dd8ddfa8ea296859443a10 -- clang/lib/Driver/ToolChains/Solaris.cpp compiler-rt/lib/safestack/safestack_platform.h `` View the diff from clang-format here. ``diff diff --git a/compiler-rt/lib/safestack/safestack_platform.h b/compiler-rt/lib/safestack/safestack_platform.h index df2f05b84f..822611315d 100644 --- a/compiler-rt/lib/safestack/safestack_platform.h +++ b/compiler-rt/lib/safestack/safestack_platform.h @@ -25,8 +25,9 @@ #include #include -#if !(SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_SOLARIS) -#error "Support for your platform has not been implemented" +#if !(SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX || \ + SANITIZER_SOLARIS) +# error "Support for your platform has not been implemented" #endif #if SANITIZER_NETBSD @@ -40,7 +41,7 @@ extern "C" void *__mmap(void *, size_t, int, int, int, int, off_t); #endif #if SANITIZER_SOLARIS -#include +# include #endif namespace safestack { `` https://github.com/llvm/llvm-project/pull/95648 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [compiler-rt] [compiler-rt] adding safestack support for sunos platforms. (PR #95648)
https://github.com/devnexen updated https://github.com/llvm/llvm-project/pull/95648 >From 33f68c3c59549a966871ea87f0f4b4c5df0a3d04 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 15 Jun 2024 09:48:58 + Subject: [PATCH] [compiler-rt] adding safestack support for sunos platforms. --- clang/lib/Driver/ToolChains/Solaris.cpp| 1 + compiler-rt/cmake/config-ix.cmake | 2 +- compiler-rt/lib/safestack/safestack_platform.h | 11 ++- compiler-rt/test/safestack/lit.cfg.py | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp index 7126e018ca5b6..e82ed2ca79ffd 100644 --- a/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/clang/lib/Driver/ToolChains/Solaris.cpp @@ -341,6 +341,7 @@ SanitizerMask Solaris::getSupportedSanitizers() const { Res |= SanitizerKind::PointerCompare; Res |= SanitizerKind::PointerSubtract; } + Res |= SanitizerKind::SafeStack; Res |= SanitizerKind::Vptr; return Res; } diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index bddaa37579fd7..c05bdd58519fb 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -833,7 +833,7 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND SAFESTACK_SUPPORTED_ARCH AND -OS_NAME MATCHES "Linux|FreeBSD|NetBSD") +OS_NAME MATCHES "Linux|FreeBSD|NetBSD|SunOS") set(COMPILER_RT_HAS_SAFESTACK TRUE) else() set(COMPILER_RT_HAS_SAFESTACK FALSE) diff --git a/compiler-rt/lib/safestack/safestack_platform.h b/compiler-rt/lib/safestack/safestack_platform.h index 2b1fc139baa90..2d952de034ea9 100644 --- a/compiler-rt/lib/safestack/safestack_platform.h +++ b/compiler-rt/lib/safestack/safestack_platform.h @@ -25,7 +25,8 @@ #include #include -#if !(SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX) +#if !(SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX || \ + SANITIZER_SOLARIS) #error "Support for your platform has not been implemented" #endif @@ -39,6 +40,10 @@ extern "C" void *__mmap(void *, size_t, int, int, int, int, off_t); #include #endif +#if SANITIZER_SOLARIS +# include +#endif + namespace safestack { #if SANITIZER_NETBSD @@ -73,6 +78,8 @@ inline ThreadId GetTid() { long Tid; thr_self(&Tid); return Tid; +#elif SANITIZER_SOLARIS + return thr_self(); #else return syscall(SYS_gettid); #endif @@ -83,6 +90,8 @@ inline int TgKill(pid_t pid, ThreadId tid, int sig) { DEFINE__REAL(int, _lwp_kill, int a, int b); (void)pid; return _REAL(_lwp_kill, tid, sig); +#elif SANITIZER_SOLARIS + return syscall(SYS_lwp_kill, tid, sig); #elif SANITIZER_FREEBSD return syscall(SYS_thr_kill2, pid, tid, sig); #else diff --git a/compiler-rt/test/safestack/lit.cfg.py b/compiler-rt/test/safestack/lit.cfg.py index aadb8bf0d5c77..17dfae46a412b 100644 --- a/compiler-rt/test/safestack/lit.cfg.py +++ b/compiler-rt/test/safestack/lit.cfg.py @@ -33,5 +33,5 @@ ) ) -if config.host_os not in ["Linux", "FreeBSD", "NetBSD"]: +if config.host_os not in ["Linux", "FreeBSD", "NetBSD", "SunOS"]: config.unsupported = True ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [compiler-rt] [compiler-rt] adding safestack support for sunos platforms. (PR #95648)
https://github.com/devnexen updated https://github.com/llvm/llvm-project/pull/95648 >From 18ce8ba99de7a42f17f0878819b20ed3faa2de13 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 15 Jun 2024 09:48:58 + Subject: [PATCH] [compiler-rt] adding safestack support for sunos platforms. --- clang/lib/Driver/ToolChains/Solaris.cpp| 1 + compiler-rt/cmake/config-ix.cmake | 2 +- compiler-rt/lib/safestack/safestack_platform.h | 13 +++-- compiler-rt/test/safestack/lit.cfg.py | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp index 7126e018ca5b6..e82ed2ca79ffd 100644 --- a/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/clang/lib/Driver/ToolChains/Solaris.cpp @@ -341,6 +341,7 @@ SanitizerMask Solaris::getSupportedSanitizers() const { Res |= SanitizerKind::PointerCompare; Res |= SanitizerKind::PointerSubtract; } + Res |= SanitizerKind::SafeStack; Res |= SanitizerKind::Vptr; return Res; } diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index bddaa37579fd7..c05bdd58519fb 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -833,7 +833,7 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND SAFESTACK_SUPPORTED_ARCH AND -OS_NAME MATCHES "Linux|FreeBSD|NetBSD") +OS_NAME MATCHES "Linux|FreeBSD|NetBSD|SunOS") set(COMPILER_RT_HAS_SAFESTACK TRUE) else() set(COMPILER_RT_HAS_SAFESTACK FALSE) diff --git a/compiler-rt/lib/safestack/safestack_platform.h b/compiler-rt/lib/safestack/safestack_platform.h index 2b1fc139baa90..822611315d010 100644 --- a/compiler-rt/lib/safestack/safestack_platform.h +++ b/compiler-rt/lib/safestack/safestack_platform.h @@ -25,8 +25,9 @@ #include #include -#if !(SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX) -#error "Support for your platform has not been implemented" +#if !(SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX || \ + SANITIZER_SOLARIS) +# error "Support for your platform has not been implemented" #endif #if SANITIZER_NETBSD @@ -39,6 +40,10 @@ extern "C" void *__mmap(void *, size_t, int, int, int, int, off_t); #include #endif +#if SANITIZER_SOLARIS +# include +#endif + namespace safestack { #if SANITIZER_NETBSD @@ -73,6 +78,8 @@ inline ThreadId GetTid() { long Tid; thr_self(&Tid); return Tid; +#elif SANITIZER_SOLARIS + return thr_self(); #else return syscall(SYS_gettid); #endif @@ -83,6 +90,8 @@ inline int TgKill(pid_t pid, ThreadId tid, int sig) { DEFINE__REAL(int, _lwp_kill, int a, int b); (void)pid; return _REAL(_lwp_kill, tid, sig); +#elif SANITIZER_SOLARIS + return syscall(SYS_lwp_kill, tid, sig); #elif SANITIZER_FREEBSD return syscall(SYS_thr_kill2, pid, tid, sig); #else diff --git a/compiler-rt/test/safestack/lit.cfg.py b/compiler-rt/test/safestack/lit.cfg.py index aadb8bf0d5c77..17dfae46a412b 100644 --- a/compiler-rt/test/safestack/lit.cfg.py +++ b/compiler-rt/test/safestack/lit.cfg.py @@ -33,5 +33,5 @@ ) ) -if config.host_os not in ["Linux", "FreeBSD", "NetBSD"]: +if config.host_os not in ["Linux", "FreeBSD", "NetBSD", "SunOS"]: config.unsupported = True ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] Support go-to-definition on type hints. The core part (PR #86629)
@@ -1637,6 +1678,144 @@ TEST(TypeHints, SubstTemplateParameterAliases) { ExpectedHint{": static_vector", "vector_name"}); } +template +void assertTypeLinkHints(StringRef Code, StringRef HintRange, + Labels... ExpectedLabels) { + Annotations Source(Code); + auto HintAt = [&](llvm::ArrayRef InlayHints, +llvm::StringRef Range) { +auto *Hint = llvm::find_if(InlayHints, [&](const InlayHint &InlayHint) { + return InlayHint.range == Source.range(Range); +}); +assert(Hint && "No range was found"); +return llvm::ArrayRef(Hint->label); + }; + + TestTU TU = TestTU::withCode(Source.code()); + TU.ExtraArgs.push_back("-std=c++2c"); + auto AST = TU.build(); + + Config C; + C.InlayHints.TypeNameLimit = 0; + WithContextValue WithCfg(Config::Key, std::move(C)); + + auto Hints = hintsOfKind(AST, InlayHintKind::Type); + EXPECT_THAT(HintAt(Hints, HintRange), + ElementsAre(HintLabelPieceMatcher(ExpectedLabels, Source)...)); +} + +TEST(TypeHints, Links) { + StringRef Source(R"cpp( +$Package[[template zyn0217 wrote: @HighCommander4 I explored it a bit more: I explored it a bit more: 1. Using `RecordDecl::getBeginLoc()` does work in terms of the protocol, but this SourceLocation points to the first keyword token of the definition, i.e., the location of struct/class, which doesn't seem acceptable to us. 2. The better approach to having the identifier location is to resort to `TypeLocs`, which is involved regarding the current implementation of `addTypeHint()` because it's taking a `QualType` as a parameter and changing it to `TypeSourceInfo/TypeLoc` might require some surgery. I think I'm in favor of shifting the current `TypeHint` implementation to rely on `TypeLocs`. We probably need a separate patch before this one. WDYT? Or is there any possible approach to obtaining the location of the identifier without using `TypeLocs`? https://github.com/llvm/llvm-project/pull/86629 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] Support go-to-definition on type hints. The core part (PR #86629)
https://github.com/zyn0217 edited https://github.com/llvm/llvm-project/pull/86629 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] Support go-to-definition on type hints. The core part (PR #86629)
https://github.com/zyn0217 edited https://github.com/llvm/llvm-project/pull/86629 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Debug Info] Fix debug info ptr to ptr test (PR #95637)
https://github.com/jmorse approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/95637 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 17712f5 - [clang][Interp] Fix checking null pointers for initialization
Author: Timm Bäder Date: 2024-06-15T11:38:57+02:00 New Revision: 17712f501c63998e67178e817ee64612cd1daae3 URL: https://github.com/llvm/llvm-project/commit/17712f501c63998e67178e817ee64612cd1daae3 DIFF: https://github.com/llvm/llvm-project/commit/17712f501c63998e67178e817ee64612cd1daae3.diff LOG: [clang][Interp] Fix checking null pointers for initialization Added: Modified: clang/lib/AST/Interp/EvaluationResult.cpp clang/test/AST/Interp/cxx20.cpp Removed: diff --git a/clang/lib/AST/Interp/EvaluationResult.cpp b/clang/lib/AST/Interp/EvaluationResult.cpp index 387e3dc88bff2..395e3f5b4348d 100644 --- a/clang/lib/AST/Interp/EvaluationResult.cpp +++ b/clang/lib/AST/Interp/EvaluationResult.cpp @@ -141,7 +141,9 @@ bool EvaluationResult::checkFullyInitialized(InterpState &S, const Pointer &Ptr) const { assert(Source); assert(empty()); - assert(!Ptr.isZero()); + + if (Ptr.isZero()) +return true; SourceLocation InitLoc; if (const auto *D = Source.dyn_cast()) diff --git a/clang/test/AST/Interp/cxx20.cpp b/clang/test/AST/Interp/cxx20.cpp index 434823644a7a3..2faacbbf70fd7 100644 --- a/clang/test/AST/Interp/cxx20.cpp +++ b/clang/test/AST/Interp/cxx20.cpp @@ -814,3 +814,16 @@ namespace GH64949 { // both-note {{subobject 'g' is not initialized}} \ // both-warning {{expression result unused}} } + +/// This used to cause an assertion failure inside EvaluationResult::checkFullyInitialized. +namespace CheckingNullPtrForInitialization { + struct X { +consteval operator const char *() const { + return nullptr; +} + }; + const char *f() { +constexpr X x; +return x; + } +} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] SourceLocIdentKind::Function should not be dependent (PR #94942)
zyn0217 wrote: nit: Please rephrase the commit message before you merge this patch. A large piece of AST involving memory addresses is really hard to decipher. In addition, it would be nice if you can simplify the test case further - it's super unclear why a bunch of templates are there outside of the `SourceLocation::Current()` - probably one or two is sufficient? https://github.com/llvm/llvm-project/pull/94942 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Clarify diagnostics of bugprone-sizeof-expression (PR #95550)
https://github.com/SimplyDanny approved this pull request. https://github.com/llvm/llvm-project/pull/95550 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Debug Info] Fix debug info ptr to ptr test (PR #95637)
jayfoad wrote: I'll merge to fix the build. https://github.com/llvm/llvm-project/pull/95637 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 47f8b85 - [Debug Info] Fix debug info ptr to ptr test (#95637)
Author: William Junda Huang Date: 2024-06-15T10:47:55+01:00 New Revision: 47f8b85b3d81ed3578cb3b8f80d69ce307e0c883 URL: https://github.com/llvm/llvm-project/commit/47f8b85b3d81ed3578cb3b8f80d69ce307e0c883 DIFF: https://github.com/llvm/llvm-project/commit/47f8b85b3d81ed3578cb3b8f80d69ce307e0c883.diff LOG: [Debug Info] Fix debug info ptr to ptr test (#95637) Fix test case in #95298 because another recent submitted patch removed llvm.dbg intrinsics, updated test case accordingly Added: Modified: clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp Removed: diff --git a/clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp b/clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp index 51ce0f107b5e3..6975eae1fb122 100644 --- a/clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp +++ b/clang/test/CodeGenCXX/debug-info-ptr-to-ptr.cpp @@ -25,7 +25,7 @@ class C { // CHECK-LABEL: define dso_local noundef i32 @{{.*}}func1{{.*}}( // CHECK: [[A_ADDR:%.*]] = getelementptr inbounds %class.B, ptr {{%.*}}, i32 0, i32 0, !dbg [[DBG1:![0-9]+]] // CHECK-NEXT:[[A:%.*]] = load ptr, ptr [[A_ADDR]], align {{.*}}, !dbg [[DBG1]] -// CHECK-NEXT:call void @llvm.dbg.value(metadata ptr [[A]], metadata [[META1:![0-9]+]], metadata !DIExpression()), !dbg [[DBG1]] +// CHECK-NEXT: #dbg_value(ptr [[A]], [[META1:![0-9]+]], !DIExpression(), [[DBG1]]) // CHECK-NEXT:{{%.*}} = getelementptr inbounds %class.A, ptr [[A]], i32 0, i32 0, int func1(B *b) { return b->a->i; @@ -33,9 +33,9 @@ int func1(B *b) { // Should generate a pseudo variable when pointer is type-casted. // CHECK-LABEL: define dso_local noundef ptr @{{.*}}func2{{.*}}( -// CHECK: call void @llvm.dbg.declare(metadata ptr [[B_ADDR:%.*]], metadata [[META2:![0-9]+]], metadata !DIExpression()) +// CHECK: #dbg_declare(ptr [[B_ADDR:%.*]], [[META2:![0-9]+]], !DIExpression(), // CHECK-NEXT:[[B:%.*]] = load ptr, ptr [[B_ADDR]], -// CHECK-NEXT:call void @llvm.dbg.value(metadata ptr [[B]], metadata [[META3:![0-9]+]], metadata !DIExpression()) +// CHECK-NEXT: #dbg_value(ptr [[B]], [[META3:![0-9]+]], !DIExpression(), // CHECK-NEXT:{{%.*}} = getelementptr inbounds %class.B, ptr [[B]], i32 0, A* func2(void *b) { return ((B*)b)->a; @@ -43,9 +43,9 @@ A* func2(void *b) { // Should not generate pseudo variable in this case. // CHECK-LABEL: define dso_local noundef i32 @{{.*}}func3{{.*}}( -// CHECK:call void @llvm.dbg.declare(metadata ptr [[B_ADDR:%.*]], metadata [[META4:![0-9]+]], metadata !DIExpression()) -// CHECK:call void @llvm.dbg.declare(metadata ptr [[LOCAL1:%.*]], metadata [[META5:![0-9]+]], metadata !DIExpression()) -// CHECK-NOT: call void @llvm.dbg.value(metadata ptr +// CHECK: #dbg_declare(ptr [[B_ADDR:%.*]], [[META4:![0-9]+]], !DIExpression(), +// CHECK: #dbg_declare(ptr [[LOCAL1:%.*]], [[META5:![0-9]+]], !DIExpression(), +// CHECK-NOT: #dbg_value(ptr int func3(B *b) { A *local1 = b->a; return local1->i; @@ -54,10 +54,10 @@ int func3(B *b) { // CHECK-LABEL: define dso_local noundef signext i8 @{{.*}}func4{{.*}}( // CHECK: [[A_ADDR:%.*]] = getelementptr inbounds %class.C, ptr {{%.*}}, i32 0, i32 1 // CHECK-NEXT:[[A:%.*]] = load ptr, ptr [[A_ADDR]], -// CHECK-NEXT:call void @llvm.dbg.value(metadata ptr [[A]], metadata [[META6:![0-9]+]], metadata !DIExpression()) +// CHECK-NEXT: #dbg_value(ptr [[A]], [[META6:![0-9]+]], !DIExpression(), // CHECK-NEXT:{{%.*}} = getelementptr inbounds %class.A, ptr [[A]], i32 0, i32 0, // CHECK: [[CALL:%.*]] = call noundef ptr @{{.*}}foo{{.*}}( -// CHECK-NEXT:call void @llvm.dbg.value(metadata ptr [[CALL]], metadata [[META6]], metadata !DIExpression()) +// CHECK-NEXT: #dbg_value(ptr [[CALL]], [[META6]], !DIExpression(), // CHECK-NEXT:[[I1:%.*]] = getelementptr inbounds %class.A, ptr [[CALL]], i32 0, i32 1 char func4(C *c) { extern A* foo(int x); @@ -65,25 +65,25 @@ char func4(C *c) { } // CHECK-LABEL: define dso_local noundef signext i8 @{{.*}}func5{{.*}}( -// CHECK: call void @llvm.dbg.declare(metadata ptr {{%.*}}, metadata [[META7:![0-9]+]], metadata !DIExpression()) -// CHECK: call void @llvm.dbg.declare(metadata ptr {{%.*}}, metadata [[META8:![0-9]+]], metadata !DIExpression()) +// CHECK: #dbg_declare(ptr {{%.*}}, [[META7:![0-9]+]], !DIExpression(), +// CHECK: #dbg_declare(ptr {{%.*}}, [[META8:![0-9]+]], !DIExpression(), // CHECK: [[A_ADDR:%.*]] = getelementptr inbounds %class.A, ptr {{%.*}}, i64 {{%.*}}, -// CHECK-NEXT:call void @llvm.dbg.value(metadata ptr [[A_ADDR]], metadata [[META9:![0-9]+]], metadata !DIExpression()) +// CHECK-NEXT: #dbg_value(ptr [[A_ADDR]], [[META9:![0-9]+]], !DIExpression(), // CHECK-NEXT:{{%.*}} = getelementptr inbounds %class.A, ptr [[A_ADDR]], i32 0, i32 1, char func5(void *arr, int n) { return
[clang] [Debug Info] Fix debug info ptr to ptr test (PR #95637)
https://github.com/jayfoad closed https://github.com/llvm/llvm-project/pull/95637 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy]fix false positives of the result of std::move() is used as rvalue for performance-move-const-arg (PR #95633)
https://github.com/SimplyDanny approved this pull request. https://github.com/llvm/llvm-project/pull/95633 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy]fix false positives of the result of std::move() is used as rvalue for performance-move-const-arg (PR #95633)
@@ -387,6 +387,10 @@ Changes in existing checks - Improved :doc:`modernize-use-using ` check by adding support for detection of typedefs declared on function level. +- Improved :doc:`performance-move-const-arg + ` check ignoring the result + of ``std::move()`` is used as rvalue. SimplyDanny wrote: ```suggestion - Improved :doc:`performance-move-const-arg ` check by ignoring ``std::move()`` calls when their target is used as an rvalue. ``` https://github.com/llvm/llvm-project/pull/95633 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy]fix false positives of the result of std::move() is used as rvalue for performance-move-const-arg (PR #95633)
https://github.com/SimplyDanny edited https://github.com/llvm/llvm-project/pull/95633 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Option to ignore anonymous namespaces in avoid-non-const-global-variables (PR #93827)
https://github.com/SimplyDanny edited https://github.com/llvm/llvm-project/pull/93827 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Option to ignore anonymous namespaces in avoid-non-const-global-variables (PR #93827)
https://github.com/SimplyDanny approved this pull request. https://github.com/llvm/llvm-project/pull/93827 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Option to ignore anonymous namespaces in avoid-non-const-global-variables (PR #93827)
@@ -7,21 +7,30 @@ //===--===// #include "AvoidNonConstGlobalVariablesCheck.h" -#include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" using namespace clang::ast_matchers; namespace clang::tidy::cppcoreguidelines { +AvoidNonConstGlobalVariablesCheck::AvoidNonConstGlobalVariablesCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context), + AllowInternalLinkage(Options.get("AllowInternalLinkage", false)) {} SimplyDanny wrote: Option name could be a constant to avoid duplication. https://github.com/llvm/llvm-project/pull/93827 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix access checking inside return-type-requirement of compound requirements (PR #95651)
https://github.com/Backl1ght created https://github.com/llvm/llvm-project/pull/95651 fixes https://github.com/llvm/llvm-project/issues/93788 . >From 7911a757d6b97a12baf465d0fe1a9442ca2ee76b Mon Sep 17 00:00:00 2001 From: Backl1ght Date: Sat, 15 Jun 2024 16:56:00 +0800 Subject: [PATCH] fix --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Sema/SemaTemplateInstantiate.cpp| 2 +- .../expr.prim.req/compound-requirement.cpp| 36 +++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 36efeb8c70cca..3717e573419e7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -858,6 +858,7 @@ Bug Fixes to C++ Support - Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307), (#GH88081), (#GH89496), (#GH90669) and (#GH91633). - Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368). +- Fixed a bug in access checking inside return-type-requirement of compound requirements. (#GH93788). Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 863cc53c55afa..1fe1fe9d4f833 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2735,7 +2735,7 @@ TemplateInstantiator::TransformExprRequirement(concepts::ExprRequirement *Req) { if (TPLInst.isInvalid()) return nullptr; TemplateParameterList *TPL = TransformTemplateParameterList(OrigTPL); -if (!TPL) +if (!TPL || Trap.hasErrorOccurred()) TransRetReq.emplace(createSubstDiag(SemaRef, Info, [&] (llvm::raw_ostream& OS) { RetReq.getTypeConstraint()->getImmediatelyDeclaredConstraint() diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp index b7366207882f9..dc0e84280e056 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp @@ -189,3 +189,39 @@ namespace std_example { template struct C5_check {}; // expected-note{{because 'short' does not satisfy 'C5'}} using c5 = C5_check; // expected-error{{constraints not satisfied for class template 'C5_check' [with T = short]}} } + +namespace access_checks { +namespace in_return_type_requirement { + +// https://github.com/llvm/llvm-project/issues/93788 +template +concept is_assignable = requires(From from, To to) { + from = to; +}; + +template +class trait { + public: + using public_type = int; + private: + using private_type = int; +}; + +template +concept has_field = requires(T t) { + { t.field } -> is_assignable::private_type>; // expected-note {{'private_type' is a private member}} +}; +template +concept has_field2 = requires(T t) { + { t.field } -> is_assignable::public_type>; +}; + +struct A { + int field; +}; +static_assert(has_field); // expected-error {{static assertion failed}} \ + // expected-note {{because 'A' does not satisfy 'has_field'}} +static_assert(has_field2); + +} // namespace access_checks +} // namespace in_return_type_requirement ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix access checking inside return-type-requirement of compound requirements (PR #95651)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Zhikai Zeng (Backl1ght) Changes fixes https://github.com/llvm/llvm-project/issues/93788 . --- Full diff: https://github.com/llvm/llvm-project/pull/95651.diff 3 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+1) - (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+1-1) - (modified) clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp (+36) ``diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 36efeb8c70cca..3717e573419e7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -858,6 +858,7 @@ Bug Fixes to C++ Support - Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307), (#GH88081), (#GH89496), (#GH90669) and (#GH91633). - Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368). +- Fixed a bug in access checking inside return-type-requirement of compound requirements. (#GH93788). Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 863cc53c55afa..1fe1fe9d4f833 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2735,7 +2735,7 @@ TemplateInstantiator::TransformExprRequirement(concepts::ExprRequirement *Req) { if (TPLInst.isInvalid()) return nullptr; TemplateParameterList *TPL = TransformTemplateParameterList(OrigTPL); -if (!TPL) +if (!TPL || Trap.hasErrorOccurred()) TransRetReq.emplace(createSubstDiag(SemaRef, Info, [&] (llvm::raw_ostream& OS) { RetReq.getTypeConstraint()->getImmediatelyDeclaredConstraint() diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp index b7366207882f9..dc0e84280e056 100644 --- a/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp +++ b/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp @@ -189,3 +189,39 @@ namespace std_example { template struct C5_check {}; // expected-note{{because 'short' does not satisfy 'C5'}} using c5 = C5_check; // expected-error{{constraints not satisfied for class template 'C5_check' [with T = short]}} } + +namespace access_checks { +namespace in_return_type_requirement { + +// https://github.com/llvm/llvm-project/issues/93788 +template +concept is_assignable = requires(From from, To to) { + from = to; +}; + +template +class trait { + public: + using public_type = int; + private: + using private_type = int; +}; + +template +concept has_field = requires(T t) { + { t.field } -> is_assignable::private_type>; // expected-note {{'private_type' is a private member}} +}; +template +concept has_field2 = requires(T t) { + { t.field } -> is_assignable::public_type>; +}; + +struct A { + int field; +}; +static_assert(has_field); // expected-error {{static assertion failed}} \ + // expected-note {{because 'A' does not satisfy 'has_field'}} +static_assert(has_field2); + +} // namespace access_checks +} // namespace in_return_type_requirement `` https://github.com/llvm/llvm-project/pull/95651 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Option to ignore anonymous namespaces in avoid-non-const-global-variables (PR #93827)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/93827 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Option to ignore anonymous namespaces in avoid-non-const-global-variables (PR #93827)
5chmidti wrote: FYI: You could remove the explicit check-nots here: ```c++ // RUN: %check_clang_tidy %s -check-suffixes=,INTERNAL-LINKAGE cppcoreguidelines-avoid-non-const-global-variables %t // RUN: %check_clang_tidy %s cppcoreguidelines-avoid-non-const-global-variables %t -- \ // RUN: -config="{CheckOptions: {cppcoreguidelines-avoid-non-const-global-variables.AllowInternalLinkage : 'true'}}" namespace { int nonConstAnonymousNamespaceInt = 0; // CHECK-MESSAGES-INTERNAL-LINKAGE: :[[@LINE-1]]:5: warning: variable 'nonConstAnonymousNamespaceInt' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables] } // namespace ``` (There are also two check-nots where the line is off by one) https://github.com/llvm/llvm-project/pull/93827 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Option to ignore anonymous namespaces in avoid-non-const-global-variables (PR #93827)
https://github.com/5chmidti approved this pull request. While I'm leaning more towards > NOLINT in the code can grab the attention of a future developer and prompt a > refactoring to avoid the pattern. , it's an off-by-default option that provides a choice. LGTM https://github.com/llvm/llvm-project/pull/93827 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][AArch64] Generalise streaming mode checks for builtins. (PR #93802)
https://github.com/paulwalker-arm approved this pull request. https://github.com/llvm/llvm-project/pull/93802 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Instantiate local constexpr functions eagerly (PR #95660)
https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/95660 We had a code path in `Sema::MarkFunctionReferenced()` that deferred local lambda instantiation even for constexprs. This resulted in any calls to them referring to function decls that lack bodies and hence failures at constant evaluation. The issue doesn't occur when the lambda has no explicit return type because the return type deduction requires instantiation. Fixes https://github.com/llvm/llvm-project/issues/35052 Fixes https://github.com/llvm/llvm-project/issues/94849 >From c288190c313d6990580048368c60a846919f98ae Mon Sep 17 00:00:00 2001 From: Younan Zhang Date: Sat, 15 Jun 2024 20:29:24 +0800 Subject: [PATCH] [Clang] Instantiate local constexpr functions eagerly --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/Sema/SemaExpr.cpp | 3 ++- .../SemaTemplate/instantiate-local-class.cpp | 24 +++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 8c2f737836a9d..a424554ed821d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -847,6 +847,7 @@ Bug Fixes to C++ Support - Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307), (#GH88081), (#GH89496), (#GH90669) and (#GH91633). - Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368). +- Clang now instantiates local constexpr functions eagerly for constant evaluators. (#GH35052), (#GH94849) Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 99a8704298314..88e9b2b00f84d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -18112,7 +18112,8 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, if (FirstInstantiation || TSK != TSK_ImplicitInstantiation || Func->isConstexpr()) { - if (isa(Func->getDeclContext()) && + if (!Func->isConstexpr() && + isa(Func->getDeclContext()) && cast(Func->getDeclContext())->isLocalClass() && CodeSynthesisContexts.size()) PendingLocalImplicitInstantiations.push_back( diff --git a/clang/test/SemaTemplate/instantiate-local-class.cpp b/clang/test/SemaTemplate/instantiate-local-class.cpp index 47591045fd26e..7eee131e28d60 100644 --- a/clang/test/SemaTemplate/instantiate-local-class.cpp +++ b/clang/test/SemaTemplate/instantiate-local-class.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -verify -std=c++11 %s // RUN: %clang_cc1 -verify -std=c++11 -fdelayed-template-parsing %s +// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s template void f0() { @@ -509,3 +510,26 @@ namespace LambdaInDefaultMemberInitializer { } template void f(); } + +#if __cplusplus >= 201703L +namespace GH35052 { + +template constexpr int func(F f) { + if constexpr (f(1UL)) { +return 1; + } + return 0; +} + +int main() { + auto predicate = [](auto v) /*implicit constexpr*/ -> bool { +return v == 1; + }; + + static_assert(predicate(1)); + return func(predicate); +} + +} // namespace GH35052 + +#endif ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy]fix false positives of the result of std::move() is used as rvalue for performance-move-const-arg (PR #95633)
https://github.com/HerrCai0907 updated https://github.com/llvm/llvm-project/pull/95633 >From 0022050f7b537914dff7adf937103def4c9c939a Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Sat, 15 Jun 2024 05:40:50 + Subject: [PATCH 1/2] [clang-tidy]fix false positives of the result of std::move() is used as rvalue for performance-move-const-arg Fixes: #86404 --- .../clang-tidy/performance/MoveConstArgCheck.cpp | 8 +++- clang-tools-extra/docs/ReleaseNotes.rst| 4 .../checkers/performance/move-const-arg.cpp| 14 +- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp b/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp index aa54cf284f627..d29b9e91f2e35 100644 --- a/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp @@ -44,7 +44,13 @@ void MoveConstArgCheck::registerMatchers(MatchFinder *Finder) { unless(isInTemplateInstantiation())) .bind("call-move"); - Finder->addMatcher(MoveCallMatcher, this); + Finder->addMatcher( + expr(anyOf( + castExpr(hasSourceExpression(MoveCallMatcher)), + cxxConstructExpr(hasDeclaration(cxxConstructorDecl(anyOf( + isCopyConstructor(), isMoveConstructor(, + hasArgument(0, MoveCallMatcher, + this); auto ConstTypeParmMatcher = qualType(references(isConstQualified())).bind("invocation-parm-type"); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 5d5aecd67b2d7..aeb0d72651c34 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -387,6 +387,10 @@ Changes in existing checks - Improved :doc:`modernize-use-using ` check by adding support for detection of typedefs declared on function level. +- Improved :doc:`performance-move-const-arg + ` check ignoring the result + of ``std::move()`` is used as rvalue. + - Improved :doc:`performance-unnecessary-copy-initialization ` check by detecting more cases of constant access. In particular, pointers can be diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/move-const-arg.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/move-const-arg.cpp index 4d90c124ad72c..4505eef6df24b 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/performance/move-const-arg.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance/move-const-arg.cpp @@ -114,14 +114,18 @@ void f8() { int f9() { return M2(1); } template -T f10(const int x10) { +T f_unknown_target(const int x10) { return std::move(x10); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the const variable 'x10' of the trivially-copyable type 'const int' has no effect; remove std::move() [performance-move-const-arg] - // CHECK-FIXES: return x10; } + void f11() { - f10(1); - f10(1); + f_unknown_target(1); + f_unknown_target(1); +} + +A&& f_return_right_ref() { + static A a{}; + return std::move(a); } class NoMoveSemantics { >From e2a8a0dbc63ad4aaceb44ddd62d56bea6142dc7d Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Sat, 15 Jun 2024 20:56:32 +0800 Subject: [PATCH 2/2] Update clang-tools-extra/docs/ReleaseNotes.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Danny Mösch --- clang-tools-extra/docs/ReleaseNotes.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index aeb0d72651c34..7092d0b6fdb02 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -388,8 +388,8 @@ Changes in existing checks check by adding support for detection of typedefs declared on function level. - Improved :doc:`performance-move-const-arg - ` check ignoring the result - of ``std::move()`` is used as rvalue. + ` check by ignoring + ``std::move()`` calls when their target is used as an rvalue. - Improved :doc:`performance-unnecessary-copy-initialization ` check by ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] a78c104 - [clang-tidy]fix false positives of the result of std::move() is used as rvalue for performance-move-const-arg (#95633)
Author: Congcong Cai Date: 2024-06-15T21:06:30+08:00 New Revision: a78c104a238566d5ba1c89384087c57668c306ae URL: https://github.com/llvm/llvm-project/commit/a78c104a238566d5ba1c89384087c57668c306ae DIFF: https://github.com/llvm/llvm-project/commit/a78c104a238566d5ba1c89384087c57668c306ae.diff LOG: [clang-tidy]fix false positives of the result of std::move() is used as rvalue for performance-move-const-arg (#95633) Fixes: #86404 - Co-authored-by: Danny Mösch Added: Modified: clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/test/clang-tidy/checkers/performance/move-const-arg.cpp Removed: diff --git a/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp b/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp index aa54cf284f627..d29b9e91f2e35 100644 --- a/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/MoveConstArgCheck.cpp @@ -44,7 +44,13 @@ void MoveConstArgCheck::registerMatchers(MatchFinder *Finder) { unless(isInTemplateInstantiation())) .bind("call-move"); - Finder->addMatcher(MoveCallMatcher, this); + Finder->addMatcher( + expr(anyOf( + castExpr(hasSourceExpression(MoveCallMatcher)), + cxxConstructExpr(hasDeclaration(cxxConstructorDecl(anyOf( + isCopyConstructor(), isMoveConstructor(, + hasArgument(0, MoveCallMatcher, + this); auto ConstTypeParmMatcher = qualType(references(isConstQualified())).bind("invocation-parm-type"); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 5d5aecd67b2d7..7092d0b6fdb02 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -387,6 +387,10 @@ Changes in existing checks - Improved :doc:`modernize-use-using ` check by adding support for detection of typedefs declared on function level. +- Improved :doc:`performance-move-const-arg + ` check by ignoring + ``std::move()`` calls when their target is used as an rvalue. + - Improved :doc:`performance-unnecessary-copy-initialization ` check by detecting more cases of constant access. In particular, pointers can be diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/move-const-arg.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/move-const-arg.cpp index 4d90c124ad72c..4505eef6df24b 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/performance/move-const-arg.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance/move-const-arg.cpp @@ -114,14 +114,18 @@ void f8() { int f9() { return M2(1); } template -T f10(const int x10) { +T f_unknown_target(const int x10) { return std::move(x10); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: std::move of the const variable 'x10' of the trivially-copyable type 'const int' has no effect; remove std::move() [performance-move-const-arg] - // CHECK-FIXES: return x10; } + void f11() { - f10(1); - f10(1); + f_unknown_target(1); + f_unknown_target(1); +} + +A&& f_return_right_ref() { + static A a{}; + return std::move(a); } class NoMoveSemantics { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy]fix false positives of the result of std::move() is used as rvalue for performance-move-const-arg (PR #95633)
https://github.com/HerrCai0907 closed https://github.com/llvm/llvm-project/pull/95633 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3e8f217 - [clang][Interp][NFC] Handle AddressSpaceConversion casts
Author: Timm Bäder Date: 2024-06-15T15:12:35+02:00 New Revision: 3e8f2170bb7772abdc6215de0dc07c3f9bd51df5 URL: https://github.com/llvm/llvm-project/commit/3e8f2170bb7772abdc6215de0dc07c3f9bd51df5 DIFF: https://github.com/llvm/llvm-project/commit/3e8f2170bb7772abdc6215de0dc07c3f9bd51df5.diff LOG: [clang][Interp][NFC] Handle AddressSpaceConversion casts Ignore them. No test yet, but this will be useful in a future commit. 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 300c013d15da8..13a68f3d05f6a 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -311,6 +311,7 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { case CK_NonAtomicToAtomic: case CK_NoOp: case CK_UserDefinedConversion: + case CK_AddressSpaceConversion: return this->delegate(SubExpr); case CK_BitCast: { ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 8e95454 - [clang][Interp] Support ExtVectorElementExprs
Author: Timm Bäder Date: 2024-06-15T15:12:36+02:00 New Revision: 8e954541581270c497cc961b08eff69dc41bc18d URL: https://github.com/llvm/llvm-project/commit/8e954541581270c497cc961b08eff69dc41bc18d DIFF: https://github.com/llvm/llvm-project/commit/8e954541581270c497cc961b08eff69dc41bc18d.diff LOG: [clang][Interp] Support ExtVectorElementExprs Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/ByteCodeExprGen.h clang/test/AST/Interp/vectors.cpp clang/test/CodeGenOpenCLCXX/constexpr.clcpp Removed: diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 13a68f3d05f6a..e61c0a70a0d8a 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -2735,6 +2735,65 @@ bool ByteCodeExprGen::VisitShuffleVectorExpr( return true; } +template +bool ByteCodeExprGen::VisitExtVectorElementExpr( +const ExtVectorElementExpr *E) { + const Expr *Base = E->getBase(); + + SmallVector Indices; + E->getEncodedElementAccess(Indices); + + if (Indices.size() == 1) { +if (!this->visit(Base)) + return false; + +if (E->isGLValue()) { + if (!this->emitConstUint32(Indices[0], E)) +return false; + return this->emitArrayElemPtrPop(PT_Uint32, E); +} +// Else, also load the value. +return this->emitArrayElemPop(classifyPrim(E->getType()), Indices[0], E); + } + + // Create a local variable for the base. + unsigned BaseOffset = allocateLocalPrimitive(Base, PT_Ptr, /*IsConst=*/true, + /*IsExtended=*/false); + if (!this->visit(Base)) +return false; + if (!this->emitSetLocal(PT_Ptr, BaseOffset, E)) +return false; + + // Now the vector variable for the return value. + if (!Initializing) { +std::optional ResultIndex; +ResultIndex = allocateLocal(E); +if (!ResultIndex) + return false; +if (!this->emitGetPtrLocal(*ResultIndex, E)) + return false; + } + + assert(Indices.size() == E->getType()->getAs()->getNumElements()); + + PrimType ElemT = + classifyPrim(E->getType()->getAs()->getElementType()); + uint32_t DstIndex = 0; + for (uint32_t I : Indices) { +if (!this->emitGetLocal(PT_Ptr, BaseOffset, E)) + return false; +if (!this->emitArrayElemPop(ElemT, I, E)) + return false; +if (!this->emitInitElem(ElemT, DstIndex, E)) + return false; +++DstIndex; + } + + // Leave the result pointer on the stack. + assert(!DiscardResult); + return true; +} + template bool ByteCodeExprGen::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) { if (!E->isExpressibleAsConstantInitializer()) diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index 7bb5304cac71e..b0faac8020fb2 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -128,6 +128,7 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, bool VisitAddrLabelExpr(const AddrLabelExpr *E); bool VisitConvertVectorExpr(const ConvertVectorExpr *E); bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E); + bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E); bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E); protected: diff --git a/clang/test/AST/Interp/vectors.cpp b/clang/test/AST/Interp/vectors.cpp index 1e0d473cbca5a..61c400b57b3f8 100644 --- a/clang/test/AST/Interp/vectors.cpp +++ b/clang/test/AST/Interp/vectors.cpp @@ -70,3 +70,14 @@ namespace BoolToSignedIntegralCast{ static_assert(intsT[2] == -1, "");// ref-error {{not an integral constant expression}} static_assert(intsT[3] == -1, "");// ref-error {{not an integral constant expression}} } + +namespace VectorElementExpr { + typedef int int2 __attribute__((ext_vector_type(2))); + typedef int int4 __attribute__((ext_vector_type(4))); + constexpr int oneElt = int4(3).x; + static_assert(oneElt == 3); + + constexpr int2 twoElts = ((int4){11, 22, 33, 44}).yz; + static_assert(twoElts.x == 22, ""); // ref-error {{not an integral constant expression}} + static_assert(twoElts.y == 33, ""); // ref-error {{not an integral constant expression}} +} diff --git a/clang/test/CodeGenOpenCLCXX/constexpr.clcpp b/clang/test/CodeGenOpenCLCXX/constexpr.clcpp index 0576418c944ba..5de7106fe5417 100644 --- a/clang/test/CodeGenOpenCLCXX/constexpr.clcpp +++ b/clang/test/CodeGenOpenCLCXX/constexpr.clcpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -triple spir-unknown-unknown -O0 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple spir-unknown-unknown -O0 -emit-llvm -o - -fexperimental-new-constant-interpreter | FileCheck %s typedef int int2 __attribute__((ext_vector_type(2))); typedef int int4 __attribute__((ext_vector_type(4))); ___ cfe-commits mailing list cfe-commits@
[clang-tools-extra] Enforce SL.con.3: Add check to replace operator[] with at() [Cont.] (PR #95220)
Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= Message-ID: In-Reply-To: https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/95220 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Enforce SL.con.3: Add check to replace operator[] with at() [Cont.] (PR #95220)
Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= Message-ID: In-Reply-To: @@ -0,0 +1,123 @@ +//===--- PreferAtOverSubscriptOperatorCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "PreferAtOverSubscriptOperatorCheck.h" +#include "../utils/OptionsUtils.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "llvm/ADT/StringRef.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::cppcoreguidelines { + +static constexpr std::array DefaultExclusions = { +llvm::StringRef("std::map"), llvm::StringRef("std::unordered_map"), +llvm::StringRef("std::flat_map")}; + +PreferAtOverSubscriptOperatorCheck::PreferAtOverSubscriptOperatorCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context) { + + ExcludedClasses = clang::tidy::utils::options::parseStringList( + Options.get("ExcludeClasses", "")); + ExcludedClasses.insert(ExcludedClasses.end(), DefaultExclusions.begin(), + DefaultExclusions.end()); +} + +void PreferAtOverSubscriptOperatorCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + + if (ExcludedClasses.size() == DefaultExclusions.size()) { +Options.store(Opts, "ExcludeClasses", ""); +return; + } + + // Sum up the sizes of the defaults ( + semicolons), so we can remove them + // from the saved options + size_t DefaultsStringLength = + std::transform_reduce(DefaultExclusions.begin(), DefaultExclusions.end(), +DefaultExclusions.size(), std::plus<>(), +[](llvm::StringRef Name) { return Name.size(); }); + + std::string Serialized = + clang::tidy::utils::options::serializeStringList(ExcludedClasses); + + Options.store(Opts, "ExcludeClasses", +Serialized.substr(0, Serialized.size() - DefaultsStringLength)); +} + +const CXXMethodDecl *findAlternative(const CXXRecordDecl *MatchedParent, + const CXXMethodDecl *MatchedOperator) { + for (const CXXMethodDecl *Method : MatchedParent->methods()) { +const bool CorrectName = Method->getNameInfo().getAsString() == "at"; +if (!CorrectName) + continue; + +const bool SameReturnType = +Method->getReturnType() == MatchedOperator->getReturnType(); +if (!SameReturnType) + continue; + +const bool SameNumberOfArguments = +Method->getNumParams() == MatchedOperator->getNumParams(); +if (!SameNumberOfArguments) + continue; + +for (unsigned ArgInd = 0; ArgInd < Method->getNumParams(); ArgInd++) { + const bool SameArgType = + Method->parameters()[ArgInd]->getOriginalType() == + MatchedOperator->parameters()[ArgInd]->getOriginalType(); + if (!SameArgType) +continue; +} + +return Method; + } + return static_cast(nullptr); +} + +void PreferAtOverSubscriptOperatorCheck::registerMatchers(MatchFinder *Finder) { + // Need a callExpr here to match CXXOperatorCallExpr ``(&a)->operator[](0)`` + // and CXXMemberCallExpr ``a[0]``. + Finder->addMatcher( + callExpr( + callee( + cxxMethodDecl(hasOverloadedOperatorName("[]")).bind("operator")), + callee(cxxMethodDecl(hasParent( 5chmidti wrote: `hasParent` -> `ofClass` for better readability https://github.com/llvm/llvm-project/pull/95220 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Enforce SL.con.3: Add check to replace operator[] with at() [Cont.] (PR #95220)
=��___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Enforce SL.con.3: Add check to replace operator[] with at() [Cont.] (PR #95220)
Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= Message-ID: In-Reply-To: @@ -0,0 +1,123 @@ +//===--- PreferAtOverSubscriptOperatorCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "PreferAtOverSubscriptOperatorCheck.h" +#include "../utils/OptionsUtils.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "llvm/ADT/StringRef.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::cppcoreguidelines { + +static constexpr std::array DefaultExclusions = { +llvm::StringRef("std::map"), llvm::StringRef("std::unordered_map"), +llvm::StringRef("std::flat_map")}; + +PreferAtOverSubscriptOperatorCheck::PreferAtOverSubscriptOperatorCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context) { + + ExcludedClasses = clang::tidy::utils::options::parseStringList( + Options.get("ExcludeClasses", "")); + ExcludedClasses.insert(ExcludedClasses.end(), DefaultExclusions.begin(), + DefaultExclusions.end()); +} + +void PreferAtOverSubscriptOperatorCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + + if (ExcludedClasses.size() == DefaultExclusions.size()) { +Options.store(Opts, "ExcludeClasses", ""); +return; + } + + // Sum up the sizes of the defaults ( + semicolons), so we can remove them + // from the saved options + size_t DefaultsStringLength = + std::transform_reduce(DefaultExclusions.begin(), DefaultExclusions.end(), +DefaultExclusions.size(), std::plus<>(), +[](llvm::StringRef Name) { return Name.size(); }); + + std::string Serialized = + clang::tidy::utils::options::serializeStringList(ExcludedClasses); + + Options.store(Opts, "ExcludeClasses", +Serialized.substr(0, Serialized.size() - DefaultsStringLength)); +} + +const CXXMethodDecl *findAlternative(const CXXRecordDecl *MatchedParent, + const CXXMethodDecl *MatchedOperator) { + for (const CXXMethodDecl *Method : MatchedParent->methods()) { +const bool CorrectName = Method->getNameInfo().getAsString() == "at"; +if (!CorrectName) + continue; + +const bool SameReturnType = +Method->getReturnType() == MatchedOperator->getReturnType(); +if (!SameReturnType) + continue; + +const bool SameNumberOfArguments = +Method->getNumParams() == MatchedOperator->getNumParams(); +if (!SameNumberOfArguments) + continue; + +for (unsigned ArgInd = 0; ArgInd < Method->getNumParams(); ArgInd++) { + const bool SameArgType = + Method->parameters()[ArgInd]->getOriginalType() == + MatchedOperator->parameters()[ArgInd]->getOriginalType(); + if (!SameArgType) +continue; +} + +return Method; + } + return static_cast(nullptr); +} + +void PreferAtOverSubscriptOperatorCheck::registerMatchers(MatchFinder *Finder) { + // Need a callExpr here to match CXXOperatorCallExpr ``(&a)->operator[](0)`` + // and CXXMemberCallExpr ``a[0]``. + Finder->addMatcher( + callExpr( + callee( + cxxMethodDecl(hasOverloadedOperatorName("[]")).bind("operator")), + callee(cxxMethodDecl(hasParent( + cxxRecordDecl(hasMethod(hasName("at"))).bind("parent") + .bind("caller"), + this); +} + +void PreferAtOverSubscriptOperatorCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *MatchedExpr = Result.Nodes.getNodeAs("caller"); + const auto *MatchedOperator = + Result.Nodes.getNodeAs("operator"); + const auto *MatchedParent = Result.Nodes.getNodeAs("parent"); + + std::string ClassIdentifier = MatchedParent->getQualifiedNameAsString(); + + if (std::find(ExcludedClasses.begin(), ExcludedClasses.end(), +ClassIdentifier) != ExcludedClasses.end()) +return; + + const CXXMethodDecl *Alternative = + findAlternative(MatchedParent, MatchedOperator); + if (!Alternative) +return; + + diag(MatchedExpr->getBeginLoc(), + "found possibly unsafe operator[], consider using at() instead"); + diag(Alternative->getBeginLoc(), "alternative at() defined here", + DiagnosticIDs::Note); 5chmidti wrote: Please add `<< MatchedExpr->getSourceRange()` and `<< Alternative->getSourceRange()` respectively to each diagnostic, so that ``` pairs[i];
[clang-tools-extra] Enforce SL.con.3: Add check to replace operator[] with at() [Cont.] (PR #95220)
Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= Message-ID: In-Reply-To: @@ -0,0 +1,40 @@ +//===--- PreferAtOverSubscriptOperatorCheck.h - clang-tidy --*- C++ -*-===// +//===--- PreferMemberInitializerCheck.h - clang-tidy *- 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_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PREFERATOVERSUBSCRIPTOPERATORCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PREFERATOVERSUBSCRIPTOPERATORCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::cppcoreguidelines { + +/// Enforce CPP core guidelines SL.con.3 5chmidti wrote: -> `C++ Core Guidelines` I'd say `Implements` instead of `Enforce`, but thats just a thought. This sentence should be the same as the release note and the first sentence of the check description. https://github.com/llvm/llvm-project/pull/95220 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Enforce SL.con.3: Add check to replace operator[] with at() [Cont.] (PR #95220)
Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= Message-ID: In-Reply-To: @@ -0,0 +1,142 @@ +namespace std { + template + struct array { +T operator[](unsigned i) { + return T{1}; +} +T at(unsigned i) { + return T{1}; +} + }; + + template + struct map { +T operator[](unsigned i) { + return T{1}; +} +T at(unsigned i) { + return T{1}; +} + }; + + template + struct unique_ptr { +T operator[](unsigned i) { + return T{1}; +} + }; + + template + struct span { +T operator[](unsigned i) { + return T{1}; +} + }; +} // namespace std + +namespace json { + template + struct node{ +T operator[](unsigned i) { + return T{1}; +} + }; +} // namespace json + +struct SubClass : std::array {}; + +class ExcludedClass1 { + public: +int operator[](unsigned i) { + return 1; +} +int at(unsigned i) { + return 1; +} +}; + +class ExcludedClass2 { + public: +int operator[](unsigned i) { + return 1; +} +int at(unsigned i) { + return 1; +} +}; + + +// RUN: %check_clang_tidy %s \ +// RUN: cppcoreguidelines-prefer-at-over-subscript-operator %t -- \ +// RUN: -config='{CheckOptions: {cppcoreguidelines-prefer-at-over-subscript-operator.ExcludeClasses: "ExcludedClass1;ExcludedClass2"}}' 5chmidti wrote: `RUN` lines should be at the top of the file https://github.com/llvm/llvm-project/pull/95220 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Enforce SL.con.3: Add check to replace operator[] with at() [Cont.] (PR #95220)
Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= Message-ID: In-Reply-To: https://github.com/5chmidti requested changes to this pull request. I also don't think the check should propose using `at()`. The rule suggests using `span`, `at()`, `range-for`, `begin(),end()` or algorithms instead of accessing elements in a container with an unchecked-bounds function. @carlosgalvezp with `AvoidSubscriptOperator` we constrain the check to be about subscript access only, which, admittedly, the check currently is. However, the rule is not constrained to subscript access and the rule has an example with `memset` which does not use the subscript operator. `AvoidBoundErrors` sounds a little bit too broad IMO, because the rule talks about containers and is in the SL containers section. What about: `cppcoreguidelines-(avoid-)container-unchecked-bounds(-access)` or `cppcoreguidelines-(avoid-)container-bounds-errors`? I specifically added `container` to both names because the check is in `SL.con`. --- > We are not sure what the best behaviour for templates is > keep the warning and add the name of the class of the object / the template > parameters that lead to the message This may result in a lot of warnings because every diagnostic to the same location will no longer be combined like it is now, and instead we get `N` diagnostics (given `N` instantiations). On the other hand, these warnings would provide context on the type being used, so I think it is better to have that instead of fewer warnings but without the type named. We could ignore instantiations and diagnose any use of `x[]` inside template declarations. We can then check, if possible, if the type of `x` is known to be excluded (e.g., normal type if it is not a dependent type, or `TemplateSpecializationType`). --- > I think clang-tidy could offer an enum option for the fix +1 That would be a good way to accommodate projects that prefer `at()`, because it requires the project to choose to go with this way of solving it (off-by-default). --- > disabling the check when exceptions are disabled That would only apply if the check (is enabled to) proposes to use `at()`. https://github.com/llvm/llvm-project/pull/95220 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Enforce SL.con.3: Add check to replace operator[] with at() [Cont.] (PR #95220)
Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= , Paul =?utf-8?q?Heidekrüger?= Message-ID: In-Reply-To: @@ -0,0 +1,123 @@ +//===--- PreferAtOverSubscriptOperatorCheck.cpp - clang-tidy --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "PreferAtOverSubscriptOperatorCheck.h" +#include "../utils/OptionsUtils.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "llvm/ADT/StringRef.h" +#include +#include + +using namespace clang::ast_matchers; + +namespace clang::tidy::cppcoreguidelines { + +static constexpr std::array DefaultExclusions = { +llvm::StringRef("std::map"), llvm::StringRef("std::unordered_map"), +llvm::StringRef("std::flat_map")}; + +PreferAtOverSubscriptOperatorCheck::PreferAtOverSubscriptOperatorCheck( +StringRef Name, ClangTidyContext *Context) +: ClangTidyCheck(Name, Context) { + + ExcludedClasses = clang::tidy::utils::options::parseStringList( + Options.get("ExcludeClasses", "")); + ExcludedClasses.insert(ExcludedClasses.end(), DefaultExclusions.begin(), + DefaultExclusions.end()); +} + +void PreferAtOverSubscriptOperatorCheck::storeOptions( +ClangTidyOptions::OptionMap &Opts) { + + if (ExcludedClasses.size() == DefaultExclusions.size()) { +Options.store(Opts, "ExcludeClasses", ""); +return; + } + + // Sum up the sizes of the defaults ( + semicolons), so we can remove them + // from the saved options + size_t DefaultsStringLength = + std::transform_reduce(DefaultExclusions.begin(), DefaultExclusions.end(), +DefaultExclusions.size(), std::plus<>(), +[](llvm::StringRef Name) { return Name.size(); }); + + std::string Serialized = + clang::tidy::utils::options::serializeStringList(ExcludedClasses); + + Options.store(Opts, "ExcludeClasses", +Serialized.substr(0, Serialized.size() - DefaultsStringLength)); +} + +const CXXMethodDecl *findAlternative(const CXXRecordDecl *MatchedParent, + const CXXMethodDecl *MatchedOperator) { + for (const CXXMethodDecl *Method : MatchedParent->methods()) { +const bool CorrectName = Method->getNameInfo().getAsString() == "at"; +if (!CorrectName) + continue; + +const bool SameReturnType = +Method->getReturnType() == MatchedOperator->getReturnType(); +if (!SameReturnType) + continue; + +const bool SameNumberOfArguments = +Method->getNumParams() == MatchedOperator->getNumParams(); +if (!SameNumberOfArguments) + continue; + +for (unsigned ArgInd = 0; ArgInd < Method->getNumParams(); ArgInd++) { + const bool SameArgType = + Method->parameters()[ArgInd]->getOriginalType() == + MatchedOperator->parameters()[ArgInd]->getOriginalType(); + if (!SameArgType) +continue; +} + +return Method; + } + return static_cast(nullptr); +} + +void PreferAtOverSubscriptOperatorCheck::registerMatchers(MatchFinder *Finder) { + // Need a callExpr here to match CXXOperatorCallExpr ``(&a)->operator[](0)`` + // and CXXMemberCallExpr ``a[0]``. + Finder->addMatcher( + callExpr( + callee( + cxxMethodDecl(hasOverloadedOperatorName("[]")).bind("operator")), + callee(cxxMethodDecl(hasParent( + cxxRecordDecl(hasMethod(hasName("at"))).bind("parent") + .bind("caller"), + this); +} + +void PreferAtOverSubscriptOperatorCheck::check( +const MatchFinder::MatchResult &Result) { + const auto *MatchedExpr = Result.Nodes.getNodeAs("caller"); + const auto *MatchedOperator = + Result.Nodes.getNodeAs("operator"); + const auto *MatchedParent = Result.Nodes.getNodeAs("parent"); + + std::string ClassIdentifier = MatchedParent->getQualifiedNameAsString(); + + if (std::find(ExcludedClasses.begin(), ExcludedClasses.end(), +ClassIdentifier) != ExcludedClasses.end()) +return; 5chmidti wrote: Prefer adding `matchers::matchesAnyListedName` from `clang-tools-extra/clang-tidy/utils/Matchers.h` to your matcher, instead of manually checking it like this (requires adding `::` in front of the exclusions in your test file, and other exclusions are prefixed as well (`map`, ...): https://github.com/llvm/llvm-project/blob/47f8b85b3d81ed3578cb3b8f80d69ce307e0c883/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringviewDataUsageCheck.cpp#L23). https://github.com/llvm/llvm-project/blob/47f8b85b3d81ed3578cb3b8f80d69ce307e0c883/clang-
[clang-tools-extra] [clang-tidy] Option to ignore anonymous namespaces in avoid-non-const-global-variables (PR #93827)
https://github.com/HerrCai0907 approved this pull request. https://github.com/llvm/llvm-project/pull/93827 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Instantiate local constexpr functions eagerly (PR #95660)
https://github.com/zyn0217 ready_for_review https://github.com/llvm/llvm-project/pull/95660 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Instantiate local constexpr functions eagerly (PR #95660)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Younan Zhang (zyn0217) Changes We had a code path in `Sema::MarkFunctionReferenced()` that deferred local lambda instantiation even for constexprs. This resulted in any calls to them referring to function decls that lack bodies and hence failures at constant evaluation. The issue doesn't occur when the lambda has no explicit return type because the return type deduction requires instantiation. Fixes https://github.com/llvm/llvm-project/issues/35052 Fixes https://github.com/llvm/llvm-project/issues/94849 --- Full diff: https://github.com/llvm/llvm-project/pull/95660.diff 3 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+1) - (modified) clang/lib/Sema/SemaExpr.cpp (+2-1) - (modified) clang/test/SemaTemplate/instantiate-local-class.cpp (+24) ``diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 8c2f737836a9d..a424554ed821d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -847,6 +847,7 @@ Bug Fixes to C++ Support - Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307), (#GH88081), (#GH89496), (#GH90669) and (#GH91633). - Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368). +- Clang now instantiates local constexpr functions eagerly for constant evaluators. (#GH35052), (#GH94849) Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 99a8704298314..88e9b2b00f84d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -18112,7 +18112,8 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, if (FirstInstantiation || TSK != TSK_ImplicitInstantiation || Func->isConstexpr()) { - if (isa(Func->getDeclContext()) && + if (!Func->isConstexpr() && + isa(Func->getDeclContext()) && cast(Func->getDeclContext())->isLocalClass() && CodeSynthesisContexts.size()) PendingLocalImplicitInstantiations.push_back( diff --git a/clang/test/SemaTemplate/instantiate-local-class.cpp b/clang/test/SemaTemplate/instantiate-local-class.cpp index 47591045fd26e..7eee131e28d60 100644 --- a/clang/test/SemaTemplate/instantiate-local-class.cpp +++ b/clang/test/SemaTemplate/instantiate-local-class.cpp @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -verify -std=c++11 %s // RUN: %clang_cc1 -verify -std=c++11 -fdelayed-template-parsing %s +// RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s template void f0() { @@ -509,3 +510,26 @@ namespace LambdaInDefaultMemberInitializer { } template void f(); } + +#if __cplusplus >= 201703L +namespace GH35052 { + +template constexpr int func(F f) { + if constexpr (f(1UL)) { +return 1; + } + return 0; +} + +int main() { + auto predicate = [](auto v) /*implicit constexpr*/ -> bool { +return v == 1; + }; + + static_assert(predicate(1)); + return func(predicate); +} + +} // namespace GH35052 + +#endif `` https://github.com/llvm/llvm-project/pull/95660 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [libclang/python] Refactor enum usage (PR #95608)
https://github.com/DeinAlptraum edited https://github.com/llvm/llvm-project/pull/95608 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][modules] HeaderSearch::MarkFileModuleHeader sets textual headers' HeaderFileInfo non-external when it shouldn't (PR #89005)
ian-twilightcoder wrote: The only error is in CodeGen/PowerPC/subreg-lanemasks.mir and doesn't look related to this change. https://github.com/llvm/llvm-project/pull/89005 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 29b0d57 - [clang][modules] HeaderSearch::MarkFileModuleHeader sets textual headers' HeaderFileInfo non-external when it shouldn't (#89005)
Author: Ian Anderson Date: 2024-06-15T07:41:58-07:00 New Revision: 29b0d5755409639cf061667233125fb75d624b7c URL: https://github.com/llvm/llvm-project/commit/29b0d5755409639cf061667233125fb75d624b7c DIFF: https://github.com/llvm/llvm-project/commit/29b0d5755409639cf061667233125fb75d624b7c.diff LOG: [clang][modules] HeaderSearch::MarkFileModuleHeader sets textual headers' HeaderFileInfo non-external when it shouldn't (#89005) HeaderSearch::MarkFileModuleHeader is no longer properly checking for no-changes, and so sets the HeaderFileInfo for every `textual header` to non-external. Added: Modified: clang/include/clang/Lex/HeaderSearch.h clang/lib/Lex/HeaderSearch.cpp clang/unittests/Lex/HeaderSearchTest.cpp Removed: diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h index 5ac634d4e..d8ca1c528de36 100644 --- a/clang/include/clang/Lex/HeaderSearch.h +++ b/clang/include/clang/Lex/HeaderSearch.h @@ -90,7 +90,9 @@ struct HeaderFileInfo { LLVM_PREFERRED_TYPE(bool) unsigned isModuleHeader : 1; - /// Whether this header is a `textual header` in a module. + /// Whether this header is a `textual header` in a module. If a header is + /// textual in one module and normal in another module, this bit will not be + /// set, only `isModuleHeader`. LLVM_PREFERRED_TYPE(bool) unsigned isTextualModuleHeader : 1; diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp index d6da6c2fe6c0e..9321a36b79a7f 100644 --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -1313,11 +1313,18 @@ OptionalFileEntryRef HeaderSearch::LookupSubframeworkHeader( // File Info Management. //===--===// +static bool moduleMembershipNeedsMerge(const HeaderFileInfo *HFI, + ModuleMap::ModuleHeaderRole Role) { + if (ModuleMap::isModular(Role)) +return !HFI->isModuleHeader || HFI->isTextualModuleHeader; + if (!HFI->isModuleHeader && (Role & ModuleMap::TextualHeader)) +return !HFI->isTextualModuleHeader; + return false; +} + static void mergeHeaderFileInfoModuleBits(HeaderFileInfo &HFI, bool isModuleHeader, bool isTextualModuleHeader) { - assert((!isModuleHeader || !isTextualModuleHeader) && - "A header can't build with a module and be textual at the same time"); HFI.isModuleHeader |= isModuleHeader; if (HFI.isModuleHeader) HFI.isTextualModuleHeader = false; @@ -1432,7 +1439,7 @@ void HeaderSearch::MarkFileModuleHeader(FileEntryRef FE, if ((Role & ModuleMap::ExcludedHeader)) return; auto *HFI = getExistingFileInfo(FE); -if (HFI && HFI->isModuleHeader) +if (HFI && !moduleMembershipNeedsMerge(HFI, Role)) return; } diff --git a/clang/unittests/Lex/HeaderSearchTest.cpp b/clang/unittests/Lex/HeaderSearchTest.cpp index a5f193ef37ce8..38ce3812c204f 100644 --- a/clang/unittests/Lex/HeaderSearchTest.cpp +++ b/clang/unittests/Lex/HeaderSearchTest.cpp @@ -323,5 +323,73 @@ TEST_F(HeaderSearchTest, HeaderMapFrameworkLookup) { EXPECT_EQ(Search.getIncludeNameForHeader(FE), "Foo/Foo.h"); } +TEST_F(HeaderSearchTest, HeaderFileInfoMerge) { + auto AddHeader = [&](std::string HeaderPath) -> FileEntryRef { +VFS->addFile(HeaderPath, 0, + llvm::MemoryBuffer::getMemBufferCopy("", HeaderPath), + /*User=*/std::nullopt, /*Group=*/std::nullopt, + llvm::sys::fs::file_type::regular_file); +return *FileMgr.getOptionalFileRef(HeaderPath); + }; + + class MockExternalHeaderFileInfoSource : public ExternalHeaderFileInfoSource { +HeaderFileInfo GetHeaderFileInfo(FileEntryRef FE) { + HeaderFileInfo HFI; + auto FileName = FE.getName(); + if (FileName == ModularPath) +HFI.mergeModuleMembership(ModuleMap::NormalHeader); + else if (FileName == TextualPath) +HFI.mergeModuleMembership(ModuleMap::TextualHeader); + HFI.External = true; + HFI.IsValid = true; + return HFI; +} + + public: +std::string ModularPath = "/modular.h"; +std::string TextualPath = "/textual.h"; + }; + + auto ExternalSource = new MockExternalHeaderFileInfoSource(); + Search.SetExternalSource(ExternalSource); + + // Everything should start out external. + auto ModularFE = AddHeader(ExternalSource->ModularPath); + auto TextualFE = AddHeader(ExternalSource->TextualPath); + EXPECT_TRUE(Search.getExistingFileInfo(ModularFE)->External); + EXPECT_TRUE(Search.getExistingFileInfo(TextualFE)->External); + + // Marking the same role should keep it external + Search.MarkFileModuleHeader(ModularFE, ModuleMap::NormalHeader, + /*isCompilingModuleHeader=*/false); + Search.MarkFileModule
[clang] [clang][modules] HeaderSearch::MarkFileModuleHeader sets textual headers' HeaderFileInfo non-external when it shouldn't (PR #89005)
https://github.com/ian-twilightcoder closed https://github.com/llvm/llvm-project/pull/89005 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [run-clang-tidy.py] Refactor, add progress indicator, add type hints (PR #89490)
https://github.com/5chmidti commented: The execution time of clang-tidy is a nice improvement as well. --- > What OS/Python version does this occur on? |OS|Python|Noisy Shutdown| |-|-|-| |Manjaro|3.11.9|Yes| |NixOS|3.9.19|No| |NixOS|3.10.14|No| |NixOS|3.11.9|No| |Manjaro|3.12.3|Yes| |Manjaro|3.13.0b2|Yes| https://github.com/llvm/llvm-project/pull/89490 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [run-clang-tidy.py] Refactor, add progress indicator, add type hints (PR #89490)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/89490 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [run-clang-tidy.py] Refactor, add progress indicator, add type hints (PR #89490)
@@ -501,70 +506,72 @@ def main(): # Build up a big regexy filter from all command line arguments. file_name_re = re.compile("|".join(args.files)) +files = {f for f in files if file_name_re.search(f)} -return_code = 0 +returncode = 0 try: -# Spin up a bunch of tidy-launching threads. -task_queue = queue.Queue(max_task) -# List of files with a non-zero return code. -failed_files = [] -lock = threading.Lock() -for _ in range(max_task): -t = threading.Thread( -target=run_tidy, -args=( -args, -clang_tidy_binary, -export_fixes_dir, -build_path, -task_queue, -lock, -failed_files, -), +semaphore = asyncio.Semaphore(max_task) +tasks = [ +run_with_semaphore( +semaphore, +run_tidy, +args, +f, +clang_tidy_binary, +export_fixes_dir, +build_path, ) -t.daemon = True -t.start() - -# Fill the queue with files. -for name in files: -if file_name_re.search(name): -task_queue.put(name) - -# Wait for all threads to be done. -task_queue.join() -if len(failed_files): -return_code = 1 - +for f in files +] + +for i, coro in enumerate(asyncio.as_completed(tasks)): +name, process_returncode, stdout, stderr = await coro +if process_returncode != 0: +returncode = 1 +if process_returncode < 0: +stderr += f"{name}: terminated by signal {-process_returncode}\n" +print(f"[{i + 1}/{len(files)}] {name}") +if stdout: +print(stdout) +if stderr: +print(stderr, file=sys.stderr) except KeyboardInterrupt: # This is a sad hack. Unfortunately subprocess goes # bonkers with ctrl-c and we start forking merrily. print("\nCtrl-C detected, goodbye.") if delete_fixes_dir: +assert export_fixes_dir shutil.rmtree(export_fixes_dir) os.kill(0, 9) if combine_fixes: -print("Writing fixes to " + args.export_fixes + " ...") +print(f"Writing fixes to {args.export_fixes} ...") try: +assert export_fixes_dir merge_replacement_files(export_fixes_dir, args.export_fixes) except: print("Error exporting fixes.\n", file=sys.stderr) traceback.print_exc() -return_code = 1 +returncode = 1 if args.fix: print("Applying fixes ...") try: +assert export_fixes_dir apply_fixes(args, clang_apply_replacements_binary, export_fixes_dir) except: print("Error applying fixes.\n", file=sys.stderr) traceback.print_exc() -return_code = 1 +returncode = 1 if delete_fixes_dir: +assert export_fixes_dir shutil.rmtree(export_fixes_dir) -sys.exit(return_code) +sys.exit(returncode) if __name__ == "__main__": -main() +# FIXME Python 3.7: This can be simplified by asyncio.run(main()). +loop = asyncio.new_event_loop() +loop.run_until_complete(main()) +loop.close() 5chmidti wrote: Sure, but why does `main` need to be `async` at all? I.e. ```python async def main(): pass if __name__ == "__main__": # FIXME Python 3.7: This can be simplified by asyncio.run(main()). loop = asyncio.new_event_loop() loop.run_until_complete(main()) loop.close() ``` vs. ```python def main(): pass if __name__ == "__main__": main() ``` https://github.com/llvm/llvm-project/pull/89490 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [run-clang-tidy.py] Refactor, add progress indicator, add type hints (PR #89490)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/89490 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Driver] Expose `-fno-eliminate-unused-debug-types` to clang-cl (PR #95259)
https://github.com/aganea edited https://github.com/llvm/llvm-project/pull/95259 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Driver] Expose `-fno-eliminate-unused-debug-types` to clang-cl (PR #95259)
aganea wrote: Thanks @amykhuang for taking a look! I won't close https://github.com/llvm/llvm-project/issues/46924 right away, since we also need https://reviews.llvm.org/D89286. Do you mind if I took ownership of that patch and send a PR crediting you? https://github.com/llvm/llvm-project/pull/95259 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 7cb5faf - [Clang][Driver] Expose `-fno-eliminate-unused-debug-types` to clang-cl (#95259)
Author: Alexandre Ganea Date: 2024-06-15T11:33:44-04:00 New Revision: 7cb5faf6da5a6f6335aca8a2532e5320ec434458 URL: https://github.com/llvm/llvm-project/commit/7cb5faf6da5a6f6335aca8a2532e5320ec434458 DIFF: https://github.com/llvm/llvm-project/commit/7cb5faf6da5a6f6335aca8a2532e5320ec434458.diff LOG: [Clang][Driver] Expose `-fno-eliminate-unused-debug-types` to clang-cl (#95259) This is used to set DebugInfoKind to "UnusedTypeInfo". This helps in the context of Unreal Engine and NATVIS files that reference unused otherwise `static constexpr` class members. See https://udn.unrealengine.com/s/question/0D5QP0N012h0AB/fname-debug-visualizer-fails-to-work-with-the-clang-compiler This partially fixes https://github.com/llvm/llvm-project/issues/46924 Added: Modified: clang/docs/UsersManual.rst clang/include/clang/Driver/Options.td clang/test/Driver/cl-options.c Removed: diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 8e01ea15064ba..d273102fe9000 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -3347,6 +3347,9 @@ below. If multiple flags are present, the last one is used. By default, Clang does not emit type information for types that are defined but not used in a program. To retain the debug info for these unused types, the negation **-fno-eliminate-unused-debug-types** can be used. + This can be particulary useful on Windows, when using NATVIS files that + can reference const symbols that would otherwise be stripped, even in full + debug or standalone debug modes. Controlling Macro Debug Info Generation ^^^ diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 4ab8638175dd3..15f62c5c1a6ab 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2122,7 +2122,7 @@ def fno_elide_type : Flag<["-"], "fno-elide-type">, Group, MarshallingInfoNegativeFlag>; def feliminate_unused_debug_symbols : Flag<["-"], "feliminate-unused-debug-symbols">, Group; defm eliminate_unused_debug_types : OptOutCC1FFlag<"eliminate-unused-debug-types", - "Do not emit ", "Emit ", " debug info for defined but unused types">; + "Do not emit ", "Emit ", " debug info for defined but unused types", [ClangOption, CLOption]>; def femit_all_decls : Flag<["-"], "femit-all-decls">, Group, Visibility<[ClangOption, CC1Option]>, HelpText<"Emit all declarations, even if unused">, diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c index 95d28e46bc582..a6f338533ad76 100644 --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -698,6 +698,8 @@ // RUN: -Wunused-variable \ // RUN: -fmacro-backtrace-limit=0 \ // RUN: -fstandalone-debug \ +// RUN: -feliminate-unused-debug-types \ +// RUN: -fno-eliminate-unused-debug-types \ // RUN: -flimit-debug-info \ // RUN: -flto \ // RUN: -fmerge-all-constants \ ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Driver] Expose `-fno-eliminate-unused-debug-types` to clang-cl (PR #95259)
https://github.com/aganea closed https://github.com/llvm/llvm-project/pull/95259 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] Support go-to-definition on type hints. The core part (PR #86629)
@@ -1637,6 +1678,144 @@ TEST(TypeHints, SubstTemplateParameterAliases) { ExpectedHint{": static_vector", "vector_name"}); } +template +void assertTypeLinkHints(StringRef Code, StringRef HintRange, + Labels... ExpectedLabels) { + Annotations Source(Code); + auto HintAt = [&](llvm::ArrayRef InlayHints, +llvm::StringRef Range) { +auto *Hint = llvm::find_if(InlayHints, [&](const InlayHint &InlayHint) { + return InlayHint.range == Source.range(Range); +}); +assert(Hint && "No range was found"); +return llvm::ArrayRef(Hint->label); + }; + + TestTU TU = TestTU::withCode(Source.code()); + TU.ExtraArgs.push_back("-std=c++2c"); + auto AST = TU.build(); + + Config C; + C.InlayHints.TypeNameLimit = 0; + WithContextValue WithCfg(Config::Key, std::move(C)); + + auto Hints = hintsOfKind(AST, InlayHintKind::Type); + EXPECT_THAT(HintAt(Hints, HintRange), + ElementsAre(HintLabelPieceMatcher(ExpectedLabels, Source)...)); +} + +TEST(TypeHints, Links) { + StringRef Source(R"cpp( +$Package[[template HighCommander4 wrote: >1. Using `RecordDecl::getBeginLoc()` does work in terms of the protocol, > but this SourceLocation points to the first keyword token of the definition, > i.e., the location of `struct/class`, which doesn't seem acceptable to us. I was thinking of `Decl::getLocation()`, which should point to the location of the declaration's name. https://github.com/llvm/llvm-project/pull/86629 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
@@ -0,0 +1,83 @@ +.. title:: clang-tidy - bugprone-exception-rethrow + +bugprone-exception-rethrow +== + +Identifies problematic exception rethrowing, especially with caught exception +variables or empty throw statements outside catch blocks. + +In C++ exception handling, a common pitfall occurs when developers rethrow +caught exceptions within catch blocks by directly passing the caught exception +variable to the ``throw`` statement. While this approach can propagate +exceptions to higher levels of the program, it often leads to code that is less +clear and more error-prone. Rethrowing caught exceptions with the same exception +object within catch blocks can obscure the original context of the exception and +make it challenging to trace program flow. Additionally, this method can +introduce issues such as exception object slicing and performance overhead due +to the invocation of the copy constructor. + +.. code-block:: c++ + + try { +// Code that may throw an exception + } catch (const std::exception& e) { +throw e; // Bad, 'e' is copied + } + +.. code-block:: c++ + + class derived_exception : public std::exception { ... }; + + void throwDerived() { throw derived_exception{}; } + + try { +throwDerived(); + } catch (const std::exception& e) { +throw e; // Bad, exception slicing occurs when 'derived_exception' is + // being rethrown as 'std::exception' + } + +To prevent these issues, it is advisable to utilize ``throw;`` statements to +rethrow the original exception object for currently handled exceptions. + +.. code-block:: c++ + + try { +// Code that may throw an exception + } catch (const std::exception&) { +throw; // Good + } + +However, when an empty throw statement is used outside a catch block, it +results in a call to ``std::terminate()``, which abruptly terminates the +application. This behavior can lead to the abnormal termination of the +program and is often unintended. Such occurrences may indicate errors or +oversights in the exception handling logic, and it is essential to avoid empty +throw statements outside catch blocks to prevent unintended program termination. + +.. code-block:: c++ + + void foo() { +// std::terminate will be called because there is no exception to rethrow +throw; + } + + int main() { +try { + foo(); +} catch(...) { + return 1; +} +return 0; + } 5chmidti wrote: I don't think the check should figure out if a dangling `throw` inside a function is actually only called from within a `catch` block, as it is IMO an antipattern that obscures error-handling. Immediately-invoked lambdas might be something to think about though. > it often leads to code that is less clear and more error-prone. Rethrowing caught exceptions with the same exception object within catch blocks can obscure the original context of the exception and make it challenging to trace program flow. https://github.com/llvm/llvm-project/pull/86448 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
@@ -0,0 +1,67 @@ +//===--- ExceptionRethrowCheck.cpp - clang-tidy ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ExceptionRethrowCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +void ExceptionRethrowCheck::registerMatchers(MatchFinder *Finder) { + + auto RefToExceptionVariable = declRefExpr(to(varDecl(isExceptionVariable(; + auto StdMoveCall = + callExpr(argumentCountIs(1), callee(functionDecl(hasName("::std::move"))), + hasArgument(0, RefToExceptionVariable)); + auto CopyOrMoveConstruction = cxxConstructExpr( + argumentCountIs(1), + traverse(TK_AsIs, hasDeclaration(cxxConstructorDecl( +anyOf(isCopyConstructor(), isMoveConstructor(), + hasArgument(0, anyOf(RefToExceptionVariable, StdMoveCall))); + + auto HasEmptyThrowExprDescendant = + hasDescendant(cxxThrowExpr(equalsBoundNode("empty-throw"))); + + Finder->addMatcher( + cxxThrowExpr( + unless(isExpansionInSystemHeader()), unless(has(expr())), + expr().bind("empty-throw"), + anyOf(unless(hasAncestor(cxxCatchStmt())), +hasAncestor(cxxCatchStmt(anyOf( +hasDescendant(functionDecl(HasEmptyThrowExprDescendant)), + hasDescendant(lambdaExpr(HasEmptyThrowExprDescendant))), + this); + Finder->addMatcher( + cxxThrowExpr(unless(isExpansionInSystemHeader()), + has(expr(anyOf(RefToExceptionVariable, StdMoveCall, + CopyOrMoveConstruction + .bind("throw"), + this); +} + +void ExceptionRethrowCheck::check(const MatchFinder::MatchResult &Result) { + if (const auto *MatchedThrow = + Result.Nodes.getNodeAs("throw")) { +const Expr *ThrownObject = MatchedThrow->getSubExpr(); +diag(MatchedThrow->getThrowLoc(), + "throwing a copy of the caught %0 exception, remove the argument to " + "throw the original exception object") +<< ThrownObject->getType().getNonReferenceType(); +return; + } + + if (const auto *MatchedEmptyThrow = + Result.Nodes.getNodeAs("empty-throw")) { +diag(MatchedEmptyThrow->getThrowLoc(), + "empty 'throw' outside a catch block triggers 'std::terminate()'"); 5chmidti wrote: Please stream the source ranges into the diagnostic https://github.com/llvm/llvm-project/pull/86448 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
@@ -0,0 +1,84 @@ +.. title:: clang-tidy - bugprone-exception-rethrow + +bugprone-exception-rethrow +== + +Identifies problematic exception rethrowing, especially with caught exception +variables or empty throw statements outside catch blocks. + +In C++ exception handling, a common pitfall occurs when developers rethrow +caught exceptions within catch blocks by directly passing the caught exception +variable to the ``throw`` statement. While this approach can propagate +exceptions to higher levels of the program, it often leads to code that is less +clear and more error-prone. Rethrowing caught exceptions with the same exception +object within catch blocks can obscure the original context of the exception and +make it challenging to trace program flow. Additionally, this method can +introduce issues such as exception object slicing and performance overhead due +to the invocation of the copy constructor. + +.. code-block:: c++ + + try { +// Code that may throw an exception + } catch (const std::exception& e) { +throw e; // Bad, 'e' is copied + } + +.. code-block:: c++ + + class derived_exception : public std::exception { ... }; + + void throwDerived() { throw derived_exception{}; } + + try { +throwDerived(); + } catch (const std::exception& e) { +throw e; // Bad, exception slicing occurs when 'derived_exception' is + // being rethrown as 'std::exception' + } + +To prevent these issues, it is advised to utilize ``throw;`` statements to +rethrow the original exception object for currently handled exceptions. + +.. code-block:: c++ + + try { +// Code that may throw an exception + } catch (const std::exception&) { +throw; // Good + } + +However, when an empty throw statement is used without an active exception, it 5chmidti wrote: `empty throw statement is used without an active exception` sounds too close to meaning `throw e;`. I think it would be better to write `However, when an empty throw statement is used and no exception is currently being handled,` https://github.com/llvm/llvm-project/pull/86448 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
@@ -0,0 +1,67 @@ +//===--- ExceptionRethrowCheck.cpp - clang-tidy ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ExceptionRethrowCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +void ExceptionRethrowCheck::registerMatchers(MatchFinder *Finder) { + + auto RefToExceptionVariable = declRefExpr(to(varDecl(isExceptionVariable(; + auto StdMoveCall = + callExpr(argumentCountIs(1), callee(functionDecl(hasName("::std::move"))), + hasArgument(0, RefToExceptionVariable)); + auto CopyOrMoveConstruction = cxxConstructExpr( + argumentCountIs(1), + traverse(TK_AsIs, hasDeclaration(cxxConstructorDecl( +anyOf(isCopyConstructor(), isMoveConstructor(), + hasArgument(0, anyOf(RefToExceptionVariable, StdMoveCall))); + + auto HasEmptyThrowExprDescendant = + hasDescendant(cxxThrowExpr(equalsBoundNode("empty-throw"))); + + Finder->addMatcher( + cxxThrowExpr( + unless(isExpansionInSystemHeader()), unless(has(expr())), + expr().bind("empty-throw"), + anyOf(unless(hasAncestor(cxxCatchStmt())), +hasAncestor(cxxCatchStmt(anyOf( +hasDescendant(functionDecl(HasEmptyThrowExprDescendant)), + hasDescendant(lambdaExpr(HasEmptyThrowExprDescendant))), + this); + Finder->addMatcher( + cxxThrowExpr(unless(isExpansionInSystemHeader()), + has(expr(anyOf(RefToExceptionVariable, StdMoveCall, + CopyOrMoveConstruction + .bind("throw"), + this); +} + +void ExceptionRethrowCheck::check(const MatchFinder::MatchResult &Result) { + if (const auto *MatchedThrow = + Result.Nodes.getNodeAs("throw")) { +const Expr *ThrownObject = MatchedThrow->getSubExpr(); +diag(MatchedThrow->getThrowLoc(), + "throwing a copy of the caught %0 exception, remove the argument to " + "throw the original exception object") +<< ThrownObject->getType().getNonReferenceType(); 5chmidti wrote: This diagnostic could also emit a fix-it that removes the arg, which should always be correct to do. https://github.com/llvm/llvm-project/pull/86448 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Improve `container-data-pointer` check to use `c_str()` (PR #71304)
https://github.com/5chmidti commented: @neoncube2 do you plan to continue working on this? --- Because we are emitting a fix-it, it might be a good idea to check if the return type of `c_str` is that of `data` (~possibly unwrapping aliases). https://github.com/llvm/llvm-project/pull/71304 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Improve `container-data-pointer` check to use `c_str()` (PR #71304)
@@ -40,8 +40,10 @@ void ContainerDataPointerCheck::registerMatchers(MatchFinder *Finder) { cxxRecordDecl( unless(matchers::matchesAnyListedName(IgnoredContainers)), isSameOrDerivedFrom( - namedDecl( - has(cxxMethodDecl(isPublic(), hasName("data")).bind("data"))) + namedDecl(anyOf(has(cxxMethodDecl(isPublic(), hasName("c_str")) + .bind("c_str")), + has(cxxMethodDecl(isPublic(), hasName("data")) + .bind("data" 5chmidti wrote: The node bound to `data` is never retrieved, so you can remove the `.bind("data")`. https://github.com/llvm/llvm-project/pull/71304 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Improve `container-data-pointer` check to use `c_str()` (PR #71304)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/71304 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Improve `container-data-pointer` check to use `c_str()` (PR #71304)
@@ -111,16 +115,18 @@ void ContainerDataPointerCheck::check(const MatchFinder::MatchResult &Result) { MemberExpr>(CE)) ReplacementText = "(" + ReplacementText + ")"; - if (CE->getType()->isPointerType()) -ReplacementText += "->data()"; - else -ReplacementText += ".data()"; + ReplacementText += CE->getType()->isPointerType() ? "->" : "."; + ReplacementText += CStrMethod ? "c_str()" : "data()"; 5chmidti wrote: Prefer to use `llvm::Twine` for this concatenation https://github.com/llvm/llvm-project/pull/71304 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
@@ -0,0 +1,67 @@ +//===--- ExceptionRethrowCheck.cpp - clang-tidy ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ExceptionRethrowCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +void ExceptionRethrowCheck::registerMatchers(MatchFinder *Finder) { + + auto RefToExceptionVariable = declRefExpr(to(varDecl(isExceptionVariable(; + auto StdMoveCall = + callExpr(argumentCountIs(1), callee(functionDecl(hasName("::std::move"))), + hasArgument(0, RefToExceptionVariable)); + auto CopyOrMoveConstruction = cxxConstructExpr( + argumentCountIs(1), + traverse(TK_AsIs, hasDeclaration(cxxConstructorDecl( +anyOf(isCopyConstructor(), isMoveConstructor(), + hasArgument(0, anyOf(RefToExceptionVariable, StdMoveCall))); + + auto HasEmptyThrowExprDescendant = + hasDescendant(cxxThrowExpr(equalsBoundNode("empty-throw"))); + + Finder->addMatcher( + cxxThrowExpr( + unless(isExpansionInSystemHeader()), unless(has(expr())), + expr().bind("empty-throw"), + anyOf(unless(hasAncestor(cxxCatchStmt())), +hasAncestor(cxxCatchStmt(anyOf( +hasDescendant(functionDecl(HasEmptyThrowExprDescendant)), + hasDescendant(lambdaExpr(HasEmptyThrowExprDescendant))), + this); + Finder->addMatcher( + cxxThrowExpr(unless(isExpansionInSystemHeader()), + has(expr(anyOf(RefToExceptionVariable, StdMoveCall, + CopyOrMoveConstruction + .bind("throw"), + this); +} + +void ExceptionRethrowCheck::check(const MatchFinder::MatchResult &Result) { + if (const auto *MatchedThrow = + Result.Nodes.getNodeAs("throw")) { +const Expr *ThrownObject = MatchedThrow->getSubExpr(); +diag(MatchedThrow->getThrowLoc(), + "throwing a copy of the caught %0 exception, remove the argument to " + "throw the original exception object") +<< ThrownObject->getType().getNonReferenceType(); isuckatcs wrote: We already [discussed](https://github.com/llvm/llvm-project/pull/86448#discussion_r1536919192) this and decided to not to do it. https://github.com/llvm/llvm-project/pull/86448 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix logical error in 'if else' condition that lead to an unreachable code (PR #95666)
https://github.com/xgupta created https://github.com/llvm/llvm-project/pull/95666 This is described in https://pvs-studio.com/en/blog/posts/cpp/1126/ so caught by the PVS Studio analyzer. Warning message - The use of 'if (A) {...} else if (A) {...}' pattern was detected There were two same 'if' conditions (Tok->is(tok::hash) but different execution blocks leading to unreachable code for the second 'if-else' condition. >From 0e88700adf7add65f3eb8a2d4d2c2de72703a0f0 Mon Sep 17 00:00:00 2001 From: Shivam Gupta Date: Sat, 15 Jun 2024 21:56:09 +0530 Subject: [PATCH] [Clang] Fix logical error in 'if else' condition that lead to an unreachable code This is describe in https://pvs-studio.com/en/blog/posts/cpp/1126/ so caught by PVS Studio analyzer. Warning message - The use of 'if (A) {...} else if (A) {...}' pattern was detected There were two same 'if' condition (Tok->is(tok::hash) but different execution blocks that was leading to unnreachable code for second 'if else' condition. --- clang/lib/Format/TokenAnnotator.cpp | 23 +-- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 1fe3b61a5a81f..5a7029bda65f3 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3369,11 +3369,19 @@ class ExpressionParser { FormatToken *Next = Tok->getNextNonComment(); if (Tok->is(tok::hash)) { -// Start of a macro expansion. -First = Tok; -Tok = Next; -if (Tok) - Tok = Tok->getNextNonComment(); + +if (Next && Next->is(tok::l_paren)) { + // Handle parameterized macro. + Next = Next->MatchingParen; + if (Next) +Tok = Next->getNextNonComment(); +} else { + // Start of a macro expansion. + First = Tok; + Tok = Next; + if (Tok) +Tok = Tok->getNextNonComment(); +} } else if (Tok->is(tok::hashhash)) { // Concatenation. Skip. Tok = Next; @@ -3410,11 +3418,6 @@ class ExpressionParser { } else { break; } - } else if (Tok->is(tok::hash)) { -if (Next->is(tok::l_paren)) - Next = Next->MatchingParen; -if (Next) - Tok = Next->getNextNonComment(); } else { break; } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] Fix logical error in 'if else' condition that lead to an unreachable code (PR #95666)
llvmbot wrote: @llvm/pr-subscribers-clang-format Author: Shivam Gupta (xgupta) Changes This is described in https://pvs-studio.com/en/blog/posts/cpp/1126/ so caught by the PVS Studio analyzer. Warning message - The use of 'if (A) {...} else if (A) {...}' pattern was detected There were two same 'if' conditions (Tok->is(tok::hash) but different execution blocks leading to unreachable code for the second 'if-else' condition. --- Full diff: https://github.com/llvm/llvm-project/pull/95666.diff 1 Files Affected: - (modified) clang/lib/Format/TokenAnnotator.cpp (+13-10) ``diff diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 1fe3b61a5a81f..5a7029bda65f3 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3369,11 +3369,19 @@ class ExpressionParser { FormatToken *Next = Tok->getNextNonComment(); if (Tok->is(tok::hash)) { -// Start of a macro expansion. -First = Tok; -Tok = Next; -if (Tok) - Tok = Tok->getNextNonComment(); + +if (Next && Next->is(tok::l_paren)) { + // Handle parameterized macro. + Next = Next->MatchingParen; + if (Next) +Tok = Next->getNextNonComment(); +} else { + // Start of a macro expansion. + First = Tok; + Tok = Next; + if (Tok) +Tok = Tok->getNextNonComment(); +} } else if (Tok->is(tok::hashhash)) { // Concatenation. Skip. Tok = Next; @@ -3410,11 +3418,6 @@ class ExpressionParser { } else { break; } - } else if (Tok->is(tok::hash)) { -if (Next->is(tok::l_paren)) - Next = Next->MatchingParen; -if (Next) - Tok = Next->getNextNonComment(); } else { break; } `` https://github.com/llvm/llvm-project/pull/95666 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)
@@ -0,0 +1,67 @@ +//===--- ExceptionRethrowCheck.cpp - clang-tidy ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "ExceptionRethrowCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +void ExceptionRethrowCheck::registerMatchers(MatchFinder *Finder) { + + auto RefToExceptionVariable = declRefExpr(to(varDecl(isExceptionVariable(; + auto StdMoveCall = + callExpr(argumentCountIs(1), callee(functionDecl(hasName("::std::move"))), + hasArgument(0, RefToExceptionVariable)); + auto CopyOrMoveConstruction = cxxConstructExpr( + argumentCountIs(1), + traverse(TK_AsIs, hasDeclaration(cxxConstructorDecl( +anyOf(isCopyConstructor(), isMoveConstructor(), + hasArgument(0, anyOf(RefToExceptionVariable, StdMoveCall))); + + auto HasEmptyThrowExprDescendant = + hasDescendant(cxxThrowExpr(equalsBoundNode("empty-throw"))); + + Finder->addMatcher( + cxxThrowExpr( + unless(isExpansionInSystemHeader()), unless(has(expr())), + expr().bind("empty-throw"), + anyOf(unless(hasAncestor(cxxCatchStmt())), +hasAncestor(cxxCatchStmt(anyOf( +hasDescendant(functionDecl(HasEmptyThrowExprDescendant)), + hasDescendant(lambdaExpr(HasEmptyThrowExprDescendant))), + this); + Finder->addMatcher( + cxxThrowExpr(unless(isExpansionInSystemHeader()), + has(expr(anyOf(RefToExceptionVariable, StdMoveCall, + CopyOrMoveConstruction + .bind("throw"), + this); +} + +void ExceptionRethrowCheck::check(const MatchFinder::MatchResult &Result) { + if (const auto *MatchedThrow = + Result.Nodes.getNodeAs("throw")) { +const Expr *ThrownObject = MatchedThrow->getSubExpr(); +diag(MatchedThrow->getThrowLoc(), + "throwing a copy of the caught %0 exception, remove the argument to " + "throw the original exception object") +<< ThrownObject->getType().getNonReferenceType(); 5chmidti wrote: Ah, ok. https://github.com/llvm/llvm-project/pull/86448 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] Support go-to-definition on type hints. The core part (PR #86629)
@@ -1637,6 +1678,144 @@ TEST(TypeHints, SubstTemplateParameterAliases) { ExpectedHint{": static_vector", "vector_name"}); } +template +void assertTypeLinkHints(StringRef Code, StringRef HintRange, + Labels... ExpectedLabels) { + Annotations Source(Code); + auto HintAt = [&](llvm::ArrayRef InlayHints, +llvm::StringRef Range) { +auto *Hint = llvm::find_if(InlayHints, [&](const InlayHint &InlayHint) { + return InlayHint.range == Source.range(Range); +}); +assert(Hint && "No range was found"); +return llvm::ArrayRef(Hint->label); + }; + + TestTU TU = TestTU::withCode(Source.code()); + TU.ExtraArgs.push_back("-std=c++2c"); + auto AST = TU.build(); + + Config C; + C.InlayHints.TypeNameLimit = 0; + WithContextValue WithCfg(Config::Key, std::move(C)); + + auto Hints = hintsOfKind(AST, InlayHintKind::Type); + EXPECT_THAT(HintAt(Hints, HintRange), + ElementsAre(HintLabelPieceMatcher(ExpectedLabels, Source)...)); +} + +TEST(TypeHints, Links) { + StringRef Source(R"cpp( +$Package[[template zyn0217 wrote: Oh, thanks - indeed we have an identifier location with `getLocation()`. (I promise I have seen `getLocation()` while looking at the definition of `Decl::getBeginLoc()`, but I thought it was the same as `getLocation()` because that's how the base `getSourceRange()` implements, although it is overridden by the subclasses. I should have looked into the subclasses' constructors, my fault!) https://github.com/llvm/llvm-project/pull/86629 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] fix false negatives for performance-inefficient-vector-operation (PR #95667)
https://github.com/HerrCai0907 created https://github.com/llvm/llvm-project/pull/95667 Fixes: #95596 Check will warn if the loop var type is not same as var init expr type >From 5a4a4aac26a2a4078f07977b5101d3a1e22a3e0c Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Sat, 15 Jun 2024 16:24:55 + Subject: [PATCH] [clang-tidy] fix false negatives for performance-inefficient-vector-operation Fixes: #95596 Check will warn if the loop var type is not same as var init expr type --- .../InefficientVectorOperationCheck.cpp | 6 ++-- clang-tools-extra/docs/ReleaseNotes.rst | 5 +++ .../inefficient-vector-operation.cpp | 35 +++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp b/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp index 20aea5a79fe9a..dc6e0cf9c7d12 100644 --- a/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp @@ -105,9 +105,9 @@ void InefficientVectorOperationCheck::addMatcher( onImplicitObjectArgument(declRefExpr(to(TargetVarDecl .bind(AppendCallName); const auto AppendCall = expr(ignoringImplicit(AppendCallExpr)); - const auto LoopVarInit = - declStmt(hasSingleDecl(varDecl(hasInitializer(integerLiteral(equals(0 - .bind(LoopInitVarName))); + const auto LoopVarInit = declStmt(hasSingleDecl( + varDecl(hasInitializer(ignoringParenImpCasts(integerLiteral(equals(0) + .bind(LoopInitVarName))); const auto RefersToLoopVar = ignoringParenImpCasts( declRefExpr(to(varDecl(equalsBoundNode(LoopInitVarName); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 7092d0b6fdb02..3bdd735f7dcf7 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -387,6 +387,11 @@ Changes in existing checks - Improved :doc:`modernize-use-using ` check by adding support for detection of typedefs declared on function level. +- Improved :doc:`performance-inefficient-vector-operation + ` fixing false + negatives caused by different variable definition type and variable initial + value type in loop initialization expression. + - Improved :doc:`performance-move-const-arg ` check by ignoring ``std::move()`` calls when their target is used as an rvalue. diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation.cpp index c28592f4d6368..50424920d72b7 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation.cpp @@ -387,3 +387,38 @@ void foo(const StructWithFieldContainer &Src) { B.push_back(Number); } } + +namespace gh95596 { + +void f(std::vector& t) { + { +std::vector gh95596_0; +// CHECK-FIXES: gh95596_0.reserve(10); +for (unsigned i = 0; i < 10; ++i) + gh95596_0.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop + } + { +std::vector gh95596_1; +// CHECK-FIXES: gh95596_1.reserve(10); +for (int i = 0U; i < 10; ++i) + gh95596_1.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop + } + { +std::vector gh95596_2; +// CHECK-FIXES: gh95596_2.reserve(10); +for (unsigned i = 0U; i < 10; ++i) + gh95596_2.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop + } + { +std::vector gh95596_3; +// CHECK-FIXES: gh95596_3.reserve(10U); +for (int i = 0; i < 10U; ++i) + gh95596_3.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop + } +} + +} // namespace gh95596 \ No newline at end of file ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] fix false negatives for performance-inefficient-vector-operation (PR #95667)
llvmbot wrote: @llvm/pr-subscribers-clang-tidy Author: Congcong Cai (HerrCai0907) Changes Fixes: #95596 Check will warn if the loop var type is not same as var init expr type --- Full diff: https://github.com/llvm/llvm-project/pull/95667.diff 3 Files Affected: - (modified) clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp (+3-3) - (modified) clang-tools-extra/docs/ReleaseNotes.rst (+5) - (modified) clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation.cpp (+35) ``diff diff --git a/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp b/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp index 20aea5a79fe9a..dc6e0cf9c7d12 100644 --- a/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp @@ -105,9 +105,9 @@ void InefficientVectorOperationCheck::addMatcher( onImplicitObjectArgument(declRefExpr(to(TargetVarDecl .bind(AppendCallName); const auto AppendCall = expr(ignoringImplicit(AppendCallExpr)); - const auto LoopVarInit = - declStmt(hasSingleDecl(varDecl(hasInitializer(integerLiteral(equals(0 - .bind(LoopInitVarName))); + const auto LoopVarInit = declStmt(hasSingleDecl( + varDecl(hasInitializer(ignoringParenImpCasts(integerLiteral(equals(0) + .bind(LoopInitVarName))); const auto RefersToLoopVar = ignoringParenImpCasts( declRefExpr(to(varDecl(equalsBoundNode(LoopInitVarName); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 7092d0b6fdb02..3bdd735f7dcf7 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -387,6 +387,11 @@ Changes in existing checks - Improved :doc:`modernize-use-using ` check by adding support for detection of typedefs declared on function level. +- Improved :doc:`performance-inefficient-vector-operation + ` fixing false + negatives caused by different variable definition type and variable initial + value type in loop initialization expression. + - Improved :doc:`performance-move-const-arg ` check by ignoring ``std::move()`` calls when their target is used as an rvalue. diff --git a/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation.cpp b/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation.cpp index c28592f4d6368..50424920d72b7 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/performance/inefficient-vector-operation.cpp @@ -387,3 +387,38 @@ void foo(const StructWithFieldContainer &Src) { B.push_back(Number); } } + +namespace gh95596 { + +void f(std::vector& t) { + { +std::vector gh95596_0; +// CHECK-FIXES: gh95596_0.reserve(10); +for (unsigned i = 0; i < 10; ++i) + gh95596_0.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop + } + { +std::vector gh95596_1; +// CHECK-FIXES: gh95596_1.reserve(10); +for (int i = 0U; i < 10; ++i) + gh95596_1.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop + } + { +std::vector gh95596_2; +// CHECK-FIXES: gh95596_2.reserve(10); +for (unsigned i = 0U; i < 10; ++i) + gh95596_2.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop + } + { +std::vector gh95596_3; +// CHECK-FIXES: gh95596_3.reserve(10U); +for (int i = 0; i < 10U; ++i) + gh95596_3.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop + } +} + +} // namespace gh95596 \ No newline at end of file `` https://github.com/llvm/llvm-project/pull/95667 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] fix false negatives for performance-inefficient-vector-operation (PR #95667)
https://github.com/HerrCai0907 edited https://github.com/llvm/llvm-project/pull/95667 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] fix false negatives for performance-inefficient-vector-operation (PR #95667)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/95667 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] fix false negatives for performance-inefficient-vector-operation (PR #95667)
@@ -387,3 +387,38 @@ void foo(const StructWithFieldContainer &Src) { B.push_back(Number); } } + +namespace gh95596 { + +void f(std::vector& t) { + { +std::vector gh95596_0; +// CHECK-FIXES: gh95596_0.reserve(10); +for (unsigned i = 0; i < 10; ++i) + gh95596_0.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop + } + { +std::vector gh95596_1; +// CHECK-FIXES: gh95596_1.reserve(10); +for (int i = 0U; i < 10; ++i) + gh95596_1.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop + } + { +std::vector gh95596_2; +// CHECK-FIXES: gh95596_2.reserve(10); +for (unsigned i = 0U; i < 10; ++i) + gh95596_2.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop + } + { +std::vector gh95596_3; +// CHECK-FIXES: gh95596_3.reserve(10U); +for (int i = 0; i < 10U; ++i) + gh95596_3.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the container capacity before the loop + } +} + +} // namespace gh95596 5chmidti wrote: missing newline https://github.com/llvm/llvm-project/pull/95667 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] fix false negatives for performance-inefficient-vector-operation (PR #95667)
https://github.com/5chmidti approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/95667 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] fix false negatives for performance-inefficient-vector-operation (PR #95667)
https://github.com/5chmidti edited https://github.com/llvm/llvm-project/pull/95667 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Handle AttributeMacro before access modifiers (PR #95634)
https://github.com/owenca updated https://github.com/llvm/llvm-project/pull/95634 >From 1c4ab4a5fd869de44795abd48bbaa43176e7275e Mon Sep 17 00:00:00 2001 From: Owen Pan Date: Fri, 14 Jun 2024 23:36:58 -0700 Subject: [PATCH 1/2] [clang-format] Handle AttributeMacro before access modifiers Closes #95094. --- clang/lib/Format/TokenAnnotator.cpp | 7 - clang/lib/Format/TokenAnnotator.h | 1 + clang/lib/Format/UnwrappedLineFormatter.cpp | 35 ++--- clang/unittests/Format/FormatTest.cpp | 15 + 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 1fe3b61a5a81f..ff00e772a75f4 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1970,6 +1970,7 @@ class AnnotatingParser { } } +bool SeenAccessModifier = false; bool KeywordVirtualFound = false; bool ImportStatement = false; @@ -1978,7 +1979,9 @@ class AnnotatingParser { ImportStatement = true; while (CurrentToken) { - if (CurrentToken->is(tok::kw_virtual)) + if (CurrentToken->isAccessSpecifier()) +SeenAccessModifier = true; + else if (CurrentToken->is(tok::kw_virtual)) KeywordVirtualFound = true; if (Style.isJavaScript()) { // export {...} from '...'; @@ -1998,6 +2001,8 @@ class AnnotatingParser { if (!consumeToken()) return LT_Invalid; } +if (SeenAccessModifier) + return LT_AccessModifier; if (KeywordVirtualFound) return LT_VirtualFunctionDecl; if (ImportStatement) diff --git a/clang/lib/Format/TokenAnnotator.h b/clang/lib/Format/TokenAnnotator.h index d19d3d061e40c..136880eca718b 100644 --- a/clang/lib/Format/TokenAnnotator.h +++ b/clang/lib/Format/TokenAnnotator.h @@ -22,6 +22,7 @@ namespace format { enum LineType { LT_Invalid, + LT_AccessModifier, // Contains public/protected/private followed by colon. LT_ImportStatement, LT_ObjCDecl, // An @interface, @implementation, or @protocol line. LT_ObjCMethodDecl, diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index 4d53361aaf333..729f3d78f4a35 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -57,7 +57,7 @@ class LevelIndentTracker { /// Update the indent state given that \p Line is going to be formatted /// next. void nextLine(const AnnotatedLine &Line) { -Offset = getIndentOffset(*Line.First); +Offset = getIndentOffset(Line); // Update the indent level cache size so that we can rely on it // having the right size in adjustToUnmodifiedline. if (Line.Level >= IndentForLevel.size()) @@ -111,42 +111,41 @@ class LevelIndentTracker { /// /// For example, 'public:' labels in classes are offset by 1 or 2 /// characters to the left from their level. - int getIndentOffset(const FormatToken &RootToken) { + int getIndentOffset(const AnnotatedLine &Line) { if (Style.Language == FormatStyle::LK_Java || Style.isJavaScript() || Style.isCSharp()) { return 0; } -auto IsAccessModifier = [this, &RootToken]() { - if (RootToken.isAccessSpecifier(Style.isCpp())) { +auto IsAccessModifier = [&](const FormatToken &RootToken) { + if (Line.Type == LT_AccessModifier || RootToken.isObjCAccessSpecifier()) return true; - } else if (RootToken.isObjCAccessSpecifier()) { -return true; - } + + const auto *Next = RootToken.Next; + // Handle Qt signals. - else if (RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) && - RootToken.Next && RootToken.Next->is(tok::colon)) { -return true; - } else if (RootToken.Next && - RootToken.Next->isOneOf(Keywords.kw_slots, - Keywords.kw_qslots) && - RootToken.Next->Next && RootToken.Next->Next->is(tok::colon)) { + if (RootToken.isOneOf(Keywords.kw_signals, Keywords.kw_qsignals) && + Next && Next->is(tok::colon)) { return true; } - // Handle malformed access specifier e.g. 'private' without trailing ':'. - else if (!RootToken.Next && RootToken.isAccessSpecifier(false)) { + + if (Next && Next->isOneOf(Keywords.kw_slots, Keywords.kw_qslots) && + Next->Next && Next->Next->is(tok::colon)) { return true; } - return false; + + // Handle malformed access specifier e.g. 'private' without trailing ':'. + return !Next && RootToken.isAccessSpecifier(false); }; -if (IsAccessModifier()) { +if (IsAccessModifier(*Line.First)) { // The AccessModifierOffset may be overridden by IndentAccessModifiers, // in which case we take a negative value of the IndentWidth to simulate // the upper indent level. return Style.In
[clang-tools-extra] [clang-tidy] fix false negatives for performance-inefficient-vector-operation (PR #95667)
https://github.com/PiotrZSL approved this pull request. https://github.com/llvm/llvm-project/pull/95667 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Offload] Introduce the concept of "default streams" (PR #95371)
https://github.com/jdoerfert updated https://github.com/llvm/llvm-project/pull/95371 >From d06585044bd6d2dd76d6110bce933e01fd4b333e Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Mon, 3 Jun 2024 19:52:12 -0700 Subject: [PATCH 1/3] [Offload][CUDA] Allow CUDA kernels to use LLVM/Offload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Through the new `-foffload-via-llvm` flag, CUDA kernels can now be lowered to the LLVM/Offload API. On the Clang side, this is simply done by using the OpenMP offload toolchain and emitting calls to `llvm*` functions to orchestrate the kernel launch rather than `cuda*` functions. These `llvm*` functions are implemented on top of the existing LLVM/Offload API. As we are about to redefine the Offload API, this wil help us in the design process as a second offload language. We do not support any CUDA APIs yet, however, we could: https://www.osti.gov/servlets/purl/1892137 For proper host execution we need to resurrect/rebase https://tianshilei.me/wp-content/uploads/2021/12/llpp-2021.pdf (which was designed for debugging). ``` ❯❯❯ cat test.cu extern "C" { void *llvm_omp_target_alloc_shared(size_t Size, int DeviceNum); void llvm_omp_target_free_shared(void *DevicePtr, int DeviceNum); } __global__ void square(int *A) { *A = 42; } int main(int argc, char **argv) { int DevNo = 0; int *Ptr = reinterpret_cast(llvm_omp_target_alloc_shared(4, DevNo)); *Ptr = 7; printf("Ptr %p, *Ptr %i\n", Ptr, *Ptr); square<<<1, 1>>>(Ptr); printf("Ptr %p, *Ptr %i\n", Ptr, *Ptr); llvm_omp_target_free_shared(Ptr, DevNo); } ❯❯❯ clang++ test.cu -O3 -o test123 -foffload-via-llvm --offload-arch=native ❯❯❯ llvm-objdump --offloading test123 test123:file format elf64-x86-64 OFFLOADING IMAGE [0]: kindelf archgfx90a triple amdgcn-amd-amdhsa produceropenmp ❯❯❯ LIBOMPTARGET_INFO=16 ./test123 Ptr 0x155448ac8000, *Ptr 7 Ptr 0x155448ac8000, *Ptr 42 ``` --- clang/include/clang/Basic/LangOptions.def | 1 + clang/include/clang/Driver/Options.td | 6 ++ clang/lib/CodeGen/CGCUDANV.cpp| 97 --- clang/lib/Driver/Driver.cpp | 19 ++-- clang/lib/Driver/ToolChains/Clang.cpp | 27 +- clang/lib/Driver/ToolChains/CommonArgs.cpp| 7 +- clang/lib/Driver/ToolChains/Cuda.cpp | 27 +++--- clang/lib/Headers/CMakeLists.txt | 18 +++- .../llvm_offload_wrappers/__llvm_offload.h| 31 ++ .../__llvm_offload_device.h | 10 ++ .../__llvm_offload_host.h | 15 +++ .../__clang_openmp_device_functions.h | 9 +- clang/lib/Sema/SemaCUDA.cpp | 3 + clang/test/CodeGenCUDA/offload_via_llvm.cu| 97 +++ clang/test/Driver/cuda-via-liboffload.cu | 23 + offload/include/Shared/APITypes.h | 5 +- offload/include/omptarget.h | 2 +- .../common/src/PluginInterface.cpp| 13 ++- offload/src/CMakeLists.txt| 1 + offload/src/KernelLanguage/API.cpp| 76 +++ offload/src/exports | 3 + offload/test/lit.cfg | 2 +- offload/test/offloading/CUDA/basic_launch.cu | 31 ++ .../CUDA/basic_launch_blocks_and_threads.cu | 32 ++ .../offloading/CUDA/basic_launch_multi_arg.cu | 41 offload/test/offloading/CUDA/kernel_tu.cu.inc | 1 + offload/test/offloading/CUDA/launch_tu.cu | 32 ++ 27 files changed, 576 insertions(+), 53 deletions(-) create mode 100644 clang/lib/Headers/llvm_offload_wrappers/__llvm_offload.h create mode 100644 clang/lib/Headers/llvm_offload_wrappers/__llvm_offload_device.h create mode 100644 clang/lib/Headers/llvm_offload_wrappers/__llvm_offload_host.h create mode 100644 clang/test/CodeGenCUDA/offload_via_llvm.cu create mode 100644 clang/test/Driver/cuda-via-liboffload.cu create mode 100644 offload/src/KernelLanguage/API.cpp create mode 100644 offload/test/offloading/CUDA/basic_launch.cu create mode 100644 offload/test/offloading/CUDA/basic_launch_blocks_and_threads.cu create mode 100644 offload/test/offloading/CUDA/basic_launch_multi_arg.cu create mode 100644 offload/test/offloading/CUDA/kernel_tu.cu.inc create mode 100644 offload/test/offloading/CUDA/launch_tu.cu diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 2dea3cd4d795b..e8d3be7e89dbb 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -288,6 +288,7 @@ LANGOPT(GPUMaxThreadsPerBlock, 32, 1024, "default max threads per block for kern LANGOPT(GPUDeferDiag, 1, 0, "defer host/device related diagnostic messages for CUDA/HIP") LANGOPT(GPUExcludeWrongSideOverloads, 1, 0, "always exclude wrong side overloads in overloading resolution for CUDA/HIP") LANGOPT(OffloadingNewDriver, 1, 0, "use
[clang] fix(93512): skip alignment checks on incomplete types (PR #94542)
https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/94542 >From da4df73607a9edefc8db721818eff50e974a0637 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 6 Jun 2024 01:55:54 +0300 Subject: [PATCH] [Clang] skip alignment checks on incomplete types to avoid an assertion failure while parsing lambda used as default argument --- clang/docs/ReleaseNotes.rst| 2 ++ clang/lib/Sema/SemaStmt.cpp| 2 +- clang/test/SemaCXX/lambda-as-default-parameter.cpp | 6 ++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 clang/test/SemaCXX/lambda-as-default-parameter.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 39a9013c75a41..819fe1811ddaf 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -840,6 +840,8 @@ Bug Fixes to C++ Support - Fix a crash caused by improper use of ``__array_extent``. (#GH80474) - Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307), (#GH88081), (#GH89496), (#GH90669) and (#GH91633). +- Fix an assertion failure caused by parsing a lambda used as a default argument for the value of a + forward-declared class. (#GH93512). Bug Fixes to AST Handling ^ diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 57465d4a77ac2..56f69dd50f361 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -3355,7 +3355,7 @@ Sema::NamedReturnInfo Sema::getNamedReturnInfo(const VarDecl *VD) { // Variables with higher required alignment than their type's ABI // alignment cannot use NRVO. - if (!VD->hasDependentAlignment() && + if (!VD->hasDependentAlignment() && !VDType->isIncompleteType() && Context.getDeclAlign(VD) > Context.getTypeAlignInChars(VDType)) Info.S = NamedReturnInfo::MoveEligible; diff --git a/clang/test/SemaCXX/lambda-as-default-parameter.cpp b/clang/test/SemaCXX/lambda-as-default-parameter.cpp new file mode 100644 index 0..1f07a7f5644b7 --- /dev/null +++ b/clang/test/SemaCXX/lambda-as-default-parameter.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +struct a; // expected-note {{forward declaration of 'a'}} \ + expected-note {{forward declaration of 'a'}} +void b(a c = [] { return c; }); // expected-error {{initialization of incomplete type 'a'}} \ + expected-error {{variable has incomplete type 'a'}} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] skip alignment checks on incomplete types to avoid an assertion failure while parsing lambda used as default argument (PR #94542)
https://github.com/a-tarasyuk edited https://github.com/llvm/llvm-project/pull/94542 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] fix(95366): enhance cast operation safety with LValue validation (PR #95479)
https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/95479 >From 125d9cdd617d6415ef24eb785fe22705149f2d01 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 14 Jun 2024 01:26:34 +0300 Subject: [PATCH 1/4] [Clang] disallow non-lvalue values in constant expressions to prevent invalid pointer offset computation --- clang/docs/ReleaseNotes.rst | 1 + clang/lib/AST/ExprConstant.cpp| 3 +++ clang/test/Sema/integral-to-ptr.c | 3 +++ 3 files changed, 7 insertions(+) create mode 100644 clang/test/Sema/integral-to-ptr.c diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 8c2f737836a9d..77906360b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -847,6 +847,7 @@ Bug Fixes to C++ Support - Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307), (#GH88081), (#GH89496), (#GH90669) and (#GH91633). - Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368). +- Fix an assertion failure caused by non-lvalue usage in lvalue context. (GH95366). Bug Fixes to AST Handling ^ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 7178f081d9cf3..08bee806f172f 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -9325,6 +9325,9 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) { Result.IsNullPtr = false; return true; } else { + if (!Value.isLValue()) +return false; + // Cast is of an lvalue, no need to change value. Result.setFrom(Info.Ctx, Value); return true; diff --git a/clang/test/Sema/integral-to-ptr.c b/clang/test/Sema/integral-to-ptr.c new file mode 100644 index 0..99f83c3e52057 --- /dev/null +++ b/clang/test/Sema/integral-to-ptr.c @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only -std=c11 + +int x(void) { e: b: ; return &&e - &&b < x; } // expected-warning {{ordered comparison between pointer and integer ('long' and 'int (*)(void)')}} >From b73cf0659a115f29c7b224a8f89ab519dac01a13 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 14 Jun 2024 08:50:03 +0300 Subject: [PATCH 2/4] update test expectations --- clang/test/Sema/integral-to-ptr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Sema/integral-to-ptr.c b/clang/test/Sema/integral-to-ptr.c index 99f83c3e52057..b8ab4cb79820d 100644 --- a/clang/test/Sema/integral-to-ptr.c +++ b/clang/test/Sema/integral-to-ptr.c @@ -1,3 +1,3 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only -std=c11 -int x(void) { e: b: ; return &&e - &&b < x; } // expected-warning {{ordered comparison between pointer and integer ('long' and 'int (*)(void)')}} +int x(void) { e: b: ; return &&e - &&b < x; } // expected-warning {{ordered comparison between pointer and integer}} >From 78fc56a0aab96984760a3874e06e51259b599bd5 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 14 Jun 2024 18:16:34 +0300 Subject: [PATCH 3/4] add detailed comment --- clang/lib/AST/ExprConstant.cpp | 4 1 file changed, 4 insertions(+) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 08bee806f172f..712c3062eb9ac 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -9325,6 +9325,10 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) { Result.IsNullPtr = false; return true; } else { + // In rare instances, the value isn't an lvalue. + // For example, when the value is the difference between the addresses of + // two labels. We reject that as a constant expression because we can't + // compute a valid offset to convert into a pointer. if (!Value.isLValue()) return false; >From 7e3af56b7fbb43041f81c982cee712f516ecc6f1 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 14 Jun 2024 18:16:58 +0300 Subject: [PATCH 4/4] update changelog message --- clang/docs/ReleaseNotes.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 77906360b..efd17d8f9a089 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -847,7 +847,8 @@ Bug Fixes to C++ Support - Fixed several bugs in capturing variables within unevaluated contexts. (#GH63845), (#GH67260), (#GH69307), (#GH88081), (#GH89496), (#GH90669) and (#GH91633). - Fixed handling of brace ellison when building deduction guides. (#GH64625), (#GH83368). -- Fix an assertion failure caused by non-lvalue usage in lvalue context. (GH95366). +- Fixed a failed assertion when attempting to convert an integer representing the difference + between the addresses of two labels (a GNU extension) to a pointer within a constant expression. (GH95366). Bug Fixes to AST Handling ^
[clang] [Clang] disallow non-lvalue values in constant expressions to prevent invalid pointer offset computation (PR #95479)
https://github.com/a-tarasyuk edited https://github.com/llvm/llvm-project/pull/95479 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] disallow non-lvalue values in constant expressions to prevent invalid pointer offset computation (PR #95479)
a-tarasyuk wrote: @cor3ntin I've updated the commit message/PR title. What do you think? https://github.com/llvm/llvm-project/pull/95479 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] fix(92759): clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp: 6 * Function parameter should be passed by const reference (PR #93252)
https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/93252 >From 8788c301adb367d34aafd3d472309ed061f0e658 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 24 May 2024 01:39:35 +0300 Subject: [PATCH] [Clang] improve RewriteModernObjC code quality by using const reference for function parameters --- .../Frontend/Rewrite/RewriteModernObjC.cpp| 31 ++- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp index 6ae955a2380b7..dd8ee117f60c6 100644 --- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -465,13 +465,14 @@ namespace { std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag); std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, - StringRef funcName, std::string Tag); + StringRef funcName, const std::string &Tag); std::string SynthesizeBlockFunc(BlockExpr *CE, int i, - StringRef funcName, std::string Tag); + StringRef funcName, const std::string &Tag); std::string SynthesizeBlockImpl(BlockExpr *CE, -std::string Tag, std::string Desc); -std::string SynthesizeBlockDescriptor(std::string DescTag, - std::string ImplTag, +const std::string &Tag, +const std::string &Desc); +std::string SynthesizeBlockDescriptor(const std::string &DescTag, + const std::string &ImplTag, int i, StringRef funcName, unsigned hasCopy); Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp); @@ -4037,7 +4038,7 @@ static bool HasLocalVariableExternalStorage(ValueDecl *VD) { std::string RewriteModernObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, StringRef funcName, - std::string Tag) { + const std::string &Tag) { const FunctionType *AFT = CE->getFunctionType(); QualType RT = AFT->getReturnType(); std::string StructRef = "struct " + Tag; @@ -4132,8 +4133,8 @@ std::string RewriteModernObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, } std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, - StringRef funcName, - std::string Tag) { + StringRef funcName, + const std::string &Tag) { std::string StructRef = "struct " + Tag; std::string S = "static void __"; @@ -4175,8 +4176,9 @@ std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i, return S; } -std::string RewriteModernObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, - std::string Desc) { +std::string RewriteModernObjC::SynthesizeBlockImpl(BlockExpr *CE, + const std::string &Tag, + const std::string &Desc) { std::string S = "\nstruct " + Tag; std::string Constructor = " " + Tag; @@ -4290,10 +4292,11 @@ std::string RewriteModernObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Ta return S; } -std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag, - std::string ImplTag, int i, - StringRef FunName, - unsigned hasCopy) { +std::string RewriteModernObjC::SynthesizeBlockDescriptor(const std::string &DescTag, + const std::string &ImplTag, + int i, + StringRef FunName, + unsigned hasCopy) { std::string S = "\nstatic struct " + DescTag; S += " {\n size_t reserved;\n"; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] improve RewriteModernObjC code quality by using const reference for function parameters (PR #93252)
https://github.com/a-tarasyuk edited https://github.com/llvm/llvm-project/pull/93252 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] fix(92755): clang/include/clang/AST/Redeclarable.h: 4 * Function parameter should be passed by const reference (PR #92963)
https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/92963 >From c94e7cbe04c0f23094a7f2a3d2a7cbd103750301 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Tue, 21 May 2024 22:56:06 +0300 Subject: [PATCH] [Clang] use const references for function parameters in operator== and operator!= overloads in Redeclarable.h --- clang/include/clang/AST/Redeclarable.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/AST/Redeclarable.h b/clang/include/clang/AST/Redeclarable.h index 091bb886f2d49..74ccd74ed60d6 100644 --- a/clang/include/clang/AST/Redeclarable.h +++ b/clang/include/clang/AST/Redeclarable.h @@ -281,10 +281,10 @@ class Redeclarable { return tmp; } -friend bool operator==(redecl_iterator x, redecl_iterator y) { +friend bool operator==(const redecl_iterator &x, const redecl_iterator &y) { return x.Current == y.Current; } -friend bool operator!=(redecl_iterator x, redecl_iterator y) { +friend bool operator!=(const redecl_iterator &x, const redecl_iterator &y) { return x.Current != y.Current; } }; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits