From cfe-commits at lists.llvm.org Mon Mar 30 00:15:01 2020 From: cfe-commits at lists.llvm.org (Adam Balogh via cfe-commits) Date: Mon, 30 Mar 2020 00:15:01 -0700 (PDT) Subject: [clang] afcb77c - [Analyzer] Fix for incorrect use of container and iterator checkers Message-ID: <5e819c75.1c69fb81.b5d20.8442@mx.google.com> Author: Adam Balogh Date: 2020-03-30T09:14:45+02:00 New Revision: afcb77cc88a2ed489bbd383774c54daa82340761 URL: https://github.com/llvm/llvm-project/commit/afcb77cc88a2ed489bbd383774c54daa82340761 DIFF: https://github.com/llvm/llvm-project/commit/afcb77cc88a2ed489bbd383774c54daa82340761.diff LOG: [Analyzer] Fix for incorrect use of container and iterator checkers Iterator checkers (and planned container checkers) need the option aggressive-binary-operation-simplification to be enabled. Without this option they may cause assertions. To prevent such misuse, this patch adds a preventive check which issues a warning and denies the registartion of the checker if this option is disabled. Differential Revision: https://reviews.llvm.org/D75171 Added: clang/test/Analysis/container-modeling-no-aggressive-binary-operation-simplification-warn.cpp clang/test/Analysis/iterator-modeling-no-aggressive-binary-operation-simplification-no-crash.cpp Modified: clang/include/clang/Basic/DiagnosticDriverKinds.td clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp clang/test/Analysis/loop-widening-notes.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 5a3249215189..27ffd562c6de 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -344,6 +344,8 @@ def err_analyzer_checker_option_unknown : Error< "checker '%0' has no option called '%1'">; def err_analyzer_checker_option_invalid_input : Error< "invalid input for checker option '%0', that expects %1">; +def err_analyzer_checker_incompatible_analyzer_option : Error< + "checker cannot be enabled with analyzer option '%0' == %1">; def err_drv_invalid_hvx_length : Error< "-mhvx-length is not supported without a -mhvx/-mhvx= flag">; diff --git a/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp index 0af10cec9378..73c6517fd0eb 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp @@ -12,6 +12,7 @@ #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/DeclTemplate.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" @@ -1068,5 +1069,15 @@ void ento::registerContainerModeling(CheckerManager &mgr) { } bool ento::shouldRegisterContainerModeling(const CheckerManager &mgr) { + if (!mgr.getLangOpts().CPlusPlus) + return false; + + if (!mgr.getAnalyzerOptions().ShouldAggressivelySimplifyBinaryOperation) { + mgr.getASTContext().getDiagnostics().Report( + diag::err_analyzer_checker_incompatible_analyzer_option) + << "aggressive-binary-operation-simplification" << "false"; + return false; + } + return true; } diff --git a/clang/test/Analysis/container-modeling-no-aggressive-binary-operation-simplification-warn.cpp b/clang/test/Analysis/container-modeling-no-aggressive-binary-operation-simplification-warn.cpp new file mode 100644 index 000000000000..1a55e878f9ef --- /dev/null +++ b/clang/test/Analysis/container-modeling-no-aggressive-binary-operation-simplification-warn.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_analyze_cc1 -std=c++11\ +// RUN: -analyzer-checker=core,cplusplus,alpha.cplusplus.ContainerModeling\ +// RUN: %s 2>&1 | FileCheck %s + +// XFAIL: * + +// CHECK: checker cannot be enabled with analyzer option 'aggressive-binary-operation-simplification' == false diff --git a/clang/test/Analysis/iterator-modeling-no-aggressive-binary-operation-simplification-no-crash.cpp b/clang/test/Analysis/iterator-modeling-no-aggressive-binary-operation-simplification-no-crash.cpp new file mode 100644 index 000000000000..4b7c52db5462 --- /dev/null +++ b/clang/test/Analysis/iterator-modeling-no-aggressive-binary-operation-simplification-no-crash.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_analyze_cc1 -std=c++11\ +// RUN: -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection\ +// RUN: %s 2>&1 | FileCheck %s + +// XFAIL: * + +// CHECK: checker cannot be enabled with analyzer option 'aggressive-binary-operation-simplification' == false + +#include "Inputs/system-header-simulator-cxx.h" + +void clang_analyzer_eval(bool); + +void comparison(std::vector &V) { + clang_analyzer_eval(V.begin() == V.end()); // no-crash +} diff --git a/clang/test/Analysis/loop-widening-notes.cpp b/clang/test/Analysis/loop-widening-notes.cpp index 2c26a1490e5c..0ba71d030d05 100644 --- a/clang/test/Analysis/loop-widening-notes.cpp +++ b/clang/test/Analysis/loop-widening-notes.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha -analyzer-max-loop 2 -analyzer-config widen-loops=true -analyzer-output=text -verify -analyzer-config eagerly-assume=false %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-max-loop 2 -analyzer-config widen-loops=true -analyzer-output=text -verify -analyzer-config eagerly-assume=false %s int *p_a; int bar(); From cfe-commits at lists.llvm.org Mon Mar 30 00:23:36 2020 From: cfe-commits at lists.llvm.org (Adam Balogh via cfe-commits) Date: Mon, 30 Mar 2020 00:23:36 -0700 (PDT) Subject: [clang] eb90692 - [Analyzer] Rename test `iterator-modelling.cpp` to `iterator-modeling.cpp` Message-ID: <5e819e78.1c69fb81.67bea.ddfa@mx.google.com> Author: Adam Balogh Date: 2020-03-30T09:23:35+02:00 New Revision: eb90692d8a660bb3172c9c2cc5adb3864c626d96 URL: https://github.com/llvm/llvm-project/commit/eb90692d8a660bb3172c9c2cc5adb3864c626d96 DIFF: https://github.com/llvm/llvm-project/commit/eb90692d8a660bb3172c9c2cc5adb3864c626d96.diff LOG: [Analyzer] Rename test `iterator-modelling.cpp` to `iterator-modeling.cpp` Typo fix. Added: clang/test/Analysis/iterator-modeling.cpp Modified: Removed: clang/test/Analysis/iterator-modelling.cpp ################################################################################ diff --git a/clang/test/Analysis/iterator-modelling.cpp b/clang/test/Analysis/iterator-modeling.cpp similarity index 100% rename from clang/test/Analysis/iterator-modelling.cpp rename to clang/test/Analysis/iterator-modeling.cpp From cfe-commits at lists.llvm.org Mon Mar 30 00:30:16 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Balogh, _=C3=81d=C3=A1m_via_Phabricator?= via cfe-commits) Date: Mon, 30 Mar 2020 07:30:16 +0000 (UTC) Subject: [PATCH] D75171: [Analyzer] Fix for incorrect use of container and iterator checkers In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rGafcb77cc88a2: [Analyzer] Fix for incorrect use of container and iterator checkers (authored by baloghadamsoftware). Herald added a subscriber: ASDenysPetrov. Changed prior to commit: https://reviews.llvm.org/D75171?vs=249352&id=253506#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75171/new/ https://reviews.llvm.org/D75171 Files: clang/include/clang/Basic/DiagnosticDriverKinds.td clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp clang/test/Analysis/container-modeling-no-aggressive-binary-operation-simplification-warn.cpp clang/test/Analysis/iterator-modeling-no-aggressive-binary-operation-simplification-no-crash.cpp clang/test/Analysis/loop-widening-notes.cpp Index: clang/test/Analysis/loop-widening-notes.cpp =================================================================== --- clang/test/Analysis/loop-widening-notes.cpp +++ clang/test/Analysis/loop-widening-notes.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha -analyzer-max-loop 2 -analyzer-config widen-loops=true -analyzer-output=text -verify -analyzer-config eagerly-assume=false %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-max-loop 2 -analyzer-config widen-loops=true -analyzer-output=text -verify -analyzer-config eagerly-assume=false %s int *p_a; int bar(); Index: clang/test/Analysis/iterator-modeling-no-aggressive-binary-operation-simplification-no-crash.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/iterator-modeling-no-aggressive-binary-operation-simplification-no-crash.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_analyze_cc1 -std=c++11\ +// RUN: -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection\ +// RUN: %s 2>&1 | FileCheck %s + +// XFAIL: * + +// CHECK: checker cannot be enabled with analyzer option 'aggressive-binary-operation-simplification' == false + +#include "Inputs/system-header-simulator-cxx.h" + +void clang_analyzer_eval(bool); + +void comparison(std::vector &V) { + clang_analyzer_eval(V.begin() == V.end()); // no-crash +} Index: clang/test/Analysis/container-modeling-no-aggressive-binary-operation-simplification-warn.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/container-modeling-no-aggressive-binary-operation-simplification-warn.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_analyze_cc1 -std=c++11\ +// RUN: -analyzer-checker=core,cplusplus,alpha.cplusplus.ContainerModeling\ +// RUN: %s 2>&1 | FileCheck %s + +// XFAIL: * + +// CHECK: checker cannot be enabled with analyzer option 'aggressive-binary-operation-simplification' == false Index: clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp +++ clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp @@ -12,6 +12,7 @@ #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/DeclTemplate.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" @@ -1068,5 +1069,15 @@ } bool ento::shouldRegisterContainerModeling(const CheckerManager &mgr) { + if (!mgr.getLangOpts().CPlusPlus) + return false; + + if (!mgr.getAnalyzerOptions().ShouldAggressivelySimplifyBinaryOperation) { + mgr.getASTContext().getDiagnostics().Report( + diag::err_analyzer_checker_incompatible_analyzer_option) + << "aggressive-binary-operation-simplification" << "false"; + return false; + } + return true; } Index: clang/include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticDriverKinds.td +++ clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -344,6 +344,8 @@ "checker '%0' has no option called '%1'">; def err_analyzer_checker_option_invalid_input : Error< "invalid input for checker option '%0', that expects %1">; +def err_analyzer_checker_incompatible_analyzer_option : Error< + "checker cannot be enabled with analyzer option '%0' == %1">; def err_drv_invalid_hvx_length : Error< "-mhvx-length is not supported without a -mhvx/-mhvx= flag">; -------------- next part -------------- A non-text attachment was scrubbed... Name: D75171.253506.patch Type: text/x-patch Size: 3705 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 01:02:40 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 08:02:40 +0000 (UTC) Subject: [PATCH] D77037: [AST] Fix crashes on decltype(recovery-expr). Message-ID: hokein created this revision. hokein added a reviewer: sammccall. Herald added a project: clang. We mark these decls as invalid. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77037 Files: clang/include/clang/AST/DependenceFlags.h clang/include/clang/AST/Type.h clang/lib/Parse/ParseExprCXX.cpp clang/lib/Sema/SemaType.cpp clang/test/AST/ast-dump-expr-errors.cpp clang/test/Sema/invalid-member.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77037.253507.patch Type: text/x-patch Size: 5004 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 01:02:41 2020 From: cfe-commits at lists.llvm.org (Kanglei Fang via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 08:02:41 +0000 (UTC) Subject: [PATCH] D77039: [clang-format] Don't break multi block parameters on ObjCBreakBeforeNestedBlockParam Message-ID: ghvg1313 created this revision. ghvg1313 added reviewers: jolesiak, benhamilton. Herald added a project: clang. Herald added a subscriber: cfe-commits. While the original diff makes a lot of sense, and multiple inline block parameter/trailing paramemter after inline block paramemter should be discouraged, the formatting result is different than what xcode does by default For the exact same example provided in the original diff: [object blockArgument:^{ a = 42; } anotherArg:42]; The code is hard to read and not very visually pleasing This diff uses `ObjCBreakBeforeNestedBlockParam` to shield from the formatting When it's set to false, don't allign the inline block paramemters. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77039 Files: clang/lib/Format/ContinuationIndenter.cpp clang/unittests/Format/FormatTestObjC.cpp Index: clang/unittests/Format/FormatTestObjC.cpp =================================================================== --- clang/unittests/Format/FormatTestObjC.cpp +++ clang/unittests/Format/FormatTestObjC.cpp @@ -1420,6 +1420,10 @@ "*b, NSNumber *c) {\n" " b = c;\n" "}]"); + verifyFormat("[self.test1 t:self w:self callback:^(typeof(self) self, " + "NSNumber *u, NSNumber *v) {\n" + " u = v;\n" + "} z:self]"); Style.ColumnLimit = 80; verifyFormat( Index: clang/lib/Format/ContinuationIndenter.cpp =================================================================== --- clang/lib/Format/ContinuationIndenter.cpp +++ clang/lib/Format/ContinuationIndenter.cpp @@ -342,6 +342,7 @@ if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection) return true; if (Style.Language == FormatStyle::LK_ObjC && + Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) { return true; -------------- next part -------------- A non-text attachment was scrubbed... Name: D77039.253510.patch Type: text/x-patch Size: 1107 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 01:02:43 2020 From: cfe-commits at lists.llvm.org (Marcel Hlopko via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 08:02:43 +0000 (UTC) Subject: [PATCH] D76922: [Syntax] Remove delayed folding from tree building. In-Reply-To: References: Message-ID: hlopko updated this revision to Diff 253517. hlopko added a comment. Rebase Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76922/new/ https://reviews.llvm.org/D76922 Files: clang/lib/Tooling/Syntax/BuildTree.cpp clang/lib/Tooling/Syntax/Tokens.cpp clang/unittests/Tooling/Syntax/TreeTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76922.253517.patch Type: text/x-patch Size: 23259 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 01:35:30 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 08:35:30 +0000 (UTC) Subject: [PATCH] D77041: [AST] Fix a crash on invalid constexpr Ctorinitializer when building RecoveryExpr. In-Reply-To: References: Message-ID: <38662362b4cb7e45b096b90dfff16ac0@localhost.localdomain> hokein added inline comments. ================ Comment at: clang/lib/Sema/SemaDecl.cpp:14359 + !ErrorsInCtorInitializer && !CheckConstexprFunctionDefinition(FD, CheckConstexprKind::Diagnose)) FD->setInvalidDecl(); ---------------- The crash is in `CheckConstexprFunctionDefinition`, I tried different ways to fixing it: 1) mark `FD` invalid when there are any errors in CtorInitailizer -- clang deliberately treats CtorDecl as valid even there are some errors in the initializer to prevent spurious diagnostics (see the cycle delegation in the test as an example), so marking them invalid may affect the quality of diagnostics; 2) Fixing it inside `CheckConstexprFunctionDefinition` or `isPotentialConstantExpr`, but it doesn't seem to be a right layer, these functions are expected to be called on a validDecl (or at least after a few sanity checks), and emit diagnostics. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77041/new/ https://reviews.llvm.org/D77041 From cfe-commits at lists.llvm.org Mon Mar 30 01:35:32 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 08:35:32 +0000 (UTC) Subject: [PATCH] D77041: [AST] Fix a crash on invalid constexpr Ctorinitializer when building RecoveryExpr. Message-ID: hokein created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. hokein edited the summary of this revision. hokein added inline comments. hokein added a reviewer: sammccall. ================ Comment at: clang/lib/Sema/SemaDecl.cpp:14359 + !ErrorsInCtorInitializer && !CheckConstexprFunctionDefinition(FD, CheckConstexprKind::Diagnose)) FD->setInvalidDecl(); ---------------- The crash is in `CheckConstexprFunctionDefinition`, I tried different ways to fixing it: 1) mark `FD` invalid when there are any errors in CtorInitailizer -- clang deliberately treats CtorDecl as valid even there are some errors in the initializer to prevent spurious diagnostics (see the cycle delegation in the test as an example), so marking them invalid may affect the quality of diagnostics; 2) Fixing it inside `CheckConstexprFunctionDefinition` or `isPotentialConstantExpr`, but it doesn't seem to be a right layer, these functions are expected to be called on a validDecl (or at least after a few sanity checks), and emit diagnostics. crash stack: lang: workspace/llvm-project/clang/lib/AST/ExprConstant.cpp:13704: bool EvaluateInPlace(clang::APValue &, (anonymous namespace)::EvalInfo &, const (anonymous namespace)::LValue &, const clang::Expr *, bool): Assertion `!E->isValueDependent()' failed. #8 EvaluateInPlace(clang::APValue&, (anonymous namespace)::EvalInfo&, (anonymous namespace)::LValue const&, clang::Expr const*, bool) workspace/llvm-project/clang/lib/AST/ExprConstant.cpp:0:0 #9 HandleConstructorCall(clang::Expr const*, (anonymous namespace)::LValue const&, clang::APValue*, clang::CXXConstructorDecl const*, (anonymous namespace)::EvalInfo&, clang::APValue&) workspace/llvm-project/clang/lib/AST/ExprConstant.cpp:5779:57 #10 HandleConstructorCall(clang::Expr const*, (anonymous namespace)::LValue const&, llvm::ArrayRef, clang::CXXConstructorDecl const*, (anonymous namespace)::EvalInfo&, clang::APValue&) workspace/llvm-project/clang/lib/AST/ExprConstant.cpp:5819:10 #11 clang::Expr::isPotentialConstantExpr(clang::FunctionDecl const*, llvm::SmallVectorImpl >&) workspace/llvm-project/clang/lib/AST/ExprConstant.cpp:14746:5 #12 CheckConstexprFunctionBody(clang::Sema&, clang::FunctionDecl const*, clang::Stmt*, clang::Sema::CheckConstexprKind) workspace/llvm-project/clang/lib/Sema/SemaDeclCXX.cpp:2306:7 #13 clang::Sema::CheckConstexprFunctionDefinition(clang::FunctionDecl const*, clang::Sema::CheckConstexprKind) workspace/llvm-project/clang/lib/Sema/SemaDeclCXX.cpp:1766:0 #14 clang::Sema::ActOnFinishFunctionBody(clang::Decl*, clang::Stmt*, bool) workspace/llvm-project/clang/lib/Sema/SemaDecl.cpp:14357:9 #15 clang::Parser::ParseFunctionStatementBody(clang::Decl*, clang::Parser::ParseScope&) workspace/llvm-project/clang/lib/Parse/ParseStmt.cpp:2213:18 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77041 Files: clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/test/SemaCXX/invalid-constructor-init.cpp Index: clang/test/SemaCXX/invalid-constructor-init.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/invalid-constructor-init.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -frecovery-ast -verify %s + +struct X { + int Y; + constexpr X() : Y(foo()) {} // expected-error {{use of undeclared identifier 'foo'}} +}; + +struct X2 { + int Y = foo(); // expected-error {{use of undeclared identifier 'foo'}} \ + // expected-note {{subexpression not valid in a constant expression}} + constexpr X2() {} // expected-error {{constexpr constructor never produces a constant expression}} +}; + +struct CycleDelegate { + int Y; + CycleDelegate(int) : Y(foo()) {} // expected-error {{use of undeclared identifier 'foo'}} + // no "delegation cycle" diagnostic emitted! + CycleDelegate(float) : CycleDelegate(1) {} +}; Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -1685,6 +1685,7 @@ // This implements C++11 [dcl.constexpr]p3,4, as amended by DR1360. bool Sema::CheckConstexprFunctionDefinition(const FunctionDecl *NewFD, CheckConstexprKind Kind) { + assert(!NewFD->isInvalidDecl()); const CXXMethodDecl *MD = dyn_cast(NewFD); if (MD && MD->isInstance()) { // C++11 [dcl.constexpr]p4: Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -45,6 +45,7 @@ #include "clang/Sema/Template.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Triple.h" +#include "llvm/Support/Casting.h" #include #include #include @@ -14345,7 +14346,16 @@ ActivePolicy = &WP; } + bool ErrorsInCtorInitializer = + llvm::isa_and_nonnull(FD) + ? llvm::any_of(llvm::dyn_cast(FD)->inits(), + [](const auto *Init) { + return Init->getInit() && + Init->getInit()->containsErrors(); + }) + : false; if (!IsInstantiation && FD && FD->isConstexpr() && !FD->isInvalidDecl() && + !ErrorsInCtorInitializer && !CheckConstexprFunctionDefinition(FD, CheckConstexprKind::Diagnose)) FD->setInvalidDecl(); -------------- next part -------------- A non-text attachment was scrubbed... Name: D77041.253521.patch Type: text/x-patch Size: 2526 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 01:35:32 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 08:35:32 +0000 (UTC) Subject: [PATCH] D76953: [AST] Fix a crash on invalid bitwidth exprs when preserving the recoveryexprs. In-Reply-To: References: Message-ID: hokein updated this revision to Diff 253523. hokein marked 2 inline comments as done. hokein added a comment. address comments. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76953/new/ https://reviews.llvm.org/D76953 Files: clang/lib/AST/ASTContext.cpp clang/lib/AST/RecordLayoutBuilder.cpp clang/lib/Sema/SemaDecl.cpp clang/test/Sema/invalid-bitwidth-expr.mm Index: clang/test/Sema/invalid-bitwidth-expr.mm =================================================================== --- /dev/null +++ clang/test/Sema/invalid-bitwidth-expr.mm @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fobjc-runtime=gcc -frecovery-ast -verify %s +// RUN: %clang_cc1 -fobjc-runtime=gcc -fno-recovery-ast -verify %s + + at interface Ivar +{ + int Foo : foo(); // expected-error {{use of undeclared identifier}} +}; + at end + +struct X { int Y: foo(); }; // expected-error {{use of undeclared identifier}} + +constexpr int s = sizeof(Ivar); +constexpr int ss = sizeof(X); Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -16172,6 +16172,10 @@ IdentifierInfo *FieldName, QualType FieldTy, bool IsMsStruct, Expr *BitWidth, bool *ZeroWidth) { + assert(BitWidth); + if (BitWidth->containsErrors()) + return ExprError(); + // Default to true; that shouldn't confuse checks for emptiness if (ZeroWidth) *ZeroWidth = true; Index: clang/lib/AST/RecordLayoutBuilder.cpp =================================================================== --- clang/lib/AST/RecordLayoutBuilder.cpp +++ clang/lib/AST/RecordLayoutBuilder.cpp @@ -3222,7 +3222,8 @@ if (D->hasExternalLexicalStorage() && !D->getDefinition()) getExternalSource()->CompleteType(const_cast(D)); D = D->getDefinition(); - assert(D && D->isThisDeclarationADefinition() && "Invalid interface decl!"); + assert(D && !D->isInvalidDecl() && D->isThisDeclarationADefinition() && + "Invalid interface decl!"); // Look up this layout, if already laid out, return what we have. const ObjCContainerDecl *Key = Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -2161,6 +2161,11 @@ return getTypeInfo(cast(T)->getAdjustedType().getTypePtr()); case Type::ObjCInterface: { const auto *ObjCI = cast(T); + if (ObjCI->getDecl()->isInvalidDecl()) { + Width = 8; + Align = 8; + break; + } const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl()); Width = toBits(Layout.getSize()); Align = toBits(Layout.getAlignment()); -------------- next part -------------- A non-text attachment was scrubbed... Name: D76953.253523.patch Type: text/x-patch Size: 2462 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 01:38:49 2020 From: cfe-commits at lists.llvm.org (=?UTF-8?B?QmFsw6F6cyBLw6lyaQ==?= via cfe-commits) Date: Mon, 30 Mar 2020 01:38:49 -0700 (PDT) Subject: [clang] dcc04e0 - [Analyzer][MallocChecker] No warning for kfree of ZERO_SIZE_PTR. Message-ID: <5e81b019.1c69fb81.c6694.7702@mx.google.com> Author: Balázs Kéri Date: 2020-03-30T10:33:14+02:00 New Revision: dcc04e09cf6e36c6d2c47057a8f201f2c0784c69 URL: https://github.com/llvm/llvm-project/commit/dcc04e09cf6e36c6d2c47057a8f201f2c0784c69 DIFF: https://github.com/llvm/llvm-project/commit/dcc04e09cf6e36c6d2c47057a8f201f2c0784c69.diff LOG: [Analyzer][MallocChecker] No warning for kfree of ZERO_SIZE_PTR. Summary: The kernel kmalloc function may return a constant value ZERO_SIZE_PTR if a zero-sized block is allocated. This special value is allowed to be passed to kfree and should produce no warning. This is a simple version but should be no problem. The macro is always detected independent of if this is a kernel source code or any other code. Reviewers: Szelethus, martong Reviewed By: Szelethus, martong Subscribers: rnkovacs, xazax.hun, baloghadamsoftware, szepet, a.sidorin, mikhail.ramalho, Szelethus, donat.nagy, dkrupp, gamesh411, Charusso, martong, ASDenysPetrov, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D76830 Added: Modified: clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp clang/test/Analysis/kmalloc-linux.c clang/test/Analysis/malloc.cpp Removed: ################################################################################ diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index baf2c48de3b2..32a500ffd102 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -58,6 +58,7 @@ #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h" #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" @@ -389,6 +390,13 @@ class MallocChecker // TODO: Remove mutable by moving the initializtaion to the registry function. mutable Optional KernelZeroFlagVal; + using KernelZeroSizePtrValueTy = Optional; + /// Store the value of macro called `ZERO_SIZE_PTR`. + /// The value is initialized at first use, before first use the outer + /// Optional is empty, afterwards it contains another Optional that indicates + /// if the macro value could be determined, and if yes the value itself. + mutable Optional KernelZeroSizePtrValue; + /// Process C++ operator new()'s allocation, which is the part of C++ /// new-expression that goes before the constructor. void processNewAllocation(const CXXNewExpr *NE, CheckerContext &C, @@ -658,6 +666,10 @@ class MallocChecker CheckerContext &C); void reportLeak(SymbolRef Sym, ExplodedNode *N, CheckerContext &C) const; + + /// Test if value in ArgVal equals to value in macro `ZERO_SIZE_PTR`. + bool isArgZERO_SIZE_PTR(ProgramStateRef State, CheckerContext &C, + SVal ArgVal) const; }; //===----------------------------------------------------------------------===// @@ -1677,7 +1689,13 @@ ProgramStateRef MallocChecker::FreeMemAux( // Nonlocs can't be freed, of course. // Non-region locations (labels and fixed addresses) also shouldn't be freed. if (!R) { - ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr, Family); + // Exception: + // If the macro ZERO_SIZE_PTR is defined, this could be a kernel source + // code. In that case, the ZERO_SIZE_PTR defines a special value used for a + // zero-sized memory block which is allowed to be freed, despite not being a + // null pointer. + if (Family != AF_Malloc || !isArgZERO_SIZE_PTR(State, C, ArgVal)) + ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr, Family); return nullptr; } @@ -3023,6 +3041,18 @@ ProgramStateRef MallocChecker::checkPointerEscapeAux( return State; } +bool MallocChecker::isArgZERO_SIZE_PTR(ProgramStateRef State, CheckerContext &C, + SVal ArgVal) const { + if (!KernelZeroSizePtrValue) + KernelZeroSizePtrValue = + tryExpandAsInteger("ZERO_SIZE_PTR", C.getPreprocessor()); + + const llvm::APSInt *ArgValKnown = + C.getSValBuilder().getKnownValue(State, ArgVal); + return ArgValKnown && *KernelZeroSizePtrValue && + ArgValKnown->getSExtValue() == **KernelZeroSizePtrValue; +} + static SymbolRef findFailedReallocSymbol(ProgramStateRef currState, ProgramStateRef prevState) { ReallocPairsTy currMap = currState->get(); diff --git a/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp b/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp index e43b172d018d..4b63ebc40ede 100644 --- a/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp +++ b/clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp @@ -126,9 +126,6 @@ llvm::Optional tryExpandAsInteger(StringRef Macro, if (!T.isOneOf(tok::l_paren, tok::r_paren)) FilteredTokens.push_back(T); - if (FilteredTokens.size() > 2) - return llvm::None; - // Parse an integer at the end of the macro definition. const Token &T = FilteredTokens.back(); if (!T.isLiteral()) @@ -140,11 +137,10 @@ llvm::Optional tryExpandAsInteger(StringRef Macro, return llvm::None; // Parse an optional minus sign. - if (FilteredTokens.size() == 2) { - if (FilteredTokens.front().is(tok::minus)) + size_t Size = FilteredTokens.size(); + if (Size >= 2) { + if (FilteredTokens[Size - 2].is(tok::minus)) IntValue = -IntValue; - else - return llvm::None; } return IntValue.getSExtValue(); diff --git a/clang/test/Analysis/kmalloc-linux.c b/clang/test/Analysis/kmalloc-linux.c index 6b17ef2d5a79..4cca5712b096 100644 --- a/clang/test/Analysis/kmalloc-linux.c +++ b/clang/test/Analysis/kmalloc-linux.c @@ -121,3 +121,17 @@ void test_3arg_malloc_leak(struct malloc_type *mtp, int flags) { if (list == NULL) return; } // expected-warning{{Potential leak of memory pointed to by 'list'}} + +// kmalloc can return a constant value defined in ZERO_SIZE_PTR +// if a block of size 0 is requested +#define ZERO_SIZE_PTR ((void *)16) + +void test_kfree_ZERO_SIZE_PTR() { + void *ptr = ZERO_SIZE_PTR; + kfree(ptr); // no warning about freeing this value +} + +void test_kfree_other_constant_value() { + void *ptr = (void *)1; + kfree(ptr); // expected-warning{{Argument to kfree() is a constant address (1)}} +} diff --git a/clang/test/Analysis/malloc.cpp b/clang/test/Analysis/malloc.cpp index 6e5a0e4d5971..cc7fefe23d75 100644 --- a/clang/test/Analysis/malloc.cpp +++ b/clang/test/Analysis/malloc.cpp @@ -164,3 +164,11 @@ void test(A a) { (void)a.getName(); } } // namespace argument_leak + +#define ZERO_SIZE_PTR ((void *)16) + +void test_delete_ZERO_SIZE_PTR() { + int *Ptr = (int *)ZERO_SIZE_PTR; + // ZERO_SIZE_PTR is specially handled but only for malloc family + delete Ptr; // expected-warning{{Argument to 'delete' is a constant address (16)}} +} From cfe-commits at lists.llvm.org Mon Mar 30 01:52:12 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via cfe-commits) Date: Mon, 30 Mar 2020 01:52:12 -0700 (PDT) Subject: [clang] f757ecb - [AST] Fix a crash on invalid bitwidth exprs when preserving the recoveryexprs. Message-ID: <5e81b33c.1c69fb81.b9861.bede@mx.google.com> Author: Haojian Wu Date: 2020-03-30T10:52:00+02:00 New Revision: f757ecbf85605735195441abefd9c291f5e317cc URL: https://github.com/llvm/llvm-project/commit/f757ecbf85605735195441abefd9c291f5e317cc DIFF: https://github.com/llvm/llvm-project/commit/f757ecbf85605735195441abefd9c291f5e317cc.diff LOG: [AST] Fix a crash on invalid bitwidth exprs when preserving the recoveryexprs. Summary: If the bitwith expr contains errors, we mark the field decl invalid. This patch also tweaks the behavior of ObjCInterfaceDecl to be consistent with existing RecordDecl -- getObjCLayout method is only called with valid decls. Reviewers: sammccall Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D76953 Added: clang/test/Sema/invalid-bitwidth-expr.mm Modified: clang/lib/AST/ASTContext.cpp clang/lib/AST/RecordLayoutBuilder.cpp clang/lib/Sema/SemaDecl.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 19f67fc2bb3f..461b155df7bf 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2161,6 +2161,11 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { return getTypeInfo(cast(T)->getAdjustedType().getTypePtr()); case Type::ObjCInterface: { const auto *ObjCI = cast(T); + if (ObjCI->getDecl()->isInvalidDecl()) { + Width = 8; + Align = 8; + break; + } const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl()); Width = toBits(Layout.getSize()); Align = toBits(Layout.getAlignment()); diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 9a21732b63e3..028e82a5df4d 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -3222,7 +3222,8 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D, if (D->hasExternalLexicalStorage() && !D->getDefinition()) getExternalSource()->CompleteType(const_cast(D)); D = D->getDefinition(); - assert(D && D->isThisDeclarationADefinition() && "Invalid interface decl!"); + assert(D && !D->isInvalidDecl() && D->isThisDeclarationADefinition() && + "Invalid interface decl!"); // Look up this layout, if already laid out, return what we have. const ObjCContainerDecl *Key = diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 9319f4eff919..ea3a0c22c401 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -16172,6 +16172,10 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, QualType FieldTy, bool IsMsStruct, Expr *BitWidth, bool *ZeroWidth) { + assert(BitWidth); + if (BitWidth->containsErrors()) + return ExprError(); + // Default to true; that shouldn't confuse checks for emptiness if (ZeroWidth) *ZeroWidth = true; diff --git a/clang/test/Sema/invalid-bitwidth-expr.mm b/clang/test/Sema/invalid-bitwidth-expr.mm new file mode 100644 index 000000000000..fe93cac683ae --- /dev/null +++ b/clang/test/Sema/invalid-bitwidth-expr.mm @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fobjc-runtime=gcc -frecovery-ast -verify %s +// RUN: %clang_cc1 -fobjc-runtime=gcc -fno-recovery-ast -verify %s + + at interface Ivar +{ + int Foo : foo(); // expected-error {{use of undeclared identifier}} +}; + at end + +struct X { int Y: foo(); }; // expected-error {{use of undeclared identifier}} + +constexpr int s = sizeof(Ivar); +constexpr int ss = sizeof(X); From cfe-commits at lists.llvm.org Mon Mar 30 02:08:03 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Bal=C3=A1zs_K=C3=A9ri_via_Phabricator?= via cfe-commits) Date: Mon, 30 Mar 2020 09:08:03 +0000 (UTC) Subject: [PATCH] D76830: [Analyzer][MallocChecker] No warning for kfree of ZERO_SIZE_PTR. In-Reply-To: References: Message-ID: <4f2bdd89051979cc03c3bff17aee68c9@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGdcc04e09cf6e: [Analyzer][MallocChecker] No warning for kfree of ZERO_SIZE_PTR. (authored by balazske). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76830/new/ https://reviews.llvm.org/D76830 Files: clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp clang/lib/StaticAnalyzer/Core/CheckerHelpers.cpp clang/test/Analysis/kmalloc-linux.c clang/test/Analysis/malloc.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76830.253526.patch Type: text/x-patch Size: 5518 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 02:08:13 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 09:08:13 +0000 (UTC) Subject: [PATCH] D76953: [AST] Fix a crash on invalid bitwidth exprs when preserving the recoveryexprs. In-Reply-To: References: Message-ID: <8553cac1d9d6a4abbc4ce2c963adf1a8@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGf757ecbf8560: [AST] Fix a crash on invalid bitwidth exprs when preserving the recoveryexprs. (authored by hokein). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76953/new/ https://reviews.llvm.org/D76953 Files: clang/lib/AST/ASTContext.cpp clang/lib/AST/RecordLayoutBuilder.cpp clang/lib/Sema/SemaDecl.cpp clang/test/Sema/invalid-bitwidth-expr.mm Index: clang/test/Sema/invalid-bitwidth-expr.mm =================================================================== --- /dev/null +++ clang/test/Sema/invalid-bitwidth-expr.mm @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fobjc-runtime=gcc -frecovery-ast -verify %s +// RUN: %clang_cc1 -fobjc-runtime=gcc -fno-recovery-ast -verify %s + + at interface Ivar +{ + int Foo : foo(); // expected-error {{use of undeclared identifier}} +}; + at end + +struct X { int Y: foo(); }; // expected-error {{use of undeclared identifier}} + +constexpr int s = sizeof(Ivar); +constexpr int ss = sizeof(X); Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -16172,6 +16172,10 @@ IdentifierInfo *FieldName, QualType FieldTy, bool IsMsStruct, Expr *BitWidth, bool *ZeroWidth) { + assert(BitWidth); + if (BitWidth->containsErrors()) + return ExprError(); + // Default to true; that shouldn't confuse checks for emptiness if (ZeroWidth) *ZeroWidth = true; Index: clang/lib/AST/RecordLayoutBuilder.cpp =================================================================== --- clang/lib/AST/RecordLayoutBuilder.cpp +++ clang/lib/AST/RecordLayoutBuilder.cpp @@ -3222,7 +3222,8 @@ if (D->hasExternalLexicalStorage() && !D->getDefinition()) getExternalSource()->CompleteType(const_cast(D)); D = D->getDefinition(); - assert(D && D->isThisDeclarationADefinition() && "Invalid interface decl!"); + assert(D && !D->isInvalidDecl() && D->isThisDeclarationADefinition() && + "Invalid interface decl!"); // Look up this layout, if already laid out, return what we have. const ObjCContainerDecl *Key = Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -2161,6 +2161,11 @@ return getTypeInfo(cast(T)->getAdjustedType().getTypePtr()); case Type::ObjCInterface: { const auto *ObjCI = cast(T); + if (ObjCI->getDecl()->isInvalidDecl()) { + Width = 8; + Align = 8; + break; + } const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl()); Width = toBits(Layout.getSize()); Align = toBits(Layout.getAlignment()); -------------- next part -------------- A non-text attachment was scrubbed... Name: D76953.253528.patch Type: text/x-patch Size: 2462 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 02:40:30 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 09:40:30 +0000 (UTC) Subject: [PATCH] D77037: [AST] Fix crashes on decltype(recovery-expr). In-Reply-To: References: Message-ID: sammccall added inline comments. ================ Comment at: clang/include/clang/AST/Type.h:2144 + bool isErrorType() const { + return getDependence() & TypeDependence::Error; + } ---------------- Why is this called `isErrorType` when the expr version is `containsErrors`? ================ Comment at: clang/lib/Parse/ParseExprCXX.cpp:3109 + QualType PreferredType; + if (TypeRep) + PreferredType = Actions.ProduceConstructorSignatureHelp( ---------------- Add a comment for what the null case means? (When do we actually hit this?) ================ Comment at: clang/lib/Sema/SemaType.cpp:1591 + if (Result.isNull() || Result->isErrorType()) { Result = Context.IntTy; declarator.setInvalidType(true); ---------------- we've added the ability to represent types containing errors, but now we're dropping the type. Is marking the declarator as invalid sufficient? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77037/new/ https://reviews.llvm.org/D77037 From cfe-commits at lists.llvm.org Mon Mar 30 02:40:33 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 09:40:33 +0000 (UTC) Subject: [PATCH] D77012: [analyzer] Fix StdLibraryFunctionsChecker NotNull Constraint Check In-Reply-To: References: Message-ID: martong accepted this revision. martong added a comment. LGTM and thanks! In D77012#1948550 , @NoQ wrote: > Thanks! > > @Szelethus can we make this checker depend on undefined value checker (probably CallAndMessage) so that uninitialized arguments were handled first? In fact, can we make a silent assumption that everything depends on `core`? If so we could eliminate all checks for undefined values in PreStmt and PreCall. +1, we should really do that. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77012/new/ https://reviews.llvm.org/D77012 From cfe-commits at lists.llvm.org Mon Mar 30 03:12:56 2020 From: cfe-commits at lists.llvm.org (Cristian Adam via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 10:12:56 +0000 (UTC) Subject: [PATCH] D75068: libclang: Add static build support for Windows In-Reply-To: References: Message-ID: <0b6e1da535421f234c2cb66b8e458379@localhost.localdomain> cristian.adam added a comment. Ping Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75068/new/ https://reviews.llvm.org/D75068 From cfe-commits at lists.llvm.org Mon Mar 30 03:13:00 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 10:13:00 +0000 (UTC) Subject: [PATCH] D77041: [AST] Fix a crash on invalid constexpr Ctorinitializer when building RecoveryExpr. In-Reply-To: References: Message-ID: <1a659722829b4500fab0918e576e962d@localhost.localdomain> sammccall added a comment. This makes me nervous, marking the constructor as invalid seems much safer. Can you show tests it regresses? ================ Comment at: clang/lib/Sema/SemaDecl.cpp:14359 + !ErrorsInCtorInitializer && !CheckConstexprFunctionDefinition(FD, CheckConstexprKind::Diagnose)) FD->setInvalidDecl(); ---------------- hokein wrote: > The crash is in `CheckConstexprFunctionDefinition`, I tried different ways to fixing it: > > 1) mark `FD` invalid when there are any errors in CtorInitailizer -- clang deliberately treats CtorDecl as valid even there are some errors in the initializer to prevent spurious diagnostics (see the cycle delegation in the test as an example), so marking them invalid may affect the quality of diagnostics; > > 2) Fixing it inside `CheckConstexprFunctionDefinition` or `isPotentialConstantExpr`, but it doesn't seem to be a right layer, these functions are expected to be called on a validDecl (or at least after a few sanity checks), and emit diagnostics. > clang deliberately treats CtorDecl as valid even there are some errors in the initializer Do you mean currently? (when such errors result in destroying the whole init expr) If so, it would be nice to preserve this indeed. I'm worried that we're going to decide that a constexpr constructor is valid and then actually try to evaluate it at compile time. What happens if we try to evaluate `constexpr int Z = X().Y` in your testcase? > Fixing it inside CheckConstexprFunctionDefinition I have a couple of concerns with where it's currently implemented: - aren't there lots of other paths we're going to call isPotentialConstantExpr and crash? CheckConstexprFunctionDefinition is large and complicated, init-lists are only a small part. - if we treat anything with errors in the ctor as valid (am I reading that right?!) then won't that mask *other* problems where the non-error parts of the definition should cause it to be treated as invalid? e.g. `Foo() : m1(broken_but_maybe_constexpr()), m2(exists_and_not_constexpr()) {}` Wherever this goes, if we're going to do something subtle like marking diagnostics as valid based on errors in them, it deserves a comment laying out the cases. ================ Comment at: clang/test/SemaCXX/invalid-constructor-init.cpp:17 + CycleDelegate(int) : Y(foo()) {} // expected-error {{use of undeclared identifier 'foo'}} + // no "delegation cycle" diagnostic emitted! + CycleDelegate(float) : CycleDelegate(1) {} ---------------- what's the behavior with -fno-recovery-ast? (It'd be nice to improve it, failing to improve it is OK. regressing is probably bad...) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77041/new/ https://reviews.llvm.org/D77041 From cfe-commits at lists.llvm.org Mon Mar 30 03:13:01 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 10:13:01 +0000 (UTC) Subject: [PATCH] D77037: [AST] Fix crashes on decltype(recovery-expr). In-Reply-To: References: Message-ID: hokein updated this revision to Diff 253537. hokein marked 3 inline comments as done. hokein added a comment. address review comments. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77037/new/ https://reviews.llvm.org/D77037 Files: clang/include/clang/AST/DependenceFlags.h clang/include/clang/AST/Type.h clang/lib/Parse/ParseExprCXX.cpp clang/lib/Sema/SemaType.cpp clang/test/AST/ast-dump-expr-errors.cpp clang/test/Sema/invalid-member.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77037.253537.patch Type: text/x-patch Size: 4988 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 03:13:01 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 10:13:01 +0000 (UTC) Subject: [PATCH] D77037: [AST] Fix crashes on decltype(recovery-expr). In-Reply-To: References: Message-ID: hokein added inline comments. ================ Comment at: clang/lib/Parse/ParseExprCXX.cpp:3109 + QualType PreferredType; + if (TypeRep) + PreferredType = Actions.ProduceConstructorSignatureHelp( ---------------- sammccall wrote: > Add a comment for what the null case means? (When do we actually hit this?) yeah, the [`CompleteTest`](https://github.com/llvm/llvm-project/blob/master/clang/unittests/Sema/CodeCompleteTest.cpp#L490) hits the assertion after this patch. the assertion seems incorrect -- IIUC, the assertion is for the `isInvalidType()` sanity check on Line 3090, however In `ActOnTypeName`, `DeclaratorInfo` could be modified (by `GetTypeForDeclarator`) before calling `isInvalidType`. btw, I think for the CodeCompleteTest, would be nicer to make `ActOnTypeName` return `decltype((bar))`, rather than the null type, but I'm not sure changing the `ActOnTypeName` behavior has any side effect. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77037/new/ https://reviews.llvm.org/D77037 From cfe-commits at lists.llvm.org Mon Mar 30 03:45:01 2020 From: cfe-commits at lists.llvm.org (Lucas Prates via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 10:45:01 +0000 (UTC) Subject: [PATCH] D77048: [Clang][CodeGen] Fixing mismatch between memory layout and const expressions for oversized bitfields Message-ID: pratlucas created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. The construction of constants for structs/unions was conflicting the expected memory layout for over-sized bit-fields. When building the necessary bits for those fields, clang was ignoring the size information computed for the struct/union memory layout and using the original data from the AST's FieldDecl information. This caused an issue in big-endian targets, where the field's contant was incorrectly misplaced due to endian calculations. This patch aims to separate the constant value from the necessary padding bits, using the proper size information for each one of them. With this, the layout of constants for over-sized bit-fields matches the ABI requirements. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77048 Files: clang/lib/CodeGen/CGExprConstant.cpp clang/test/CodeGenCXX/bitfield-layout.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77048.253544.patch Type: text/x-patch Size: 4317 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 04:17:53 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 11:17:53 +0000 (UTC) Subject: [PATCH] D77037: [AST] Fix crashes on decltype(recovery-expr). In-Reply-To: References: Message-ID: <144f202c639b420a3affcd6a63a9f4a7@localhost.localdomain> sammccall accepted this revision. sammccall added inline comments. This revision is now accepted and ready to land. ================ Comment at: clang/lib/Parse/ParseExprCXX.cpp:3109 + QualType PreferredType; + if (TypeRep) + PreferredType = Actions.ProduceConstructorSignatureHelp( ---------------- hokein wrote: > sammccall wrote: > > Add a comment for what the null case means? (When do we actually hit this?) > yeah, the [`CompleteTest`](https://github.com/llvm/llvm-project/blob/master/clang/unittests/Sema/CodeCompleteTest.cpp#L490) hits the assertion after this patch. > > the assertion seems incorrect -- IIUC, the assertion is for the `isInvalidType()` sanity check on Line 3090, however > In `ActOnTypeName`, `DeclaratorInfo` could be modified (by `GetTypeForDeclarator`) before calling `isInvalidType`. > > > btw, I think for the CodeCompleteTest, would be nicer to make `ActOnTypeName` return `decltype((bar))`, rather than the null type, but I'm not sure changing the `ActOnTypeName` behavior has any side effect. > the assertion seems incorrect -- IIUC, the assertion is for the isInvalidType() sanity check on Line 3090, however What you say makes sense, but I think it's worth probing why it's not currently hit (e.g. by `int x(auto);`, where `GetDeclSpecTypeForDeclarator` marks the decl as invalid because auto isn't allowed in a prototype). > btw, I think for the CodeCompleteTest, would be nicer to make ActOnTypeName return decltype((bar)), rather than the null type Definitely. I think "invalid" on a type-concept is stronger than what we're looking for - since we're not tracking errors in decls, we'd want to use "haserrors" on type-concepts and then promote to "invalid" on decl-concepts. Ugh, the design of "Declarator" makes this difficult, because there's no distinction between "type of this declarator is invalid" and "type of this declarator makes the declarator invalid". I'd suggest leaving a FIXME on the changes in SemaType, saying something like "we want resulting declarations to be marked invalid, but claiming the type is invalid is too strong - e.g. it causes ActOnTypeName to return a null type." ================ Comment at: clang/lib/Sema/SemaType.cpp:1594 } + if (Result->containsErrors()) + declarator.setInvalidType(true); ---------------- are you sure you want this in the individual cases, rather than once at the end of this function? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77037/new/ https://reviews.llvm.org/D77037 From cfe-commits at lists.llvm.org Mon Mar 30 04:22:05 2020 From: cfe-commits at lists.llvm.org (Krasimir Georgiev via cfe-commits) Date: Mon, 30 Mar 2020 04:22:05 -0700 (PDT) Subject: [clang] 0574030 - [clang-format] only parse C# generic type constraints in C# Message-ID: <5e81d65d.1c69fb81.b76ad.c343@mx.google.com> Author: Krasimir Georgiev Date: 2020-03-30T13:13:07+02:00 New Revision: 0574030c01615d4ce26de0d9b0d64292ab3eac9b URL: https://github.com/llvm/llvm-project/commit/0574030c01615d4ce26de0d9b0d64292ab3eac9b DIFF: https://github.com/llvm/llvm-project/commit/0574030c01615d4ce26de0d9b0d64292ab3eac9b.diff LOG: [clang-format] only parse C# generic type constraints in C# Commit "[clang-format] Handle C# generic type constraints", https://github.com/llvm/llvm-project/commit/dcbcec4822f47ec5b638dd9c20dcebd464569dae regressed the formatting of code containing `where` as an identifier in other languages. Added: Modified: clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTestCSharp.cpp Removed: ################################################################################ diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 8a1e247463d5..8f40fc7bdcb6 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1047,7 +1047,7 @@ class AnnotatingParser { Keywords.kw___has_include_next)) { parseHasInclude(); } - if (Tok->is(Keywords.kw_where) && Tok->Next && + if (Style.isCSharp() && Tok->is(Keywords.kw_where) && Tok->Next && Tok->Next->isNot(tok::l_paren)) { Tok->Type = TT_CSharpGenericTypeConstraint; parseCSharpGenericTypeConstraint(); diff --git a/clang/unittests/Format/FormatTestCSharp.cpp b/clang/unittests/Format/FormatTestCSharp.cpp index 17b8e070c36a..f5e0bab1cb31 100644 --- a/clang/unittests/Format/FormatTestCSharp.cpp +++ b/clang/unittests/Format/FormatTestCSharp.cpp @@ -709,6 +709,14 @@ class ItemFactory IAnotherInterface, IAnotherInterfaceStill {})", Style); + + // In other languages `where` can be used as a normal identifier. + // This example is in C++! + verifyFormat(R"(// +class A { + int f(int where) {} +};)", + getGoogleStyle(FormatStyle::LK_Cpp)); } } // namespace format From cfe-commits at lists.llvm.org Mon Mar 30 04:50:28 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 11:50:28 +0000 (UTC) Subject: [PATCH] D76725: [clangd] Build ASTs only with fresh preambles or after building a new preamble In-Reply-To: References: Message-ID: <5a579be2670afa1cc7ad111ca0f7cfa6@localhost.localdomain> kadircet updated this revision to Diff 253552. kadircet added a comment. - Make use of a separate queue for golden ASTs to prevent any races that might occur due PreambleThread finishing multiple preambles before ASTWorker gets to process others. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76725/new/ https://reviews.llvm.org/D76725 Files: clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Preamble.h clang-tools-extra/clangd/TUScheduler.cpp clang-tools-extra/clangd/unittests/FileIndexTests.cpp clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp clang-tools-extra/clangd/unittests/TestTU.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76725.253552.patch Type: text/x-patch Size: 46176 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 04:50:29 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 11:50:29 +0000 (UTC) Subject: [PATCH] D76594: [clang][AST] Support AST files larger than 512M In-Reply-To: References: Message-ID: sammccall added inline comments. ================ Comment at: clang/include/clang/Serialization/ASTBitCodes.h:220 /// Source range/offset of a preprocessed entity. struct DeclOffset { + /// Raw source location. The unsigned i.e. 32-bit integer is enough for ---------------- Is there one of these for every decl in the module? It seems like we're probably giving up a good fraction of the 4% increase for just using absolute 64 bit offsets everywhere :-( Is there still a significant gain from using section-relative elsewhere? If there are indeed lots of these, giving up 4 bytes to padding (in addition to the wide offset) seems unfortunate and because we memcpy the structs into the AST file seems like a sad reason :-) Can we align this to 4 bytes instead? (e.g. by splitting into two fields and encapsulating the few direct accesses, though there's probably a neater way) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76594/new/ https://reviews.llvm.org/D76594 From cfe-commits at lists.llvm.org Mon Mar 30 05:22:52 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 12:22:52 +0000 (UTC) Subject: [PATCH] D76725: [clangd] Build ASTs only with fresh preambles or after building a new preamble In-Reply-To: References: Message-ID: <4835bb514b42552b05d0356803777057@localhost.localdomain> kadircet updated this revision to Diff 253556. kadircet added a comment. - Add assertion to explicitly spell out scheduling for golden ASTs. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76725/new/ https://reviews.llvm.org/D76725 Files: clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Preamble.h clang-tools-extra/clangd/TUScheduler.cpp clang-tools-extra/clangd/unittests/FileIndexTests.cpp clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp clang-tools-extra/clangd/unittests/TestTU.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76725.253556.patch Type: text/x-patch Size: 46547 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 05:22:52 2020 From: cfe-commits at lists.llvm.org (Tamas Petz via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 12:22:52 +0000 (UTC) Subject: [PATCH] D75364: [clang-format] Handle macros in function params and return value In-Reply-To: References: Message-ID: <7f9d46f7dd86db3315bd9fe6a6e29d29@localhost.localdomain> tamas.petz added a comment. Friendly ping. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75364/new/ https://reviews.llvm.org/D75364 From cfe-commits at lists.llvm.org Mon Mar 30 05:23:16 2020 From: cfe-commits at lists.llvm.org (Ulrich Weigand via cfe-commits) Date: Mon, 30 Mar 2020 05:23:16 -0700 (PDT) Subject: [clang] 9c9d88d - [SystemZ] Allow configuring default CLANG_SYSTEMZ_ARCH Message-ID: <5e81e4b4.1c69fb81.84d40.d278@mx.google.com> Author: Ulrich Weigand Date: 2020-03-30T14:20:48+02:00 New Revision: 9c9d88d8b1bb6468f6c4258fe41bbcd01f742801 URL: https://github.com/llvm/llvm-project/commit/9c9d88d8b1bb6468f6c4258fe41bbcd01f742801 DIFF: https://github.com/llvm/llvm-project/commit/9c9d88d8b1bb6468f6c4258fe41bbcd01f742801.diff LOG: [SystemZ] Allow configuring default CLANG_SYSTEMZ_ARCH On Ubuntu, we want to raise default CLANG_SYSTEMZ_ARCH to z13, thus allow configuring this via CMake. On Debian, we want to raise it to z196. Author: Dimitri John Ledkov Differential Revision: https://reviews.llvm.org/D75914 Added: Modified: clang/CMakeLists.txt clang/lib/Driver/ToolChains/Arch/SystemZ.cpp Removed: ################################################################################ diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index 7809d6529195..c9e76c5e4518 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -306,6 +306,10 @@ if (NOT DEFINED MATCHED_ARCH OR "${CMAKE_MATCH_1}" LESS 35) "Default architecture for OpenMP offloading to Nvidia GPUs." FORCE) endif() +set(CLANG_SYSTEMZ_DEFAULT_ARCH "z10" CACHE STRING + "SystemZ Default Arch") +add_definitions( -DCLANG_SYSTEMZ_DEFAULT_ARCH="${CLANG_SYSTEMZ_DEFAULT_ARCH}") + set(CLANG_VENDOR ${PACKAGE_VENDOR} CACHE STRING "Vendor-specific text for showing with version information.") diff --git a/clang/lib/Driver/ToolChains/Arch/SystemZ.cpp b/clang/lib/Driver/ToolChains/Arch/SystemZ.cpp index 4d871104c95a..b263fb7df09e 100644 --- a/clang/lib/Driver/ToolChains/Arch/SystemZ.cpp +++ b/clang/lib/Driver/ToolChains/Arch/SystemZ.cpp @@ -47,7 +47,7 @@ std::string systemz::getSystemZTargetCPU(const ArgList &Args) { return std::string(CPUName); } - return "z10"; + return CLANG_SYSTEMZ_DEFAULT_ARCH; } void systemz::getSystemZTargetFeatures(const Driver &D, const ArgList &Args, From cfe-commits at lists.llvm.org Mon Mar 30 05:23:25 2020 From: cfe-commits at lists.llvm.org (Ulrich Weigand via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 12:23:25 +0000 (UTC) Subject: [PATCH] D75914: systemz: allow configuring default CLANG_SYSTEMZ_ARCH In-Reply-To: References: Message-ID: <91f491c6af7d8ee155acfcc998c73b3c@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG9c9d88d8b1bb: [SystemZ] Allow configuring default CLANG_SYSTEMZ_ARCH (authored by uweigand). Herald added a subscriber: cfe-commits. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75914/new/ https://reviews.llvm.org/D75914 Files: clang/CMakeLists.txt clang/lib/Driver/ToolChains/Arch/SystemZ.cpp Index: clang/lib/Driver/ToolChains/Arch/SystemZ.cpp =================================================================== --- clang/lib/Driver/ToolChains/Arch/SystemZ.cpp +++ clang/lib/Driver/ToolChains/Arch/SystemZ.cpp @@ -47,7 +47,7 @@ return std::string(CPUName); } - return "z10"; + return CLANG_SYSTEMZ_DEFAULT_ARCH; } void systemz::getSystemZTargetFeatures(const Driver &D, const ArgList &Args, Index: clang/CMakeLists.txt =================================================================== --- clang/CMakeLists.txt +++ clang/CMakeLists.txt @@ -306,6 +306,10 @@ "Default architecture for OpenMP offloading to Nvidia GPUs." FORCE) endif() +set(CLANG_SYSTEMZ_DEFAULT_ARCH "z10" CACHE STRING + "SystemZ Default Arch") +add_definitions( -DCLANG_SYSTEMZ_DEFAULT_ARCH="${CLANG_SYSTEMZ_DEFAULT_ARCH}") + set(CLANG_VENDOR ${PACKAGE_VENDOR} CACHE STRING "Vendor-specific text for showing with version information.") -------------- next part -------------- A non-text attachment was scrubbed... Name: D75914.253559.patch Type: text/x-patch Size: 942 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 05:55:19 2020 From: cfe-commits at lists.llvm.org (Marcel Hlopko via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 12:55:19 +0000 (UTC) Subject: [PATCH] D77053: [Syntax] A tool to dump syntax tree and token buffer Message-ID: hlopko created this revision. Herald added subscribers: cfe-commits, mgorny. Herald added a project: clang. hlopko updated this revision to Diff 253561. hlopko added a comment. hlopko updated this revision to Diff 253562. hlopko added a reviewer: gribozavr2. hlopko edited the summary of this revision. Cleanup hlopko added a comment. Cleanup Taking over of https://reviews.llvm.org/D70788. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77053 Files: clang/test/CMakeLists.txt clang/test/clang-syntax/no_args.cpp clang/test/clang-syntax/syntax_hello_world.cpp clang/test/clang-syntax/syntax_no_file_arg.cpp clang/test/clang-syntax/tokens_hello_world.cpp clang/test/clang-syntax/tokens_no_file_arg.cpp clang/tools/CMakeLists.txt clang/tools/clang-syntax/CMakeLists.txt clang/tools/clang-syntax/SyntaxMain.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77053.253562.patch Type: text/x-patch Size: 8055 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 05:55:19 2020 From: cfe-commits at lists.llvm.org (Marcel Hlopko via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 12:55:19 +0000 (UTC) Subject: [PATCH] D77053: [Syntax] A tool to dump syntax tree and token buffer In-Reply-To: References: Message-ID: <564265e0ef0a6b87a655ca0a0c62ca44@localhost.localdomain> hlopko updated this revision to Diff 253562. hlopko added a comment. Cleanup Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77053/new/ https://reviews.llvm.org/D77053 Files: clang/test/CMakeLists.txt clang/test/clang-syntax/no_args.cpp clang/test/clang-syntax/syntax_hello_world.cpp clang/test/clang-syntax/syntax_no_file_arg.cpp clang/test/clang-syntax/tokens_hello_world.cpp clang/test/clang-syntax/tokens_no_file_arg.cpp clang/tools/CMakeLists.txt clang/tools/clang-syntax/CMakeLists.txt clang/tools/clang-syntax/SyntaxMain.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77053.253562.patch Type: text/x-patch Size: 8055 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 05:55:19 2020 From: cfe-commits at lists.llvm.org (Marcel Hlopko via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 12:55:19 +0000 (UTC) Subject: [PATCH] D77053: [Syntax] A tool to dump syntax tree and token buffer In-Reply-To: References: Message-ID: <8b4c400b2107ff1b4f2ede8c650a88a8@localhost.localdomain> hlopko updated this revision to Diff 253561. hlopko added a comment. Cleanup Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77053/new/ https://reviews.llvm.org/D77053 Files: clang/test/CMakeLists.txt clang/test/clang-syntax/no_args.cpp clang/test/clang-syntax/syntax_hello_world.cpp clang/test/clang-syntax/syntax_no_file_arg.cpp clang/test/clang-syntax/tokens_hello_world.cpp clang/test/clang-syntax/tokens_no_file_arg.cpp clang/tools/CMakeLists.txt clang/tools/clang-syntax/CMakeLists.txt clang/tools/clang-syntax/SyntaxMain.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77053.253561.patch Type: text/x-patch Size: 8087 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 05:55:20 2020 From: cfe-commits at lists.llvm.org (Daniel Kiss via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 12:55:20 +0000 (UTC) Subject: [PATCH] D75181: [AArch64] Handle BTI/PAC in case of generated functions. In-Reply-To: References: Message-ID: <8008f6aa8f5ca9fa1251dcf29b5a7609@localhost.localdomain> danielkiss added a comment. ping CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75181/new/ https://reviews.llvm.org/D75181 From cfe-commits at lists.llvm.org Mon Mar 30 05:55:22 2020 From: cfe-commits at lists.llvm.org (Lucas Prates via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 12:55:22 +0000 (UTC) Subject: [PATCH] D77048: [Clang][CodeGen] Fixing mismatch between memory layout and const expressions for oversized bitfields In-Reply-To: References: Message-ID: <83c4aa8c95624381d98e1f9536feb814@localhost.localdomain> pratlucas updated this revision to Diff 253568. pratlucas added a comment. Formatting. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77048/new/ https://reviews.llvm.org/D77048 Files: clang/lib/CodeGen/CGExprConstant.cpp clang/test/CodeGenCXX/bitfield-layout.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77048.253568.patch Type: text/x-patch Size: 4322 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 05:55:23 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 12:55:23 +0000 (UTC) Subject: [PATCH] D77037: [AST] Fix crashes on decltype(recovery-expr). In-Reply-To: References: Message-ID: <716b8aa16f5ac2467e266d5f54f6db6b@localhost.localdomain> hokein updated this revision to Diff 253567. hokein marked 4 inline comments as done. hokein added a comment. address comments. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77037/new/ https://reviews.llvm.org/D77037 Files: clang/include/clang/AST/DependenceFlags.h clang/include/clang/AST/Type.h clang/lib/Parse/ParseExprCXX.cpp clang/lib/Sema/SemaType.cpp clang/test/AST/ast-dump-expr-errors.cpp clang/test/Sema/invalid-member.cpp clang/unittests/Sema/CodeCompleteTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77037.253567.patch Type: text/x-patch Size: 5461 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 05:55:23 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 12:55:23 +0000 (UTC) Subject: [PATCH] D77037: [AST] Fix crashes on decltype(recovery-expr). In-Reply-To: References: Message-ID: <82c59e92f3bfa13ebde4025650e6f84d@localhost.localdomain> hokein added inline comments. ================ Comment at: clang/lib/Parse/ParseExprCXX.cpp:3109 + QualType PreferredType; + if (TypeRep) + PreferredType = Actions.ProduceConstructorSignatureHelp( ---------------- sammccall wrote: > hokein wrote: > > sammccall wrote: > > > Add a comment for what the null case means? (When do we actually hit this?) > > yeah, the [`CompleteTest`](https://github.com/llvm/llvm-project/blob/master/clang/unittests/Sema/CodeCompleteTest.cpp#L490) hits the assertion after this patch. > > > > the assertion seems incorrect -- IIUC, the assertion is for the `isInvalidType()` sanity check on Line 3090, however > > In `ActOnTypeName`, `DeclaratorInfo` could be modified (by `GetTypeForDeclarator`) before calling `isInvalidType`. > > > > > > btw, I think for the CodeCompleteTest, would be nicer to make `ActOnTypeName` return `decltype((bar))`, rather than the null type, but I'm not sure changing the `ActOnTypeName` behavior has any side effect. > > the assertion seems incorrect -- IIUC, the assertion is for the isInvalidType() sanity check on Line 3090, however > > What you say makes sense, but I think it's worth probing why it's not currently hit (e.g. by `int x(auto);`, where `GetDeclSpecTypeForDeclarator` marks the decl as invalid because auto isn't allowed in a prototype). > > > btw, I think for the CodeCompleteTest, would be nicer to make ActOnTypeName return decltype((bar)), rather than the null type > > Definitely. I think "invalid" on a type-concept is stronger than what we're looking for - since we're not tracking errors in decls, we'd want to use "haserrors" on type-concepts and then promote to "invalid" on decl-concepts. > > Ugh, the design of "Declarator" makes this difficult, because there's no distinction between "type of this declarator is invalid" and "type of this declarator makes the declarator invalid". > > I'd suggest leaving a FIXME on the changes in SemaType, saying something like "we want resulting declarations to be marked invalid, but claiming the type is invalid is too strong - e.g. it causes ActOnTypeName to return a null type." > What you say makes sense, but I think it's worth probing why it's not currently hit (e.g. by int x(auto);, where GetDeclSpecTypeForDeclarator marks the decl as invalid because auto isn't allowed in a prototype). I believe the issue exists even before this patch, it was just not caught by tests. Added one. ================ Comment at: clang/lib/Sema/SemaType.cpp:1594 } + if (Result->containsErrors()) + declarator.setInvalidType(true); ---------------- sammccall wrote: > are you sure you want this in the individual cases, rather than once at the end of this function? ah, good point, moved the end of the `switch` statement. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77037/new/ https://reviews.llvm.org/D77037 From cfe-commits at lists.llvm.org Mon Mar 30 05:55:24 2020 From: cfe-commits at lists.llvm.org (Jonas Hahnfeld via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 12:55:24 +0000 (UTC) Subject: [PATCH] D75914: systemz: allow configuring default CLANG_SYSTEMZ_ARCH In-Reply-To: References: Message-ID: <34ffbe5fe75f5e3e7e374635dcd6405a@localhost.localdomain> Hahnfeld added inline comments. ================ Comment at: clang/CMakeLists.txt:311 + "SystemZ Default Arch") +add_definitions( -DCLANG_SYSTEMZ_DEFAULT_ARCH="${CLANG_SYSTEMZ_DEFAULT_ARCH}") + ---------------- Passing values like this is unusual for CMake and causes all source files to be recompiled if the value is changed. Instead could we add this to `include/clang/Config/config.h.cmake` like other `CLANG_DEFAULT_*` options? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75914/new/ https://reviews.llvm.org/D75914 From cfe-commits at lists.llvm.org Mon Mar 30 05:56:45 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via cfe-commits) Date: Mon, 30 Mar 2020 05:56:45 -0700 (PDT) Subject: [clang] 6f428e0 - [AST] Fix crashes on decltype(recovery-expr). Message-ID: <5e81ec8d.1c69fb81.c6694.8b3c@mx.google.com> Author: Haojian Wu Date: 2020-03-30T14:56:33+02:00 New Revision: 6f428e09fbe8ce7e3510ae024031a5fc19653483 URL: https://github.com/llvm/llvm-project/commit/6f428e09fbe8ce7e3510ae024031a5fc19653483 DIFF: https://github.com/llvm/llvm-project/commit/6f428e09fbe8ce7e3510ae024031a5fc19653483.diff LOG: [AST] Fix crashes on decltype(recovery-expr). Summary: We mark these decls as invalid. Reviewers: sammccall Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77037 Added: Modified: clang/include/clang/AST/DependenceFlags.h clang/include/clang/AST/Type.h clang/lib/Parse/ParseExprCXX.cpp clang/lib/Sema/SemaType.cpp clang/test/AST/ast-dump-expr-errors.cpp clang/test/Sema/invalid-member.cpp clang/unittests/Sema/CodeCompleteTest.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/DependenceFlags.h b/clang/include/clang/AST/DependenceFlags.h index 75c9aa1656b8..0b24bae6df9b 100644 --- a/clang/include/clang/AST/DependenceFlags.h +++ b/clang/include/clang/AST/DependenceFlags.h @@ -50,14 +50,16 @@ struct TypeDependenceScope { /// Whether this type is a variably-modified type (C99 6.7.5). VariablyModified = 8, - // FIXME: add Error bit. + /// Whether this type references an error, e.g. decltype(err-expression) + /// yields an error type. + Error = 16, None = 0, - All = 15, + All = 31, DependentInstantiation = Dependent | Instantiation, - LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified) + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) }; }; using TypeDependence = TypeDependenceScope::TypeDependence; @@ -147,6 +149,7 @@ class Dependence { return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) | translate(V, Instantiation, TypeDependence::Instantiation) | translate(V, Dependent, TypeDependence::Dependent) | + translate(V, Error, TypeDependence::Error) | translate(V, VariablyModified, TypeDependence::VariablyModified); } diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 248fbcfba98e..5d2c035ea0fe 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2139,6 +2139,11 @@ class alignas(8) Type : public ExtQualsTypeCommonBase { return static_cast(TypeBits.Dependence); } + /// Whether this type is an error type. + bool containsErrors() const { + return getDependence() & TypeDependence::Error; + } + /// Whether this type is a dependent type, meaning that its definition /// somehow depends on a template parameter (C++ [temp.dep.type]). bool isDependentType() const { diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 761fad9456be..4389c8777c6d 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -3105,10 +3105,14 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { auto RunSignatureHelp = [&]() { ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get(); - assert(TypeRep && "invalid types should be handled before"); - QualType PreferredType = Actions.ProduceConstructorSignatureHelp( - getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), - DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen); + QualType PreferredType; + // ActOnTypeName might adjust DeclaratorInfo and return a null type even + // the passing DeclaratorInfo is valid, e.g. running SignatureHelp on + // `new decltype(invalid) (^)`. + if (TypeRep) + PreferredType = Actions.ProduceConstructorSignatureHelp( + getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), + DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen); CalledSignatureHelp = true; return PreferredType; }; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 55ce028fb8c2..e128ebf31270 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1678,6 +1678,12 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { break; } + // FIXME: we want resulting declarations to be marked invalid, but claiming + // the type is invalid is too strong - e.g. it causes ActOnTypeName to return + // a null type. + if (Result->containsErrors()) + declarator.setInvalidType(); + if (S.getLangOpts().OpenCL && S.checkOpenCLDisabledTypeDeclSpec(DS, Result)) declarator.setInvalidType(true); diff --git a/clang/test/AST/ast-dump-expr-errors.cpp b/clang/test/AST/ast-dump-expr-errors.cpp index e623fad04f4c..9334b73a4354 100644 --- a/clang/test/AST/ast-dump-expr-errors.cpp +++ b/clang/test/AST/ast-dump-expr-errors.cpp @@ -42,5 +42,9 @@ int d = static_cast(bar() + 1); // FIXME: store initializer even when 'auto' could not be deduced. // Expressions with errors currently do not keep initializers around. -// CHECK: `-VarDecl {{.*}} invalid e 'auto' +// CHECK: -VarDecl {{.*}} invalid e 'auto' auto e = bar(); + +// Error type should result in an invalid decl. +// CHECK: -VarDecl {{.*}} invalid f 'decltype((bar))' +decltype(bar()) f; diff --git a/clang/test/Sema/invalid-member.cpp b/clang/test/Sema/invalid-member.cpp index 5475157e936e..544979980fc9 100644 --- a/clang/test/Sema/invalid-member.cpp +++ b/clang/test/Sema/invalid-member.cpp @@ -1,7 +1,15 @@ -// RUN: %clang_cc1 -verify -fsyntax-only %s -void foo(); // expected-note {{requires 0 arguments}} +// RUN: %clang_cc1 -verify -fsyntax-only -fno-recovery-ast %s +// RUN: %clang_cc1 -verify -fsyntax-only -frecovery-ast %s + +void foo(); // expected-note 2{{requires 0 arguments}} class X { decltype(foo(42)) invalid; // expected-error {{no matching function}} }; // Should be able to evaluate sizeof without crashing. static_assert(sizeof(X) == 1, "No valid members"); + +class Y { + typeof(foo(42)) invalid; // expected-error {{no matching function}} +}; +// Should be able to evaluate sizeof without crashing. +static_assert(sizeof(Y) == 1, "No valid members"); diff --git a/clang/unittests/Sema/CodeCompleteTest.cpp b/clang/unittests/Sema/CodeCompleteTest.cpp index a9441a679cac..d8b303d77bb9 100644 --- a/clang/unittests/Sema/CodeCompleteTest.cpp +++ b/clang/unittests/Sema/CodeCompleteTest.cpp @@ -486,7 +486,10 @@ TEST(PreferredTypeTest, NoCrashOnInvalidTypes) { StringRef Code = R"cpp( auto x = decltype(&1)(^); auto y = new decltype(&1)(^); + // GNU decimal type extension is not supported in clang. + auto z = new _Decimal128(^); )cpp"; EXPECT_THAT(collectPreferredTypes(Code), Each("NULL TYPE")); } + } // namespace From cfe-commits at lists.llvm.org Mon Mar 30 06:27:52 2020 From: cfe-commits at lists.llvm.org (Kerry McLaughlin via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 13:27:52 +0000 (UTC) Subject: [PATCH] D77054: [AArch64][SVE] Add SVE intrinsics for saturating add & subtract Message-ID: kmclaughlin created this revision. kmclaughlin added reviewers: sdesmalen, c-rhodes, dancgr, efriedma, cameron.mcinally. Herald added subscribers: danielkiss, psnobl, rkruppe, hiraditya, kristof.beyls, tschuett. Herald added a reviewer: rengolin. Herald added a project: LLVM. Adds the following intrinsics: - @llvm.aarch64.sve.[s|u]qadd.x - @llvm.aarch64.sve.[s|u]qsub.x Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77054 Files: llvm/include/llvm/IR/IntrinsicsAArch64.td llvm/lib/Target/AArch64/AArch64ISelLowering.cpp llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td llvm/test/CodeGen/AArch64/sve-int-arith.ll llvm/test/CodeGen/AArch64/sve-int-imm.ll llvm/test/CodeGen/AArch64/sve-intrinsics-int-arith.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D77054.253578.patch Type: text/x-patch Size: 47267 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 06:27:51 2020 From: cfe-commits at lists.llvm.org (Ulrich Weigand via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 13:27:51 +0000 (UTC) Subject: [PATCH] D75914: systemz: allow configuring default CLANG_SYSTEMZ_ARCH In-Reply-To: References: Message-ID: uweigand added a comment. Ah, good point. Dimitry, can you prepare an updated patch to implement Jonas' suggestion? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75914/new/ https://reviews.llvm.org/D75914 From cfe-commits at lists.llvm.org Mon Mar 30 06:28:14 2020 From: cfe-commits at lists.llvm.org (Digger via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 13:28:14 +0000 (UTC) Subject: [PATCH] D76932: [AIX] emit .extern and .weak directive linkage In-Reply-To: References: Message-ID: <1d7e9260072b528e9d94013e3bd6845d@localhost.localdomain> DiggerLin updated this revision to Diff 253579. DiggerLin added a comment. delete -u from clang test case aix-as.c Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76932/new/ https://reviews.llvm.org/D76932 Files: clang/lib/Driver/ToolChains/AIX.cpp clang/test/Driver/aix-as.c llvm/include/llvm/CodeGen/AsmPrinter.h llvm/include/llvm/MC/MCAsmInfo.h llvm/include/llvm/MC/MCDirectives.h llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp llvm/lib/MC/MCAsmInfoXCOFF.cpp llvm/lib/MC/MCAsmStreamer.cpp llvm/lib/MC/MCXCOFFStreamer.cpp llvm/lib/MC/XCOFFObjectWriter.cpp llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp llvm/test/CodeGen/PowerPC/aix-extern-weak.ll llvm/test/CodeGen/PowerPC/aix-reference-func-addr-const.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D76932.253579.patch Type: text/x-patch Size: 40177 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 06:28:07 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 13:28:07 +0000 (UTC) Subject: [PATCH] D77037: [AST] Fix crashes on decltype(recovery-expr). In-Reply-To: References: Message-ID: <77a0e57676034fe222f8e04e758ff01f@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG6f428e09fbe8: [AST] Fix crashes on decltype(recovery-expr). (authored by hokein). Changed prior to commit: https://reviews.llvm.org/D77037?vs=253567&id=253581#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77037/new/ https://reviews.llvm.org/D77037 Files: clang/include/clang/AST/DependenceFlags.h clang/include/clang/AST/Type.h clang/lib/Parse/ParseExprCXX.cpp clang/lib/Sema/SemaType.cpp clang/test/AST/ast-dump-expr-errors.cpp clang/test/Sema/invalid-member.cpp clang/unittests/Sema/CodeCompleteTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77037.253581.patch Type: text/x-patch Size: 5524 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 06:28:38 2020 From: cfe-commits at lists.llvm.org (Alexey Bataev via cfe-commits) Date: Mon, 30 Mar 2020 06:28:38 -0700 (PDT) Subject: [clang] 7ac9efb - [OPENMP50]Add basic support for array-shaping operation. Message-ID: <5e81f406.1c69fb81.11cf6.df57@mx.google.com> Author: Alexey Bataev Date: 2020-03-30T09:18:24-04:00 New Revision: 7ac9efb0c322bacd4f09e6aed82466116b685892 URL: https://github.com/llvm/llvm-project/commit/7ac9efb0c322bacd4f09e6aed82466116b685892 DIFF: https://github.com/llvm/llvm-project/commit/7ac9efb0c322bacd4f09e6aed82466116b685892.diff LOG: [OPENMP50]Add basic support for array-shaping operation. Summary: Added basic representation and parsing/sema handling of array-shaping operations. Array shaping expression is an expression of form ([s0]..[sn])base, where s0, ..., sn must be a positive integer, base - a pointer. This expression is a kind of cast operation that converts pointer expression into an array-like kind of expression. Reviewers: rjmccall, rsmith, jdoerfert Subscribers: guansong, arphaman, cfe-commits, caomhin, kkwli0 Tags: #clang Differential Revision: https://reviews.llvm.org/D74144 Added: Modified: clang/include/clang-c/Index.h clang/include/clang/AST/ASTContext.h clang/include/clang/AST/BuiltinTypes.def clang/include/clang/AST/ComputeDependence.h clang/include/clang/AST/ExprOpenMP.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Basic/StmtNodes.td clang/include/clang/Parse/Parser.h clang/include/clang/Sema/Sema.h clang/include/clang/Serialization/ASTBitCodes.h clang/lib/AST/ASTContext.cpp clang/lib/AST/ComputeDependence.cpp clang/lib/AST/Expr.cpp clang/lib/AST/ExprClassification.cpp clang/lib/AST/ExprConstant.cpp clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/NSAPI.cpp clang/lib/AST/StmtPrinter.cpp clang/lib/AST/StmtProfile.cpp clang/lib/AST/Type.cpp clang/lib/AST/TypeLoc.cpp clang/lib/Parse/ParseExpr.cpp clang/lib/Sema/SemaExceptionSpec.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTCommon.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriterStmt.cpp clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp clang/lib/StaticAnalyzer/Core/ExprEngine.cpp clang/test/OpenMP/depobj_messages.cpp clang/test/OpenMP/parallel_reduction_messages.c clang/test/OpenMP/task_ast_print.cpp clang/test/OpenMP/task_depend_messages.cpp clang/tools/libclang/CIndex.cpp clang/tools/libclang/CXCursor.cpp Removed: ################################################################################ diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index cca7198d2f9f..641f058dafaa 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2176,7 +2176,11 @@ enum CXCursorKind { */ CXCursor_FixedPointLiteral = 149, - CXCursor_LastExpr = CXCursor_FixedPointLiteral, + /** OpenMP 5.0 [2.1.4, Array Shaping]. + */ + CXCursor_OMPArrayShapingExpr = 150, + + CXCursor_LastExpr = CXCursor_OMPArrayShapingExpr, /* Statements */ CXCursor_FirstStmt = 200, diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index ca0f991c24e3..ebb5ca593843 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -970,7 +970,7 @@ class ASTContext : public RefCountedBase { #include "clang/Basic/OpenCLImageTypes.def" CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; CanQualType OCLQueueTy, OCLReserveIDTy; - CanQualType OMPArraySectionTy; + CanQualType OMPArraySectionTy, OMPArrayShapingTy; #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ CanQualType Id##Ty; #include "clang/Basic/OpenCLExtensionTypes.def" diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index 74a45ee4ccc0..f42503773945 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -313,8 +313,11 @@ PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy) // A placeholder type for OpenMP array sections. PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy) +// A placeholder type for OpenMP array shaping operation. +PLACEHOLDER_TYPE(OMPArrayShaping, OMPArrayShapingTy) + #ifdef LAST_BUILTIN_TYPE -LAST_BUILTIN_TYPE(OMPArraySection) +LAST_BUILTIN_TYPE(OMPArrayShaping) #undef LAST_BUILTIN_TYPE #endif diff --git a/clang/include/clang/AST/ComputeDependence.h b/clang/include/clang/AST/ComputeDependence.h index 02f826438d4d..63947eaff73b 100644 --- a/clang/include/clang/AST/ComputeDependence.h +++ b/clang/include/clang/AST/ComputeDependence.h @@ -87,6 +87,7 @@ class ParenListExpr; class PseudoObjectExpr; class AtomicExpr; class OMPArraySectionExpr; +class OMPArrayShapingExpr; class ObjCArrayLiteral; class ObjCDictionaryLiteral; class ObjCBoxedExpr; @@ -172,6 +173,7 @@ ExprDependence computeDependence(PseudoObjectExpr *E); ExprDependence computeDependence(AtomicExpr *E); ExprDependence computeDependence(OMPArraySectionExpr *E); +ExprDependence computeDependence(OMPArrayShapingExpr *E); ExprDependence computeDependence(ObjCArrayLiteral *E); ExprDependence computeDependence(ObjCDictionaryLiteral *E); diff --git a/clang/include/clang/AST/ExprOpenMP.h b/clang/include/clang/AST/ExprOpenMP.h index f971ed8457bc..4a0cd07f1dab 100644 --- a/clang/include/clang/AST/ExprOpenMP.h +++ b/clang/include/clang/AST/ExprOpenMP.h @@ -116,6 +116,95 @@ class OMPArraySectionExpr : public Expr { return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]); } }; + +/// An explicit cast in C or a C-style cast in C++, which uses the syntax +/// ([s1][s2]...[sn])expr. For example: @c ([3][3])f. +class OMPArrayShapingExpr final + : public Expr, + private llvm::TrailingObjects { + friend TrailingObjects; + friend class ASTStmtReader; + friend class ASTStmtWriter; + /// Base node. + SourceLocation LPLoc; /// The location of the left paren + SourceLocation RPLoc; /// The location of the right paren + unsigned NumDims = 0; /// Number of dimensions in the shaping expression. + + /// Construct full expression. + OMPArrayShapingExpr(QualType ExprTy, Expr *Op, SourceLocation L, + SourceLocation R, ArrayRef Dims); + + /// Construct an empty expression. + explicit OMPArrayShapingExpr(EmptyShell Shell, unsigned NumDims) + : Expr(OMPArrayShapingExprClass, Shell), NumDims(NumDims) {} + + /// Sets the dimensions for the array shaping. + void setDimensions(ArrayRef Dims); + + /// Sets the base expression for array shaping operation. + void setBase(Expr *Op) { getTrailingObjects()[NumDims] = Op; } + + /// Sets source ranges for the brackets in the array shaping operation. + void setBracketsRanges(ArrayRef BR); + + unsigned numTrailingObjects(OverloadToken) const { + // Add an extra one for the base expression. + return NumDims + 1; + } + + unsigned numTrailingObjects(OverloadToken) const { + return NumDims; + } + +public: + static OMPArrayShapingExpr *Create(const ASTContext &Context, QualType T, + Expr *Op, SourceLocation L, + SourceLocation R, ArrayRef Dims, + ArrayRef BracketRanges); + + static OMPArrayShapingExpr *CreateEmpty(const ASTContext &Context, + unsigned NumDims); + + SourceLocation getLParenLoc() const { return LPLoc; } + void setLParenLoc(SourceLocation L) { LPLoc = L; } + + SourceLocation getRParenLoc() const { return RPLoc; } + void setRParenLoc(SourceLocation L) { RPLoc = L; } + + SourceLocation getBeginLoc() const LLVM_READONLY { return LPLoc; } + SourceLocation getEndLoc() const LLVM_READONLY { + return getBase()->getEndLoc(); + } + + /// Fetches the dimensions for array shaping expression. + ArrayRef getDimensions() const { + return llvm::makeArrayRef(getTrailingObjects(), NumDims); + } + + /// Fetches source ranges for the brackets os the array shaping expression. + ArrayRef getBracketsRanges() const { + return llvm::makeArrayRef(getTrailingObjects(), NumDims); + } + + /// Fetches base expression of array shaping expression. + Expr *getBase() { return getTrailingObjects()[NumDims]; } + const Expr *getBase() const { return getTrailingObjects()[NumDims]; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPArrayShapingExprClass; + } + + // Iterators + child_range children() { + Stmt **Begin = reinterpret_cast(getTrailingObjects()); + return child_range(Begin, Begin + NumDims + 1); + } + const_child_range children() const { + Stmt *const *Begin = + reinterpret_cast(getTrailingObjects()); + return const_child_range(Begin, Begin + NumDims + 1); + } +}; } // end namespace clang #endif diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 2f598564f307..46661e59f181 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2551,6 +2551,7 @@ DEF_TRAVERSE_STMT(CXXMemberCallExpr, {}) DEF_TRAVERSE_STMT(AddrLabelExpr, {}) DEF_TRAVERSE_STMT(ArraySubscriptExpr, {}) DEF_TRAVERSE_STMT(OMPArraySectionExpr, {}) +DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {}) DEF_TRAVERSE_STMT(BlockExpr, { TRY_TO(TraverseDecl(S->getBlockDecl())); diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index cdc0d9688c08..26a9cabfc741 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9685,7 +9685,7 @@ def err_omp_expected_var_name_member_expr : Error< def err_omp_expected_var_name_member_expr_or_array_item : Error< "expected variable name%select{|, data member of current class}0, array element or array section">; def err_omp_expected_addressable_lvalue_or_array_item : Error< - "expected addressable lvalue expression, array element or array section%select{| of non 'omp_depend_t' type}0">; + "expected addressable lvalue expression, array element%select{ or array section|, array section or array shaping expression}0%select{| of non 'omp_depend_t' type}1">; def err_omp_expected_named_var_member_or_array_expression: Error< "expected expression containing only member accesses and/or array sections based on named variables">; def err_omp_bit_fields_forbidden_in_clause : Error< @@ -9952,10 +9952,15 @@ def err_omp_declare_mapper_redefinition : Error< def err_omp_invalid_mapper: Error< "cannot find a valid user-defined mapper for type %0 with name %1">; def err_omp_array_section_use : Error<"OpenMP array section is not allowed here">; +def err_omp_array_shaping_use : Error<"OpenMP array shaping operation is not allowed here">; def err_omp_typecheck_section_value : Error< "subscripted value is not an array or pointer">; def err_omp_typecheck_section_not_integer : Error< "array section %select{lower bound|length}0 is not an integer">; +def err_omp_typecheck_shaping_not_integer : Error< + "array shaping operation dimension is not an integer">; +def err_omp_shaping_dimension_not_positive : Error< + "array shaping dimension is evaluated to a non-positive value %0">; def err_omp_section_function_type : Error< "section of pointer to function type %0">; def warn_omp_section_is_char : Warning<"array section %select{lower bound|length}0 is of type 'char'">, @@ -10190,14 +10195,15 @@ def err_omp_flush_order_clause_and_list : Error< def note_omp_flush_order_clause_here : Note< "memory order clause '%0' is specified here">; def err_omp_non_lvalue_in_map_or_motion_clauses: Error< - "expected addressable lvalue in '%0' clause" - >; + "expected addressable lvalue in '%0' clause">; def err_omp_event_var_expected : Error< "expected variable of the 'omp_event_handle_t' type%select{|, not %1}0">; def warn_nested_declare_variant : Warning<"nesting `omp begin/end declare variant` is not supported yet; " "nested context ignored">, InGroup; +def err_omp_non_pointer_type_array_shaping_base : Error< + "expected pointer type expression as a base of an array shaping operation">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index 478179d4131f..ba1b5ebd6305 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -81,6 +81,7 @@ def BinaryConditionalOperator : StmtNode; def ImplicitCastExpr : StmtNode; def ExplicitCastExpr : StmtNode; def CStyleCastExpr : StmtNode; +def OMPArrayShapingExpr : StmtNode; def CompoundLiteralExpr : StmtNode; def ExtVectorElementExpr : StmtNode; def InitListExpr : StmtNode; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 333c96e8cd27..c64a01b73a4a 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3010,6 +3010,10 @@ class Parser : public CodeCompletionHandler { DeclarationName &Name, AccessSpecifier AS = AS_none); + /// Tries to parse cast part of OpenMP array shaping operation: + /// '[' expression ']' { '[' expression ']' } ')'. + bool tryParseOpenMPArrayShapingCastPart(); + /// Parses simple list of variables. /// /// \param Kind Kind of the directive. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index ecda3f4692a5..9a41356ddb70 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -4899,6 +4899,10 @@ class Sema final { ExprResult ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, Expr *LowerBound, SourceLocation ColonLoc, Expr *Length, SourceLocation RBLoc); + ExprResult ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, + SourceLocation RParenLoc, + ArrayRef Dims, + ArrayRef Brackets); // This struct is for use by ActOnMemberAccess to allow // BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index f185c1a16834..68bcb26b6df5 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1016,6 +1016,9 @@ namespace serialization { /// \brief The '_Sat unsigned long _Fract' type PREDEF_TYPE_SAT_ULONG_FRACT_ID = 69, + /// The placeholder type for OpenMP array shaping operation. + PREDEF_TYPE_OMP_ARRAY_SHAPING = 70, + /// OpenCL image types with auto numeration #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ PREDEF_TYPE_##Id##_ID, @@ -1868,6 +1871,7 @@ namespace serialization { STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE, STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE, EXPR_OMP_ARRAY_SECTION, + EXPR_OMP_ARRAY_SHAPING, // ARC EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 461b155df7bf..8bee34e65754 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1386,8 +1386,10 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target, InitBuiltinType(BuiltinFnTy, BuiltinType::BuiltinFn); // Placeholder type for OMP array sections. - if (LangOpts.OpenMP) + if (LangOpts.OpenMP) { InitBuiltinType(OMPArraySectionTy, BuiltinType::OMPArraySection); + InitBuiltinType(OMPArrayShapingTy, BuiltinType::OMPArrayShaping); + } // C99 6.2.5p11. FloatComplexTy = getComplexType(FloatTy); diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp index b51164e54926..a023ed173184 100644 --- a/clang/lib/AST/ComputeDependence.cpp +++ b/clang/lib/AST/ComputeDependence.cpp @@ -363,6 +363,15 @@ ExprDependence clang::computeDependence(OMPArraySectionExpr *E) { return D; } +ExprDependence clang::computeDependence(OMPArrayShapingExpr *E) { + auto D = E->getBase()->getDependence() | + toExprDependence(E->getType()->getDependence()); + for (Expr *Dim: E->getDimensions()) + if (Dim) + D |= Dim->getDependence(); + return D; +} + /// Compute the type-, value-, and instantiation-dependence of a /// declaration reference /// based on the declaration being referenced. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index f0f22b6e4690..fb63897d871f 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -3398,6 +3398,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, case ParenExprClass: case ArraySubscriptExprClass: case OMPArraySectionExprClass: + case OMPArrayShapingExprClass: case MemberExprClass: case ConditionalOperatorClass: case BinaryConditionalOperatorClass: @@ -4569,3 +4570,50 @@ RecoveryExpr *RecoveryExpr::CreateEmpty(ASTContext &Ctx, unsigned NumSubExprs) { alignof(RecoveryExpr)); return new (Mem) RecoveryExpr(EmptyShell()); } + +void OMPArrayShapingExpr::setDimensions(ArrayRef Dims) { + assert( + NumDims == Dims.size() && + "Preallocated number of dimensions is diff erent from the provided one."); + llvm::copy(Dims, getTrailingObjects()); +} + +void OMPArrayShapingExpr::setBracketsRanges(ArrayRef BR) { + assert( + NumDims == BR.size() && + "Preallocated number of dimensions is diff erent from the provided one."); + llvm::copy(BR, getTrailingObjects()); +} + +OMPArrayShapingExpr::OMPArrayShapingExpr(QualType ExprTy, Expr *Op, + SourceLocation L, SourceLocation R, + ArrayRef Dims) + : Expr(OMPArrayShapingExprClass, ExprTy, VK_LValue, OK_Ordinary), LPLoc(L), + RPLoc(R), NumDims(Dims.size()) { + setBase(Op); + setDimensions(Dims); + setDependence(computeDependence(this)); +} + +OMPArrayShapingExpr * +OMPArrayShapingExpr::Create(const ASTContext &Context, QualType T, Expr *Op, + SourceLocation L, SourceLocation R, + ArrayRef Dims, + ArrayRef BracketRanges) { + assert(Dims.size() == BracketRanges.size() && + "Different number of dimensions and brackets ranges."); + void *Mem = Context.Allocate( + totalSizeToAlloc(Dims.size() + 1, Dims.size()), + alignof(OMPArrayShapingExpr)); + auto *E = new (Mem) OMPArrayShapingExpr(T, Op, L, R, Dims); + E->setBracketsRanges(BracketRanges); + return E; +} + +OMPArrayShapingExpr *OMPArrayShapingExpr::CreateEmpty(const ASTContext &Context, + unsigned NumDims) { + void *Mem = Context.Allocate( + totalSizeToAlloc(NumDims + 1, NumDims), + alignof(OMPArrayShapingExpr)); + return new (Mem) OMPArrayShapingExpr(EmptyShell(), NumDims); +} diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 58e70347292c..4505626bb61f 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -140,6 +140,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::MSPropertyRefExprClass: case Expr::MSPropertySubscriptExprClass: case Expr::OMPArraySectionExprClass: + case Expr::OMPArrayShapingExprClass: return Cl::CL_LValue; // C99 6.5.2.5p5 says that compound literals are lvalues. diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 53e168a81bc3..4a11c846f4ab 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -14180,6 +14180,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { case Expr::StringLiteralClass: case Expr::ArraySubscriptExprClass: case Expr::OMPArraySectionExprClass: + case Expr::OMPArrayShapingExprClass: case Expr::MemberExprClass: case Expr::CompoundAssignOperatorClass: case Expr::CompoundLiteralExprClass: diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 9c1e6b503eaa..4c05990ee410 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3714,6 +3714,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { case Expr::TypoExprClass: // This should no longer exist in the AST by now. case Expr::RecoveryExprClass: case Expr::OMPArraySectionExprClass: + case Expr::OMPArrayShapingExprClass: case Expr::CXXInheritedCtorInitExprClass: llvm_unreachable("unexpected statement kind"); diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp index ae6ff04f5126..2bfe977a5ba5 100644 --- a/clang/lib/AST/NSAPI.cpp +++ b/clang/lib/AST/NSAPI.cpp @@ -483,6 +483,7 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const { case BuiltinType::PseudoObject: case BuiltinType::BuiltinFn: case BuiltinType::OMPArraySection: + case BuiltinType::OMPArrayShaping: break; } diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 80fdc09a8a6c..3d03f3902d61 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1350,6 +1350,17 @@ void StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) { OS << "]"; } +void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) { + OS << "("; + for (Expr *E : Node->getDimensions()) { + OS << "["; + PrintExpr(E); + OS << "]"; + } + OS << ")"; + PrintExpr(Node->getBase()); +} + void StmtPrinter::PrintCallArgs(CallExpr *Call) { for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { if (isa(Call->getArg(i))) { diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 5e87eb3e237c..054276a98424 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -1194,6 +1194,10 @@ void StmtProfiler::VisitOMPArraySectionExpr(const OMPArraySectionExpr *S) { VisitExpr(S); } +void StmtProfiler::VisitOMPArrayShapingExpr(const OMPArrayShapingExpr *S) { + VisitExpr(S); +} + void StmtProfiler::VisitCallExpr(const CallExpr *S) { VisitExpr(S); } diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 279c0d140959..f90eb5cb9c92 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2908,6 +2908,8 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { return "reserve_id_t"; case OMPArraySection: return ""; + case OMPArrayShaping: + return ""; #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ case Id: \ return #ExtType; @@ -3914,6 +3916,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const { case BuiltinType::BuiltinFn: case BuiltinType::NullPtr: case BuiltinType::OMPArraySection: + case BuiltinType::OMPArrayShaping: return false; } llvm_unreachable("unknown builtin type"); diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index 665a86f2c143..dd48ae3fc262 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -404,6 +404,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const { #include "clang/Basic/AArch64SVEACLETypes.def" case BuiltinType::BuiltinFn: case BuiltinType::OMPArraySection: + case BuiltinType::OMPArrayShaping: return TST_unspecified; } diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 4cb828cd23cc..80592671dcd0 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -2648,6 +2648,33 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { return ParsePostfixExpressionSuffix(Res.get()); } +bool Parser::tryParseOpenMPArrayShapingCastPart() { + assert(Tok.is(tok::l_square) && "Expected open bracket"); + bool ErrorFound = true; + TentativeParsingAction TPA(*this); + do { + if (Tok.isNot(tok::l_square)) + break; + // Consume '[' + ConsumeBracket(); + // Skip inner expression. + while (!SkipUntil(tok::r_square, tok::annot_pragma_openmp_end, + StopAtSemi | StopBeforeMatch)) + ; + if (Tok.isNot(tok::r_square)) + break; + // Consume ']' + ConsumeBracket(); + // Found ')' - done. + if (Tok.is(tok::r_paren)) { + ErrorFound = false; + break; + } + } while (Tok.isNot(tok::annot_pragma_openmp_end)); + TPA.Revert(); + return !ErrorFound; +} + /// ParseParenExpression - This parses the unit that starts with a '(' token, /// based on what is allowed by ExprType. The actual thing parsed is returned /// in ExprType. If stopIfCastExpr is true, it will only return the parsed type, @@ -2672,6 +2699,8 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() { /// '(' '...' fold-operator cast-expression ')' /// '(' cast-expression fold-operator '...' /// fold-operator cast-expression ')' +/// [OPENMP] Array shaping operation +/// '(' '[' expression ']' { '[' expression ']' } cast-expression /// \endverbatim ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, @@ -2948,6 +2977,38 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, Result = Actions.ActOnParenListExpr(OpenLoc, Tok.getLocation(), ArgExprs); } + } else if (getLangOpts().OpenMP >= 50 && OpenMPDirectiveParsing && + ExprType == CastExpr && Tok.is(tok::l_square) && + tryParseOpenMPArrayShapingCastPart()) { + bool ErrorFound = false; + SmallVector OMPDimensions; + SmallVector OMPBracketsRanges; + do { + BalancedDelimiterTracker TS(*this, tok::l_square); + TS.consumeOpen(); + ExprResult NumElements = + Actions.CorrectDelayedTyposInExpr(ParseExpression()); + if (!NumElements.isUsable()) { + ErrorFound = true; + while (!SkipUntil(tok::r_square, tok::r_paren, + StopAtSemi | StopBeforeMatch)) + ; + } + TS.consumeClose(); + OMPDimensions.push_back(NumElements.get()); + OMPBracketsRanges.push_back(TS.getRange()); + } while (Tok.isNot(tok::r_paren)); + // Match the ')'. + T.consumeClose(); + RParenLoc = T.getCloseLocation(); + Result = Actions.CorrectDelayedTyposInExpr(ParseExpression()); + if (ErrorFound) { + Result = ExprError(); + } else if (!Result.isInvalid()) { + Result = Actions.ActOnOMPArrayShapingExpr( + Result.get(), OpenLoc, RParenLoc, OMPDimensions, OMPBracketsRanges); + } + return Result; } else { InMessageExpressionRAIIObject InMessage(*this, false); diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 53c62a1a4017..fad2ae1cc066 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1299,6 +1299,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { // Some might be dependent for other reasons. case Expr::ArraySubscriptExprClass: case Expr::OMPArraySectionExprClass: + case Expr::OMPArrayShapingExprClass: case Expr::BinaryOperatorClass: case Expr::DependentCoawaitExprClass: case Expr::CompoundAssignOperatorClass: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 756833c44380..44f51f1a432d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4798,6 +4798,75 @@ ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, VK_LValue, OK_Ordinary, ColonLoc, RBLoc); } +ExprResult Sema::ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, + SourceLocation RParenLoc, + ArrayRef Dims, + ArrayRef Brackets) { + if (Base->getType()->isPlaceholderType()) { + ExprResult Result = CheckPlaceholderExpr(Base); + if (Result.isInvalid()) + return ExprError(); + Base = Result.get(); + } + QualType BaseTy = Base->getType(); + // Delay analysis of the types/expressions if instantiation/specialization is + // required. + if (!BaseTy->isPointerType() && Base->isTypeDependent()) + return OMPArrayShapingExpr::Create(Context, Context.DependentTy, Base, + LParenLoc, RParenLoc, Dims, Brackets); + if (!BaseTy->isPointerType()) + return ExprError(Diag(Base->getExprLoc(), + diag::err_omp_non_pointer_type_array_shaping_base) + << Base->getSourceRange()); + SmallVector NewDims; + bool ErrorFound = false; + for (Expr *Dim : Dims) { + if (Dim->getType()->isPlaceholderType()) { + ExprResult Result = CheckPlaceholderExpr(Dim); + if (Result.isInvalid()) { + ErrorFound = true; + continue; + } + Result = DefaultLvalueConversion(Result.get()); + if (Result.isInvalid()) { + ErrorFound = true; + continue; + } + Dim = Result.get(); + } + if (!Dim->isTypeDependent()) { + ExprResult Result = + PerformOpenMPImplicitIntegerConversion(Dim->getExprLoc(), Dim); + if (Result.isInvalid()) { + ErrorFound = true; + Diag(Dim->getExprLoc(), diag::err_omp_typecheck_shaping_not_integer) + << Dim->getSourceRange(); + continue; + } + Dim = Result.get(); + Expr::EvalResult EvResult; + if (!Dim->isValueDependent() && Dim->EvaluateAsInt(EvResult, Context)) { + // OpenMP 5.0, [2.1.4 Array Shaping] + // Each si is an integral type expression that must evaluate to a + // positive integer. + llvm::APSInt Value = EvResult.Val.getInt(); + if (!Value.isStrictlyPositive()) { + Diag(Dim->getExprLoc(), diag::err_omp_shaping_dimension_not_positive) + << Value.toString(/*Radix=*/10, /*Signed=*/true) + << Dim->getSourceRange(); + ErrorFound = true; + continue; + } + } + } + NewDims.push_back(Dim); + } + if (ErrorFound) + return ExprError(); + return OMPArrayShapingExpr::Create(Context, Context.OMPArrayShapingTy, Base, + LParenLoc, RParenLoc, NewDims, Brackets); +} + ExprResult Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc) { @@ -5558,6 +5627,7 @@ static bool isPlaceholderToRemoveAsArg(QualType type) { case BuiltinType::BoundMember: case BuiltinType::BuiltinFn: case BuiltinType::OMPArraySection: + case BuiltinType::OMPArrayShaping: return true; } @@ -18433,6 +18503,10 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { Diag(E->getBeginLoc(), diag::err_omp_array_section_use); return ExprError(); + // Expressions of unknown type. + case BuiltinType::OMPArrayShaping: + return ExprError(Diag(E->getBeginLoc(), diag::err_omp_array_shaping_use)); + // Everything else should be impossible. #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ case BuiltinType::Id: diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 14aa446cc6ef..f9e8e3d6ccc8 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -15824,7 +15824,8 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, (OMPDependTFound && DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) - << 1 << RefExpr->getSourceRange(); + << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 + << RefExpr->getSourceRange(); continue; } @@ -15837,6 +15838,7 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, ->isPointerType() && !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) + << (LangOpts.OpenMP >= 50 ? 1 : 0) << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); continue; } @@ -15847,8 +15849,10 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); } - if (!Res.isUsable() && !isa(SimpleExpr)) { + if (!Res.isUsable() && !isa(SimpleExpr) && + !isa(SimpleExpr)) { Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) + << (LangOpts.OpenMP >= 50 ? 1 : 0) << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); continue; } diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index dda3a3934d3b..82cfa246e3f7 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2379,6 +2379,18 @@ class TreeTransform { ColonLoc, Length, RBracketLoc); } + /// Build a new array shaping expression. + /// + /// By default, performs semantic analysis to build the new expression. + /// Subclasses may override this routine to provide diff erent behavior. + ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, + SourceLocation RParenLoc, + ArrayRef Dims, + ArrayRef BracketsRanges) { + return getSema().ActOnOMPArrayShapingExpr(Base, LParenLoc, RParenLoc, Dims, + BracketsRanges); + } + /// Build a new call expression. /// /// By default, performs semantic analysis to build the new expression. @@ -10017,6 +10029,31 @@ TreeTransform::TransformOMPArraySectionExpr(OMPArraySectionExpr *E) { Length.get(), E->getRBracketLoc()); } +template +ExprResult +TreeTransform::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) { + ExprResult Base = getDerived().TransformExpr(E->getBase()); + if (Base.isInvalid()) + return ExprError(); + + SmallVector Dims; + bool ErrorFound = false; + for (Expr *Dim : E->getDimensions()) { + ExprResult DimRes = getDerived().TransformExpr(Dim); + if (DimRes.isInvalid()) { + ErrorFound = true; + continue; + } + Dims.push_back(DimRes.get()); + } + + if (ErrorFound) + return ExprError(); + return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(), + E->getRParenLoc(), Dims, + E->getBracketsRanges()); +} + template ExprResult TreeTransform::TransformCallExpr(CallExpr *E) { diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp index f93f1f77405d..158a12f0329d 100644 --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -243,6 +243,9 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) { case BuiltinType::OMPArraySection: ID = PREDEF_TYPE_OMP_ARRAY_SECTION; break; + case BuiltinType::OMPArrayShaping: + ID = PREDEF_TYPE_OMP_ARRAY_SHAPING; + break; } return TypeIdx(ID); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index c2d28f436241..7437f649a090 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -6957,6 +6957,9 @@ QualType ASTReader::GetType(TypeID ID) { case PREDEF_TYPE_OMP_ARRAY_SECTION: T = Context.OMPArraySectionTy; break; + case PREDEF_TYPE_OMP_ARRAY_SHAPING: + T = Context.OMPArraySectionTy; + break; #define SVE_TYPE(Name, Id, SingletonId) \ case PREDEF_TYPE_##Id##_ID: \ T = Context.SingletonId; \ diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 3f56968a51dc..bc8c231731e8 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -911,6 +911,22 @@ void ASTStmtReader::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) { E->setRBracketLoc(readSourceLocation()); } +void ASTStmtReader::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { + VisitExpr(E); + unsigned NumDims = Record.readInt(); + E->setBase(Record.readSubExpr()); + SmallVector Dims(NumDims); + for (unsigned I = 0; I < NumDims; ++I) + Dims[I] = Record.readSubExpr(); + E->setDimensions(Dims); + SmallVector SRs(NumDims); + for (unsigned I = 0; I < NumDims; ++I) + SRs[I] = readSourceRange(); + E->setBracketsRanges(SRs); + E->setLParenLoc(readSourceLocation()); + E->setRParenLoc(readSourceLocation()); +} + void ASTStmtReader::VisitCallExpr(CallExpr *E) { VisitExpr(E); unsigned NumArgs = Record.readInt(); @@ -2866,6 +2882,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = new (Context) OMPArraySectionExpr(Empty); break; + case EXPR_OMP_ARRAY_SHAPING: + S = OMPArrayShapingExpr::CreateEmpty( + Context, Record[ASTStmtReader::NumExprFields]); + break; + case EXPR_CALL: S = CallExpr::CreateEmpty( Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index d64e2330850a..840823298be7 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -774,6 +774,19 @@ void ASTStmtWriter::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) { Code = serialization::EXPR_OMP_ARRAY_SECTION; } +void ASTStmtWriter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { + VisitExpr(E); + Record.push_back(E->getDimensions().size()); + Record.AddStmt(E->getBase()); + for (Expr *Dim : E->getDimensions()) + Record.AddStmt(Dim); + for (SourceRange SR : E->getBracketsRanges()) + Record.AddSourceRange(SR); + Record.AddSourceLocation(E->getLParenLoc()); + Record.AddSourceLocation(E->getRParenLoc()); + Code = serialization::EXPR_OMP_ARRAY_SHAPING; +} + void ASTStmtWriter::VisitCallExpr(CallExpr *E) { VisitExpr(E); Record.push_back(E->getNumArgs()); diff --git a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp index f226609d8027..d16410a19b97 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp @@ -351,6 +351,7 @@ static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1, case Stmt::CallExprClass: case Stmt::ArraySubscriptExprClass: case Stmt::OMPArraySectionExprClass: + case Stmt::OMPArrayShapingExprClass: case Stmt::ImplicitCastExprClass: case Stmt::ParenExprClass: case Stmt::BreakStmtClass: diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 5405c812faca..4c0914628a0d 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1413,6 +1413,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::SubstNonTypeTemplateParmExprClass: case Stmt::CXXNullPtrLiteralExprClass: case Stmt::OMPArraySectionExprClass: + case Stmt::OMPArrayShapingExprClass: case Stmt::TypeTraitExprClass: { Bldr.takeNodes(Pred); ExplodedNodeSet preVisit; diff --git a/clang/test/OpenMP/depobj_messages.cpp b/clang/test/OpenMP/depobj_messages.cpp index ad28dffe184a..a33b16f985a0 100644 --- a/clang/test/OpenMP/depobj_messages.cpp +++ b/clang/test/OpenMP/depobj_messages.cpp @@ -158,7 +158,7 @@ label1 : { #pragma omp depend(out:x) depobj(x) // expected-error {{expected an OpenMP directive}} #pragma omp destroy depobj(x) // expected-error {{expected an OpenMP directive}} #pragma omp update(out) depobj(x) // expected-error {{expected an OpenMP directive}} -#pragma omp depobj depend(in:x) (x) // expected-error {{expected depobj expression}} expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}} expected-error {{expected addressable lvalue expression, array element or array section of non 'omp_depend_t' type}} +#pragma omp depobj depend(in:x) (x) // expected-error {{expected depobj expression}} expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}} expected-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} #pragma omp depobj destroy (x) // expected-error {{expected depobj expression}} expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}} #pragma omp depobj update(in) (x) // expected-error {{expected depobj expression}} expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}} return tmain(argc); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} diff --git a/clang/test/OpenMP/parallel_reduction_messages.c b/clang/test/OpenMP/parallel_reduction_messages.c index b5e66672cde9..5d6010d59d50 100644 --- a/clang/test/OpenMP/parallel_reduction_messages.c +++ b/clang/test/OpenMP/parallel_reduction_messages.c @@ -2,7 +2,7 @@ int incomplete[]; -void test() { +void test(int *p) { int a; #pragma omp parallel reduction( // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-note {{to match this '('}} ; @@ -16,7 +16,7 @@ void test() { ; #pragma omp parallel reduction(inscan, + : a) // expected-error {{'inscan' modifier can be used only in 'omp for', 'omp simd', 'omp for simd', 'omp parallel for', or 'omp parallel for simd' directive}} ; -#pragma omp parallel reduction(+ : incomplete) // expected-error {{a reduction list item with incomplete type 'int []'}} +#pragma omp parallel reduction(+ : incomplete, ([10])p) // expected-error {{a reduction list item with incomplete type 'int []'}} expected-error {{expected variable name, array element or array section}} ; } diff --git a/clang/test/OpenMP/task_ast_print.cpp b/clang/test/OpenMP/task_ast_print.cpp index 41c9bd0b308d..0f11b390f7fa 100644 --- a/clang/test/OpenMP/task_ast_print.cpp +++ b/clang/test/OpenMP/task_ast_print.cpp @@ -99,7 +99,7 @@ T tmain(T argc, T *argv) { T arr[argc]; omp_depend_t x; omp_event_handle_t evt; -#pragma omp task untied depend(in : argc, argv[b:argc], arr[:]) if (task : argc > 0) depend(depobj: x) detach(evt) +#pragma omp task untied depend(in : argc, argv[b:argc], arr[:], ([argc][sizeof(T)])argv) if (task : argc > 0) depend(depobj: x) detach(evt) a = 2; #pragma omp task default(none), private(argc, b) firstprivate(argv) shared(d) if (argc > 0) final(S::TS > 0) priority(argc) foo(); @@ -116,7 +116,7 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: T arr[argc]; // CHECK-NEXT: omp_depend_t x; // CHECK-NEXT: omp_event_handle_t evt; -// CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:]) if(task: argc > 0) depend(depobj : x) detach(evt) +// CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:],([argc][sizeof(T)])argv) if(task: argc > 0) depend(depobj : x) detach(evt) // CHECK-NEXT: a = 2; // CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S::TS > 0) priority(argc) // CHECK-NEXT: foo() @@ -130,7 +130,7 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: int arr[argc]; // CHECK-NEXT: omp_depend_t x; // CHECK-NEXT: omp_event_handle_t evt; -// CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:]) if(task: argc > 0) depend(depobj : x) detach(evt) +// CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:],([argc][sizeof(int)])argv) if(task: argc > 0) depend(depobj : x) detach(evt) // CHECK-NEXT: a = 2; // CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S::TS > 0) priority(argc) // CHECK-NEXT: foo() @@ -144,7 +144,7 @@ T tmain(T argc, T *argv) { // CHECK-NEXT: long arr[argc]; // CHECK-NEXT: omp_depend_t x; // CHECK-NEXT: omp_event_handle_t evt; -// CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:]) if(task: argc > 0) depend(depobj : x) detach(evt) +// CHECK-NEXT: #pragma omp task untied depend(in : argc,argv[b:argc],arr[:],([argc][sizeof(long)])argv) if(task: argc > 0) depend(depobj : x) detach(evt) // CHECK-NEXT: a = 2; // CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S::TS > 0) priority(argc) // CHECK-NEXT: foo() @@ -164,14 +164,14 @@ int main(int argc, char **argv) { #pragma omp threadprivate(a) Enum ee; // CHECK: Enum ee; -#pragma omp task untied mergeable depend(out:argv[:a][1], (arr)[0:]) if(task: argc > 0) priority(f) depend(depobj:y) - // CHECK-NEXT: #pragma omp task untied mergeable depend(out : argv[:a][1],(arr)[0:]) if(task: argc > 0) priority(f) depend(depobj : y) +#pragma omp task untied mergeable depend(out:argv[:a][1], (arr)[0:],([argc][10])argv) if(task: argc > 0) priority(f) depend(depobj:y) + // CHECK-NEXT: #pragma omp task untied mergeable depend(out : argv[:a][1],(arr)[0:],([argc][10])argv) if(task: argc > 0) priority(f) depend(depobj : y) a = 2; // CHECK-NEXT: a = 2; #pragma omp taskgroup task_reduction(min: arr1) -#pragma omp task default(none), private(argc, b) firstprivate(argv, evt) if (argc > 0) final(a > 0) depend(inout : a, argv[:argc],arr[:a]) priority(23) in_reduction(min: arr1), detach(evt) +#pragma omp task default(none), private(argc, b) firstprivate(argv, evt) if (argc > 0) final(a > 0) depend(inout : a, argv[:argc],arr[:a], ([10][argc])argv) priority(23) in_reduction(min: arr1), detach(evt) // CHECK-NEXT: #pragma omp taskgroup task_reduction(min: arr1) - // CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv,evt) if(argc > 0) final(a > 0) depend(inout : a,argv[:argc],arr[:a]) priority(23) in_reduction(min: arr1) detach(evt) + // CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv,evt) if(argc > 0) final(a > 0) depend(inout : a,argv[:argc],arr[:a],([10][argc])argv) priority(23) in_reduction(min: arr1) detach(evt) foo(); // CHECK-NEXT: foo(); #pragma omp taskgroup task_reduction(min: arr1) diff --git a/clang/test/OpenMP/task_depend_messages.cpp b/clang/test/OpenMP/task_depend_messages.cpp index ea55cdaa84af..7d976eca2ec1 100644 --- a/clang/test/OpenMP/task_depend_messages.cpp +++ b/clang/test/OpenMP/task_depend_messages.cpp @@ -35,14 +35,14 @@ int main(int argc, char **argv, char *env[]) { #pragma omp task depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} #pragma omp task depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}} #pragma omp task depend (out: ) // expected-error {{expected expression}} - #pragma omp task depend (inout : foobool(argc)), depend (in, argc) // expected-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} + #pragma omp task depend (inout : foobool(argc)), depend (in, argc) // omp50-error {{expected addressable lvalue expression, array element, array section or array shaping expression}} omp45-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} #pragma omp task depend (out :S1) // expected-error {{'S1' does not refer to a value}} #pragma omp task depend(in : argv[1][1] = '2') - #pragma omp task depend (in : vec[1]) // expected-error {{expected addressable lvalue expression, array element or array section}} + #pragma omp task depend (in : vec[1]) // omp50-error {{expected addressable lvalue expression, array element, array section or array shaping expression}} omp45-error {{expected addressable lvalue expression, array element or array section}} #pragma omp task depend (in : argv[0]) #pragma omp task depend (in : ) // expected-error {{expected expression}} #pragma omp task depend (in : main) - #pragma omp task depend(in : a[0]) // expected-error{{expected addressable lvalue expression, array element or array section}} + #pragma omp task depend(in : a[0]) // omp50-error {{expected addressable lvalue expression, array element, array section or array shaping expression}} omp45-error {{expected addressable lvalue expression, array element or array section}} #pragma omp task depend (in : vec[1:2]) // expected-error {{ value is not an array or pointer}} #pragma omp task depend (in : argv[ // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} #pragma omp task depend (in : argv[: // expected-error {{expected expression}} expected-error {{expected ']'}} expected-error {{expected ')'}} expected-note {{to match this '['}} expected-note {{to match this '('}} @@ -62,6 +62,14 @@ int main(int argc, char **argv, char *env[]) { #pragma omp task depend(depobj:argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected lvalue expression of 'omp_depend_t' type, not 'int'}} #pragma omp task depend(depobj : argv[ : argc][1 : argc - 1]) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected lvalue expression of 'omp_depend_t' type, not ''}} #pragma omp task depend(depobj : arr[0]) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} + #pragma omp task depend(in : ([ // expected-error {{expected variable name or 'this' in lambda capture list}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task depend(in : ([] // expected-error {{expected body of lambda expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp task depend(in : ([]) // omp45-error {{expected body of lambda expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error 2 {{expected expression}} + #pragma omp task depend(in : ([])a // omp45-error {{expected body of lambda expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error {{expected expression}} + #pragma omp task depend(in : ([])a) // omp45-error {{expected body of lambda expression}} omp50-error {{expected expression}} + #pragma omp task depend(in : ([a])a) // omp45-error {{expected body of lambda expression}} omp50-error {{expected pointer type expression as a base of an array shaping operation}} + #pragma omp task depend(in : ([a])argc) // omp45-error {{expected body of lambda expression}} omp50-error {{expected pointer type expression as a base of an array shaping operation}} + #pragma omp task depend(in : ([-1][0])argv) // omp45-error {{expected variable name or 'this' in lambda capture list}} omp45-error {{expected ')'}} omp45-note {{to match this '('}} omp50-error {{array shaping dimension is evaluated to a non-positive value -1}} omp50-error {{array shaping dimension is evaluated to a non-positive value 0}} foo(); return 0; diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index c878f454aad0..bb9fed165679 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -5183,6 +5183,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return cxstring::createRef("ArraySubscriptExpr"); case CXCursor_OMPArraySectionExpr: return cxstring::createRef("OMPArraySectionExpr"); + case CXCursor_OMPArrayShapingExpr: + return cxstring::createRef("OMPArrayShapingExpr"); case CXCursor_BinaryOperator: return cxstring::createRef("BinaryOperator"); case CXCursor_CompoundAssignOperator: diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index 1f6304a08bca..4f4e0c4ea1d5 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -423,6 +423,10 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent, K = CXCursor_OMPArraySectionExpr; break; + case Stmt::OMPArrayShapingExprClass: + K = CXCursor_OMPArrayShapingExpr; + break; + case Stmt::BinaryOperatorClass: K = CXCursor_BinaryOperator; break; From cfe-commits at lists.llvm.org Mon Mar 30 07:00:36 2020 From: cfe-commits at lists.llvm.org (Digger via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 14:00:36 +0000 (UTC) Subject: [PATCH] D76932: [AIX] emit .extern and .weak directive linkage In-Reply-To: References: Message-ID: <0410757296b2b068c5e5883e993d2d7e@localhost.localdomain> DiggerLin marked an inline comment as done. DiggerLin added inline comments. ================ Comment at: llvm/include/llvm/MC/MCDirectives.h:47 + MCSA_WeakReference, ///< .weak_reference (MachO) + MCSA_WeakDefAutoPrivate ///< .weak_def_can_be_hidden (MachO) }; ---------------- @hubert.reinterpretcast , @jasonliu , do we need to create a NFC patch for the clang format problem of the above first ? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76932/new/ https://reviews.llvm.org/D76932 From cfe-commits at lists.llvm.org Mon Mar 30 07:00:39 2020 From: cfe-commits at lists.llvm.org (Adam Czachorowski via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 14:00:39 +0000 (UTC) Subject: [PATCH] D76432: [clangd] Add a tweak for adding "using" statement. In-Reply-To: References: Message-ID: <478a76bf917ec5d67f7f4437c659fdcb@localhost.localdomain> adamcz updated this revision to Diff 253583. adamcz marked 10 inline comments as done. adamcz added a comment. review round 2 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76432/new/ https://reviews.llvm.org/D76432 Files: clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt clang-tools-extra/clangd/unittests/TweakTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76432.253583.patch Type: text/x-patch Size: 16470 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 07:00:40 2020 From: cfe-commits at lists.llvm.org (Adam Czachorowski via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 14:00:40 +0000 (UTC) Subject: [PATCH] D76432: [clangd] Add a tweak for adding "using" statement. In-Reply-To: References: Message-ID: <75c0155334eb11d342b40fcddca55791@localhost.localdomain> adamcz added inline comments. ================ Comment at: clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp:89 + + // If we're looking at a type or NestedNameSpecifier, walk up the tree until + // we find the "main" node we care about, which would be ElaboratedTypeLoc or ---------------- sammccall wrote: > adamcz wrote: > > sammccall wrote: > > > I like the idea here, but I'm not sure it quite works. e.g. any typeloc has a directly enclosing typeloc, the inner one can't be targeted. So what about `x::S*`? (pointertypeloc > elaboratedtypeloc > recordtypeloc)? > > > > > > - looping up from NNS until you get to something else makes sense > > > - unwrapping typeloc -> elaboratedtypeloc makes sense, but I don't think you ever want to unwrap multiple levels? > > > - i don't think these cases overlap at all, you want one or the other > > > > > > Am I missing something? > > If you have a class foo::bar::cc and a struct st inside it, and then do: > > foo::bar::c^c::st *p; > > you end up with: > > PointerTypeLoc -> ElaboratedTypeLoc ->NestedNameSpecifierLoc -> RecordTypeLoc > > in which case you need to go up from type to NNSL and then up again, from NNSL to something that's not NNSL. > > > > You have a good point with the PointerTypeLoc, that's a bug. We should stop going up the tree as soon as we find ElaboratedTypeLoc. I added a test for that. > > foo::bar::c^c::st *p; > > But this isn't a case we support, right? We only support extraction when the NNS consists entirely of namespaces, and such NNSes don't have any children apart from the qualifier NNS. Not right now, but I left a comment that we should improve that. The way it is now, code is correct, always, and improving it is just a matter or removing the "no record types" check and replacing with a bit more code. Seems better to me. ================ Comment at: clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp:206 + tooling::Replacements R; + if (auto Err = R.add(tooling::Replacement( + SM, CharSourceRange::getTokenRange(NNSL.getSourceRange()), "", ---------------- kadircet wrote: > sammccall wrote: > > adamcz wrote: > > > sammccall wrote: > > > > (Sorry if some of this is obvious: TL;DR: we should use TokenBuffer to handle macros in this case) > > > > > > > > Whenever we try to use SourceLocations to reason about written source code, we have to think about macros. Some libraries try to encapsulate this, but the road to confusion is paved with good intentions, and it's often best to decide on the policy and be explicit about it. > > > > > > > > For example, when provided a macro location, the tooling::Replacement constructor uses its spelling location. > > > > Given: > > > > ``` > > > > // imagine we're trying to abstract away namespaces for C or something > > > > #define NS(X) foo::X > > > > NS(Bar) boo; > > > > ``` > > > > Running this action on `N` would result in changing the definition of the `NS` macro to delete the "foo::", as that's where the qualifier was spelled! > > > > > > > > It would be reasonable (but actually not trivial!) to try to detect any macro usage and bail out. The general case of "is there some sequence of source-code tokens that correspond to this range of preprocessed tokens and nothing else" is pretty hard. > > > > > > > > However TokenBuffer does have APIs for this exact question, as it was designed for writing refactorings that replace nodes. I think you want: > > > > - `expandedTokens(NNSL.getSourceRange())` > > > > - `spelledForExpanded(ExpandedTokens)` > > > > - `Token::range(SM, Spelled.front(), Spelled.back())` > > > > - `Replacement("fname", Range.Offset, Range.Length, "")` > > > > > > > > (ugh, that's really awkward. Maybe we should have a helper in TokenBuffer that combines 1-3) > > > > > > > You have a good point that this doesn't work well with macros, but I'm not entirely sure how you think this should work. > > > > > > I'd argue that code actions should refer to the thing under the cursor, not it's expansion. That would be confusing to the user, as they would not be able to understand what the action offered is, nor how it would affect other places. So in your example of > > > #define NS(X) foo::X > > > I'd argue that we should not offer the action. > > > We should, however, support something like: > > > EXPECT_TRUE(fo^o::bar()); > > > In this case, the qualifier is spelled under the cursor and the fact that EXPECT_TRUE is a macro and not a function should not matter to the user. > > > > > > I updated the code to support that and added tests. > > > We can use isMacroID() and isMacroArgExpansion() to filter out macros, except for macro arguments. Note that we can't use spelledForExpanded(), since the qualifier might not be the entire expansion of the macro, thus spelledForExpanded will return None. > > > > > > Let me know if any of what I did here now doesn't make sense. > > > > > > in your example of #define NS(X) foo::X I'd argue that we should not offer the action. > > > > Indeed, sorry I didn't spell that out - I was highlighting it because the original code silently did something (bad) in this case. > > > > > can't use spelledForExpanded(), since the qualifier might not be the entire expansion of the macro > > > > Ah, D75446 hasn't landed yet. @kadircet, want to land this soon? :-) > > > > > done, let me know if it doesn't work :D Works great, thanks! ================ Comment at: clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp:226 + + if (auto Err = R.add(tooling::Replacement(SM, InsertionPoint->Loc, 0, + UsingTextStream.str()))) { ---------------- sammccall wrote: > adamcz wrote: > > sammccall wrote: > > > Again macros. > > > This seems a bit more pressing, there's a nontrivial chance that you're inserting inside a namespace which is introduced by invoking a `FOO_NS_BEGIN` macro. > > > > > > Unfortunately I don't see a really simple way to insert after this macro - using the expansion location fails if macro doesn't end after the `}`. (e.g. `ANON_NAMESPACE(f::X y;)`) > > > (Also you'd need to take care of inserting a space after the macro invocation to avoid `FOO_NS_BEGINusing`.) > > > > > > I'd suggest simply skipping over any candidate locations (namespaces or using declarations) that aren't in the main file, using the expansion location of the first-top-level-decl fallback, and asserting here that the location is in the main file. (We use raw `assert()` in LLVM) > > We already skip over "using" not in main file. I added check for namespace and fixed the above-first-top-level-decl to be above getExpandedLoc() of that, which works for something like a macro declaring a namespace. It's not ideal, but I think it should be good enough, at least for now. Also added a test. > > > > Not sure what the point of assert() here would be? Wouldn't it be far better to return an error, since it's trivial at this point and it won't crash the whole server, including the background index and such? I get that assert() can be useful in places where returning error is difficult and for things that should never, ever happen, but here seems like an overkill. > > > > Anyway, editMainFile() already returns an error when the edit is not in the main file. IMHO that's good enough, what do you think? > Behaviour looks good. > > > Not sure what the point of assert() here would be? > This is a consistency check - we're relying on an invariant we think we've established elsewhere. If this goes wrong, it's a programmer error, and for better or worse, LLVM defines those as asserts. > > Practical benefits: > - developers are more likely to notice when these are violated (assuming an -UNDEBUG build) > - we get a stacktrace, which is often useful (not really here). Returning an error doesn't give us that. > - we don't pay for the check in release builds > - it documents the distinction between invariant-breaking bugs and dynamically-possible error conditions > - consistency (in principle we could change all our err-handling, but we can't change this in clang) OK, I added the assert(). I'm not against asserts in general, I just find them often insufficient and not a replacement for better error handling. In this case, it certainly won't hurt. ================ Comment at: clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp:245 + auto &SM = Inputs.AST->getSourceManager(); + auto TB = Inputs.AST->getTokens(); + // Determine the length of the qualifier under the cursor, then remove it. ---------------- sammccall wrote: > sammccall wrote: > > yikes, this copies the tokenbuffer, I didn't think that was even possible! > > auto& > Copy constructor deleted in 94938d7d41cd11c4539ff93b801fe53cb4fddba2 Haha, that's a lovely bug. Thanks for fixing the ctor. ================ Comment at: clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp:249 + const auto *SpelledBeginTok = + TB.spelledTokenAt(SM.getSpellingLoc(ExpandedTokens.front().location())); + const auto *SpelledEndTok = ---------------- kadircet wrote: > why not use spelledForExpanded in here as well? It didn't work before. Thanks for improving it! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76432/new/ https://reviews.llvm.org/D76432 From cfe-commits at lists.llvm.org Mon Mar 30 07:00:43 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 14:00:43 +0000 (UTC) Subject: [PATCH] D76996: [analyzer] Improve PlacementNewChecker In-Reply-To: References: Message-ID: <845a47e96f1bf5422745ca94a8d61aae@localhost.localdomain> martong added a comment. Wohoow! I am impressed, this is really nice work, I like it! :) Could not find any glitch, looks good from my side once you address NoQ's concerns. ================ Comment at: clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp:125 + Msg = std::string(llvm::formatv( + "Possibly not enough {0} bytes for array allocation which " + "requires " ---------------- Maybe the below could be a wording that's more easy to follow? `{0} bytes is possibly not enough for array allocation which ...` Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76996/new/ https://reviews.llvm.org/D76996 From cfe-commits at lists.llvm.org Mon Mar 30 07:01:11 2020 From: cfe-commits at lists.llvm.org (Alexey Bataev via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 14:01:11 +0000 (UTC) Subject: [PATCH] D74144: [OPENMP50]Add basic support for array-shaping operation. In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rG7ac9efb0c322: [OPENMP50]Add basic support for array-shaping operation. (authored by ABataev). Changed prior to commit: https://reviews.llvm.org/D74144?vs=252859&id=253584#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D74144/new/ https://reviews.llvm.org/D74144 Files: clang/include/clang-c/Index.h clang/include/clang/AST/ASTContext.h clang/include/clang/AST/BuiltinTypes.def clang/include/clang/AST/ComputeDependence.h clang/include/clang/AST/ExprOpenMP.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Basic/StmtNodes.td clang/include/clang/Parse/Parser.h clang/include/clang/Sema/Sema.h clang/include/clang/Serialization/ASTBitCodes.h clang/lib/AST/ASTContext.cpp clang/lib/AST/ComputeDependence.cpp clang/lib/AST/Expr.cpp clang/lib/AST/ExprClassification.cpp clang/lib/AST/ExprConstant.cpp clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/NSAPI.cpp clang/lib/AST/StmtPrinter.cpp clang/lib/AST/StmtProfile.cpp clang/lib/AST/Type.cpp clang/lib/AST/TypeLoc.cpp clang/lib/Parse/ParseExpr.cpp clang/lib/Sema/SemaExceptionSpec.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTCommon.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriterStmt.cpp clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp clang/lib/StaticAnalyzer/Core/ExprEngine.cpp clang/test/OpenMP/depobj_messages.cpp clang/test/OpenMP/parallel_reduction_messages.c clang/test/OpenMP/task_ast_print.cpp clang/test/OpenMP/task_depend_messages.cpp clang/tools/libclang/CIndex.cpp clang/tools/libclang/CXCursor.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D74144.253584.patch Type: text/x-patch Size: 47893 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 07:01:47 2020 From: cfe-commits at lists.llvm.org (Marcel Hlopko via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 14:01:47 +0000 (UTC) Subject: [PATCH] D77053: [Syntax] A tool to dump syntax tree and token buffer In-Reply-To: References: Message-ID: <3a55d94fdc0a5f379ab01e166c25a51c@localhost.localdomain> hlopko abandoned this revision. hlopko added a comment. Talked to gribozavr2 offline and decided to abandon this patch. If in the future we'll have a need for a tool to dump syntax trees, we'll probably implement it in clang behind hidden options, and we'll provide a json output format as well. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77053/new/ https://reviews.llvm.org/D77053 From cfe-commits at lists.llvm.org Mon Mar 30 07:02:11 2020 From: cfe-commits at lists.llvm.org (=?UTF-8?Q?Kirst=C3=B3f_Umann?= via cfe-commits) Date: Mon, 30 Mar 2020 07:02:11 -0700 (PDT) Subject: [clang] 703a1b8 - [analyzer][MallocChecker][NFC] Split checkPostCall up, deploy CallDescriptionMap Message-ID: <5e81fbe3.1c69fb81.50d82.bfb7@mx.google.com> Author: Louis Dionne Date: 2020-03-30T16:01:58+02:00 New Revision: 703a1b8caf09a5262a45c2179b8131922f71cf25 URL: https://github.com/llvm/llvm-project/commit/703a1b8caf09a5262a45c2179b8131922f71cf25 DIFF: https://github.com/llvm/llvm-project/commit/703a1b8caf09a5262a45c2179b8131922f71cf25.diff LOG: [analyzer][MallocChecker][NFC] Split checkPostCall up, deploy CallDescriptionMap Since its important to know whether a function frees memory (even if its a reallocating function!), I used two CallDescriptionMaps to merge all CallDescriptions into it. MemFunctionInfoTy no longer makes sense, it may never have, but for now, it would be more of a distraction then anything else. Differential Revision: https://reviews.llvm.org/D68165 Added: Modified: clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Removed: ################################################################################ diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index 32a500ffd102..52786bcaf072 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -62,16 +62,19 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/ErrorHandling.h" #include +#include #include using namespace clang; using namespace ento; +using namespace std::placeholders; //===----------------------------------------------------------------------===// // The types of allocation we're modeling. This is used to check whether a @@ -93,8 +96,6 @@ enum AllocationFamily { AF_InnerBuffer }; -struct MemFunctionInfoTy; - } // end of anonymous namespace /// Print names of allocators and deallocators. @@ -263,47 +264,6 @@ struct ReallocPair { REGISTER_MAP_WITH_PROGRAMSTATE(ReallocPairs, SymbolRef, ReallocPair) -//===----------------------------------------------------------------------===// -// Kinds of memory operations, information about resource managing functions. -//===----------------------------------------------------------------------===// - -namespace { - -struct MemFunctionInfoTy { - /// The value of the MallocChecker:Optimistic is stored in this variable. - /// - /// In pessimistic mode, the checker assumes that it does not know which - /// functions might free the memory. - /// In optimistic mode, the checker assumes that all user-defined functions - /// which might free a pointer are annotated. - DefaultBool ShouldIncludeOwnershipAnnotatedFunctions; - - CallDescription CD_alloca{{"alloca"}, 1}, CD_win_alloca{{"_alloca"}, 1}, - CD_malloc{{"malloc"}, 1}, CD_BSD_malloc{{"malloc"}, 3}, - CD_free{{"free"}, 1}, CD_realloc{{"realloc"}, 2}, - CD_calloc{{"calloc"}, 2}, CD_valloc{{"valloc"}, 1}, - CD_reallocf{{"reallocf"}, 2}, CD_strndup{{"strndup"}, 2}, - CD_strdup{{"strdup"}, 1}, CD_win_strdup{{"_strdup"}, 1}, - CD_kmalloc{{"kmalloc"}, 2}, CD_if_nameindex{{"if_nameindex"}, 1}, - CD_if_freenameindex{{"if_freenameindex"}, 1}, CD_wcsdup{{"wcsdup"}, 1}, - CD_win_wcsdup{{"_wcsdup"}, 1}, CD_kfree{{"kfree"}, 1}, - CD_g_malloc{{"g_malloc"}, 1}, CD_g_malloc0{{"g_malloc0"}, 1}, - CD_g_realloc{{"g_realloc"}, 2}, CD_g_try_malloc{{"g_try_malloc"}, 1}, - CD_g_try_malloc0{{"g_try_malloc0"}, 1}, - CD_g_try_realloc{{"g_try_realloc"}, 2}, CD_g_free{{"g_free"}, 1}, - CD_g_memdup{{"g_memdup"}, 2}, CD_g_malloc_n{{"g_malloc_n"}, 2}, - CD_g_malloc0_n{{"g_malloc0_n"}, 2}, CD_g_realloc_n{{"g_realloc_n"}, 3}, - CD_g_try_malloc_n{{"g_try_malloc_n"}, 2}, - CD_g_try_malloc0_n{{"g_try_malloc0_n"}, 2}, - CD_g_try_realloc_n{{"g_try_realloc_n"}, 3}; - - bool isMemFunction(const CallEvent &Call) const; - bool isCMemFunction(const CallEvent &Call) const; - bool isCMemFreeFunction(const CallEvent &Call) const; - bool isCMemAllocFunction(const CallEvent &Call) const; -}; -} // end of anonymous namespace - /// Tells if the callee is one of the builtin new/delete operators, including /// placement operators and other standard overloads. static bool isStandardNewDelete(const FunctionDecl *FD); @@ -327,7 +287,11 @@ class MallocChecker check::PreStmt, check::PostStmt, check::PostObjCMessage, check::Location, eval::Assume> { public: - MemFunctionInfoTy MemFunctionInfo; + /// In pessimistic mode, the checker assumes that it does not know which + /// functions might free the memory. + /// In optimistic mode, the checker assumes that all user-defined functions + /// which might free a pointer are annotated. + DefaultBool ShouldIncludeOwnershipAnnotatedFunctions; /// Many checkers are essentially built into this one, so enabling them will /// make MallocChecker perform additional modeling and reporting. @@ -387,6 +351,81 @@ class MallocChecker mutable std::unique_ptr BT_OffsetFree[CK_NumCheckKinds]; mutable std::unique_ptr BT_UseZerroAllocated[CK_NumCheckKinds]; +#define CHECK_FN(NAME) \ + void NAME(CheckerContext &C, const CallExpr *CE, ProgramStateRef State) const; + + CHECK_FN(checkFree) + CHECK_FN(checkIfNameIndex) + CHECK_FN(checkBasicAlloc) + CHECK_FN(checkKernelMalloc) + CHECK_FN(checkCalloc) + CHECK_FN(checkAlloca) + CHECK_FN(checkStrdup) + CHECK_FN(checkIfFreeNameIndex) + CHECK_FN(checkCXXNewOrCXXDelete) + CHECK_FN(checkGMalloc0) + CHECK_FN(checkGMemdup) + CHECK_FN(checkGMallocN) + CHECK_FN(checkGMallocN0) + CHECK_FN(checkReallocN) + CHECK_FN(checkOwnershipAttr) + + void checkRealloc(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State, bool ShouldFreeOnFail) const; + + using CheckFn = + std::function; + + const CallDescriptionMap FreeingMemFnMap{ + {{"free", 1}, &MallocChecker::checkFree}, + {{"if_freenameindex", 1}, &MallocChecker::checkIfFreeNameIndex}, + {{"kfree", 1}, &MallocChecker::checkFree}, + {{"g_free", 1}, &MallocChecker::checkFree}, + }; + + bool isFreeingCall(const CallEvent &Call) const; + + CallDescriptionMap AllocatingMemFnMap{ + {{"alloca", 1}, &MallocChecker::checkAlloca}, + {{"_alloca", 1}, &MallocChecker::checkAlloca}, + {{"malloc", 1}, &MallocChecker::checkBasicAlloc}, + {{"malloc", 3}, &MallocChecker::checkKernelMalloc}, + {{"calloc", 2}, &MallocChecker::checkCalloc}, + {{"valloc", 1}, &MallocChecker::checkBasicAlloc}, + {{CDF_MaybeBuiltin, "strndup", 2}, &MallocChecker::checkStrdup}, + {{CDF_MaybeBuiltin, "strdup", 1}, &MallocChecker::checkStrdup}, + {{"_strdup", 1}, &MallocChecker::checkStrdup}, + {{"kmalloc", 2}, &MallocChecker::checkKernelMalloc}, + {{"if_nameindex", 1}, &MallocChecker::checkIfNameIndex}, + {{CDF_MaybeBuiltin, "wcsdup", 1}, &MallocChecker::checkStrdup}, + {{CDF_MaybeBuiltin, "_wcsdup", 1}, &MallocChecker::checkStrdup}, + {{"g_malloc", 1}, &MallocChecker::checkBasicAlloc}, + {{"g_malloc0", 1}, &MallocChecker::checkGMalloc0}, + {{"g_try_malloc", 1}, &MallocChecker::checkBasicAlloc}, + {{"g_try_malloc0", 1}, &MallocChecker::checkGMalloc0}, + {{"g_memdup", 2}, &MallocChecker::checkGMemdup}, + {{"g_malloc_n", 2}, &MallocChecker::checkGMallocN}, + {{"g_malloc0_n", 2}, &MallocChecker::checkGMallocN0}, + {{"g_try_malloc_n", 2}, &MallocChecker::checkGMallocN}, + {{"g_try_malloc0_n", 2}, &MallocChecker::checkGMallocN0}, + }; + + CallDescriptionMap ReallocatingMemFnMap{ + {{"realloc", 2}, + std::bind(&MallocChecker::checkRealloc, _1, _2, _3, _4, false)}, + {{"reallocf", 2}, + std::bind(&MallocChecker::checkRealloc, _1, _2, _3, _4, true)}, + {{"g_realloc", 2}, + std::bind(&MallocChecker::checkRealloc, _1, _2, _3, _4, false)}, + {{"g_try_realloc", 2}, + std::bind(&MallocChecker::checkRealloc, _1, _2, _3, _4, false)}, + {{"g_realloc_n", 3}, &MallocChecker::checkReallocN}, + {{"g_try_realloc_n", 3}, &MallocChecker::checkReallocN}, + }; + + bool isMemCall(const CallEvent &Call) const; + // TODO: Remove mutable by moving the initializtaion to the registry function. mutable Optional KernelZeroFlagVal; @@ -822,28 +861,31 @@ class StopTrackingCallback final : public SymbolVisitor { }; } // end anonymous namespace -//===----------------------------------------------------------------------===// -// Methods of MemFunctionInfoTy. -//===----------------------------------------------------------------------===// +static bool isStandardNewDelete(const FunctionDecl *FD) { + if (!FD) + return false; -bool MemFunctionInfoTy::isMemFunction(const CallEvent &Call) const { - return isCMemFunction(Call) || isStandardNewDelete(Call); -} + OverloadedOperatorKind Kind = FD->getOverloadedOperator(); + if (Kind != OO_New && Kind != OO_Array_New && Kind != OO_Delete && + Kind != OO_Array_Delete) + return false; -bool MemFunctionInfoTy::isCMemFunction(const CallEvent &Call) const { - return isCMemFreeFunction(Call) || isCMemAllocFunction(Call); + // This is standard if and only if it's not defined in a user file. + SourceLocation L = FD->getLocation(); + // If the header for operator delete is not included, it's still defined + // in an invalid source location. Check to make sure we don't crash. + return !L.isValid() || + FD->getASTContext().getSourceManager().isInSystemHeader(L); } -bool MemFunctionInfoTy::isCMemFreeFunction(const CallEvent &Call) const { - if (Call.isCalled(CD_free, CD_realloc, CD_reallocf, CD_g_free, CD_kfree)) - return true; +//===----------------------------------------------------------------------===// +// Methods of MallocChecker and MallocBugVisitor. +//===----------------------------------------------------------------------===// - if (Call.isCalled(CD_if_freenameindex)) +bool MallocChecker::isFreeingCall(const CallEvent &Call) const { + if (FreeingMemFnMap.lookup(Call) || ReallocatingMemFnMap.lookup(Call)) return true; - if (!ShouldIncludeOwnershipAnnotatedFunctions) - return false; - const auto *Func = dyn_cast(Call.getDecl()); if (Func && Func->hasAttrs()) { for (const auto *I : Func->specific_attrs()) { @@ -855,60 +897,21 @@ bool MemFunctionInfoTy::isCMemFreeFunction(const CallEvent &Call) const { return false; } -bool MemFunctionInfoTy::isCMemAllocFunction(const CallEvent &Call) const { - if (Call.isCalled(CD_malloc, CD_realloc, CD_reallocf, CD_calloc, CD_valloc, - CD_strdup, CD_win_strdup, CD_strndup, CD_wcsdup, - CD_win_wcsdup, CD_kmalloc, CD_g_malloc, CD_g_malloc0, - CD_g_realloc, CD_g_try_malloc, CD_g_try_malloc0, - CD_g_try_realloc, CD_g_memdup, CD_g_malloc_n, - CD_g_malloc0_n, CD_g_realloc_n, CD_g_try_malloc_n, - CD_g_try_malloc0_n, CD_g_try_realloc_n)) - return true; - - if (Call.isCalled(CD_if_nameindex)) - return true; - - if (Call.isCalled(CD_alloca, CD_win_alloca)) +bool MallocChecker::isMemCall(const CallEvent &Call) const { + if (FreeingMemFnMap.lookup(Call) || AllocatingMemFnMap.lookup(Call) || + ReallocatingMemFnMap.lookup(Call)) return true; if (!ShouldIncludeOwnershipAnnotatedFunctions) return false; const auto *Func = dyn_cast(Call.getDecl()); - if (Func && Func->hasAttrs()) { - for (const auto *I : Func->specific_attrs()) { - OwnershipAttr::OwnershipKind OwnKind = I->getOwnKind(); - if (OwnKind == OwnershipAttr::Returns) - return true; - } - } - - return false; -} - -static bool isStandardNewDelete(const FunctionDecl *FD) { - if (!FD) - return false; - - OverloadedOperatorKind Kind = FD->getOverloadedOperator(); - if (Kind != OO_New && Kind != OO_Array_New && Kind != OO_Delete && - Kind != OO_Array_Delete) - return false; - - // This is standard if and only if it's not defined in a user file. - SourceLocation L = FD->getLocation(); - // If the header for operator delete is not included, it's still defined - // in an invalid source location. Check to make sure we don't crash. - return !L.isValid() || - FD->getASTContext().getSourceManager().isInSystemHeader(L); + return Func && Func->hasAttr(); } -//===----------------------------------------------------------------------===// -// Methods of MallocChecker and MallocBugVisitor. -//===----------------------------------------------------------------------===// - -llvm::Optional MallocChecker::performKernelMalloc( - const CallExpr *CE, CheckerContext &C, const ProgramStateRef &State) const { +llvm::Optional +MallocChecker::performKernelMalloc(const CallExpr *CE, CheckerContext &C, + const ProgramStateRef &State) const { // 3-argument malloc(), as commonly used in {Free,Net,Open}BSD Kernels: // // void *malloc(unsigned long size, struct malloc_type *mtp, int flags); @@ -996,173 +999,169 @@ SVal MallocChecker::evalMulForBufferSize(CheckerContext &C, const Expr *Blocks, return TotalSize; } -void MallocChecker::checkPostCall(const CallEvent &Call, - CheckerContext &C) const { - if (C.wasInlined) - return; +void MallocChecker::checkBasicAlloc(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State) const { + State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, AF_Malloc); + State = ProcessZeroAllocCheck(C, CE, 0, State); + C.addTransition(State); +} - const auto *CE = dyn_cast_or_null(Call.getOriginExpr()); - if (!CE) - return; +void MallocChecker::checkKernelMalloc(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State) const { + llvm::Optional MaybeState = + performKernelMalloc(CE, C, State); + if (MaybeState.hasValue()) + State = MaybeState.getValue(); + else + State = + MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, AF_Malloc); + C.addTransition(State); +} - const FunctionDecl *FD = C.getCalleeDecl(CE); - if (!FD) +void MallocChecker::checkRealloc(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State, + bool ShouldFreeOnFail) const { + State = ReallocMemAux(C, CE, ShouldFreeOnFail, State, AF_Malloc); + State = ProcessZeroAllocCheck(C, CE, 1, State); + C.addTransition(State); +} + +void MallocChecker::checkCalloc(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State) const { + State = CallocMem(C, CE, State); + State = ProcessZeroAllocCheck(C, CE, 0, State); + State = ProcessZeroAllocCheck(C, CE, 1, State); + C.addTransition(State); +} + +void MallocChecker::checkFree(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State) const { + bool IsKnownToBeAllocatedMemory = false; + if (suppressDeallocationsInSuspiciousContexts(CE, C)) return; + State = + FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocatedMemory, AF_Malloc); + C.addTransition(State); +} - ProgramStateRef State = C.getState(); +void MallocChecker::checkAlloca(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State) const { + State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, AF_Alloca); + State = ProcessZeroAllocCheck(C, CE, 0, State); + C.addTransition(State); +} + +void MallocChecker::checkStrdup(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State) const { + State = MallocUpdateRefState(C, CE, State, AF_Malloc); + + C.addTransition(State); +} + +void MallocChecker::checkIfNameIndex(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State) const { + // Should we model this diff erently? We can allocate a fixed number of + // elements with zeros in the last one. + State = + MallocMemAux(C, CE, UnknownVal(), UnknownVal(), State, AF_IfNameIndex); + + C.addTransition(State); +} + +void MallocChecker::checkIfFreeNameIndex(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State) const { bool IsKnownToBeAllocatedMemory = false; + State = FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocatedMemory, + AF_IfNameIndex); + C.addTransition(State); +} - if (FD->getKind() == Decl::Function) { - if (Call.isCalled(MemFunctionInfo.CD_malloc, MemFunctionInfo.CD_BSD_malloc, - MemFunctionInfo.CD_g_malloc, - MemFunctionInfo.CD_g_try_malloc)) { - switch (CE->getNumArgs()) { - default: - return; - case 1: - State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, - AF_Malloc); - State = ProcessZeroAllocCheck(C, CE, 0, State); - break; - case 2: - llvm_unreachable("There shouldn't be a 2-argument malloc!"); - break; - case 3: - llvm::Optional MaybeState = - performKernelMalloc(CE, C, State); - if (MaybeState.hasValue()) - State = MaybeState.getValue(); - else - State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, - AF_Malloc); - break; - } - } else if (Call.isCalled(MemFunctionInfo.CD_kmalloc)) { - if (CE->getNumArgs() < 1) - return; - llvm::Optional MaybeState = - performKernelMalloc(CE, C, State); - if (MaybeState.hasValue()) - State = MaybeState.getValue(); - else - State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, - AF_Malloc); - } else if (Call.isCalled(MemFunctionInfo.CD_valloc)) { - if (CE->getNumArgs() < 1) - return; - State = - MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, AF_Malloc); - State = ProcessZeroAllocCheck(C, CE, 0, State); - } else if (Call.isCalled(MemFunctionInfo.CD_realloc, - MemFunctionInfo.CD_g_realloc, - MemFunctionInfo.CD_g_try_realloc)) { - State = - ReallocMemAux(C, CE, /*ShouldFreeOnFail*/ false, State, AF_Malloc); - State = ProcessZeroAllocCheck(C, CE, 1, State); - } else if (Call.isCalled(MemFunctionInfo.CD_reallocf)) { - State = ReallocMemAux(C, CE, /*ShouldFreeOnFail*/ true, State, AF_Malloc); - State = ProcessZeroAllocCheck(C, CE, 1, State); - } else if (Call.isCalled(MemFunctionInfo.CD_calloc)) { - State = CallocMem(C, CE, State); - State = ProcessZeroAllocCheck(C, CE, 0, State); - State = ProcessZeroAllocCheck(C, CE, 1, State); - } else if (Call.isCalled(MemFunctionInfo.CD_free, MemFunctionInfo.CD_g_free, - MemFunctionInfo.CD_kfree)) { - if (suppressDeallocationsInSuspiciousContexts(CE, C)) - return; +void MallocChecker::checkCXXNewOrCXXDelete(CheckerContext &C, + const CallExpr *CE, + ProgramStateRef State) const { + bool IsKnownToBeAllocatedMemory = false; - State = FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocatedMemory, - AF_Malloc); - } else if (Call.isCalled( - MemFunctionInfo.CD_strdup, MemFunctionInfo.CD_win_strdup, - MemFunctionInfo.CD_wcsdup, MemFunctionInfo.CD_win_wcsdup)) { - State = MallocUpdateRefState(C, CE, State, AF_Malloc); - } else if (Call.isCalled(MemFunctionInfo.CD_strndup)) { - State = MallocUpdateRefState(C, CE, State, AF_Malloc); - } else if (Call.isCalled(MemFunctionInfo.CD_alloca, - MemFunctionInfo.CD_win_alloca)) { - if (CE->getNumArgs() < 1) - return; - State = - MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, AF_Alloca); - State = ProcessZeroAllocCheck(C, CE, 0, State); - } else if (isStandardNewDelete(FD)) { - // Process direct calls to operator new/new[]/delete/delete[] functions - // as distinct from new/new[]/delete/delete[] expressions that are - // processed by the checkPostStmt callbacks for CXXNewExpr and - // CXXDeleteExpr. - switch (FD->getOverloadedOperator()) { - case OO_New: - State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, - AF_CXXNew); - State = ProcessZeroAllocCheck(C, CE, 0, State); - break; - case OO_Array_New: - State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, - AF_CXXNewArray); - State = ProcessZeroAllocCheck(C, CE, 0, State); - break; - case OO_Delete: - State = FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocatedMemory, - AF_CXXNew); - break; - case OO_Array_Delete: - State = FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocatedMemory, - AF_CXXNewArray); - break; - default: - llvm_unreachable("not a new/delete operator"); - } - } else if (Call.isCalled(MemFunctionInfo.CD_if_nameindex)) { - // Should we model this diff erently? We can allocate a fixed number of - // elements with zeros in the last one. - State = MallocMemAux(C, CE, UnknownVal(), UnknownVal(), State, - AF_IfNameIndex); - } else if (Call.isCalled(MemFunctionInfo.CD_if_freenameindex)) { - State = FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocatedMemory, - AF_IfNameIndex); - } else if (Call.isCalled(MemFunctionInfo.CD_g_malloc0, - MemFunctionInfo.CD_g_try_malloc0)) { - if (CE->getNumArgs() < 1) - return; - SValBuilder &svalBuilder = C.getSValBuilder(); - SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy); - State = MallocMemAux(C, CE, CE->getArg(0), zeroVal, State, AF_Malloc); - State = ProcessZeroAllocCheck(C, CE, 0, State); - } else if (Call.isCalled(MemFunctionInfo.CD_g_memdup)) { - if (CE->getNumArgs() < 2) - return; - State = - MallocMemAux(C, CE, CE->getArg(1), UndefinedVal(), State, AF_Malloc); - State = ProcessZeroAllocCheck(C, CE, 1, State); - } else if (Call.isCalled(MemFunctionInfo.CD_g_malloc_n, - MemFunctionInfo.CD_g_try_malloc_n, - MemFunctionInfo.CD_g_malloc0_n, - MemFunctionInfo.CD_g_try_malloc0_n)) { - if (CE->getNumArgs() < 2) - return; - SVal Init = UndefinedVal(); - if (Call.isCalled(MemFunctionInfo.CD_g_malloc0_n, - MemFunctionInfo.CD_g_try_malloc0_n)) { - SValBuilder &SB = C.getSValBuilder(); - Init = SB.makeZeroVal(SB.getContext().CharTy); - } - SVal TotalSize = evalMulForBufferSize(C, CE->getArg(0), CE->getArg(1)); - State = MallocMemAux(C, CE, TotalSize, Init, State, AF_Malloc); - State = ProcessZeroAllocCheck(C, CE, 0, State); - State = ProcessZeroAllocCheck(C, CE, 1, State); - } else if (Call.isCalled(MemFunctionInfo.CD_g_realloc_n, - MemFunctionInfo.CD_g_try_realloc_n)) { - if (CE->getNumArgs() < 3) - return; - State = ReallocMemAux(C, CE, /*ShouldFreeOnFail*/ false, State, AF_Malloc, - /*SuffixWithN*/ true); - State = ProcessZeroAllocCheck(C, CE, 1, State); - State = ProcessZeroAllocCheck(C, CE, 2, State); - } + const FunctionDecl *FD = C.getCalleeDecl(CE); + // Process direct calls to operator new/new[]/delete/delete[] functions + // as distinct from new/new[]/delete/delete[] expressions that are + // processed by the checkPostStmt callbacks for CXXNewExpr and + // CXXDeleteExpr. + switch (FD->getOverloadedOperator()) { + case OO_New: + State = + MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, AF_CXXNew); + State = ProcessZeroAllocCheck(C, CE, 0, State); + break; + case OO_Array_New: + State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State, + AF_CXXNewArray); + State = ProcessZeroAllocCheck(C, CE, 0, State); + break; + case OO_Delete: + State = FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocatedMemory, + AF_CXXNew); + break; + case OO_Array_Delete: + State = FreeMemAux(C, CE, State, 0, false, IsKnownToBeAllocatedMemory, + AF_CXXNewArray); + break; + default: + llvm_unreachable("not a new/delete operator"); } - if (MemFunctionInfo.ShouldIncludeOwnershipAnnotatedFunctions || + C.addTransition(State); +} + +void MallocChecker::checkGMalloc0(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State) const { + SValBuilder &svalBuilder = C.getSValBuilder(); + SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy); + State = MallocMemAux(C, CE, CE->getArg(0), zeroVal, State, AF_Malloc); + State = ProcessZeroAllocCheck(C, CE, 0, State); + C.addTransition(State); +} + +void MallocChecker::checkGMemdup(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State) const { + State = MallocMemAux(C, CE, CE->getArg(1), UndefinedVal(), State, AF_Malloc); + State = ProcessZeroAllocCheck(C, CE, 1, State); + C.addTransition(State); +} + +void MallocChecker::checkGMallocN(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State) const { + SVal Init = UndefinedVal(); + SVal TotalSize = evalMulForBufferSize(C, CE->getArg(0), CE->getArg(1)); + State = MallocMemAux(C, CE, TotalSize, Init, State, AF_Malloc); + State = ProcessZeroAllocCheck(C, CE, 0, State); + State = ProcessZeroAllocCheck(C, CE, 1, State); + C.addTransition(State); +} + +void MallocChecker::checkGMallocN0(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State) const { + SValBuilder &SB = C.getSValBuilder(); + SVal Init = SB.makeZeroVal(SB.getContext().CharTy); + SVal TotalSize = evalMulForBufferSize(C, CE->getArg(0), CE->getArg(1)); + State = MallocMemAux(C, CE, TotalSize, Init, State, AF_Malloc); + State = ProcessZeroAllocCheck(C, CE, 0, State); + State = ProcessZeroAllocCheck(C, CE, 1, State); + C.addTransition(State); +} + +void MallocChecker::checkReallocN(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State) const { + State = ReallocMemAux(C, CE, /*ShouldFreeOnFail=*/false, State, AF_Malloc, + /*SuffixWithN=*/true); + State = ProcessZeroAllocCheck(C, CE, 1, State); + State = ProcessZeroAllocCheck(C, CE, 2, State); + C.addTransition(State); +} + +void MallocChecker::checkOwnershipAttr(CheckerContext &C, const CallExpr *CE, + ProgramStateRef State) const { + const FunctionDecl *FD = C.getCalleeDecl(CE); + if (ShouldIncludeOwnershipAnnotatedFunctions || ChecksEnabled[CK_MismatchedDeallocatorChecker]) { // Check all the attributes, if there are any. // There can be multiple of these attributes. @@ -1182,6 +1181,44 @@ void MallocChecker::checkPostCall(const CallEvent &Call, C.addTransition(State); } +void MallocChecker::checkPostCall(const CallEvent &Call, + CheckerContext &C) const { + if (C.wasInlined) + return; + + const auto *CE = dyn_cast_or_null(Call.getOriginExpr()); + if (!CE) + return; + + const FunctionDecl *FD = C.getCalleeDecl(CE); + if (!FD) + return; + + ProgramStateRef State = C.getState(); + + if (const CheckFn *Callback = FreeingMemFnMap.lookup(Call)) { + (*Callback)(this, C, CE, State); + return; + } + + if (const CheckFn *Callback = AllocatingMemFnMap.lookup(Call)) { + (*Callback)(this, C, CE, State); + return; + } + + if (const CheckFn *Callback = ReallocatingMemFnMap.lookup(Call)) { + (*Callback)(this, C, CE, State); + return; + } + + if (isStandardNewDelete(Call)) { + checkCXXNewOrCXXDelete(C, CE, State); + return; + } + + checkOwnershipAttr(C, CE, State); +} + // Performs a 0-sized allocations check. ProgramStateRef MallocChecker::ProcessZeroAllocCheck( CheckerContext &C, const Expr *E, const unsigned IndexOfSizeArg, @@ -1448,8 +1485,7 @@ MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE, if (!State) return nullptr; - if (Att->getModule()->getName() != - MemFunctionInfo.CD_malloc.getFunctionName()) + if (Att->getModule()->getName() != "malloc") return nullptr; OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end(); @@ -1545,8 +1581,7 @@ ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C, if (!State) return nullptr; - if (Att->getModule()->getName() != - MemFunctionInfo.CD_malloc.getFunctionName()) + if (Att->getModule()->getName() != "malloc") return nullptr; bool IsKnownToBeAllocated = false; @@ -2597,8 +2632,7 @@ void MallocChecker::checkPreCall(const CallEvent &Call, if (!FD) return; - if (ChecksEnabled[CK_MallocChecker] && - (MemFunctionInfo.isCMemFreeFunction(Call))) + if (ChecksEnabled[CK_MallocChecker] && isFreeingCall(Call)) return; } @@ -2897,7 +2931,7 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly( // If it's one of the allocation functions we can reason about, we model // its behavior explicitly. - if (MemFunctionInfo.isMemFunction(*Call)) + if (isMemCall(*Call)) return false; // If it's not a system call, assume it frees memory. @@ -3315,7 +3349,7 @@ void ento::registerInnerPointerCheckerAux(CheckerManager &mgr) { void ento::registerDynamicMemoryModeling(CheckerManager &mgr) { auto *checker = mgr.registerChecker(); - checker->MemFunctionInfo.ShouldIncludeOwnershipAnnotatedFunctions = + checker->ShouldIncludeOwnershipAnnotatedFunctions = mgr.getAnalyzerOptions().getCheckerBooleanOption(checker, "Optimistic"); } From cfe-commits at lists.llvm.org Mon Mar 30 07:33:11 2020 From: cfe-commits at lists.llvm.org (Niko Weh via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 14:33:11 +0000 (UTC) Subject: [PATCH] D76496: [clang-tidy] StringFindStartswith should ignore 3-arg find() In-Reply-To: References: Message-ID: niko added a comment. In D76496#1947127 , @njames93 wrote: > In D76496#1947059 , @niko wrote: > > > In D76496#1935127 , @njames93 wrote: > > > > > I'm not hugely familiar with the abseil library, but from what I can see `absl::StartsWith` takes `absl::string_view` as args. Therefore surely it makes sense to handle the 3rd arg for `str::find` by explicitly constructing the `absl::string_view` from the pointer and size. > > > > > > I am mainly worried that the 3-arg find is rarely used, and using absl::string_view requires another option to be specified for the header file. If you think that's still a good tradeoff i'll change it to construct a string_view. > > > The `absl/strings/match` header includes the `absl/strings/string_view` header so you wouldn't need to include another header file. Well that's as long as the user hasn't done something funky with header files, but arguably the shouldn't be using Fix-Its if they have done something like that. Correct me if I'm wrong, but that seems to be in violation of IWYU? Maybe I'm misreading this, or is the idea that higher-lever tooling (e.g. IWYU fixer) is supposed to address that? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76496/new/ https://reviews.llvm.org/D76496 From cfe-commits at lists.llvm.org Mon Mar 30 07:33:13 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Bal=C3=A1zs_K=C3=A9ri_via_Phabricator?= via cfe-commits) Date: Mon, 30 Mar 2020 14:33:13 +0000 (UTC) Subject: [PATCH] D75682: [Analyzer][StreamChecker] Introduction of stream error handling. In-Reply-To: References: Message-ID: balazske updated this revision to Diff 253587. balazske added a comment. Added test checker. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75682/new/ https://reviews.llvm.org/D75682 Files: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp clang/test/Analysis/stream-error.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D75682.253587.patch Type: text/x-patch Size: 14523 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 07:33:13 2020 From: cfe-commits at lists.llvm.org (Richard Sandiford via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 14:33:13 +0000 (UTC) Subject: [PATCH] D77056: RFC: [Sema][SVE] Allow non-member operators for SVE types Message-ID: rsandifo-arm created this revision. rsandifo-arm added reviewers: sdesmalen, efriedma, rovka, rjmccall. Herald added subscribers: cfe-commits, danielkiss, psnobl, rkruppe, kristof.beyls, tschuett. Herald added a reviewer: rengolin. Herald added a project: clang. rsandifo-arm edited the summary of this revision. SVE types are defined to be opaque built-in types that by default can only be used via intrinsics. One consequence of this is that the types provide no built-in versions of the unary and binary arithmetic operators. Instead, we'd like to allow users to define non-member operators for SVE types, in much the same way as for enumeration types. This specifically means: - replacing "enumeration" in sections [over.match.oper] and [over.oper] of the C++ standard with wording that includes both enumerations and SVE types. - extending the enumeration handling of operator= in [over.built] to include SVE types. This feature is defined by a to-be-published update to the SVE ACLE spec. The feature is optional and its availability can be tested by the preprocessor condition: __ARM_FEATURE_SVE_NONMEMBER_OPERATORS==1 An alternative would be to build the operators into the compiler. However, we didn't want to do that for several reasons: - Some of the operators would not be performance-portable. (E.g. %, and the 8-bit and 16-bit integer versions of /.) The SVE ACLE is supposed to be a low-level, almost asm-level interface to the architecture, so synthesising this kind of operation seems out-of-place. - SVE types cannot be used in structures, so unlike with normal vector types, the user doesn't have the option of using a wrapper class to opt out of the standard handling. - If in future we do want to provide a core group of operators in a standard header file/module, we could use this extension to write it. The patch triggers a duplicate warning for: ref_int8 = ref_int8; but it seemed better to fix that separately. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77056 Files: clang/include/clang/AST/Type.h clang/lib/Basic/Targets/AArch64.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaOverload.cpp clang/test/SemaCXX/sizeless-1.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77056.253586.patch Type: text/x-patch Size: 13259 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 07:33:17 2020 From: cfe-commits at lists.llvm.org (Florian Hahn via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 14:33:17 +0000 (UTC) Subject: [PATCH] D77058: [Clang] Add llvm.loop.unroll.disable to loops with -fno-unroll-loops. Message-ID: fhahn created this revision. fhahn added reviewers: Meinersbur, hfinkel, dexonsmith, tejohnson. Herald added a subscriber: zzheng. Herald added a project: clang. Currently Clang does not respect -fno-unroll-loops during LTO. During D76916 it was suggested to respect -fno-unroll-loops on a TU basis. This patch uses the existing llvm.loop.unroll.disable metadata to disable loop unrolling explicitly for each loop in the TU if unrolling is disabled. This should ensure that loops from TUs compiled with -fno-unroll-loops are skipped by the unroller during LTO. This also means that if a loop from a TU with -fno-unroll-loops gets inlined into a TU without this option, the loop won't be unrolled. Due to the fact that some transforms might drop loop metadata, there potentially are cases in which we still unroll loops from TUs with -fno-unroll-loops. I think we should fix those issues rather than introducing a function attribute to disable loop unrolling during LTO. Improving the metadata handling will benefit other use cases, like various loop pragmas, too. And it is an improvement to clang completely ignoring -fno-unroll-loops during LTO. If that direction looks good, we can use a similar approach to also respect -fno-vectorize during LTO, at least for LoopVectorize. In the future, this might also allow us to remove the UnrollLoops option LLVM's PassManagerBuilder. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77058 Files: clang/lib/CodeGen/CGLoopInfo.cpp clang/lib/CodeGen/CGLoopInfo.h clang/lib/CodeGen/CGStmt.cpp clang/test/CodeGenCXX/fno-unroll-loops-metadata.cpp clang/test/CodeGenCXX/pragma-unroll.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77058.253589.patch Type: text/x-patch Size: 6815 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 07:33:18 2020 From: cfe-commits at lists.llvm.org (Dmitri Gribenko via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 14:33:18 +0000 (UTC) Subject: [PATCH] D76922: [Syntax] Remove delayed folding from tree building. In-Reply-To: References: Message-ID: <1c57b012073c1a3954906aab0c78a1d9@localhost.localdomain> gribozavr2 accepted this revision. gribozavr2 added a comment. This revision is now accepted and ready to land. Could you add the following tests? struct Point { int x, y; } point, *pointPtr; typedef struct Point { int x, y; } PointTy, *PointPtr; typedef struct { int x, y; } PointTy, *PointPtr; ================ Comment at: clang/lib/Tooling/Syntax/BuildTree.cpp:278 + + const auto *TD = llvm::dyn_cast(D); + if (TD == nullptr) { ---------------- I think this cast should not be necessary -- `D` is already a `const T*`. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76922/new/ https://reviews.llvm.org/D76922 From cfe-commits at lists.llvm.org Mon Mar 30 07:33:17 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Mon, 30 Mar 2020 14:33:17 +0000 (UTC) Subject: [PATCH] D77012: [analyzer] Fix StdLibraryFunctionsChecker NotNull Constraint Check In-Reply-To: References: Message-ID: Szelethus accepted this revision. Szelethus added a comment. Oh, yea, LGTM! Thanks! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77012/new/ https://reviews.llvm.org/D77012 From cfe-commits at lists.llvm.org Mon Mar 30 07:33:18 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Mon, 30 Mar 2020 14:33:18 +0000 (UTC) Subject: [PATCH] D77012: [analyzer] Fix StdLibraryFunctionsChecker NotNull Constraint Check In-Reply-To: References: Message-ID: Szelethus added a comment. In D77012#1948550 , @NoQ wrote: > @Szelethus can we make this checker depend on undefined value checker (probably CallAndMessage) so that uninitialized arguments were handled first? I'll drop some pointers to previous discussions: D67336#1928925 , D69662#1891124 . I took a look, the evaluation order indeed depends on the order of registration, and the order of registration can be controlled with checker dependencies. > In fact, can we make a silent assumption that everything depends on `core`? If so we could eliminate all checks for undefined values in PreStmt and PreCall. I wouldn't be comfortable doing that before we can separate the modeling portions from the diagnostics. [cfe-dev] [analyzer][RFC] Our stance on checker dependencies and disabling core checkers: http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77012/new/ https://reviews.llvm.org/D77012 From cfe-commits at lists.llvm.org Mon Mar 30 07:33:34 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Mon, 30 Mar 2020 14:33:34 +0000 (UTC) Subject: [PATCH] D68165: [analyzer][MallocChecker][NFC] Split checkPostCall up, deploy CallDescriptionMap In-Reply-To: References: Message-ID: <96f82863427d7b539e8e65ec27ae5a7c@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Szelethus marked 5 inline comments as done. Closed by commit rG703a1b8caf09: [analyzer][MallocChecker][NFC] Split checkPostCall up, deploy CallDescriptionMap (authored by ldionne, committed by Szelethus). Herald added a subscriber: ASDenysPetrov. Changed prior to commit: https://reviews.llvm.org/D68165?vs=247512&id=253593#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68165/new/ https://reviews.llvm.org/D68165 Files: clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D68165.253593.patch Type: text/x-patch Size: 29498 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 07:36:51 2020 From: cfe-commits at lists.llvm.org (Florian Hahn via cfe-commits) Date: Mon, 30 Mar 2020 07:36:51 -0700 (PDT) Subject: [clang] 7899a11 - Revert "[Darwin] Respect -fno-unroll-loops during LTO." Message-ID: <5e820403.1c69fb81.e6cf3.d9de@mx.google.com> Author: Florian Hahn Date: 2020-03-30T15:20:30+01:00 New Revision: 7899a111ea1160e2ae0aae42de37b14a0b75d71b URL: https://github.com/llvm/llvm-project/commit/7899a111ea1160e2ae0aae42de37b14a0b75d71b DIFF: https://github.com/llvm/llvm-project/commit/7899a111ea1160e2ae0aae42de37b14a0b75d71b.diff LOG: Revert "[Darwin] Respect -fno-unroll-loops during LTO." As per post-commit comment at https://reviews.llvm.org/D76916, this should better be done at the TU level. This reverts commit 9ce198d6ed371399e9bd9ba8b48fbab0f4e60240. Added: Modified: clang/lib/Driver/ToolChains/Darwin.cpp llvm/lib/LTO/LTOCodeGenerator.cpp Removed: clang/test/Driver/darwin-ld-lto-fno-unroll-loops.c llvm/test/tools/llvm-lto/fno-unroll-loops-option.ll ################################################################################ diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 951c71bff00e..451d0d206d07 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -543,12 +543,6 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString("-lto-stats-file=" + StatsFile.str())); } - // Forward -fno-unroll-loops to the linker in LTO. - if (Args.hasArg(options::OPT_fno_unroll_loops)) { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back(Args.MakeArgString("-lto-no-unroll-loops")); - } - // It seems that the 'e' option is completely ignored for dynamic executables // (the default), and with static executables, the last one wins, as expected. Args.AddAllArgs(CmdArgs, {options::OPT_d_Flag, options::OPT_s, options::OPT_t, diff --git a/clang/test/Driver/darwin-ld-lto-fno-unroll-loops.c b/clang/test/Driver/darwin-ld-lto-fno-unroll-loops.c deleted file mode 100644 index b248898a89f5..000000000000 --- a/clang/test/Driver/darwin-ld-lto-fno-unroll-loops.c +++ /dev/null @@ -1,17 +0,0 @@ -// REQUIRES: system-darwin - -// RUN: mkdir -p %t/bin -// RUN: mkdir -p %t/lib -// RUN: touch %t/lib/libLTO.dylib - -// Check that ld gets "-lto-no-unroll-loops" when -fno-unroll-loops is passed. -// -// RUN: %clang -target x86_64-apple-darwin10 %s -fno-unroll-loops -flto=full -### 2>&1 | \ -// RUN: FileCheck --check-prefix=NOUNROLL %s - -// NOUNROLL: "-mllvm" "-lto-no-unroll-loops" -// -// RUN: %clang -target x86_64-apple-darwin10 %s -flto=full -### 2>&1 | \ -// RUN: FileCheck --check-prefix=UNROLL %s - -// UNROLL-NOT: -lto-no-unroll-loops diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp index d2ae956b7823..a8a7877f66da 100644 --- a/llvm/lib/LTO/LTOCodeGenerator.cpp +++ b/llvm/lib/LTO/LTOCodeGenerator.cpp @@ -109,10 +109,6 @@ cl::opt LTOStatsFile( cl::Hidden); } -cl::opt LTONoUnrollLoops("lto-no-unroll-loops", - cl::desc("Disable unrolling during LTO."), - cl::Hidden, cl::init(false)); - LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context) : Context(Context), MergedModule(new Module("ld-temp.o", Context)), TheLinker(new Linker(*MergedModule)) { @@ -574,7 +570,6 @@ bool LTOCodeGenerator::optimize(bool DisableVerify, bool DisableInline, Triple TargetTriple(TargetMach->getTargetTriple()); PassManagerBuilder PMB; - PMB.DisableUnrollLoops = LTONoUnrollLoops; PMB.DisableGVNLoadPRE = DisableGVNLoadPRE; PMB.LoopVectorize = !DisableVectorization; PMB.SLPVectorize = !DisableVectorization; diff --git a/llvm/test/tools/llvm-lto/fno-unroll-loops-option.ll b/llvm/test/tools/llvm-lto/fno-unroll-loops-option.ll deleted file mode 100644 index 3ac4c285ffe7..000000000000 --- a/llvm/test/tools/llvm-lto/fno-unroll-loops-option.ll +++ /dev/null @@ -1,34 +0,0 @@ -; REQUIRES: asserts - -; RUN: llvm-as < %s > %t1.bc - -; Build with unrolling disabled (-lto-no-unroll-loops). -; RUN: llvm-lto %t1.bc -o %t.nounroll.o -lto-no-unroll-loops --exported-symbol=foo -save-merged-module -; RUN: llvm-dis -o - %t.nounroll.o.merged.bc | FileCheck --check-prefix=NOUNROLL %s - -; NOUNROLL: br label %loop -; NOUNROLL: br i1 %ec, label %exit, label %loop - -; Build with unrolling enabled (by not passing -lto-no-unroll-loops). All -; branches should be gone. -; RUN: llvm-lto %t1.bc -o %t.nounroll.o --exported-symbol=foo -save-merged-module -; RUN: llvm-dis -o - %t.nounroll.o.merged.bc | FileCheck --check-prefix=UNROLL %s - -; UNROLL-NOT: br - -define void @foo(i32* %ptr) { - -entry: - br label %loop - -loop: - %iv = phi i32 [ 0, %entry], [ %iv.next, %loop ] - %iv.ptr = getelementptr i32, i32* %ptr, i32 %iv - store i32 %iv, i32* %iv.ptr - %iv.next = add i32 %iv, 1 - %ec = icmp eq i32 %iv.next, 10 - br i1 %ec, label %exit, label %loop - -exit: - ret void -} From cfe-commits at lists.llvm.org Mon Mar 30 08:03:31 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 15:03:31 +0000 (UTC) Subject: [PATCH] D76790: [analyzer] StdLibraryFunctionsChecker: fix bug with arg constraints In-Reply-To: References: Message-ID: <49d1f42612e1b5c6be92f9e7925e4fd4@localhost.localdomain> martong updated this revision to Diff 253595. martong added a comment. - Test multiple constraints on the same arg Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76790/new/ https://reviews.llvm.org/D76790 Files: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp clang/test/Analysis/std-c-library-functions-arg-constraints.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D76790.253595.patch Type: text/x-patch Size: 6728 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 08:03:35 2020 From: cfe-commits at lists.llvm.org (Florian Hahn via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 15:03:35 +0000 (UTC) Subject: [PATCH] D76916: [Darwin] Respect -fno-unroll-loops during LTO. In-Reply-To: References: Message-ID: <8e9861153c33ce41a43567807f0d2895@localhost.localdomain> fhahn marked an inline comment as done. fhahn added a comment. Thanks for taking a look @dexonsmith! In D76916#1947324 , @dexonsmith wrote: > @fhahn, please revert, this isn't how we usually pass options in LTO. Reverted in 7899a111ea1160e2ae0aae42de37b14a0b75d71b . It looks like there are similar options exposed by libLTO (-disable-inlining, -disable-gvn-loadpre, -disable-lto-vectorization). However those are not hooked up in the driver, presumably expecting the user to pass them to the linker through clang. It seems like currently clang is not too consistent when it comes to handling arguments for LTO. Is there some documentation describing how various options should interact with LTO? > If this is something we expect developers to use, it should be specifiable on a per-TU basis. The way we do this is by specifying it during compilation, attaching string-based function attributes, and checking that attribute at the beginning of the "unroll loop" pass to see whether to skip it for that function. Agreed, I think we should respect -fno-unroll-loops on a TU basis. I've put up D77058 to use the existing llvm.loop.unroll.disable metadata. Is there any documentation on how TU level flags should interact with inlining across TU without those options? D77058 means that the loops in TUs compiled with -fno-unroll-loops won't be unrolled if they are inlined in functions in TUs without -fno-unroll-loops and loops from functions without -fno-unrolled-loops inlined into functions in TUs with -fno-unroll-loops will get unrolled. That is, -fno-unroll-loops will get applied exactly to the loops in the original TU, regardless where they are inlined. It is not applied to functions that get inlined from TUs without -fno-unroll-loops. ================ Comment at: clang/lib/Driver/ToolChains/Darwin.cpp:546-551 + // Forward -fno-unroll-loops to the linker in LTO. + if (Args.hasArg(options::OPT_fno_unroll_loops)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString("-lto-no-unroll-loops")); + } + ---------------- dexonsmith wrote: > I don't understand why we need driver support for this... is this something we expect users to do? Clang provides a -fno-unroll-loops option and allows users to specify it together with LTO. I think it is desirable for users to respect the option during LTO. For example, projects might have to disable unrolling, because their code is only correct assuming unrolling does not happen. I think for the user it would be most convenient to disable unrolling during the clang linker invocation with LTO, together with an option to disable it per TU. I think that is similarly to how the mcpu option is handled during LTO with the gold plugin for example. Only providing a way to disable it per TU should also be fine as well I think, but then Clang should at least warn if -fno-unroll-loops is passed for linking with LTO (and ignored). Does that seem reasonable? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76916/new/ https://reviews.llvm.org/D76916 From cfe-commits at lists.llvm.org Mon Mar 30 08:03:40 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 15:03:40 +0000 (UTC) Subject: [PATCH] D76211: OpenMP Metadirective with user defined condition In-Reply-To: References: Message-ID: <3d0c02d7693b6d6a072f9a7df3dea51a@localhost.localdomain> jdoerfert added inline comments. ================ Comment at: clang/lib/Sema/SemaOpenMP.cpp:5801 + Expr *expr = whenClause->getExpr(); + Stmt *stmt = NULL; + ---------------- Style: start names with upper case letter. ================ Comment at: clang/lib/Sema/SemaOpenMP.cpp:5817 + llvm::errs() << "Misplaced default clause! Only one default clause is"; + llvm::errs() << " allowed in metadirective in the end\n"; + return StmtError(); ---------------- You need to use `Diag` here. See other uses in this file. ================ Comment at: clang/lib/Sema/SemaOpenMP.cpp:5834 + stmt, SourceLocation(), ElseStmt); + } + ---------------- Doesn't this produce: ``` if (when1) case1; if (when2) case2; ... ``` while we need: ``` if (when1) case1; else if (when2) case2; ... ``` ================ Comment at: clang/lib/Sema/SemaOpenMP.cpp:11987 + } + break; } ---------------- I think a simple `if (DKind == ...)` makes more sense here. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76211/new/ https://reviews.llvm.org/D76211 From cfe-commits at lists.llvm.org Mon Mar 30 08:03:43 2020 From: cfe-commits at lists.llvm.org (Jason Liu via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 15:03:43 +0000 (UTC) Subject: [PATCH] D76360: [PPC][AIX] Emit correct Vaarg for 32BIT-AIX in clang In-Reply-To: References: Message-ID: <2745ae69a175f83b6dbe7d9dd881c2e7@localhost.localdomain> jasonliu added inline comments. ================ Comment at: clang/lib/CodeGen/TargetInfo.cpp:10019 + return SetCGInfo( + new PPCAIX32TargetCodeGenInfo(Types, CodeGenOpts.FloatABI == "soft")); return SetCGInfo( ---------------- Does AIX have soft Float? If not, do we want to always pass in 'false'? ================ Comment at: clang/test/CodeGen/aix-vararg.c:4 +// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -emit-llvm -o - %s | FileCheck %s --check-prefix=32BIT +#include + ---------------- Any reason we don't use __builtin_va... any more? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76360/new/ https://reviews.llvm.org/D76360 From cfe-commits at lists.llvm.org Mon Mar 30 08:03:48 2020 From: cfe-commits at lists.llvm.org (Louis Dionne via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 15:03:48 +0000 (UTC) Subject: [PATCH] D68165: [analyzer][MallocChecker][NFC] Split checkPostCall up, deploy CallDescriptionMap In-Reply-To: References: Message-ID: <287845e57b58b426ece0560fa385fd15@localhost.localdomain> ldionne added a comment. > Closed by commit rG703a1b8caf09 : [analyzer][MallocChecker][NFC] Split checkPostCall up, deploy CallDescriptionMap (authored by ldionne, committed by Szelethus). · Explain Why This is really strange -- it looks like 703a1b8caf09 was attributed to me in git, but I have nothing to do with this change. How did you commit the patch? Is that some Phabricator bug? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68165/new/ https://reviews.llvm.org/D68165 From cfe-commits at lists.llvm.org Mon Mar 30 08:09:47 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 15:09:47 +0000 (UTC) Subject: [PATCH] D77061: [analyzer] Add core.CallAndMessage to StdCLibraryFunctionArgsChecker's dependency Message-ID: martong created this revision. martong added reviewers: Szelethus, NoQ. Herald added subscribers: cfe-commits, ASDenysPetrov, steakhal, Charusso, gamesh411, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware, xazax.hun, whisperity. Herald added a project: clang. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77061 Files: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/test/Analysis/analyzer-enabled-checkers.c Index: clang/test/Analysis/analyzer-enabled-checkers.c =================================================================== --- clang/test/Analysis/analyzer-enabled-checkers.c +++ clang/test/Analysis/analyzer-enabled-checkers.c @@ -7,11 +7,11 @@ // CHECK: OVERVIEW: Clang Static Analyzer Enabled Checkers List // CHECK-EMPTY: // CHECK-NEXT: apiModeling.StdCLibraryFunctions +// CHECK-NEXT: core.CallAndMessage // CHECK-NEXT: apiModeling.StdCLibraryFunctionArgs // CHECK-NEXT: apiModeling.TrustNonnull // CHECK-NEXT: apiModeling.llvm.CastValue // CHECK-NEXT: apiModeling.llvm.ReturnValue -// CHECK-NEXT: core.CallAndMessage // CHECK-NEXT: core.DivideZero // CHECK-NEXT: core.DynamicTypePropagation // CHECK-NEXT: core.NonNullParamChecker Index: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td =================================================================== --- clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -299,7 +299,7 @@ HelpText<"Check constraints of arguments of C standard library functions, " "such as whether the parameter of isalpha is in the range [0, 255] " "or is EOF.">, - Dependencies<[StdCLibraryFunctionsChecker]>, + Dependencies<[StdCLibraryFunctionsChecker, CallAndMessageChecker]>, Documentation; def TrustNonnullChecker : Checker<"TrustNonnull">, -------------- next part -------------- A non-text attachment was scrubbed... Name: D77061.253599.patch Type: text/x-patch Size: 1415 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 08:38:03 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Mon, 30 Mar 2020 15:38:03 +0000 (UTC) Subject: [PATCH] D77061: [analyzer] Add core.CallAndMessage to StdCLibraryFunctionArgsChecker's dependency In-Reply-To: References: Message-ID: Szelethus accepted this revision. Szelethus added a comment. This revision is now accepted and ready to land. LGTM! It would be great if we could separate the modeling portions of the `CallAndMessage` checker out, but hey, there are only so many hours in each day :^) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77061/new/ https://reviews.llvm.org/D77061 From cfe-commits at lists.llvm.org Mon Mar 30 08:38:04 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 15:38:04 +0000 (UTC) Subject: [PATCH] D77013: [AMDGPU] Add options -mamdgpu-ieee -mno-amdgpu-ieee In-Reply-To: References: Message-ID: <59e02da46ea9b2132fd6bd0c247eff37@localhost.localdomain> arsenm added inline comments. ================ Comment at: clang/include/clang/Basic/CodeGenOptions.def:399 +/// Whether to emit IEEE754-2008 NaN compliant instructions if available (AMDGPU Only) +CODEGENOPT(EmitIEEENaNCompliantInsts, 1, 1) ---------------- Description is misleading. Better description would be the first line from the manual, "Floating point opcodes that support exception flag gathering quiet and propagate sig- naling NaN inputs per IEEE 754-2008" ================ Comment at: clang/include/clang/Driver/Options.td:2406 +def mamdgpu_ieee : Flag<["-"], "mamdgpu-ieee">, Flags<[CC1Option]>, + Group, HelpText<"Enable IEEE754-2008 NaN compliance in supported AMDGPU instructions">; +def mno_amdgpu_ieee : Flag<["-"], "mno-amdgpu-ieee">, Flags<[CC1Option]>, ---------------- Ditto ================ Comment at: clang/lib/Frontend/CompilerInvocation.cpp:1434 + + Opts.EmitIEEENaNCompliantInsts = + Args.hasFlag(options::OPT_mamdgpu_ieee, options::OPT_mno_amdgpu_ieee, ---------------- Add a comment explaining why to turn it off? Also should note this is only really concerns signaling nans ================ Comment at: clang/test/CodeGenOpenCL/amdgpu-ieee.cl:20 +} + +// ON-NOT: attributes [[ATTRS]] = {{.*}} "amdgpu-ieee" ---------------- Should also test a non-kernel function CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77013/new/ https://reviews.llvm.org/D77013 From cfe-commits at lists.llvm.org Mon Mar 30 08:38:04 2020 From: cfe-commits at lists.llvm.org (Teresa Johnson via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 15:38:04 +0000 (UTC) Subject: [PATCH] D77058: [Clang] Add llvm.loop.unroll.disable to loops with -fno-unroll-loops. In-Reply-To: References: Message-ID: <5546708e0190ff2773713e757e714bf9@localhost.localdomain> tejohnson added a comment. I think this is a good approach, rather than a per-function attribute, since as mentioned this will be preserved through inlining. @dexonsmith, does that seem reasonable to you? I missed the original patch and agree with you that we don't want to fix this in LTO by passing the option through to LTO. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77058/new/ https://reviews.llvm.org/D77058 From cfe-commits at lists.llvm.org Mon Mar 30 08:38:05 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 15:38:05 +0000 (UTC) Subject: [PATCH] D77063: [WIP][clangd] Dont block for preamble builds Message-ID: kadircet created this revision. Herald added subscribers: cfe-commits, usaxena95, jfb, arphaman, jkorous, MaskRay, javed.absar, ilya-biryukov. Herald added a project: clang. kadircet added a parent revision: D76725: [clangd] Build ASTs only with fresh preambles or after building a new preamble. kadircet added a comment. This requires patched-up ASTs and getting rid of consistent preamble needs first. Build preambles fully asynchronously. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77063 Files: clang-tools-extra/clangd/TUScheduler.cpp clang-tools-extra/clangd/unittests/ClangdTests.cpp clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp clang-tools-extra/clangd/unittests/XRefsTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77063.253601.patch Type: text/x-patch Size: 14197 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 08:38:06 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 15:38:06 +0000 (UTC) Subject: [PATCH] D77063: [WIP][clangd] Dont block for preamble builds In-Reply-To: References: Message-ID: <02b171feea8e4938b40c67c9726b553c@localhost.localdomain> kadircet added a comment. This requires patched-up ASTs and getting rid of consistent preamble needs first. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77063/new/ https://reviews.llvm.org/D77063 From cfe-commits at lists.llvm.org Mon Mar 30 08:38:06 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 15:38:06 +0000 (UTC) Subject: [PATCH] D77013: [AMDGPU] Add options -mamdgpu-ieee -mno-amdgpu-ieee In-Reply-To: References: Message-ID: arsenm added inline comments. ================ Comment at: clang/test/CodeGenOpenCL/amdgpu-ieee.cl:20 +} + +// ON-NOT: attributes [[ATTRS]] = {{.*}} "amdgpu-ieee" ---------------- arsenm wrote: > Should also test a non-kernel function I think we should also have some ISA check run lines that show the final result for minnum/maxnum lowering, as well as if output modifiers are used CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77013/new/ https://reviews.llvm.org/D77013 From cfe-commits at lists.llvm.org Mon Mar 30 08:38:07 2020 From: cfe-commits at lists.llvm.org (Jonathan B Coe via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 15:38:07 +0000 (UTC) Subject: [PATCH] D77064: [clang-format] Correct line breaks in C# generic type constraints Message-ID: jbcoe created this revision. jbcoe added a reviewer: krasimir. jbcoe added a project: clang-format. Herald added a project: clang. Herald added a subscriber: cfe-commits. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77064 Files: clang/lib/Format/TokenAnnotator.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTestCSharp.cpp Index: clang/unittests/Format/FormatTestCSharp.cpp =================================================================== --- clang/unittests/Format/FormatTestCSharp.cpp +++ clang/unittests/Format/FormatTestCSharp.cpp @@ -702,12 +702,13 @@ })", Style); + Style.ColumnLimit = 50; // Force lines to be wrapped. verifyFormat(R"(// -class ItemFactory - where T : new(), - IAnInterface, - IAnotherInterface, - IAnotherInterfaceStill {})", +class ItemFactory + where T : new(), + IAnInterface, + IAnotherInterface, + IAnotherInterfaceStill {})", Style); // In other languages `where` can be used as a normal identifier. Index: clang/lib/Format/UnwrappedLineParser.cpp =================================================================== --- clang/lib/Format/UnwrappedLineParser.cpp +++ clang/lib/Format/UnwrappedLineParser.cpp @@ -2339,7 +2339,13 @@ break; } if (FormatTok->Tok.is(tok::semi)) + return; + if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) { + addUnwrappedLine(); + nextToken(); + parseCSharpGenericTypeConstraint(); return; + } nextToken(); } } @@ -2354,6 +2360,11 @@ /*MunchSemi=*/false); } } + // if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) { + // addUnwrappedLine(); + // nextToken(); + // parseCSharpGenericTypeConstraint(); + // } // There is no addUnwrappedLine() here so that we fall through to parsing a // structural element afterwards. Thus, in "class A {} n, m;", // "} n, m;" will end up in one unwrapped line. Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -1060,15 +1060,20 @@ } void parseCSharpGenericTypeConstraint() { + int OpenAngleBracketsCount = 0; while (CurrentToken) { if (CurrentToken->is(tok::less)) { // parseAngle is too greedy and will consume the whole line. CurrentToken->Type = TT_TemplateOpener; + ++OpenAngleBracketsCount; next(); } else if (CurrentToken->is(tok::greater)) { CurrentToken->Type = TT_TemplateCloser; + --OpenAngleBracketsCount; next(); - } else if (CurrentToken->is(tok::comma)) { + } else if (CurrentToken->is(tok::comma) && OpenAngleBracketsCount==0) { + // We allow line breaks after GenericTypeConstraintComma's + // so do not flag commas in Generics as GenericTypeConstraintComma's. CurrentToken->Type = TT_CSharpGenericTypeConstraintComma; next(); } else if (CurrentToken->is(Keywords.kw_where)) { -------------- next part -------------- A non-text attachment was scrubbed... Name: D77064.253603.patch Type: text/x-patch Size: 2865 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 09:02:15 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via cfe-commits) Date: Mon, 30 Mar 2020 09:02:15 -0700 (PDT) Subject: [clang] 1a1bb87 - [analyzer] Add core.CallAndMessage to StdCLibraryFunctionArgsChecker's dependency Message-ID: <5e821807.1c69fb81.fabc5.dd3c@mx.google.com> Author: Gabor Marton Date: 2020-03-30T17:57:15+02:00 New Revision: 1a1bb876dba41066f6e9a273c24fad04e0f9f2da URL: https://github.com/llvm/llvm-project/commit/1a1bb876dba41066f6e9a273c24fad04e0f9f2da DIFF: https://github.com/llvm/llvm-project/commit/1a1bb876dba41066f6e9a273c24fad04e0f9f2da.diff LOG: [analyzer] Add core.CallAndMessage to StdCLibraryFunctionArgsChecker's dependency Reviewers: Szelethus, NoQ Subscribers: whisperity, xazax.hun, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, Charusso, steakhal, ASDenysPetrov, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77061 Added: Modified: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/test/Analysis/analyzer-enabled-checkers.c Removed: ################################################################################ diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index a21107cd4c2d..136a0fb6a374 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -299,7 +299,7 @@ def StdCLibraryFunctionArgsChecker : Checker<"StdCLibraryFunctionArgs">, HelpText<"Check constraints of arguments of C standard library functions, " "such as whether the parameter of isalpha is in the range [0, 255] " "or is EOF.">, - Dependencies<[StdCLibraryFunctionsChecker]>, + Dependencies<[StdCLibraryFunctionsChecker, CallAndMessageChecker]>, Documentation; def TrustNonnullChecker : Checker<"TrustNonnull">, diff --git a/clang/test/Analysis/analyzer-enabled-checkers.c b/clang/test/Analysis/analyzer-enabled-checkers.c index 55f15f6d37c8..6f719ec15d4f 100644 --- a/clang/test/Analysis/analyzer-enabled-checkers.c +++ b/clang/test/Analysis/analyzer-enabled-checkers.c @@ -7,11 +7,11 @@ // CHECK: OVERVIEW: Clang Static Analyzer Enabled Checkers List // CHECK-EMPTY: // CHECK-NEXT: apiModeling.StdCLibraryFunctions +// CHECK-NEXT: core.CallAndMessage // CHECK-NEXT: apiModeling.StdCLibraryFunctionArgs // CHECK-NEXT: apiModeling.TrustNonnull // CHECK-NEXT: apiModeling.llvm.CastValue // CHECK-NEXT: apiModeling.llvm.ReturnValue -// CHECK-NEXT: core.CallAndMessage // CHECK-NEXT: core.DivideZero // CHECK-NEXT: core.DynamicTypePropagation // CHECK-NEXT: core.NonNullParamChecker From cfe-commits at lists.llvm.org Mon Mar 30 09:10:57 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 16:10:57 +0000 (UTC) Subject: [PATCH] D76937: Fix infinite recursion in deferred diagnostic emitter In-Reply-To: References: Message-ID: <1613a59b3aff56153a4e4ebcca7eeb49@localhost.localdomain> rjmccall added a comment. Can you explain what exactly the emission/semantic model is for variables? Normal code-generation absolutely triggers the emission of many variables lazily (e.g. internal-linkage globals, C++ inline variables); and any variable that's *not* being emitted lazily actually needs to be treated as a potential root into the delayed-diagnostic graph. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76937/new/ https://reviews.llvm.org/D76937 From cfe-commits at lists.llvm.org Mon Mar 30 09:11:00 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 16:11:00 +0000 (UTC) Subject: [PATCH] D77066: [analyzer] ApiModeling: Add buffer size arg constraint Message-ID: martong created this revision. martong added reviewers: NoQ, Szelethus, Charusso, steakhal. Herald added subscribers: cfe-commits, ASDenysPetrov, gamesh411, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware, xazax.hun, whisperity. Herald added a project: clang. martong added a parent revision: D76790: [analyzer] StdLibraryFunctionsChecker: fix bug with arg constraints. Introducing a new argument constraint to confine buffer sizes. It is typical in C APIs that a parameter represents a buffer and another param holds the size of the buffer (or the size of the data we want to handle from the buffer). Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77066 Files: clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp clang/lib/StaticAnalyzer/Core/DynamicSize.cpp clang/test/Analysis/std-c-library-functions-arg-constraints.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77066.253606.patch Type: text/x-patch Size: 12358 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 09:11:03 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 16:11:03 +0000 (UTC) Subject: [PATCH] D77013: [AMDGPU] Add options -mamdgpu-ieee -mno-amdgpu-ieee In-Reply-To: References: Message-ID: <9b699571b555c47917ab5935bd66c543@localhost.localdomain> yaxunl planned changes to this revision. yaxunl added a comment. This patch is put on hold due to some concerns. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77013/new/ https://reviews.llvm.org/D77013 From cfe-commits at lists.llvm.org Mon Mar 30 09:11:04 2020 From: cfe-commits at lists.llvm.org (Nigel Perks via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 16:11:04 +0000 (UTC) Subject: [PATCH] D77068: [XCore] fix crash on unused inline in EmitTargetMetadata Message-ID: nigelp-xmos created this revision. nigelp-xmos added a reviewer: rsmith. nigelp-xmos added a project: clang. EmitTargetMetadata passes to emitTargetMD a null pointer as returned from GetGlobalValue for an unused inline function which has been removed from the module at that point. Richard Smith comments in CodeGenModule.cpp that the calling code in EmitTargetMetadata should be moved into the one target that needs it (XCore). I thought it best to start with the quicker change, restricted to XCore code, checking for null, to prevent the crash. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77068 Files: clang/lib/CodeGen/TargetInfo.cpp clang/test/CodeGen/xcore-unused-inline.c Index: clang/test/CodeGen/xcore-unused-inline.c =================================================================== --- /dev/null +++ clang/test/CodeGen/xcore-unused-inline.c @@ -0,0 +1,4 @@ +// REQUIRES: xcore-registered-target +// RUN: %clang_cc1 -triple xcore-unknown-unknown -emit-llvm -o - %s + +inline void dead_function(void) {} Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ clang/lib/CodeGen/TargetInfo.cpp @@ -9354,6 +9354,8 @@ /// XCore uses emitTargetMD to emit TypeString metadata for global symbols. void XCoreTargetCodeGenInfo::emitTargetMD(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const { + if (!GV) + return; SmallStringEnc Enc; if (getTypeString(Enc, D, CGM, TSC)) { llvm::LLVMContext &Ctx = CGM.getModule().getContext(); -------------- next part -------------- A non-text attachment was scrubbed... Name: D77068.253604.patch Type: text/x-patch Size: 928 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 09:11:06 2020 From: cfe-commits at lists.llvm.org (Mariya Podchishchaeva via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 16:11:06 +0000 (UTC) Subject: [PATCH] D74387: [SYCL] Defer __float128 type usage diagnostics In-Reply-To: References: Message-ID: Fznamznon added inline comments. ================ Comment at: clang/include/clang/Sema/Sema.h:12248 + /// SYCLDiagIfDeviceCode(Loc, diag::err_type_unsupported) << "__float128"; + DeviceDiagBuilder SYCLDiagIfDeviceCode(SourceLocation Loc, unsigned DiagID); + ---------------- rjmccall wrote: > Will this collect notes associated with the diagnostic correctly? Could you please make your question a bit more concrete? This function is supposed to work in the same way as `Sema::CUDADiagIfDeviceCode` and `Sema::diagIfOpenMPDeviceCode` . It emits given diagnostic if the current context is known as "device code" and makes this diagnostic deferred otherwise. It uses the `DeviceDiagBuilder` which was implemented earlier. This `DeviceDiagBuilder` also tries to emit callstack notes for the given diagnostics. Do you mean these callstack notes or something else? ================ Comment at: clang/lib/Sema/SemaAvailability.cpp:479 + case UnavailableAttr::IR_SYCLForbiddenType: + diag_available_here = diag::err_type_unsupported; + break; ---------------- rjmccall wrote: > All of the other cases are setting this to a note, not an error, so I suspect this will read wrong. Yes, this is not a note. For such samples: ``` int main() { __float128 CapturedToDevice = 1; kernel([=]() { decltype(CapturedToDevice) D; }); } ``` It looks like this: ``` float128.cpp:63:14: error: 'CapturedToDevice' is unavailable decltype(CapturedToDevice) D; ^ float128.cpp:59:14: error: '__float128' is not supported on this target /// This emitted instead of note __float128 CapturedToDevice = 1; ^ ``` I had feeling that it should probably be a note. But there is no implemented note for unsupported types. I think I can add a new one if it will make it better. Should I? ================ Comment at: clang/lib/Sema/SemaAvailability.cpp:534 + if (S.getLangOpts().SYCLIsDevice) + S.SYCLDiagIfDeviceCode(Loc, diag) << ReferringDecl; + else ---------------- rjmccall wrote: > Are you sure you want to be applying this to all of the possible diagnostics here, rather than just for SYCLForbiddenType unavailable attributes? I suppose it is reasonable if we want to reuse unavaliable attribute for other SYCL use cases. Plus, In SYCL we don't know where is device code until we instantiate templates, it happens late, so we have to defer any diagnostic while compiling for device, otherwise we can point to host code where much more is allowed. ================ Comment at: clang/lib/Sema/SemaDecl.cpp:18030 + if (LangOpts.SYCLIsDevice && FD->hasAttr()) + return FunctionEmissionStatus::Emitted; + ---------------- rjmccall wrote: > So you want to emit it for the definition in addition to emitting it for specific specializations? Somehow diagnostics are emitted only for the definitions. Without this change diagnostics aren't emitted at all. ================ Comment at: clang/lib/Sema/SemaDeclAttr.cpp:7771 + return true; + } + ---------------- rjmccall wrote: > I wonder if it's reasonable to treat all forbidden types the same here or if we want different functions for the ARC and SYCL use cases. I think it could be reasonable if we will have forbidden type cases for SYCL sometime. For now, I don't see the purpose in a separate function for SYCL. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D74387/new/ https://reviews.llvm.org/D74387 From cfe-commits at lists.llvm.org Mon Mar 30 09:11:23 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 16:11:23 +0000 (UTC) Subject: [PATCH] D77061: [analyzer] Add core.CallAndMessage to StdCLibraryFunctionArgsChecker's dependency In-Reply-To: References: Message-ID: <1914b583e00b9866e4bfa8ac48d2697e@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG1a1bb876dba4: [analyzer] Add core.CallAndMessage to StdCLibraryFunctionArgsChecker's… (authored by martong). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77061/new/ https://reviews.llvm.org/D77061 Files: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/test/Analysis/analyzer-enabled-checkers.c Index: clang/test/Analysis/analyzer-enabled-checkers.c =================================================================== --- clang/test/Analysis/analyzer-enabled-checkers.c +++ clang/test/Analysis/analyzer-enabled-checkers.c @@ -7,11 +7,11 @@ // CHECK: OVERVIEW: Clang Static Analyzer Enabled Checkers List // CHECK-EMPTY: // CHECK-NEXT: apiModeling.StdCLibraryFunctions +// CHECK-NEXT: core.CallAndMessage // CHECK-NEXT: apiModeling.StdCLibraryFunctionArgs // CHECK-NEXT: apiModeling.TrustNonnull // CHECK-NEXT: apiModeling.llvm.CastValue // CHECK-NEXT: apiModeling.llvm.ReturnValue -// CHECK-NEXT: core.CallAndMessage // CHECK-NEXT: core.DivideZero // CHECK-NEXT: core.DynamicTypePropagation // CHECK-NEXT: core.NonNullParamChecker Index: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td =================================================================== --- clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -299,7 +299,7 @@ HelpText<"Check constraints of arguments of C standard library functions, " "such as whether the parameter of isalpha is in the range [0, 255] " "or is EOF.">, - Dependencies<[StdCLibraryFunctionsChecker]>, + Dependencies<[StdCLibraryFunctionsChecker, CallAndMessageChecker]>, Documentation; def TrustNonnullChecker : Checker<"TrustNonnull">, -------------- next part -------------- A non-text attachment was scrubbed... Name: D77061.253611.patch Type: text/x-patch Size: 1415 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 09:44:19 2020 From: cfe-commits at lists.llvm.org (Erik Pilkington via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 16:44:19 +0000 (UTC) Subject: [PATCH] D77070: [SemaObjC] Add a warning for declarations of BOOL:1 when BOOL is a signed char Message-ID: erik.pilkington created this revision. erik.pilkington added reviewers: rjmccall, steven_wu. Herald added subscribers: ributzka, dexonsmith, jkorous. Instead, recommend using a real boolean type. Its possible to get away with BOOL:1, if you only read from it in a context where its contextually converted to bool, but its still broken if you, for instance, store it into a BOOL variable or try to compare it with another BOOL. Given that, I don't think there is any good reason to use it when there are better alternatives available. rdar://29707989 https://reviews.llvm.org/D77070 Files: clang/include/clang/Basic/DiagnosticGroups.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaDecl.cpp clang/test/SemaObjC/signed-char-bool-bitfield-fixit.m clang/test/SemaObjC/signed-char-bool-bitfield.m -------------- next part -------------- A non-text attachment was scrubbed... Name: D77070.253608.patch Type: text/x-patch Size: 5506 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 09:44:20 2020 From: cfe-commits at lists.llvm.org (Mariya Podchishchaeva via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 16:44:20 +0000 (UTC) Subject: [PATCH] D74387: [SYCL] Defer __float128 type usage diagnostics In-Reply-To: References: Message-ID: Fznamznon updated this revision to Diff 253615. Fznamznon added a comment. Herald added a reviewer: jdoerfert. Rebased to fresh version. Applied fixes after https://reviews.llvm.org/D70172 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D74387/new/ https://reviews.llvm.org/D74387 Files: clang/include/clang/Basic/Attr.td clang/include/clang/Sema/Sema.h clang/lib/Sema/CMakeLists.txt clang/lib/Sema/SemaAvailability.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclAttr.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaSYCL.cpp clang/lib/Sema/SemaType.cpp clang/test/SemaSYCL/float128.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D74387.253615.patch Type: text/x-patch Size: 14044 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 09:44:25 2020 From: cfe-commits at lists.llvm.org (Artem Dergachev via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 16:44:25 +0000 (UTC) Subject: [PATCH] D68165: [analyzer][MallocChecker][NFC] Split checkPostCall up, deploy CallDescriptionMap In-Reply-To: References: Message-ID: <73ee570460cbd7619f728351714eb212@localhost.localdomain> NoQ added a comment. **`$ git show --pretty=full 703a1b8caf09`** commit 703a1b8caf09a5262a45c2179b8131922f71cf25 Author: Louis Dionne Commit: Kirstóf Umann [analyzer][MallocChecker][NFC] Split checkPostCall up, deploy CallDescriptionMap ... Not a phabricator bug. Maybe @Szelethus's local git somehow got in a weird state(?) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68165/new/ https://reviews.llvm.org/D68165 From cfe-commits at lists.llvm.org Mon Mar 30 10:16:38 2020 From: cfe-commits at lists.llvm.org (Vy Nguyen via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 17:16:38 +0000 (UTC) Subject: [PATCH] D75951: Keep a list of already-included pragma-once files for mods. In-Reply-To: References: Message-ID: oontvoo updated this revision to Diff 253623. oontvoo added a comment. Rebaase Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75951/new/ https://reviews.llvm.org/D75951 Files: clang/include/clang/Lex/HeaderSearch.h clang/include/clang/Lex/Preprocessor.h clang/include/clang/Serialization/ASTBitCodes.h clang/include/clang/Serialization/ASTReader.h clang/include/clang/Serialization/ASTWriter.h clang/lib/Lex/HeaderSearch.cpp clang/lib/Lex/Preprocessor.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/test/Modules/Inputs/dummy_pragma_once.h clang/test/Modules/Inputs/dummy_textual_header.h clang/test/Modules/Inputs/header_in_imported_module.h clang/test/Modules/Inputs/imported_module.cppm clang/test/Modules/Inputs/module.map clang/test/Modules/header-in-imported-module.c clang/test/Modules/import-pragma-once.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D75951.253623.patch Type: text/x-patch Size: 26581 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 10:16:39 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 17:16:39 +0000 (UTC) Subject: [PATCH] D76887: AMDGPU: Make HIPToolChain a subclass of ROCMToolChain In-Reply-To: References: Message-ID: yaxunl accepted this revision. yaxunl added a comment. This revision is now accepted and ready to land. LGTM. Thanks! CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76887/new/ https://reviews.llvm.org/D76887 From cfe-commits at lists.llvm.org Mon Mar 30 10:16:43 2020 From: cfe-commits at lists.llvm.org (Artem Belevich via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 17:16:43 +0000 (UTC) Subject: [PATCH] D76365: [cuda][hip] Add CUDA builtin surface/texture reference support. In-Reply-To: References: Message-ID: tra added a comment. In D76365#1947479 , @hliao wrote: > Nice! I'll file a bug with NVIDIA. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76365/new/ https://reviews.llvm.org/D76365 From cfe-commits at lists.llvm.org Mon Mar 30 10:17:01 2020 From: cfe-commits at lists.llvm.org (Kevin P. Neal via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 17:17:01 +0000 (UTC) Subject: [PATCH] D77074: [FPEnv][AArch64] Platform-specific builtin constrained FP enablement Message-ID: kpn created this revision. kpn added reviewers: t.p.northover, john.brawn, az, dnsampaio, cameron.mcinally. Herald added subscribers: cfe-commits, danielkiss, arphaman, hiraditya, kristof.beyls. Herald added a project: clang. When constrained floating point is enabled the AArch64-specific builtins don't use constrained intrinsics in some cases. Fix that. Neon is part of this patch, so ARM is affected as well. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77074 Files: clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/aarch64-neon-intrinsics-constrained.c clang/test/CodeGen/aarch64-neon-misc-constrained.c clang/test/CodeGen/aarch64-neon-scalar-x-indexed-elem-constrained.c clang/test/CodeGen/aarch64-v8.2a-fp16-intrinsics-constrained.c clang/test/CodeGen/aarch64-v8.2a-neon-intrinsics-constrained.c clang/test/CodeGen/arm-neon-directed-rounding-constrained.c clang/test/CodeGen/arm64-vrnd-constrained.c llvm/include/llvm/IR/Function.h llvm/lib/IR/Function.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77074.253626.patch Type: text/x-patch Size: 126826 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 10:17:31 2020 From: cfe-commits at lists.llvm.org (Karasev Nikita via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 17:17:31 +0000 (UTC) Subject: [PATCH] D76996: [analyzer] Improve PlacementNewChecker In-Reply-To: References: Message-ID: <91ee7a4a2c1be0d6b7800abb8c1139a9@localhost.localdomain> f00kat updated this revision to Diff 253628. f00kat marked 3 inline comments as done. f00kat added a comment. 1. Removed code and tests for ConcreteInt cases 2. Fixed FieldRegion check 3. Added handling for ElementRegion cases such as void f7() { short b[10]; // ok. 2(short align) + 3*2(index '1' offset) ::new (&b[3]) long; } 4. Fixed align error message 5. Maybe fixed lint warnings Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76996/new/ https://reviews.llvm.org/D76996 Files: clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp clang/test/Analysis/placement-new.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76996.253628.patch Type: text/x-patch Size: 14992 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 10:19:14 2020 From: cfe-commits at lists.llvm.org (Kevin P. Neal via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 17:19:14 +0000 (UTC) Subject: [PATCH] D77074: [FPEnv][AArch64] Platform-specific builtin constrained FP enablement In-Reply-To: References: Message-ID: kpn marked 3 inline comments as done. kpn added a comment. Note that the AArch64 backend isn't ready for some of these changes. That's why the test is marked XFAIL. ================ Comment at: clang/lib/CodeGen/CGBuiltin.cpp:5706 + Function *F; + //exit(2); // XXX + if (Builder.getIsFPConstrained()) ---------------- These exit() calls tie back into my test matrix. They'll be removed when I eventually push. ================ Comment at: clang/test/CodeGen/aarch64-neon-intrinsics-constrained.c:288 + +// XXX FIXME do we need to check for both w and x registers? +// COMMON-LABEL: test_vceq_f64 ---------------- Anyone? I'm not an ARM expert. ================ Comment at: clang/test/CodeGen/aarch64-neon-intrinsics-constrained.c:889 + +// FIXME why the unused bitcast? There are several of them! +// COMMON-LABEL: test_vrnda_f64 ---------------- ??? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77074/new/ https://reviews.llvm.org/D77074 From cfe-commits at lists.llvm.org Mon Mar 30 10:34:23 2020 From: cfe-commits at lists.llvm.org (Sid Manning via cfe-commits) Date: Mon, 30 Mar 2020 10:34:23 -0700 (PDT) Subject: [clang] 81194bf - [Hexagon] MaxAtomicPromoteWidth and MaxAtomicInlineWidth are not getting set. Message-ID: <5e822d9f.1c69fb81.dd00a.cf88@mx.google.com> Author: Sid Manning Date: 2020-03-30T12:33:51-05:00 New Revision: 81194bfeea7b40b6e8c543bb4ae49b59f590475b URL: https://github.com/llvm/llvm-project/commit/81194bfeea7b40b6e8c543bb4ae49b59f590475b DIFF: https://github.com/llvm/llvm-project/commit/81194bfeea7b40b6e8c543bb4ae49b59f590475b.diff LOG: [Hexagon] MaxAtomicPromoteWidth and MaxAtomicInlineWidth are not getting set. Noticed when building llvm's c++ library. Differential Revision: https://reviews.llvm.org/D76546 Added: Modified: clang/lib/Basic/Targets/Hexagon.h clang/test/Preprocessor/hexagon-predefines.c Removed: ################################################################################ diff --git a/clang/lib/Basic/Targets/Hexagon.h b/clang/lib/Basic/Targets/Hexagon.h index 89e3fa3fa6bf..7e173df81683 100644 --- a/clang/lib/Basic/Targets/Hexagon.h +++ b/clang/lib/Basic/Targets/Hexagon.h @@ -57,6 +57,7 @@ class LLVM_LIBRARY_VISIBILITY HexagonTargetInfo : public TargetInfo { LargeArrayAlign = 64; UseBitFieldTypeAlignment = true; ZeroLengthBitfieldBoundary = 32; + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; // These are the default values anyway, but explicitly make sure // that the size of the boolean type is 8 bits. Bool vectors are used diff --git a/clang/test/Preprocessor/hexagon-predefines.c b/clang/test/Preprocessor/hexagon-predefines.c index 54013ceffa64..7979d567134b 100644 --- a/clang/test/Preprocessor/hexagon-predefines.c +++ b/clang/test/Preprocessor/hexagon-predefines.c @@ -113,3 +113,18 @@ // CHECK-LINUX: #define __unix__ 1 // CHECK-LINUX: #define linux 1 // CHECK-LINUX: #define unix 1 + +// RUN: %clang_cc1 -E -dM -triple hexagon-unknown-linux-musl \ +// RUN: -target-cpu hexagonv67 -target-feature +hvxv67 \ +// RUN: -target-feature +hvx-length128b %s | FileCheck \ +// RUN: %s -check-prefix CHECK-ATOMIC +// CHECK-ATOMIC: #define __CLANG_ATOMIC_BOOL_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_CHAR_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_INT_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_LLONG_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_LONG_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_POINTER_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_SHORT_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2 From cfe-commits at lists.llvm.org Mon Mar 30 10:40:38 2020 From: cfe-commits at lists.llvm.org (Alexey Bataev via cfe-commits) Date: Mon, 30 Mar 2020 10:40:38 -0700 (PDT) Subject: [clang] 7842e7e - [OPENMP50]Add codegen support for array shaping expression in depend Message-ID: <5e822f16.1c69fb81.3db86.ca0e@mx.google.com> Author: Alexey Bataev Date: 2020-03-30T13:37:21-04:00 New Revision: 7842e7ebbf3b68ebe52592d51aaf7a20f94d047b URL: https://github.com/llvm/llvm-project/commit/7842e7ebbf3b68ebe52592d51aaf7a20f94d047b DIFF: https://github.com/llvm/llvm-project/commit/7842e7ebbf3b68ebe52592d51aaf7a20f94d047b.diff LOG: [OPENMP50]Add codegen support for array shaping expression in depend clauses. Implemented codegen for array shaping operation in depend clauses. The begin of the expression is the pointer itself, while the size of the dependence data is the mukltiplacation of all dimensions in the array shaping expression. Added: Modified: clang/lib/CodeGen/CGOpenMPRuntime.cpp clang/test/OpenMP/depobj_ast_print.cpp clang/test/OpenMP/depobj_codegen.cpp clang/test/OpenMP/task_codegen.c Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 1bb001ced31a..4b913607c1db 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -5363,11 +5363,29 @@ std::pair CGOpenMPRuntime::emitDependClause( if (Dependencies[I].first == OMPC_DEPEND_depobj) continue; const Expr *E = Dependencies[I].second; - LValue Addr = CGF.EmitLValue(E); + const auto *OASE = dyn_cast(E); + LValue Addr; + if (OASE) { + const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); + Addr = + CGF.EmitLoadOfPointerLValue(CGF.EmitLValue(Base).getAddress(CGF), + Base->getType()->castAs()); + } else { + Addr = CGF.EmitLValue(E); + } llvm::Value *Size; QualType Ty = E->getType(); - if (const auto *ASE = - dyn_cast(E->IgnoreParenImpCasts())) { + if (OASE) { + Size = llvm::ConstantInt::get(CGF.SizeTy,/*V=*/1); + for (const Expr *SE : OASE->getDimensions()) { + llvm::Value *Sz = CGF.EmitScalarExpr(SE); + Sz = CGF.EmitScalarConversion(Sz, SE->getType(), + CGF.getContext().getSizeType(), + SE->getExprLoc()); + Size = CGF.Builder.CreateNUWMul(Size, Sz); + } + } else if (const auto *ASE = + dyn_cast(E->IgnoreParenImpCasts())) { LValue UpAddrLVal = CGF.EmitOMPArraySectionExpr(ASE, /*IsLowerBound=*/false); llvm::Value *UpAddr = CGF.Builder.CreateConstGEP1_32( diff --git a/clang/test/OpenMP/depobj_ast_print.cpp b/clang/test/OpenMP/depobj_ast_print.cpp index 8b6586ca2b26..f3076646a25e 100644 --- a/clang/test/OpenMP/depobj_ast_print.cpp +++ b/clang/test/OpenMP/depobj_ast_print.cpp @@ -17,17 +17,20 @@ void foo() {} template T tmain(T argc) { static T a; -#pragma omp depobj(a) depend(in:argc) + int *b; +#pragma omp depobj(a) depend(in:argc, ([4][*b][4])b) #pragma omp depobj(argc) destroy #pragma omp depobj(argc) update(inout) return argc; } // CHECK: static T a; -// CHECK-NEXT: #pragma omp depobj (a) depend(in : argc){{$}} +// CHECK-NEXT: int *b; +// CHECK-NEXT: #pragma omp depobj (a) depend(in : argc,([4][*b][4])b){{$}} // CHECK-NEXT: #pragma omp depobj (argc) destroy{{$}} // CHECK-NEXT: #pragma omp depobj (argc) update(inout){{$}} // CHECK: static void *a; -// CHECK-NEXT: #pragma omp depobj (a) depend(in : argc){{$}} +// CHECK-NEXT: int *b; +// CHECK-NEXT: #pragma omp depobj (a) depend(in : argc,([4][*b][4])b){{$}} // CHECK-NEXT: #pragma omp depobj (argc) destroy{{$}} // CHECK-NEXT: #pragma omp depobj (argc) update(inout){{$}} diff --git a/clang/test/OpenMP/depobj_codegen.cpp b/clang/test/OpenMP/depobj_codegen.cpp index 61b97d0b8479..2c7509babc17 100644 --- a/clang/test/OpenMP/depobj_codegen.cpp +++ b/clang/test/OpenMP/depobj_codegen.cpp @@ -22,7 +22,7 @@ template T tmain(T argc) { static T a; void *argv; -#pragma omp depobj(a) depend(in:argv) +#pragma omp depobj(a) depend(in:argv, ([3][*(int*)argv][4])argv) #pragma omp depobj(argc) destroy #pragma omp depobj(argc) update(inout) return argc; @@ -87,19 +87,30 @@ int main(int argc, char **argv) { // CHECK-LABEL: tmain // CHECK: [[ARGC_ADDR:%.+]] = alloca i8*, // CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num( -// CHECK: [[DEP_ADDR_VOID:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID]], i64 48, i8* null) -// CHECK: [[DEP_ADDR:%.+]] = bitcast i8* [[DEP_ADDR_VOID]] to [2 x %struct.kmp_depend_info]* -// CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds [2 x %struct.kmp_depend_info], [2 x %struct.kmp_depend_info]* [[DEP_ADDR]], i{{.+}} 0, i{{.+}} 0 +// CHECK: [[DEP_ADDR_VOID:%.+]] = call i8* @__kmpc_alloc(i32 [[GTID]], i64 72, i8* null) +// CHECK: [[DEP_ADDR:%.+]] = bitcast i8* [[DEP_ADDR_VOID]] to [3 x %struct.kmp_depend_info]* +// CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* [[DEP_ADDR]], i{{.+}} 0, i{{.+}} 0 // CHECK: [[SZ_BASE:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 0 -// CHECK: store i64 1, i64* [[SZ_BASE]], -// CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds [2 x %struct.kmp_depend_info], [2 x %struct.kmp_depend_info]* [[DEP_ADDR]], i{{.+}} 0, i{{.+}} 1 +// CHECK: store i64 2, i64* [[SZ_BASE]], +// CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* [[DEP_ADDR]], i{{.+}} 0, i{{.+}} 1 // CHECK: [[ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 0 // CHECK: store i64 %{{.+}}, i64* [[ADDR]], // CHECK: [[SZ_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 1 // CHECK: store i64 8, i64* [[SZ_ADDR]], // CHECK: [[FLAGS_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 2 // CHECK: store i8 1, i8* [[FLAGS_ADDR]], -// CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds [2 x %struct.kmp_depend_info], [2 x %struct.kmp_depend_info]* [[DEP_ADDR]], i{{.+}} 0, i{{.+}} 1 +// CHECK: [[SHAPE_ADDR:%.+]] = load i8*, i8** [[ARGV_ADDR:%.+]], +// CHECK: [[SZ1:%.+]] = mul nuw i64 3, %{{.+}} +// CHECK: [[SZ:%.+]] = mul nuw i64 [[SZ1]], 4 +// CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* [[DEP_ADDR]], i{{.+}} 0, i{{.+}} 2 +// CHECK: [[ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 0 +// CHECK: [[SHAPE:%.+]] = ptrtoint i8* [[SHAPE_ADDR]] to i64 +// CHECK: store i64 [[SHAPE]], i64* [[ADDR]], +// CHECK: [[SZ_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 1 +// CHECK: store i64 [[SZ]], i64* [[SZ_ADDR]], +// CHECK: [[FLAGS_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 2 +// CHECK: store i8 1, i8* [[FLAGS_ADDR]], +// CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* [[DEP_ADDR]], i{{.+}} 0, i{{.+}} 1 // CHECK: [[DEP:%.+]] = bitcast %struct.kmp_depend_info* [[BASE_ADDR]] to i8* // CHECK: store i8* [[DEP]], i8** [[TMAIN_A]], // CHECK: [[ARGC:%.+]] = load i8*, i8** [[ARGC_ADDR]], diff --git a/clang/test/OpenMP/task_codegen.c b/clang/test/OpenMP/task_codegen.c index d0bbe5670d69..9376c375d5a8 100644 --- a/clang/test/OpenMP/task_codegen.c +++ b/clang/test/OpenMP/task_codegen.c @@ -19,7 +19,7 @@ void foo(); int main() { omp_depend_t d, x; omp_event_handle_t evt; - int a; + int a, *b; // CHECK: [[D_ADDR:%.+]] = alloca i8*, // CHECK: [[X_ADDR:%.+]] = alloca i8*, // CHECK: [[EVT_ADDR:%.+]] = alloca i64, @@ -42,7 +42,7 @@ int main() { // CHECK: [[X_DEP_BASE_SIZE:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[X_DEP_BASE]], i{{.+}} 0, i{{.+}} 0 // CHECK: [[SIZE2:%.+]] = load i64, i64* [[X_DEP_BASE_SIZE]], // CHECK: [[SIZE3:%.+]] = add nuw i64 [[SIZE]], [[SIZE2]] - // CHECK: [[SIZE:%.+]] = add nuw i64 [[SIZE3]], 1 + // CHECK: [[SIZE:%.+]] = add nuw i64 [[SIZE3]], 2 // CHECK: [[SIZE32:%.+]] = trunc i64 [[SIZE]] to i32 // CHECK: [[SIZE64:%.+]] = zext i32 [[SIZE32]] to i64 // CHECK: [[SV:%.+]] = call i8* @llvm.stacksave() @@ -56,11 +56,26 @@ int main() { // CHECK: store i64 4, i64* [[SIZE_ADDR]], // CHECK: [[FLAGS_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA0]], i{{.+}} 0, i{{.+}} 2 // CHECK: store i8 1, i8* [[FLAGS_ADDR]], - // CHECK: [[VLA_D:%.+]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA]], i64 1 + // CHECK: [[B_ADDR:%.+]] = load i32*, i32** %{{.+}}, + // CHECK: [[A:%.+]] = load i32, i32* [[A_ADDR]], + // CHECK: [[A_CAST:%.+]] = sext i32 [[A]] to i64 + // CHECK: [[SZ1:%.+]] = mul nuw i64 3, [[A_CAST]] + // CHECK: [[A:%.+]] = load i32, i32* [[A_ADDR]], + // CHECK: [[A_CAST:%.+]] = sext i32 [[A]] to i64 + // CHECK: [[SZ:%.+]] = mul nuw i64 [[SZ1]], [[A_CAST]] + // CHECK: [[VLA1:%.+]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA]], i64 1 + // CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA1]], i{{.+}} 0, i{{.+}} 0 + // CHECK: [[B_ADDR_CAST:%.+]] = ptrtoint i32* [[B_ADDR]] to i64 + // CHECK: store i64 [[B_ADDR_CAST]], i64* [[BASE_ADDR]], + // CHECK: [[SIZE_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA1]], i{{.+}} 0, i{{.+}} 1 + // CHECK: store i64 [[SZ]], i64* [[SIZE_ADDR]], + // CHECK: [[FLAGS_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA1]], i{{.+}} 0, i{{.+}} 2 + // CHECK: store i8 1, i8* [[FLAGS_ADDR]], + // CHECK: [[VLA_D:%.+]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA]], i64 2 // CHECK: [[D_SIZE:%.+]] = mul nuw i64 24, [[SIZE1]] // CHECK: [[DEST:%.+]] = bitcast %struct.kmp_depend_info* [[VLA_D]] to i8* // CHECK: [[SRC:%.+]] = bitcast %struct.kmp_depend_info* [[D_DEP]] to i8* - // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[DEST]], i8* align 8 [[SRC]], i64 [[D_SIZE]], i1 false) + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align {{.+}} [[DEST]], i8* align {{.+}} [[SRC]], i64 [[D_SIZE]], i1 false) // CHECK: [[VLA_X:%.+]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA_D]], i64 [[SIZE1]] // CHECK: [[X_SIZE:%.+]] = mul nuw i64 24, [[SIZE2]] // CHECK: [[DEST:%.+]] = bitcast %struct.kmp_depend_info* [[VLA_X]] to i8* @@ -70,7 +85,7 @@ int main() { // CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* @{{.+}}, i32 [[GTID]], i8* [[ALLOC]], i32 [[SIZE32]], i8* [[BC]], i32 0, i8* null) // CHECK: [[SV:%.+]] = load i8*, i8** [[SV_ADDR]], // CHECK: call void @llvm.stackrestore(i8* [[SV]]) -#pragma omp task depend(in: a) depend(depobj: d, x) detach(evt) +#pragma omp task depend(in: a, ([3][a][a])b) depend(depobj: d, x) detach(evt) { #pragma omp taskgroup { From cfe-commits at lists.llvm.org Mon Mar 30 10:49:53 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Mon, 30 Mar 2020 17:49:53 +0000 (UTC) Subject: [PATCH] D68165: [analyzer][MallocChecker][NFC] Split checkPostCall up, deploy CallDescriptionMap In-Reply-To: References: Message-ID: <29d77322461a837bedcb980fde171023@localhost.localdomain> Szelethus added a comment. In D68165#1949954 , @ldionne wrote: > > Closed by commit rG703a1b8caf09 : [analyzer][MallocChecker][NFC] Split checkPostCall up, deploy CallDescriptionMap (authored by ldionne, committed by Szelethus). · Explain Why > > This is really strange -- it looks like 703a1b8caf09 was attributed to me in git, but I have nothing to do with this change. How did you commit the patch? Is that some Phabricator bug? Ugh, I squashed my local commits and pushed, it seems like for some reason it made you the author... it has happened to me before (always with you, for some reason), but was able to notice and correct it. There is little we can do about this, right? In D68165#1950212 , @NoQ wrote: > Not a phabricator bug. Maybe @Szelethus's local git somehow got in a weird state(?) Its been a source of endless misery :) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68165/new/ https://reviews.llvm.org/D68165 From cfe-commits at lists.llvm.org Mon Mar 30 10:49:54 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 17:49:54 +0000 (UTC) Subject: [PATCH] D77056: RFC: [Sema][SVE] Allow non-member operators for SVE types In-Reply-To: References: Message-ID: efriedma added a comment. I'm concerned we're going to run into trouble if two people define different SVE "libraries", and you try to link both of them into the same program. If you're not careful, you end up with ODR violations. The scope of this is sort of restricted in normal C++: class and enumerated types sort of have an informal "owner", and people tend to respect that. I mean, you could say it's the user's own fault if they break ODR, but we're essentially making a trap here. Maybe it would make sense to require that SVE operators are defined in a namespace? That would make the user think about the issue. We're also basically committing to never building these operators into the compiler, for all sizeless types for all targets. It would probably make sense to send this to cfe-dev, to get more perspectives on the language change. ================ Comment at: clang/include/clang/AST/Type.h:6833 inline bool Type::isOverloadableType() const { - return isDependentType() || isRecordType() || isEnumeralType(); + return (isDependentType() || isRecordType() || isEnumeralType() || + isSizelessBuiltinType()); ---------------- Unnecessary parentheses ================ Comment at: clang/test/SemaCXX/sizeless-1.cpp:659 +svint8_t &operator--(svint8_t &, int); +int operator,(svint8_t, svint8_t); + ---------------- Need some testcases with template operators. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77056/new/ https://reviews.llvm.org/D77056 From cfe-commits at lists.llvm.org Mon Mar 30 10:49:59 2020 From: cfe-commits at lists.llvm.org (Greg Rodgers via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 17:49:59 +0000 (UTC) Subject: [PATCH] D76987: Rename options --cuda-gpu-arch and --no-cuda-gpu-arch In-Reply-To: References: Message-ID: <5a65bbde2a8ef18d007997efa4151bf6@localhost.localdomain> gregrodgers added a comment. This was discussed on llvm-dev three years ago. Here is the thread. http://lists.llvm.org/pipermail/llvm-dev/2017-February/109930.html The last name discussed was "-- offload-arch". I don't believe we need a list option anymore. So ignore the very old request for --offload-archs. I am ok with the patch the way it is. In the future, we should consider renaming the CudaArch class to OffloadArch class . Also the GpuArchList is currently only initialized in CudaActionBuilder. Eventually this is will have to be done for HIPActionBuilder and OpenMPActionBuilder. Could you consider creating a function to InitializeGpuArchList ? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76987/new/ https://reviews.llvm.org/D76987 From cfe-commits at lists.llvm.org Mon Mar 30 10:50:59 2020 From: cfe-commits at lists.llvm.org (Sid Manning via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 17:50:59 +0000 (UTC) Subject: [PATCH] D76546: [Hexagon] MaxAtomicPromoteWidth, MaxAtomicInlineWidth are not getting set. In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rG81194bfeea7b: [Hexagon] MaxAtomicPromoteWidth and MaxAtomicInlineWidth are not getting set. (authored by sidneym). Changed prior to commit: https://reviews.llvm.org/D76546?vs=251896&id=253640#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76546/new/ https://reviews.llvm.org/D76546 Files: clang/lib/Basic/Targets/Hexagon.h clang/test/Preprocessor/hexagon-predefines.c Index: clang/test/Preprocessor/hexagon-predefines.c =================================================================== --- clang/test/Preprocessor/hexagon-predefines.c +++ clang/test/Preprocessor/hexagon-predefines.c @@ -113,3 +113,18 @@ // CHECK-LINUX: #define __unix__ 1 // CHECK-LINUX: #define linux 1 // CHECK-LINUX: #define unix 1 + +// RUN: %clang_cc1 -E -dM -triple hexagon-unknown-linux-musl \ +// RUN: -target-cpu hexagonv67 -target-feature +hvxv67 \ +// RUN: -target-feature +hvx-length128b %s | FileCheck \ +// RUN: %s -check-prefix CHECK-ATOMIC +// CHECK-ATOMIC: #define __CLANG_ATOMIC_BOOL_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_CHAR16_T_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_CHAR32_T_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_CHAR_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_INT_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_LLONG_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_LONG_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_POINTER_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_SHORT_LOCK_FREE 2 +// CHECK-ATOMIC: #define __CLANG_ATOMIC_WCHAR_T_LOCK_FREE 2 Index: clang/lib/Basic/Targets/Hexagon.h =================================================================== --- clang/lib/Basic/Targets/Hexagon.h +++ clang/lib/Basic/Targets/Hexagon.h @@ -57,6 +57,7 @@ LargeArrayAlign = 64; UseBitFieldTypeAlignment = true; ZeroLengthBitfieldBoundary = 32; + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; // These are the default values anyway, but explicitly make sure // that the size of the boolean type is 8 bits. Bool vectors are used -------------- next part -------------- A non-text attachment was scrubbed... Name: D76546.253640.patch Type: text/x-patch Size: 1665 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 11:16:27 2020 From: cfe-commits at lists.llvm.org (Nico Weber via cfe-commits) Date: Mon, 30 Mar 2020 11:16:27 -0700 (PDT) Subject: [clang] c506adc - Move CLANG_SYSTEMZ_DEFAULT_ARCH to config.h. Message-ID: <5e82377b.1c69fb81.ecb07.0801@mx.google.com> Author: Nico Weber Date: 2020-03-30T14:16:17-04:00 New Revision: c506adcdf2ca3ba6459e52e09c55868e3b57af46 URL: https://github.com/llvm/llvm-project/commit/c506adcdf2ca3ba6459e52e09c55868e3b57af46 DIFF: https://github.com/llvm/llvm-project/commit/c506adcdf2ca3ba6459e52e09c55868e3b57af46.diff LOG: Move CLANG_SYSTEMZ_DEFAULT_ARCH to config.h. Instead of using a global define; see comments on D75914. While here, port 9c9d88d8b1b to the GN build. Added: Modified: clang/CMakeLists.txt clang/include/clang/Config/config.h.cmake clang/lib/Driver/ToolChains/Arch/SystemZ.cpp llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn Removed: ################################################################################ diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index c9e76c5e4518..88e556fd88a0 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -306,9 +306,7 @@ if (NOT DEFINED MATCHED_ARCH OR "${CMAKE_MATCH_1}" LESS 35) "Default architecture for OpenMP offloading to Nvidia GPUs." FORCE) endif() -set(CLANG_SYSTEMZ_DEFAULT_ARCH "z10" CACHE STRING - "SystemZ Default Arch") -add_definitions( -DCLANG_SYSTEMZ_DEFAULT_ARCH="${CLANG_SYSTEMZ_DEFAULT_ARCH}") +set(CLANG_SYSTEMZ_DEFAULT_ARCH "z10" CACHE STRING "SystemZ Default Arch") set(CLANG_VENDOR ${PACKAGE_VENDOR} CACHE STRING "Vendor-specific text for showing with version information.") diff --git a/clang/include/clang/Config/config.h.cmake b/clang/include/clang/Config/config.h.cmake index 261b3841b86f..a0f8b6b1b0da 100644 --- a/clang/include/clang/Config/config.h.cmake +++ b/clang/include/clang/Config/config.h.cmake @@ -83,4 +83,7 @@ /* Spawn a new process clang.exe for the CC1 tool invocation, when necessary */ #cmakedefine01 CLANG_SPAWN_CC1 +/* Default to all compiler invocations for --sysroot=. */ +#define CLANG_SYSTEMZ_DEFAULT_ARCH "${CLANG_SYSTEMZ_DEFAULT_ARCH}" + #endif diff --git a/clang/lib/Driver/ToolChains/Arch/SystemZ.cpp b/clang/lib/Driver/ToolChains/Arch/SystemZ.cpp index b263fb7df09e..f81bf68172de 100644 --- a/clang/lib/Driver/ToolChains/Arch/SystemZ.cpp +++ b/clang/lib/Driver/ToolChains/Arch/SystemZ.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "SystemZ.h" +#include "clang/Config/config.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "llvm/Option/ArgList.h" diff --git a/llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn b/llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn index cc2c4e19ad49..7fbfb46a41c5 100644 --- a/llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn @@ -36,6 +36,7 @@ write_cmake_config("Config") { "ENABLE_X86_RELAX_RELOCATIONS=", "ENABLE_EXPERIMENTAL_NEW_PASS_MANAGER=", "CLANG_ENABLE_OBJC_REWRITER=1", # FIXME: flag? + "CLANG_SYSTEMZ_DEFAULT_ARCH=z10", ] if (clang_enable_arcmt) { From cfe-commits at lists.llvm.org Mon Mar 30 11:24:24 2020 From: cfe-commits at lists.llvm.org (Karasev Nikita via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 18:24:24 +0000 (UTC) Subject: [PATCH] D76996: [analyzer] Improve PlacementNewChecker In-Reply-To: References: Message-ID: f00kat updated this revision to Diff 253642. f00kat marked an inline comment as done. f00kat added a comment. test fix Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76996/new/ https://reviews.llvm.org/D76996 Files: clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp clang/test/Analysis/placement-new.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76996.253642.patch Type: text/x-patch Size: 14995 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 11:24:24 2020 From: cfe-commits at lists.llvm.org (Nico Weber via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 18:24:24 +0000 (UTC) Subject: [PATCH] D77022: [analyzer] Use IgnoreImpCasts() instead of reimplementing it. In-Reply-To: References: Message-ID: thakis marked an inline comment as done. thakis added inline comments. ================ Comment at: clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp:512 + return E->IgnoreImpCasts(); } ---------------- NoQ wrote: > Charusso wrote: > > I think it would make sense to remove the helper-function completely. (Being used 2 times.) > Yup. I didn't do that because I liked the comment that this is for the _Nonnull implicit ARC casts – if I inline the function I have to duplicate the comment. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77022/new/ https://reviews.llvm.org/D77022 From cfe-commits at lists.llvm.org Mon Mar 30 11:24:25 2020 From: cfe-commits at lists.llvm.org (Nico Weber via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 18:24:25 +0000 (UTC) Subject: [PATCH] D75914: systemz: allow configuring default CLANG_SYSTEMZ_ARCH In-Reply-To: References: Message-ID: <64780a79ffaba0d4ef03f9f4005a8258@localhost.localdomain> thakis added inline comments. ================ Comment at: clang/CMakeLists.txt:311 + "SystemZ Default Arch") +add_definitions( -DCLANG_SYSTEMZ_DEFAULT_ARCH="${CLANG_SYSTEMZ_DEFAULT_ARCH}") + ---------------- Hahnfeld wrote: > Passing values like this is unusual for CMake and causes all source files to be recompiled if the value is changed. Instead could we add this to `include/clang/Config/config.h.cmake` like other `CLANG_DEFAULT_*` options? +1 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75914/new/ https://reviews.llvm.org/D75914 From cfe-commits at lists.llvm.org Mon Mar 30 11:24:26 2020 From: cfe-commits at lists.llvm.org (Hubert Tong via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 18:24:26 +0000 (UTC) Subject: [PATCH] D76932: [AIX] emit .extern and .weak directive linkage In-Reply-To: References: Message-ID: <83cc28e3e8f074d407dd17fe48a1fee8@localhost.localdomain> hubert.reinterpretcast added inline comments. ================ Comment at: llvm/include/llvm/MC/MCDirectives.h:47 + MCSA_WeakReference, ///< .weak_reference (MachO) + MCSA_WeakDefAutoPrivate ///< .weak_def_can_be_hidden (MachO) }; ---------------- DiggerLin wrote: > @hubert.reinterpretcast , @jasonliu , do we need to create a NFC patch for the clang format problem of the above first ? I think it would help; yes. Please drop one at your earliest convenience and then rebase this patch on top of it. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76932/new/ https://reviews.llvm.org/D76932 From cfe-commits at lists.llvm.org Mon Mar 30 11:24:26 2020 From: cfe-commits at lists.llvm.org (Nico Weber via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 18:24:26 +0000 (UTC) Subject: [PATCH] D75914: systemz: allow configuring default CLANG_SYSTEMZ_ARCH In-Reply-To: References: Message-ID: <0a088b05345f456321897fc4cb194f3f@localhost.localdomain> thakis added inline comments. ================ Comment at: clang/CMakeLists.txt:311 + "SystemZ Default Arch") +add_definitions( -DCLANG_SYSTEMZ_DEFAULT_ARCH="${CLANG_SYSTEMZ_DEFAULT_ARCH}") + ---------------- thakis wrote: > Hahnfeld wrote: > > Passing values like this is unusual for CMake and causes all source files to be recompiled if the value is changed. Instead could we add this to `include/clang/Config/config.h.cmake` like other `CLANG_DEFAULT_*` options? > +1 Also, this is used in one cpp file; passing the define to every compilation unit seems a bit aggressive. I'll try to land a patch to fix this. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75914/new/ https://reviews.llvm.org/D75914 From cfe-commits at lists.llvm.org Mon Mar 30 11:24:28 2020 From: cfe-commits at lists.llvm.org (Nico Weber via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 18:24:28 +0000 (UTC) Subject: [PATCH] D75914: systemz: allow configuring default CLANG_SYSTEMZ_ARCH In-Reply-To: References: Message-ID: thakis added inline comments. ================ Comment at: clang/CMakeLists.txt:311 + "SystemZ Default Arch") +add_definitions( -DCLANG_SYSTEMZ_DEFAULT_ARCH="${CLANG_SYSTEMZ_DEFAULT_ARCH}") + ---------------- thakis wrote: > thakis wrote: > > Hahnfeld wrote: > > > Passing values like this is unusual for CMake and causes all source files to be recompiled if the value is changed. Instead could we add this to `include/clang/Config/config.h.cmake` like other `CLANG_DEFAULT_*` options? > > +1 > Also, this is used in one cpp file; passing the define to every compilation unit seems a bit aggressive. > > I'll try to land a patch to fix this. Done in c506adcdf2ca3ba6459e52e09c55868e3b57af46. (This only changes the implementation of the feature; the way people who build clang tell cmake what they want didn't change.) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75914/new/ https://reviews.llvm.org/D75914 From cfe-commits at lists.llvm.org Mon Mar 30 11:24:29 2020 From: cfe-commits at lists.llvm.org (Philip Reames via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 18:24:29 +0000 (UTC) Subject: [PATCH] D76140: [InlineFunction] update attributes during inlining In-Reply-To: References: Message-ID: <676bf88d3563ce2169501c6e876da533@localhost.localdomain> reames accepted this revision. reames added a comment. This revision is now accepted and ready to land. LGTM, but with two specific required follow ups. If you're not comfortable committing to both, please don't land this one. ================ Comment at: llvm/lib/Transforms/Utils/InlineFunction.cpp:93 +static cl::opt MaxInstCheckedForThrow( + "max-inst-checked-for-throw-during-inlining", cl::Hidden, + cl::desc("the maximum number of instructions analyzed for may throw during " ---------------- I'd suggest a name change here. Maybe: "inliner-attribute-window"? ================ Comment at: llvm/lib/Transforms/Utils/InlineFunction.cpp:1159 + + auto MayContainThrowingOrExitingCall = [&](Instruction *RVal, + Instruction *RInst) { ---------------- Pull this out as a static helper instead of a lambda, add an assert internally that the two instructions are in the same block. Why? Because I'm 80% sure the state capture on the lambda isn't needed, and having it as a separate function forces that discipline. ================ Comment at: llvm/lib/Transforms/Utils/InlineFunction.cpp:1175 + continue; + // Sanity check that the cloned return instruction exists and is a return + // instruction itself. ---------------- Ok, after staring at it a bit, I've convinced myself the code here is correct, just needlessly conservative. What you're doing is: If the callees return instruction and returned call both map to the same instructions once inlined, determine whether there's a possible exit between the inlined copy. What you could be doing: If the callee returns a call, check if *in the callee* there's a possible exit between call and return, then apply attribute to cloned call. The key difference is when the caller directly returns the result vs uses it locally. The result here is that your transform is much more narrow in applicability than it first appears. ================ Comment at: llvm/test/Transforms/Inline/ret_attr_update.ll:112 + ret i8* %s +} ---------------- There's a critical missing test case here: - Callee and caller have the same attributes w/different values (i.e. deref) And thinking through the code, I think there might be a bug here. It's not a serious one, but the if the callee specifies a larger deref than the caller, it looks like the the smaller value is being written over the larger. Actually, digging through the attribute code, I think I'm wrong about the bug. However, you should definitely write the test to confirm and document merging behaviour! If it does turn out I'm correct, I'm fine with this being addressed in a follow up patch provided that the test is added in this one and isn't a functional issue. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76140/new/ https://reviews.llvm.org/D76140 From cfe-commits at lists.llvm.org Mon Mar 30 11:24:30 2020 From: cfe-commits at lists.llvm.org (Louis Dionne via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 18:24:30 +0000 (UTC) Subject: [PATCH] D68165: [analyzer][MallocChecker][NFC] Split checkPostCall up, deploy CallDescriptionMap In-Reply-To: References: Message-ID: <632319d9917c56ac5df3cc03c891fa25@localhost.localdomain> ldionne added a comment. In D68165#1950357 , @Szelethus wrote: > Ugh, I squashed my local commits and pushed, it seems like for some reason it made you the author... it has happened to me before (always with you, for some reason), but was able to notice and correct it. Always with me? Maybe you should double-check that you don't have something weird in your git config, aliases or other? I don't know *why* it would be me in particular, but the fact that it is consistently the same person is kind of suspicious. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68165/new/ https://reviews.llvm.org/D68165 From cfe-commits at lists.llvm.org Mon Mar 30 11:25:03 2020 From: cfe-commits at lists.llvm.org (Arnold Schwaighofer via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 18:25:03 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift Message-ID: aschwaighofer created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Swift would like to use clang's abis to emit protocol declarations. It needs to a hook to register when inherited protocols are emitted. This commits adds the public API: emitProtocolDecl(CodeGenModule &CGM, const ObjCProtocolDecl *p, llvm::function_ref createProtocolReference); rdar://60888524 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77077 Files: clang/include/clang/CodeGen/CodeGenABITypes.h clang/lib/CodeGen/CGObjCGNU.cpp clang/lib/CodeGen/CGObjCMac.cpp clang/lib/CodeGen/CGObjCRuntime.cpp clang/lib/CodeGen/CGObjCRuntime.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D77077.253647.patch Type: text/x-patch Size: 16709 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 11:27:57 2020 From: cfe-commits at lists.llvm.org (David Blaikie via cfe-commits) Date: Mon, 30 Mar 2020 11:27:57 -0700 Subject: [clang] 857bf5d - [FIX] Do not copy an llvm::function_ref if it has to be reused In-Reply-To: References: <5e48e74b.1c69fb81.6fbb8.f937@mx.google.com> <4854a561-aa22-74b9-43a8-d8ae52db0d86@jdoerfert.de> Message-ID: On Fri, Mar 27, 2020 at 5:16 PM Arthur O'Dwyer via cfe-commits < cfe-commits at lists.llvm.org> wrote: > Richard: Okay, filed https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94376 ! > > David: You are correct, the bug in function_ref appeared only when > constructing from `const function_ref&&`. When I said that the constructor > template suppressed the copy constructor, I was wrong. The implicitly > generated copy constructor is still there, and it's the best match for > `const function_ref&` but not for `const function_ref&&`. The bug would > also appear with construction from `volatile function_ref&`, but, let's not > go there. :) > > IMHO (YMMV), it would be worth *additionally* adding a complex but > "realistic" test case that depends on the GCC bug, as opposed to your own > test's simple but "unrealistic" cast to `const function_ref&&`. Here's a > test case that I believe would have dereferenced null on GCC but would have > worked fine on Clang— > > TEST(FunctionRefTest, BadCopyGCCBug) { > > auto A = [] { return 1; }; > > function_ref W = A; > > auto LW = [=]() { // captures a data member 'const function_ref W' > > return [=]() { > > return W(); > > }; > > }(); > > auto LX = std::move(LW); // calls function_ref's 'const&&' constructor > > W = nullptr; > > ASSERT_EQ(LX(), 1); > > } > Yeah, I tend to err on the side of fairly isolated testing. I guess a fairly closer-to-practical, though smaller (in terms of feature interactions, not necessarily in lines of code) example might be to std::move on a const ref, rather than the raw cast - the next step beyond that would be to use a template to make it more realistic as to why you'd be moving a const ref, etc. But I think the narrower test is alright. - Dave > > –Arthur > > > On Fri, Mar 27, 2020 at 7:48 PM Richard Smith > wrote: > >> On Thu, 26 Mar 2020 at 21:50, Arthur O'Dwyer via cfe-commits < >> cfe-commits at lists.llvm.org> wrote: >> >>> [...] >>> Argh! That is insanely sneaky, and it is quite probable IMHO that this >>> is a core-language bug in GCC, because GCC behaves differently from EDG and >>> Clang here. >>> https://godbolt.org/z/oCvLpv >>> On GCC, when you have a lambda nested within a lambda, and you >>> capture-by-copy a variable which was captured-by-copy using [=] or [i] (but >>> not C++14 init-capture [i=i]), then your data member for that capture will >>> have type `const I`, not just `I`. >>> On Clang and EDG, [=], [i], and [i=i] all behave equivalently, and >>> capture a data member with type `I`. >>> >>> I don't see anything about this on >>> https://gcc.gnu.org/bugzilla/buglist.cgi?quicksearch=lambda%20capture%20const >>> — Richard, you might be best able to describe the issue correctly ;) but if >>> you want me to file it, I will. (Might be a corollary of bug 86697 >>> .) >>> >> >> Oh wow, so this would only fail with a combination of libstdc++ (which >> makes a copy of the lambda and destroy the original before copying the >> lambda) and GCC (which has a bug in how it determines the type of a nested >> capture)? Fascinating! :) >> >> [expr.prim.lambda.capture]p10 is the relevant rule: "The type of such a >> data member is the referenced type if the entity is a reference to an >> object, an lvalue reference to the referenced function type if the entity >> is a reference to a function, or the type of the corresponding captured >> entity otherwise." >> >> Regardless of whether you think the captured entity is the original >> variable or the member of the outer closure type, the type of that entity >> is not const-qualified. So the inner capture should not have a >> const-qualified type. >> >> Given that you identified the GCC capture bug, I think you should do the >> honors :) >> >> >>> Regardless, llvm::function_ref's SFINAE should still be fixed. This is a >>> bug in llvm::function_ref, exposed by a bug in GCC. (Or vice versa.) >>> >> >> Yup. >> > _______________________________________________ > cfe-commits mailing list > cfe-commits at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cfe-commits at lists.llvm.org Mon Mar 30 11:46:30 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via cfe-commits) Date: Mon, 30 Mar 2020 11:46:30 -0700 (PDT) Subject: [clang] 24485ae - [clang analysis] Make mutex guard detection more reliable. Message-ID: <5e823e86.1c69fb81.de314.fd48@mx.google.com> Author: Eli Friedman Date: 2020-03-30T11:46:02-07:00 New Revision: 24485aec4750255574a9a8211b3aef1ce00e83b6 URL: https://github.com/llvm/llvm-project/commit/24485aec4750255574a9a8211b3aef1ce00e83b6 DIFF: https://github.com/llvm/llvm-project/commit/24485aec4750255574a9a8211b3aef1ce00e83b6.diff LOG: [clang analysis] Make mutex guard detection more reliable. -Wthread-safety was failing to detect certain AST patterns it should detect. Make the pattern detection a bit more comprehensive. Due to an unrelated bug involving template instantiation, this showed up as a regression in 10.0 vs. 9.0 in the original bug report. The included testcase fails on older versions of clang, though. Fixes https://bugs.llvm.org/show_bug.cgi?id=45323 . Differential Revision: https://reviews.llvm.org/D76943 Added: Modified: clang/lib/Analysis/ThreadSafety.cpp clang/test/SemaCXX/warn-thread-safety-analysis.cpp Removed: ################################################################################ diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp index 252083f377d9..e0ff23df5ab4 100644 --- a/clang/lib/Analysis/ThreadSafety.cpp +++ b/clang/lib/Analysis/ThreadSafety.cpp @@ -2139,12 +2139,14 @@ void BuildLockset::VisitDeclStmt(const DeclStmt *S) { // handle constructors that involve temporaries if (auto *EWC = dyn_cast(E)) - E = EWC->getSubExpr(); - if (auto *ICE = dyn_cast(E)) - if (ICE->getCastKind() == CK_NoOp) - E = ICE->getSubExpr(); + E = EWC->getSubExpr()->IgnoreParens(); + if (auto *CE = dyn_cast(E)) + if (CE->getCastKind() == CK_NoOp || + CE->getCastKind() == CK_ConstructorConversion || + CE->getCastKind() == CK_UserDefinedConversion) + E = CE->getSubExpr()->IgnoreParens(); if (auto *BTE = dyn_cast(E)) - E = BTE->getSubExpr(); + E = BTE->getSubExpr()->IgnoreParens(); if (const auto *CE = dyn_cast(E)) { const auto *CtorD = dyn_cast_or_null(CE->getConstructor()); diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index 23255a53eae7..cdb22cd22a99 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -5648,6 +5648,22 @@ namespace ReturnScopedLockable { auto ptr = get(); return ptr->f(); } + void use_constructor() { + auto ptr = ReadLockedPtr(nullptr); + ptr->f(); + auto ptr2 = ReadLockedPtr{nullptr}; + ptr2->f(); + auto ptr3 = (ReadLockedPtr{nullptr}); + ptr3->f(); + } + struct Convertible { + Convertible(); + operator ReadLockedPtr(); + }; + void use_conversion() { + ReadLockedPtr ptr = Convertible(); + ptr->f(); + } } namespace PR38640 { From cfe-commits at lists.llvm.org Mon Mar 30 11:56:54 2020 From: cfe-commits at lists.llvm.org (Richard Sandiford via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 18:56:54 +0000 (UTC) Subject: [PATCH] D77056: RFC: [Sema][SVE] Allow non-member operators for SVE types In-Reply-To: References: Message-ID: <3efa3ac5085947aab5547fcaab1fe466@localhost.localdomain> rsandifo-arm added a comment. In D77056#1950358 , @efriedma wrote: > I'm concerned we're going to run into trouble if two people define different SVE "libraries", and you try to link both of them into the same program. If you're not careful, you end up with ODR violations. The scope of this is sort of restricted in normal C++: class and enumerated types sort of have an informal "owner", and people tend to respect that. I mean, you could say it's the user's own fault if they break ODR, but we're essentially making a trap here. Maybe it would make sense to require that SVE operators are defined in a namespace? That would make the user think about the issue. Thanks for the suggestion. Requiring a namespace sounds like a good plan -- will give it some more thought. > We're also basically committing to never building these operators into the compiler, for all sizeless types for all targets. I guess this brings up the question of when we should introduce a specific isSizelessSVEBuiltinType() query. One option would to be wait until there's at least one type that isSizelessBuiltinType but isn't an SVE type. Another would be to introduce it when a feature seems too SVE-specific. If you think this qualifies for the latter then I can add the query now. For AArch64, it would always be possible in future to provide a standard header file that defines certain operators for SVE types. One way of implementing the header file would be to use magic attributes that get the compiler to fill in the implementation. (Or it could perhaps just use a pragma to "enable" built-in operators, but that sounds riskier.) > It would probably make sense to send this to cfe-dev, to get more perspectives on the language change. OK. I'll address your comments first and then post there. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77056/new/ https://reviews.llvm.org/D77056 From cfe-commits at lists.llvm.org Mon Mar 30 11:56:58 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Mon, 30 Mar 2020 18:56:58 +0000 (UTC) Subject: [PATCH] D68165: [analyzer][MallocChecker][NFC] Split checkPostCall up, deploy CallDescriptionMap In-Reply-To: References: Message-ID: <5476b954d0eae18a92d2b70cb1ae7396@localhost.localdomain> Szelethus added a comment. In D68165#1950451 , @ldionne wrote: > Always with me? Maybe you should double-check that you don't have something weird in your git config, aliases or other? I don't know *why* it would be me in particular, but the fact that it is consistently the same person is kind of suspicious. Will do. Sorry for the trouble! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68165/new/ https://reviews.llvm.org/D68165 From cfe-commits at lists.llvm.org Mon Mar 30 11:57:01 2020 From: cfe-commits at lists.llvm.org (Anna Thomas via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 18:57:01 +0000 (UTC) Subject: [PATCH] D76140: [InlineFunction] update attributes during inlining In-Reply-To: References: Message-ID: anna marked 3 inline comments as done. anna added inline comments. ================ Comment at: llvm/lib/Transforms/Utils/InlineFunction.cpp:1159 + + auto MayContainThrowingOrExitingCall = [&](Instruction *RVal, + Instruction *RInst) { ---------------- reames wrote: > Pull this out as a static helper instead of a lambda, add an assert internally that the two instructions are in the same block. > > Why? Because I'm 80% sure the state capture on the lambda isn't needed, and having it as a separate function forces that discipline. agreed. I'll do that in this change itself before landing. I am using this static helper in followon change D76792. ================ Comment at: llvm/lib/Transforms/Utils/InlineFunction.cpp:1175 + continue; + // Sanity check that the cloned return instruction exists and is a return + // instruction itself. ---------------- reames wrote: > Ok, after staring at it a bit, I've convinced myself the code here is correct, just needlessly conservative. > > What you're doing is: > If the callees return instruction and returned call both map to the same instructions once inlined, determine whether there's a possible exit between the inlined copy. > > What you could be doing: > If the callee returns a call, check if *in the callee* there's a possible exit between call and return, then apply attribute to cloned call. > > The key difference is when the caller directly returns the result vs uses it locally. The result here is that your transform is much more narrow in applicability than it first appears. yes, thanks for pointing it out. I realized it after our offline discussion :) For now, I will add a FIXME testcase which showcases the difference in code and handle that testcase in a followon change. ================ Comment at: llvm/test/Transforms/Inline/ret_attr_update.ll:112 + ret i8* %s +} ---------------- reames wrote: > There's a critical missing test case here: > - Callee and caller have the same attributes w/different values (i.e. deref) > > And thinking through the code, I think there might be a bug here. It's not a serious one, but the if the callee specifies a larger deref than the caller, it looks like the the smaller value is being written over the larger. > > Actually, digging through the attribute code, I think I'm wrong about the bug. However, you should definitely write the test to confirm and document merging behaviour! > > If it does turn out I'm correct, I'm fine with this being addressed in a follow up patch provided that the test is added in this one and isn't a functional issue. will check this. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76140/new/ https://reviews.llvm.org/D76140 From cfe-commits at lists.llvm.org Mon Mar 30 11:57:12 2020 From: cfe-commits at lists.llvm.org (Dan Albert via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 18:57:12 +0000 (UTC) Subject: [PATCH] D76452: Use LLD by default for Android. In-Reply-To: References: Message-ID: danalbert added a comment. In D76452#1945084 , @srhines wrote: > In D76452#1945029 , @MaskRay wrote: > > > To cross build ELF object on macOS, another alternative is a wrapper named `ld` which invokes `lld -flavor gnu "$@"` > > > @danalbert Would this kind of idea work with your other reverted patch? I'm not sure exactly what broke on those builds. Not really. Windows complicates things here, since it operates based on file extensions rather than shebangs. `ld.exe` is not `ld.cmd`, and `ld` (with no extension) doesn't work. Any system that expects one form won't work with the other. Beyond that, process creation is expensive on Windows so we should be avoiding as many superfluous processes as we can. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76452/new/ https://reviews.llvm.org/D76452 From cfe-commits at lists.llvm.org Mon Mar 30 11:58:09 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 18:58:09 +0000 (UTC) Subject: [PATCH] D76943: [clang analysis] Make mutex guard detection more reliable. In-Reply-To: References: Message-ID: <3d174f5135cfc187ee0269a00f205a43@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG24485aec4750: [clang analysis] Make mutex guard detection more reliable. (authored by efriedma). Changed prior to commit: https://reviews.llvm.org/D76943?vs=253253&id=253657#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76943/new/ https://reviews.llvm.org/D76943 Files: clang/lib/Analysis/ThreadSafety.cpp clang/test/SemaCXX/warn-thread-safety-analysis.cpp Index: clang/test/SemaCXX/warn-thread-safety-analysis.cpp =================================================================== --- clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -5648,6 +5648,22 @@ auto ptr = get(); return ptr->f(); } + void use_constructor() { + auto ptr = ReadLockedPtr(nullptr); + ptr->f(); + auto ptr2 = ReadLockedPtr{nullptr}; + ptr2->f(); + auto ptr3 = (ReadLockedPtr{nullptr}); + ptr3->f(); + } + struct Convertible { + Convertible(); + operator ReadLockedPtr(); + }; + void use_conversion() { + ReadLockedPtr ptr = Convertible(); + ptr->f(); + } } namespace PR38640 { Index: clang/lib/Analysis/ThreadSafety.cpp =================================================================== --- clang/lib/Analysis/ThreadSafety.cpp +++ clang/lib/Analysis/ThreadSafety.cpp @@ -2139,12 +2139,14 @@ // handle constructors that involve temporaries if (auto *EWC = dyn_cast(E)) - E = EWC->getSubExpr(); - if (auto *ICE = dyn_cast(E)) - if (ICE->getCastKind() == CK_NoOp) - E = ICE->getSubExpr(); + E = EWC->getSubExpr()->IgnoreParens(); + if (auto *CE = dyn_cast(E)) + if (CE->getCastKind() == CK_NoOp || + CE->getCastKind() == CK_ConstructorConversion || + CE->getCastKind() == CK_UserDefinedConversion) + E = CE->getSubExpr()->IgnoreParens(); if (auto *BTE = dyn_cast(E)) - E = BTE->getSubExpr(); + E = BTE->getSubExpr()->IgnoreParens(); if (const auto *CE = dyn_cast(E)) { const auto *CtorD = dyn_cast_or_null(CE->getConstructor()); -------------- next part -------------- A non-text attachment was scrubbed... Name: D76943.253657.patch Type: text/x-patch Size: 1827 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 12:13:29 2020 From: cfe-commits at lists.llvm.org (via cfe-commits) Date: Mon, 30 Mar 2020 12:13:29 -0700 (PDT) Subject: [clang] defd95e - [analyzer] Fix StdLibraryFunctionsChecker NotNull Constraint Check Message-ID: <5e8244d9.1c69fb81.90153.c0f1@mx.google.com> Author: Vince Bridgers Date: 2020-03-30T14:13:08-05:00 New Revision: defd95ef45171252ee8491729d3f3c863bbfe530 URL: https://github.com/llvm/llvm-project/commit/defd95ef45171252ee8491729d3f3c863bbfe530 DIFF: https://github.com/llvm/llvm-project/commit/defd95ef45171252ee8491729d3f3c863bbfe530.diff LOG: [analyzer] Fix StdLibraryFunctionsChecker NotNull Constraint Check Summary: This check was causing a crash in a test case where the 0th argument was uninitialized ('Assertion `T::isKind(*this)' at line SVals.h:104). This was happening since the argument was actually undefined, but the castAs assumes the value is DefinedOrUnknownSVal. The fix appears to be simply to check for an undefined value and skip the check allowing the uninitalized value checker to detect the error. I included a test case that I verified to produce the negative case prior to the fix, and passes with the fix. Reviewers: martong, NoQ Subscribers: xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, Szelethus, donat.nagy, Charusso, ASDenysPetrov, baloghadamsoftware, dkrupp, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77012 Added: Modified: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp clang/test/Analysis/std-c-library-functions.c Removed: ################################################################################ diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index cd257ffdc939..6e5f5f8b5874 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -190,6 +190,9 @@ class StdLibraryFunctionsChecker ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call, const Summary &Summary) const override { SVal V = getArgSVal(Call, getArgNo()); + if (V.isUndef()) + return State; + DefinedOrUnknownSVal L = V.castAs(); if (!L.getAs()) return State; diff --git a/clang/test/Analysis/std-c-library-functions.c b/clang/test/Analysis/std-c-library-functions.c index 3f700a7c39a4..a275ea6720ad 100644 --- a/clang/test/Analysis/std-c-library-functions.c +++ b/clang/test/Analysis/std-c-library-functions.c @@ -89,6 +89,14 @@ void test_fread_fwrite(FILE *fp, int *buf) { clang_analyzer_eval(z <= y); // expected-warning{{TRUE}} } +void test_fread_uninitialized(void) { + void *ptr; + size_t sz; + size_t nmem; + FILE *fp; + (void)fread(ptr, sz, nmem, fp); // expected-warning {{1st function call argument is an uninitialized value}} +} + ssize_t getline(char **, size_t *, FILE *); void test_getline(FILE *fp) { char *line = 0; From cfe-commits at lists.llvm.org Mon Mar 30 12:30:18 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 19:30:18 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift In-Reply-To: References: Message-ID: <4c18115e5d76b998580ec3f0c1ecc334@localhost.localdomain> rjmccall added inline comments. ================ Comment at: clang/include/clang/CodeGen/CodeGenABITypes.h:148 + llvm::function_ref + createProtocolReference); } // end namespace CodeGen ---------------- I would call this `emitObjCProtocolObject` or something, and maybe say in the comment: > Get a pointer to a protocol object for the given declaration, emitting it if it hasn't already been emitted in this translation unit. Note that the ABI for emitting a protocol reference in code (e.g. for a `@protocol` expression) in most runtimes is not as simple as just materializing a pointer to this object. Can you explain the need for the callback? Are you expecting to use this for Swift-declared protocols by synthesizing an ObjC protocol declaration for them? I can see why you'd need a callback in that case. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77077/new/ https://reviews.llvm.org/D77077 From cfe-commits at lists.llvm.org Mon Mar 30 12:30:17 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 19:30:17 +0000 (UTC) Subject: [PATCH] D74387: [SYCL] Defer __float128 type usage diagnostics In-Reply-To: References: Message-ID: jdoerfert added a comment. This is needed for OpenMP as well. Does it make sense to include it in this patch or in another one? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D74387/new/ https://reviews.llvm.org/D74387 From cfe-commits at lists.llvm.org Mon Mar 30 12:30:18 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 19:30:18 +0000 (UTC) Subject: [PATCH] D77081: [MS] Mark vbase dtors ref'd when ref'ing dtor Message-ID: rnk created this revision. rnk added a reviewer: rsmith. Herald added a project: clang. DONOTSUBMIT: Uploading for feedback on approach, still have test failures: ******************** Failing Tests (1): Clang :: CXX/class.access/p4.cpp In the MS C++ ABI, complete destructors for classes with virtual bases are emitted whereever they are needed. The complete destructor calls: - the base dtor - for each vbase, its base dtor Even when a destructor is user-defined in another TU, clang needs to mark the virtual base dtors referenced in TUs that call destructors. This fixes PR38521. FIXME: What about separating base and complete dtors? i.e. what about when only base dtors are ref'd? Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77081 Files: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaExpr.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77081.253662.patch Type: text/x-patch Size: 4582 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 12:30:19 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 19:30:19 +0000 (UTC) Subject: [PATCH] D77070: [SemaObjC] Add a warning for declarations of BOOL:1 when BOOL is a signed char In-Reply-To: References: Message-ID: rjmccall added a comment. This feels like it's going to bite a lot of people, but maybe it's the best option. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77070/new/ https://reviews.llvm.org/D77070 From cfe-commits at lists.llvm.org Mon Mar 30 12:30:19 2020 From: cfe-commits at lists.llvm.org (Artem Belevich via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 19:30:19 +0000 (UTC) Subject: [PATCH] D76987: Rename options --cuda-gpu-arch and --no-cuda-gpu-arch In-Reply-To: References: Message-ID: <4a348119e3be71e2e79a0528a34dc64f@localhost.localdomain> tra added a reviewer: echristo. tra accepted this revision. tra added a subscriber: echristo. tra added a comment. This revision is now accepted and ready to land. + @echristo who OK'ed the idea conditional on the actual patch. :-) LGTM overall. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76987/new/ https://reviews.llvm.org/D76987 From cfe-commits at lists.llvm.org Mon Mar 30 12:30:21 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 19:30:21 +0000 (UTC) Subject: [PATCH] D77056: RFC: [Sema][SVE] Allow non-member operators for SVE types In-Reply-To: References: Message-ID: <05c450c996e571dfac1b7f8676c32162@localhost.localdomain> efriedma added a comment. > One option would to be wait until there's at least one type that isSizelessBuiltinType but isn't an SVE type. Another would be to introduce it when a feature seems too SVE-specific Probably not a big deal either way, as long as we document the intent in the code. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77056/new/ https://reviews.llvm.org/D77056 From cfe-commits at lists.llvm.org Mon Mar 30 12:30:22 2020 From: cfe-commits at lists.llvm.org (Dmitry Polukhin via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 19:30:22 +0000 (UTC) Subject: [PATCH] D76594: [clang][AST] Support AST files larger than 512M In-Reply-To: References: Message-ID: <687aae72c06b35b623aacc00afc53b9c@localhost.localdomain> DmitryPolukhin marked an inline comment as done. DmitryPolukhin added inline comments. ================ Comment at: clang/include/clang/Serialization/ASTBitCodes.h:220 /// Source range/offset of a preprocessed entity. struct DeclOffset { + /// Raw source location. The unsigned i.e. 32-bit integer is enough for ---------------- sammccall wrote: > Is there one of these for every decl in the module? It seems like we're probably giving up a good fraction of the 4% increase for just using absolute 64 bit offsets everywhere :-( Is there still a significant gain from using section-relative elsewhere? > > If there are indeed lots of these, giving up 4 bytes to padding (in addition to the wide offset) seems unfortunate and because we memcpy the structs into the AST file seems like a sad reason :-) > Can we align this to 4 bytes instead? > (e.g. by splitting into two fields and encapsulating the few direct accesses, though there's probably a neater way) Yes, it seems that all referenced decls should have an entry in this table. 4% increase was counted on previous diff before I discovered DeclOffsets and TypeOffsets. This diff uses relative offsets for previous cases and increase is only 2 additional 64-bit integers per file. DeclOffsets are about 4.7% and TypeOffsets are about 2.5% of the whole file. With this diff both number will be 2x, splitting DeclOffset in two separate arrays could make the increase only 1.5x for DeclOffsets. If approach from this diff looks fine, I can split array of DeclOffset into 2 separate arrays. It could be a bit less efficient because of worse memory locality but will save some space. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76594/new/ https://reviews.llvm.org/D76594 From cfe-commits at lists.llvm.org Mon Mar 30 12:30:23 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 19:30:23 +0000 (UTC) Subject: [PATCH] D77054: [AArch64][SVE] Add SVE intrinsics for saturating add & subtract In-Reply-To: References: Message-ID: <3e0c5d47ecb89e77c173142f0b34e30a@localhost.localdomain> efriedma added a comment. I can understand why you might want the new intrinsics as a temporary measure, but I don't see the point of removing the already working support for llvm.sadd. etc. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77054/new/ https://reviews.llvm.org/D77054 From cfe-commits at lists.llvm.org Mon Mar 30 12:31:32 2020 From: cfe-commits at lists.llvm.org (Vince Bridgers via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 19:31:32 +0000 (UTC) Subject: [PATCH] D77012: [analyzer] Fix StdLibraryFunctionsChecker NotNull Constraint Check In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rGdefd95ef4517: [analyzer] Fix StdLibraryFunctionsChecker NotNull Constraint Check (authored by vabridgers, committed by einvbri <vince.a.bridgers at ericsson.com>). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77012/new/ https://reviews.llvm.org/D77012 Files: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp clang/test/Analysis/std-c-library-functions.c Index: clang/test/Analysis/std-c-library-functions.c =================================================================== --- clang/test/Analysis/std-c-library-functions.c +++ clang/test/Analysis/std-c-library-functions.c @@ -89,6 +89,14 @@ clang_analyzer_eval(z <= y); // expected-warning{{TRUE}} } +void test_fread_uninitialized(void) { + void *ptr; + size_t sz; + size_t nmem; + FILE *fp; + (void)fread(ptr, sz, nmem, fp); // expected-warning {{1st function call argument is an uninitialized value}} +} + ssize_t getline(char **, size_t *, FILE *); void test_getline(FILE *fp) { char *line = 0; Index: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -190,6 +190,9 @@ ProgramStateRef apply(ProgramStateRef State, const CallEvent &Call, const Summary &Summary) const override { SVal V = getArgSVal(Call, getArgNo()); + if (V.isUndef()) + return State; + DefinedOrUnknownSVal L = V.castAs(); if (!L.getAs()) return State; -------------- next part -------------- A non-text attachment was scrubbed... Name: D77012.253666.patch Type: text/x-patch Size: 1264 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 12:37:20 2020 From: cfe-commits at lists.llvm.org (Jonas Hahnfeld via cfe-commits) Date: Mon, 30 Mar 2020 12:37:20 -0700 (PDT) Subject: [clang] ced99a1 - Fix comment for CLANG_SYSTEMZ_DEFAULT_ARCH Message-ID: <5e824a70.1c69fb81.dbc6b.0a3a@mx.google.com> Author: Jonas Hahnfeld Date: 2020-03-30T21:36:18+02:00 New Revision: ced99a1a6368b117384935957e2329ec4ba7784b URL: https://github.com/llvm/llvm-project/commit/ced99a1a6368b117384935957e2329ec4ba7784b DIFF: https://github.com/llvm/llvm-project/commit/ced99a1a6368b117384935957e2329ec4ba7784b.diff LOG: Fix comment for CLANG_SYSTEMZ_DEFAULT_ARCH Also move up, next to the other *_DEFAULT_* configurations. Added: Modified: clang/include/clang/Config/config.h.cmake Removed: ################################################################################ diff --git a/clang/include/clang/Config/config.h.cmake b/clang/include/clang/Config/config.h.cmake index a0f8b6b1b0da..26e9d5c4eb4d 100644 --- a/clang/include/clang/Config/config.h.cmake +++ b/clang/include/clang/Config/config.h.cmake @@ -35,6 +35,9 @@ /* Default architecture for OpenMP offloading to Nvidia GPUs. */ #define CLANG_OPENMP_NVPTX_DEFAULT_ARCH "${CLANG_OPENMP_NVPTX_DEFAULT_ARCH}" +/* Default architecture for SystemZ. */ +#define CLANG_SYSTEMZ_DEFAULT_ARCH "${CLANG_SYSTEMZ_DEFAULT_ARCH}" + /* Multilib suffix for libdir. */ #define CLANG_LIBDIR_SUFFIX "${CLANG_LIBDIR_SUFFIX}" @@ -83,7 +86,4 @@ /* Spawn a new process clang.exe for the CC1 tool invocation, when necessary */ #cmakedefine01 CLANG_SPAWN_CC1 -/* Default to all compiler invocations for --sysroot=. */ -#define CLANG_SYSTEMZ_DEFAULT_ARCH "${CLANG_SYSTEMZ_DEFAULT_ARCH}" - #endif From cfe-commits at lists.llvm.org Mon Mar 30 13:04:30 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 20:04:30 +0000 (UTC) Subject: [PATCH] D77048: [Clang][CodeGen] Fixing mismatch between memory layout and const expressions for oversized bitfields In-Reply-To: References: Message-ID: <4c82fe452ebe46b152e62c1991d01929@localhost.localdomain> efriedma added inline comments. ================ Comment at: clang/lib/CodeGen/CGExprConstant.cpp:613 + + // Add padding bits in case of over-sized bit-field. + // "The first sizeof(T)*8 bits are used to hold the value of the bit-field, ---------------- The existing code in ConstantAggregateBuilder::add should skip over padding. I'm not sure what you're trying to accomplish by adding more code dealing with padding here. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77048/new/ https://reviews.llvm.org/D77048 From cfe-commits at lists.llvm.org Mon Mar 30 13:04:36 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 20:04:36 +0000 (UTC) Subject: [PATCH] D75903: [AArch64][CodeGen] Fixing stack alignment of HFA arguments on AArch64 PCS In-Reply-To: References: Message-ID: rnk added a comment. In D75903#1914715 , @ostannard wrote: > This means that `stk1` should be passed as a copy with alignment 16 bytes, putting it at `sp+16`. GCC does this, clang without this patch passes it at `sp+8`, and clang with this patch passes it at `sp+32`. MSVC puts it at `sp+8`: https://gcc.godbolt.org/z/aAku9j They allegedly follow this same document. Either way, we need to remain compatible. Given that neither GCC nor MSVC do things they way you are proposing, are you sure this is correct? What compiler does this change make us more compatible with? I don't believe there is an issue from the user's standpoint, since Clang copies the entire argument into an appropriately aligned alloca. If it is address-taken and stored to, there will not be any faults. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75903/new/ https://reviews.llvm.org/D75903 From cfe-commits at lists.llvm.org Mon Mar 30 13:37:19 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 20:37:19 +0000 (UTC) Subject: [PATCH] D77085: [clang-tidy] Added support for validating configuration options Message-ID: njames93 created this revision. njames93 added reviewers: aaron.ballman, alexfh, gribozavr2. Herald added subscribers: cfe-commits, xazax.hun. Herald added a project: clang. njames93 added a comment. njames93 added a project: clang-tools-extra. This pretty much nulls out (clang-tidy) Warn on invalid "case" configurations for readability-identifier-naming I have moved that into a follow up patch that can be submitted now if you'd like. Adds support for `ClangTidyCheck::OptionsView` to deteremine: - If an option is found in the configuration. - If an integer option read from configuration is parsable to an integer. - Parse and Serialize enum configuration options directly using a mapping from `llvm::StringRef` to `EnumType`. - If an integer or enum option isn't parseable but there is a default value it will issue a warning to stderr that the config value hasn't been used. - If an enum option isn't parsable it can provide a hint if the value was a typo. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77085 Files: clang-tools-extra/clang-tidy/ClangTidyCheck.cpp clang-tools-extra/clang-tidy/ClangTidyCheck.h clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77085.253679.patch Type: text/x-patch Size: 26756 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 13:37:22 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 20:37:22 +0000 (UTC) Subject: [PATCH] D76937: Fix infinite recursion in deferred diagnostic emitter In-Reply-To: References: Message-ID: yaxunl added a comment. In D76937#1950077 , @rjmccall wrote: > Can you explain what exactly the emission/semantic model is for variables? Normal code-generation absolutely triggers the emission of many variables lazily (e.g. internal-linkage globals, C++ inline variables); and any variable that's *not* being emitted lazily actually needs to be treated as a potential root into the delayed-diagnostic graph. Currently only in the following case a global variable can change the emission state of a function: int foobar3() { return 1; } #pragma omp declare target int (*C)() = &foobar3; #pragma omp end declare target The global variable needs to be in a omp declare target directive. Its initializer references a host function. This will cause the function emitted in device compilation. This is not transitive for variable declaration/references, e.g. the following case will not cause foobar3 to be emitted in device compilation, unless variable C itself is enclosed in omp declare target directive. int foobar3() { return 1; } int (*C)() = &foobar3; #pragma omp declare target int (*D)() = C; #pragma omp end declare target Since we logged all such variable declarations in DeclsToCheckForDeferredDiags, we only need to check variables decls in DeclsToCheckForDeferredDiags and do not need to check variable decls in DeclRefExpr. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76937/new/ https://reviews.llvm.org/D76937 From cfe-commits at lists.llvm.org Mon Mar 30 13:37:25 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 20:37:25 +0000 (UTC) Subject: [PATCH] D77085: [clang-tidy] Added support for validating configuration options In-Reply-To: References: Message-ID: <9f4f3a6ce6bb66fa92c312c6c0043e1f@localhost.localdomain> njames93 added a comment. This pretty much nulls out (clang-tidy) Warn on invalid "case" configurations for readability-identifier-naming I have moved that into a follow up patch that can be submitted now if you'd like. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77085/new/ https://reviews.llvm.org/D77085 From cfe-commits at lists.llvm.org Mon Mar 30 14:07:27 2020 From: cfe-commits at lists.llvm.org (Alexey Bataev via cfe-commits) Date: Mon, 30 Mar 2020 14:07:27 -0700 (PDT) Subject: [clang] a4f74f3 - [OPENMP50]Do not imply lvalue as base expression in array shaping Message-ID: <5e825f8f.1c69fb81.18ab9.f3c7@mx.google.com> Author: Alexey Bataev Date: 2020-03-30T17:07:08-04:00 New Revision: a4f74f377b7c42d38a230a19996e3a7fa5a328c7 URL: https://github.com/llvm/llvm-project/commit/a4f74f377b7c42d38a230a19996e3a7fa5a328c7 DIFF: https://github.com/llvm/llvm-project/commit/a4f74f377b7c42d38a230a19996e3a7fa5a328c7.diff LOG: [OPENMP50]Do not imply lvalue as base expression in array shaping expression. We should not assume that the base expression in the array shaping operation is an lvalue of some form, it may be an rvalue. Added: Modified: clang/lib/CodeGen/CGOpenMPRuntime.cpp clang/lib/Sema/SemaExpr.cpp clang/test/OpenMP/task_codegen.c Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 4b913607c1db..ae98433acb48 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -5364,14 +5364,12 @@ std::pair CGOpenMPRuntime::emitDependClause( continue; const Expr *E = Dependencies[I].second; const auto *OASE = dyn_cast(E); - LValue Addr; + llvm::Value *Addr; if (OASE) { - const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); - Addr = - CGF.EmitLoadOfPointerLValue(CGF.EmitLValue(Base).getAddress(CGF), - Base->getType()->castAs()); + const Expr *Base = OASE->getBase(); + Addr = CGF.EmitScalarExpr(Base); } else { - Addr = CGF.EmitLValue(E); + Addr = CGF.EmitLValue(E).getPointer(CGF); } llvm::Value *Size; QualType Ty = E->getType(); @@ -5390,8 +5388,7 @@ std::pair CGOpenMPRuntime::emitDependClause( CGF.EmitOMPArraySectionExpr(ASE, /*IsLowerBound=*/false); llvm::Value *UpAddr = CGF.Builder.CreateConstGEP1_32( UpAddrLVal.getPointer(CGF), /*Idx0=*/1); - llvm::Value *LowIntPtr = - CGF.Builder.CreatePtrToInt(Addr.getPointer(CGF), CGM.SizeTy); + llvm::Value *LowIntPtr = CGF.Builder.CreatePtrToInt(Addr, CGM.SizeTy); llvm::Value *UpIntPtr = CGF.Builder.CreatePtrToInt(UpAddr, CGM.SizeTy); Size = CGF.Builder.CreateNUWSub(UpIntPtr, LowIntPtr); } else { @@ -5410,9 +5407,8 @@ std::pair CGOpenMPRuntime::emitDependClause( // deps[i].base_addr = &; LValue BaseAddrLVal = CGF.EmitLValueForField( Base, *std::next(KmpDependInfoRD->field_begin(), BaseAddr)); - CGF.EmitStoreOfScalar( - CGF.Builder.CreatePtrToInt(Addr.getPointer(CGF), CGF.IntPtrTy), - BaseAddrLVal); + CGF.EmitStoreOfScalar(CGF.Builder.CreatePtrToInt(Addr, CGF.IntPtrTy), + BaseAddrLVal); // deps[i].len = sizeof(); LValue LenLVal = CGF.EmitLValueForField( Base, *std::next(KmpDependInfoRD->field_begin(), Len)); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 44f51f1a432d..1a18eab72527 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4804,6 +4804,9 @@ ExprResult Sema::ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, ArrayRef Brackets) { if (Base->getType()->isPlaceholderType()) { ExprResult Result = CheckPlaceholderExpr(Base); + if (Result.isInvalid()) + return ExprError(); + Result = DefaultLvalueConversion(Result.get()); if (Result.isInvalid()) return ExprError(); Base = Result.get(); diff --git a/clang/test/OpenMP/task_codegen.c b/clang/test/OpenMP/task_codegen.c index 9376c375d5a8..9e4b3b59d6d5 100644 --- a/clang/test/OpenMP/task_codegen.c +++ b/clang/test/OpenMP/task_codegen.c @@ -56,7 +56,6 @@ int main() { // CHECK: store i64 4, i64* [[SIZE_ADDR]], // CHECK: [[FLAGS_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA0]], i{{.+}} 0, i{{.+}} 2 // CHECK: store i8 1, i8* [[FLAGS_ADDR]], - // CHECK: [[B_ADDR:%.+]] = load i32*, i32** %{{.+}}, // CHECK: [[A:%.+]] = load i32, i32* [[A_ADDR]], // CHECK: [[A_CAST:%.+]] = sext i32 [[A]] to i64 // CHECK: [[SZ1:%.+]] = mul nuw i64 3, [[A_CAST]] @@ -65,7 +64,7 @@ int main() { // CHECK: [[SZ:%.+]] = mul nuw i64 [[SZ1]], [[A_CAST]] // CHECK: [[VLA1:%.+]] = getelementptr %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA]], i64 1 // CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA1]], i{{.+}} 0, i{{.+}} 0 - // CHECK: [[B_ADDR_CAST:%.+]] = ptrtoint i32* [[B_ADDR]] to i64 + // CHECK: [[B_ADDR_CAST:%.+]] = ptrtoint i32** %{{.+}} to i64 // CHECK: store i64 [[B_ADDR_CAST]], i64* [[BASE_ADDR]], // CHECK: [[SIZE_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[VLA1]], i{{.+}} 0, i{{.+}} 1 // CHECK: store i64 [[SZ]], i64* [[SIZE_ADDR]], @@ -85,7 +84,7 @@ int main() { // CHECK: call i32 @__kmpc_omp_task_with_deps(%struct.ident_t* @{{.+}}, i32 [[GTID]], i8* [[ALLOC]], i32 [[SIZE32]], i8* [[BC]], i32 0, i8* null) // CHECK: [[SV:%.+]] = load i8*, i8** [[SV_ADDR]], // CHECK: call void @llvm.stackrestore(i8* [[SV]]) -#pragma omp task depend(in: a, ([3][a][a])b) depend(depobj: d, x) detach(evt) +#pragma omp task depend(in: a, ([3][a][a])&b) depend(depobj: d, x) detach(evt) { #pragma omp taskgroup { From cfe-commits at lists.llvm.org Mon Mar 30 14:11:38 2020 From: cfe-commits at lists.llvm.org (Arnold Schwaighofer via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 21:11:38 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift In-Reply-To: References: Message-ID: <73c085bec31e36dc9b008f4b42ebd487@localhost.localdomain> aschwaighofer added a comment. > Can you explain the need for the callback? Are you expecting to use this for Swift-declared protocols by synthesizing an ObjC protocol declaration for them? I can see why you'd need a callback in that case. The objective C protocol references other protocols in its inherited list. Swift has an internal list that keeps track of those protocols references and makes sure to initialized them for the debugger and also makes sure that the underlying protocol structure is emitted. The call back is to keep this list in sync. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77077/new/ https://reviews.llvm.org/D77077 From cfe-commits at lists.llvm.org Mon Mar 30 14:11:39 2020 From: cfe-commits at lists.llvm.org (Dimitri John Ledkov via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 21:11:39 +0000 (UTC) Subject: [PATCH] D75914: systemz: allow configuring default CLANG_SYSTEMZ_ARCH In-Reply-To: References: Message-ID: xnox added a comment. Sorry for being too slow =) I like all the fixes done to move the define into a more natural config.h location, thank you. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75914/new/ https://reviews.llvm.org/D75914 From cfe-commits at lists.llvm.org Mon Mar 30 14:44:21 2020 From: cfe-commits at lists.llvm.org (Thomas Lively via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 21:44:21 +0000 (UTC) Subject: [PATCH] D76959: [WebAssembly] Import wasm_simd128.h from Emscripten In-Reply-To: References: Message-ID: <947bb0a562dd57fe34db3eba81926a7a@localhost.localdomain> tlively updated this revision to Diff 253703. tlively marked 3 inline comments as done. tlively added a comment. - Prefix identifiers with `__` - Use specific bit-widths where possible - Do not change semantics under -funsigned-char Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76959/new/ https://reviews.llvm.org/D76959 Files: clang/lib/Headers/CMakeLists.txt clang/lib/Headers/wasm_simd128.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D76959.253703.patch Type: text/x-patch Size: 48309 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 14:44:26 2020 From: cfe-commits at lists.llvm.org (Anna Thomas via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 21:44:26 +0000 (UTC) Subject: [PATCH] D76140: [InlineFunction] update attributes during inlining In-Reply-To: References: Message-ID: <1b020a82156ae62306e7d70612620afa@localhost.localdomain> anna updated this revision to Diff 253704. anna added a comment. addressed review comments. Added two test cases: deref value being different, inlined callee body better optimized compared to callee. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76140/new/ https://reviews.llvm.org/D76140 Files: clang/test/CodeGen/builtins-systemz-zvector.c clang/test/CodeGen/builtins-systemz-zvector2.c clang/test/CodeGen/movbe-builtins.c clang/test/CodeGen/rot-intrinsics.c llvm/lib/Transforms/Utils/InlineFunction.cpp llvm/test/Transforms/Inline/ret_attr_update.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D76140.253704.patch Type: text/x-patch Size: 15788 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 15:17:09 2020 From: cfe-commits at lists.llvm.org (Anna Thomas via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 22:17:09 +0000 (UTC) Subject: [PATCH] D76140: [InlineFunction] update attributes during inlining In-Reply-To: References: Message-ID: anna marked 3 inline comments as done. anna added inline comments. ================ Comment at: llvm/lib/Transforms/Utils/InlineFunction.cpp:1175 + continue; + // Sanity check that the cloned return instruction exists and is a return + // instruction itself. ---------------- anna wrote: > reames wrote: > > Ok, after staring at it a bit, I've convinced myself the code here is correct, just needlessly conservative. > > > > What you're doing is: > > If the callees return instruction and returned call both map to the same instructions once inlined, determine whether there's a possible exit between the inlined copy. > > > > What you could be doing: > > If the callee returns a call, check if *in the callee* there's a possible exit between call and return, then apply attribute to cloned call. > > > > The key difference is when the caller directly returns the result vs uses it locally. The result here is that your transform is much more narrow in applicability than it first appears. > yes, thanks for pointing it out. I realized it after our offline discussion :) > For now, I will add a FIXME testcase which showcases the difference in code and handle that testcase in a followon change. > The key difference is when the caller directly returns the result vs uses it locally. The result here is that your transform is much more narrow in applicability than it first appears. I tried multiple test cases to showcase the difference between the two ideas above but failed. Specifically, `simplifyInstruction` used during inlining the callee is not too great at optimizing the body. For example, see added testcase `test7`. I also tried the less restrictive version (check the safety of the optimization in the callee itself, and do the attribute update on the cloned instruction), but didn't see any testcases in clang that needed update. Of course, that doesn't mean anything :) ================ Comment at: llvm/test/Transforms/Inline/ret_attr_update.ll:112 + ret i8* %s +} ---------------- anna wrote: > reames wrote: > > There's a critical missing test case here: > > - Callee and caller have the same attributes w/different values (i.e. deref) > > > > And thinking through the code, I think there might be a bug here. It's not a serious one, but the if the callee specifies a larger deref than the caller, it looks like the the smaller value is being written over the larger. > > > > Actually, digging through the attribute code, I think I'm wrong about the bug. However, you should definitely write the test to confirm and document merging behaviour! > > > > If it does turn out I'm correct, I'm fine with this being addressed in a follow up patch provided that the test is added in this one and isn't a functional issue. > will check this. added test case and documented merge behaviour. No bug in code, since we use the already existing value on attribute. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76140/new/ https://reviews.llvm.org/D76140 From cfe-commits at lists.llvm.org Mon Mar 30 15:17:14 2020 From: cfe-commits at lists.llvm.org (Arnold Schwaighofer via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 22:17:14 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift In-Reply-To: References: Message-ID: <6caca50081dd4ad944a9655291ac7e8e@localhost.localdomain> aschwaighofer updated this revision to Diff 253712. aschwaighofer added a comment. - Change API name to emitObjCProtocolObject. - Make stuff compile on current ToT. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77077/new/ https://reviews.llvm.org/D77077 Files: clang/include/clang/CodeGen/CodeGenABITypes.h clang/lib/CodeGen/CGObjCGNU.cpp clang/lib/CodeGen/CGObjCMac.cpp clang/lib/CodeGen/CGObjCRuntime.cpp clang/lib/CodeGen/CGObjCRuntime.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D77077.253712.patch Type: text/x-patch Size: 17063 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 15:17:14 2020 From: cfe-commits at lists.llvm.org (Arnold Schwaighofer via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 22:17:14 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift In-Reply-To: References: Message-ID: aschwaighofer marked an inline comment as done. aschwaighofer added inline comments. ================ Comment at: clang/include/clang/CodeGen/CodeGenABITypes.h:148 + llvm::function_ref + createProtocolReference); } // end namespace CodeGen ---------------- rjmccall wrote: > I would call this `emitObjCProtocolObject` or something, and maybe say in the comment: > > > Get a pointer to a protocol object for the given declaration, emitting it if it hasn't already been emitted in this translation unit. Note that the ABI for emitting a protocol reference in code (e.g. for a `@protocol` expression) in most runtimes is not as simple as just materializing a pointer to this object. > > Can you explain the need for the callback? Are you expecting to use this for Swift-declared protocols by synthesizing an ObjC protocol declaration for them? I can see why you'd need a callback in that case. > Can you explain the need for the callback? Are you expecting to use this for Swift-declared protocols by synthesizing an ObjC protocol declaration for them? I can see why you'd need a callback in that case. The objective C protocol references other protocols in its inherited list. Swift has an internal list that keeps track of those protocols references and makes sure to initialized them for the debugger and also makes sure that the underlying protocol structure is emitted. The call back is to keep this list in sync. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77077/new/ https://reviews.llvm.org/D77077 From cfe-commits at lists.llvm.org Mon Mar 30 15:17:18 2020 From: cfe-commits at lists.llvm.org (Thomas Lively via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 22:17:18 +0000 (UTC) Subject: [PATCH] D76959: [WebAssembly] Import wasm_simd128.h from Emscripten In-Reply-To: References: Message-ID: <1a1fd2b882be4b30e663aedc9e7df64c@localhost.localdomain> tlively updated this revision to Diff 253713. tlively added a comment. - Use header guard macro instead of pragma Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76959/new/ https://reviews.llvm.org/D76959 Files: clang/lib/Headers/CMakeLists.txt clang/lib/Headers/wasm_simd128.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D76959.253713.patch Type: text/x-patch Size: 48377 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 15:17:19 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 22:17:19 +0000 (UTC) Subject: [PATCH] D77081: [MS] Mark vbase dtors ref'd when ref'ing dtor In-Reply-To: References: Message-ID: rnk updated this revision to Diff 253715. rnk added a comment. - add def data bit - add tests - fix test Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77081/new/ https://reviews.llvm.org/D77081 Files: clang/include/clang/AST/CXXRecordDeclDefinitionBits.def clang/include/clang/AST/DeclCXX.h clang/include/clang/Sema/Sema.h clang/lib/AST/DeclCXX.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaExpr.cpp clang/test/CXX/class.access/p4.cpp clang/test/CodeGenCXX/microsoft-abi-vbase-dtor.cpp clang/test/SemaCXX/ms-implicit-complete-dtor.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77081.253715.patch Type: text/x-patch Size: 11127 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 15:19:18 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 22:19:18 +0000 (UTC) Subject: [PATCH] D77081: [MS] Mark vbase dtors ref'd when ref'ing dtor In-Reply-To: References: Message-ID: rnk added a comment. PTAL, here's how I imagine this is supposed to look, but the definition data bit name could probably be improved. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77081/new/ https://reviews.llvm.org/D77081 From cfe-commits at lists.llvm.org Mon Mar 30 15:51:41 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 22:51:41 +0000 (UTC) Subject: [PATCH] D76389: [NewPM] Run the Speculative Execution Pass if the target has divergent branches In-Reply-To: References: Message-ID: <8c028a731d9d4d3282117e6294c04fb9@localhost.localdomain> arsenm added a comment. Commit message should say only if? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76389/new/ https://reviews.llvm.org/D76389 From cfe-commits at lists.llvm.org Mon Mar 30 15:51:45 2020 From: cfe-commits at lists.llvm.org (Artem Dergachev via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 22:51:45 +0000 (UTC) Subject: [PATCH] D74541: [Analyzer] Use note tags to track iterator increments and decrements In-Reply-To: References: Message-ID: <3866214f9ed5fe10b27cd0dd9f71ef90@localhost.localdomain> NoQ added inline comments. ================ Comment at: clang/test/Analysis/iterator-modelling.cpp:434 + //expected-note at -1 0-1{{Calling 'next}} + //expected-note at -2 0-1{{Passing the value 1 via 2nd parameter 'n'}} + //expected-note at Inputs/system-header-simulator-cxx.h:814 0-1{{Iterator 'it' incremented by 1}} ---------------- baloghadamsoftware wrote: > Strange, that we do not get this note for `prev`. Mmm, why `0-1`? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D74541/new/ https://reviews.llvm.org/D74541 From cfe-commits at lists.llvm.org Mon Mar 30 15:51:52 2020 From: cfe-commits at lists.llvm.org (Richard Smith - zygoloid via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 22:51:52 +0000 (UTC) Subject: [PATCH] D77081: [MS] Mark vbase dtors ref'd when ref'ing dtor In-Reply-To: References: Message-ID: <08a6df7358dfae7eb3738cb2661b78d4@localhost.localdomain> rsmith added inline comments. ================ Comment at: clang/include/clang/AST/DeclCXX.h:959-963 + /// Indicates if the complete destructor has been implicitly declared + /// yet. Only relevant in the Microsoft C++. + bool definedImplicitCompleteDestructor() const { + return data().DefinedImplicitCompleteDestructor; + } ---------------- "declared" in comment but "defined" in function name. Which is it? I wonder if perhaps the right answer is neither: if we had separate `Decl`s for the complete and base destructors, this would be tracked by the "used" bit on the complete object destructor. So perhaps `isCompleteDestructorUsed` and `setCompleteDestructorUsed` would make sense? (We could consider tracking this on the destructor instead of here, but I suppose tracking it here gives us the serialization and merging logic for free.) ================ Comment at: clang/include/clang/Sema/Sema.h:5562-5565 + /// Define an implicit complete constructor for classes with vbases in the MS + /// ABI. + void DefineImplicitCompleteDestructor(SourceLocation CurrentLocation, + CXXDestructorDecl *Dtor); ---------------- Following the prior comment, naming this `MarkCompleteDestructorUsed` might make sense. ================ Comment at: clang/lib/Sema/SemaExpr.cpp:16008-16013 + // In the MS ABI, the complete destructor is implicitly defined, + // even if the base destructor is user defined. + CXXRecordDecl *Parent = Destructor->getParent(); + if (Parent->getNumVBases() > 0 && + !Parent->definedImplicitCompleteDestructor()) + DefineImplicitCompleteDestructor(Loc, Destructor); ---------------- Can we avoid doing this when we know the call is to a base subobject destructor or uses virtual dispatch? Should we? (I mean I guess ideally we'd change this function to take a `GlobalDecl` instead of a `FunctionDecl*`, but that seems like a lot of work.) How does MSVC behave? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77081/new/ https://reviews.llvm.org/D77081 From cfe-commits at lists.llvm.org Mon Mar 30 16:24:20 2020 From: cfe-commits at lists.llvm.org (Leonard Chan via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 23:24:20 +0000 (UTC) Subject: [PATCH] D76389: [NewPM] Run the Speculative Execution Pass only if the target has divergent branches In-Reply-To: References: Message-ID: <6b8c687ef9d496601535cefe2e3cb8c4@localhost.localdomain> leonardchan added a comment. In D76389#1951135 , @arsenm wrote: > Commit message should say only if? Updated Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76389/new/ https://reviews.llvm.org/D76389 From cfe-commits at lists.llvm.org Mon Mar 30 16:24:24 2020 From: cfe-commits at lists.llvm.org (Thomas Lively via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 23:24:24 +0000 (UTC) Subject: [PATCH] D76959: [WebAssembly] Import wasm_simd128.h from Emscripten In-Reply-To: References: Message-ID: tlively added a comment. I believe all the feedback has now been addressed. ================ Comment at: clang/lib/Headers/wasm_simd128.h:30 +typedef long long __i64x2 __attribute__((__vector_size__(16), __aligned__(16))); +typedef unsigned long long __u64x2 + __attribute__((__vector_size__(16), __aligned__(16))); ---------------- sunfish wrote: > Since this file is already including , instead of `char`, `unsigned char`, `short`, `unsigned short`, etc., can these use `int8_t`, `uint8_t`, `int16_t`, `uint16_t`, and so on, for clarity? Also, this would avoid any possible behavior change under `-funsigned-char`. Unfortunately not :( This change gives errors like ``` error: cannot initialize a parameter of type '__attribute__((__vector_size__(16 * sizeof(char)))) char' (vector of 16 'char' values) with an rvalue of type '__i8x16' (vector of 16 'int8_t' values) return (v128_t)__builtin_wasm_abs_i8x16((__i8x16)a); ``` Even changing `char` to `signed char` doesn't work. I would change the builtins to use the better types, but the builtin definition system does not allow those more interesting types. This is especially annoying because `-funsigned-char` does indeed change the behavior of the comparison intrinsics. I will have to do extra work in those functions to make it work. ================ Comment at: clang/lib/Headers/wasm_simd128.h:40 +#define __REQUIRE_CONSTANT(e) \ + _Static_assert(__builtin_constant_p(e), "Expected constant") + ---------------- sunfish wrote: > In clang's xmmintrin.h, helper macros like these `__DEFAULT_FN_ATTRS` and `__REQUIRE_CONSTANT` are `#undef`ed at the end of the file. I can do that for `__DEFAULT_FN_ATTRS` but unfortunately not for `__REQUIRE_CONSTANT` because `__REQUIRE_CONSTANT` is present in the macro expansion of `wasm_i8x16_const` and friends. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76959/new/ https://reviews.llvm.org/D76959 From cfe-commits at lists.llvm.org Mon Mar 30 16:24:32 2020 From: cfe-commits at lists.llvm.org (Fangrui Song via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 23:24:32 +0000 (UTC) Subject: [PATCH] D73307: Unique Names for Functions with Internal Linkage In-Reply-To: References: Message-ID: <534b090248ae263a95f9b63d01690967@localhost.localdomain> MaskRay added a comment. In D73307#1942838 , @tmsriram wrote: > In D73307#1942805 , @MaskRay wrote: > > > In D73307#1932131 , @rnk wrote: > > > > > At a higher level, should this just be an IR pass that clang adds into the pipeline when the flag is set? It should be safe to rename internal functions and give private functions internal linkage. It would be less invasive to clang and have better separation of concerns. As written, this is based on the source filename on the module, which is accessible from IR. The only reason I can think of against this is that the debug info might refer to the function linkage name, but maybe that is calculated later during codegen. > > > > > > I second this suggestion. `clang/lib/CodeGen/BackendUtil.cpp` `EmitAssemblyHelper::EmitAssemblyWithNewPassManager` ModulePassManager may be a more appropriate place for this feature. There are examples from both sides: > > > @rnk getMangledNameImpl for example adds multi-versioning suffixes, "__regcall3_" and "__device_stub". Adding the hash is just so simple. Is a pass really needed? If so, I should parse "." suffixed Multi-versioining names and insert the hash in between as the demangling looks better? > > > > > > > - clang frontend: `#pragma redefine_extname` > > - middle end IR->IR: the old pass manager has a feature -frewrite-map-file, which does a similar thing but is implemented as an IR transformation. There may be some other interactions @rnk noticed. I am happy with either way. ================ Comment at: clang/test/CodeGen/unique-internal-linkage-names.cpp:5 +// RUN: %clang_cc1 -triple x86_64 -x c++ -S -emit-llvm -funique-internal-linkage-names -o - < %s | FileCheck %s --check-prefix=UNIQUE + +static int glob; ---------------- Might be worth adding a few other internal linkage names. * an object in an unnamed namespace * an extern "C" static function * a function-local static variable * `label: &&label` Hope @mtrofin and @davidxl can clarify what internal names may benefit AFDO and we can add such internal names specifically. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73307/new/ https://reviews.llvm.org/D73307 From cfe-commits at lists.llvm.org Mon Mar 30 16:24:33 2020 From: cfe-commits at lists.llvm.org (Amara Emerson via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 23:24:33 +0000 (UTC) Subject: [PATCH] D77103: Add a new -fglobal-isel option and make -fexperimental-isel an alias for it. Message-ID: aemerson created this revision. aemerson added reviewers: paquette, arsenm, qcolombet, bogner. aemerson added a project: LLVM. Herald added subscribers: cfe-commits, danielkiss, kristof.beyls, wdng. Herald added a project: clang. aemerson added a comment. Sorry, forgot to add cfe-commits to the original diff. Since GlobalISel is maturing and is already on at -O0 for AArch64, it's not completely "experimental". Create a more appropriate driver flag and make the older option an alias for it. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77103 Files: clang/include/clang/Basic/DiagnosticDriverKinds.td clang/include/clang/Basic/DiagnosticGroups.td clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Clang.cpp clang/test/Driver/global-isel.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77103.253729.patch Type: text/x-patch Size: 7630 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 16:24:33 2020 From: cfe-commits at lists.llvm.org (Amara Emerson via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 23:24:33 +0000 (UTC) Subject: [PATCH] D77103: Add a new -fglobal-isel option and make -fexperimental-isel an alias for it. In-Reply-To: References: Message-ID: <4d8b1d47ad0261f35bafe3a71b7f98fe@localhost.localdomain> aemerson added a comment. Sorry, forgot to add cfe-commits to the original diff. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77103/new/ https://reviews.llvm.org/D77103 From cfe-commits at lists.llvm.org Mon Mar 30 16:24:34 2020 From: cfe-commits at lists.llvm.org (Fangrui Song via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 23:24:34 +0000 (UTC) Subject: [PATCH] D73307: Unique Names for Functions with Internal Linkage In-Reply-To: References: Message-ID: <8f0ec5c409344f9ea74d6c92d77e3538@localhost.localdomain> MaskRay added inline comments. ================ Comment at: clang/lib/CodeGen/CodeGenModule.cpp:1165 const auto *ND = cast(GD.getDecl()); + std::string MangledName = getMangledNameImpl(*this, GD, ND); ---------------- Delete this unrelated cosmetic change. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73307/new/ https://reviews.llvm.org/D73307 From cfe-commits at lists.llvm.org Mon Mar 30 16:57:18 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 23:57:18 +0000 (UTC) Subject: [PATCH] D77081: [MS] Mark vbase dtors ref'd when ref'ing dtor In-Reply-To: References: Message-ID: <320267310c85cfc38dd955f75a4e04d9@localhost.localdomain> rnk marked 2 inline comments as done. rnk added a comment. Thanks for the feedback, I'm going to investigate if we can use the `used` destructor bit to do this. ================ Comment at: clang/include/clang/AST/DeclCXX.h:959-963 + /// Indicates if the complete destructor has been implicitly declared + /// yet. Only relevant in the Microsoft C++. + bool definedImplicitCompleteDestructor() const { + return data().DefinedImplicitCompleteDestructor; + } ---------------- rsmith wrote: > "declared" in comment but "defined" in function name. Which is it? > > I wonder if perhaps the right answer is neither: if we had separate `Decl`s for the complete and base destructors, this would be tracked by the "used" bit on the complete object destructor. So perhaps `isCompleteDestructorUsed` and `setCompleteDestructorUsed` would make sense? (We could consider tracking this on the destructor instead of here, but I suppose tracking it here gives us the serialization and merging logic for free.) Actually, can we just reuse the `used` bit on the destructor? I don't think there is any way for the user to "use" the base destructor without using the complete destructor. The only case I can think of that calls the base destructor (ignoring aliasing optimizations) is the complete destructor of a derived class. Such a class will also reference all the virtual bases of the current class, so the semantic checks we are doing here are redundant, not wrong. Calling a pseudo-destructor for example uses the complete destructor, I think. ================ Comment at: clang/lib/Sema/SemaExpr.cpp:16008-16013 + // In the MS ABI, the complete destructor is implicitly defined, + // even if the base destructor is user defined. + CXXRecordDecl *Parent = Destructor->getParent(); + if (Parent->getNumVBases() > 0 && + !Parent->definedImplicitCompleteDestructor()) + DefineImplicitCompleteDestructor(Loc, Destructor); ---------------- rsmith wrote: > Can we avoid doing this when we know the call is to a base subobject destructor or uses virtual dispatch? Should we? (I mean I guess ideally we'd change this function to take a `GlobalDecl` instead of a `FunctionDecl*`, but that seems like a lot of work.) > > How does MSVC behave? I think we can skip this if virtual dispatch is used, but I'm not sure what kinds of devirtualization might break my assumptions. For example, uncommenting `final` here causes MSVC to diagnose the error, but it otherwise it compiles: ``` struct NoDtor { ~NoDtor() = delete; }; struct DefaultedDtor : NoDtor { ~DefaultedDtor() = default; }; struct HasVBases /*final*/ : virtual DefaultedDtor { virtual ~HasVBases(); }; void deleteIt1(HasVBases *p) { delete p; } ``` If the NoDtor destructor is undeleted and the class is made final, then both deleting and complete dtors are emitted for HasVBases. Clang would need to mark DefaultedDtor referenced in this case. I think it's OK to "overdiagnose" in this case. It's not possible to emit a vtable here without diagnosing the error. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77081/new/ https://reviews.llvm.org/D77081 From cfe-commits at lists.llvm.org Mon Mar 30 16:57:19 2020 From: cfe-commits at lists.llvm.org (Dan Gohman via Phabricator via cfe-commits) Date: Mon, 30 Mar 2020 23:57:19 +0000 (UTC) Subject: [PATCH] D76959: [WebAssembly] Import wasm_simd128.h from Emscripten In-Reply-To: References: Message-ID: sunfish accepted this revision. sunfish added a comment. This revision is now accepted and ready to land. Cool, LGTM, with optional suggestion for signed char below: ================ Comment at: clang/lib/Headers/wasm_simd128.h:30 +typedef long long __i64x2 __attribute__((__vector_size__(16), __aligned__(16))); +typedef unsigned long long __u64x2 + __attribute__((__vector_size__(16), __aligned__(16))); ---------------- tlively wrote: > sunfish wrote: > > Since this file is already including , instead of `char`, `unsigned char`, `short`, `unsigned short`, etc., can these use `int8_t`, `uint8_t`, `int16_t`, `uint16_t`, and so on, for clarity? Also, this would avoid any possible behavior change under `-funsigned-char`. > Unfortunately not :( This change gives errors like > > ``` > error: cannot initialize a parameter of type '__attribute__((__vector_size__(16 * sizeof(char)))) char' (vector of 16 'char' values) with an rvalue of type '__i8x16' (vector of 16 'int8_t' values) > return (v128_t)__builtin_wasm_abs_i8x16((__i8x16)a); > ``` > > Even changing `char` to `signed char` doesn't work. I would change the builtins to use the better types, but the builtin definition system does not allow those more interesting types. > > This is especially annoying because `-funsigned-char` does indeed change the behavior of the comparison intrinsics. I will have to do extra work in those functions to make it work. Would changing the clang definitions of the builtins to use signed char (Sc) explicitly fix this, like: -TARGET_BUILTIN(__builtin_wasm_swizzle_v8x16, "V16cV16cV16c", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_swizzle_v8x16, "V16ScV16ScV16Sc", "nc", "unimplemented-simd128") and so on for all the wasm simd builtins? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76959/new/ https://reviews.llvm.org/D76959 From cfe-commits at lists.llvm.org Mon Mar 30 17:10:24 2020 From: cfe-commits at lists.llvm.org (Thomas Lively via cfe-commits) Date: Mon, 30 Mar 2020 17:10:24 -0700 (PDT) Subject: [clang] 5074776 - [WebAssembly] Import wasm_simd128.h from Emscripten Message-ID: <5e828a70.1c69fb81.8a1a3.221c@mx.google.com> Author: Thomas Lively Date: 2020-03-30T17:04:18-07:00 New Revision: 5074776de478a114ece3f82668aa1363b2f17c92 URL: https://github.com/llvm/llvm-project/commit/5074776de478a114ece3f82668aa1363b2f17c92 DIFF: https://github.com/llvm/llvm-project/commit/5074776de478a114ece3f82668aa1363b2f17c92.diff LOG: [WebAssembly] Import wasm_simd128.h from Emscripten Summary: As the WebAssembly SIMD proposal nears stabilization, there is desire to use it with toolchains other than Emscripten. Moving the intrinsics header to clang will make it available to WASI toolchains as well. Reviewers: aheejin, sunfish Subscribers: dschuff, mgorny, sbc100, jgravelle-google, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D76959 Added: clang/lib/Headers/wasm_simd128.h Modified: clang/lib/Headers/CMakeLists.txt Removed: ################################################################################ diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index 28d43cb7ed35..8124549bfc48 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -109,6 +109,7 @@ set(files vecintrin.h vpclmulqdqintrin.h waitpkgintrin.h + wasm_simd128.h wbnoinvdintrin.h wmmintrin.h __wmmintrin_aes.h diff --git a/clang/lib/Headers/wasm_simd128.h b/clang/lib/Headers/wasm_simd128.h new file mode 100644 index 000000000000..3b30ddbd527b --- /dev/null +++ b/clang/lib/Headers/wasm_simd128.h @@ -0,0 +1,1145 @@ +/*===---- wasm_simd128.h - WebAssembly portable SIMD intrinsics ------------=== + * + * 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 __WASM_SIMD128_H +#define __WASM_SIMD128_H + +#include +#include + +// User-facing type +typedef int32_t v128_t __attribute__((__vector_size__(16), __aligned__(16))); + +// Internal types determined by clang builtin definitions +typedef int32_t __v128_u __attribute__((__vector_size__(16), __aligned__(1))); +typedef char __i8x16 __attribute__((__vector_size__(16), __aligned__(16))); +typedef signed char __s8x16 + __attribute__((__vector_size__(16), __aligned__(16))); +typedef unsigned char __u8x16 + __attribute__((__vector_size__(16), __aligned__(16))); +typedef short __i16x8 __attribute__((__vector_size__(16), __aligned__(16))); +typedef unsigned short __u16x8 + __attribute__((__vector_size__(16), __aligned__(16))); +typedef int __i32x4 __attribute__((__vector_size__(16), __aligned__(16))); +typedef unsigned int __u32x4 + __attribute__((__vector_size__(16), __aligned__(16))); +typedef long long __i64x2 __attribute__((__vector_size__(16), __aligned__(16))); +typedef unsigned long long __u64x2 + __attribute__((__vector_size__(16), __aligned__(16))); +typedef float __f32x4 __attribute__((__vector_size__(16), __aligned__(16))); +typedef double __f64x2 __attribute__((__vector_size__(16), __aligned__(16))); + +#define __DEFAULT_FN_ATTRS \ + __attribute__((__always_inline__, __nodebug__, __target__("simd128"), \ + __min_vector_width__(128))) + +#define __REQUIRE_CONSTANT(e) \ + _Static_assert(__builtin_constant_p(e), "Expected constant") + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v128_load(const void *__mem) { + // UB-free unaligned access copied from xmmintrin.h + struct __wasm_v128_load_struct { + __v128_u __v; + } __attribute__((__packed__, __may_alias__)); + return ((const struct __wasm_v128_load_struct *)__mem)->__v; +} + +#ifdef __wasm_unimplemented_simd128__ + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_v8x16_load_splat(const void *__mem) { + struct __wasm_v8x16_load_splat_struct { + uint8_t __v; + } __attribute__((__packed__, __may_alias__)); + uint8_t __v = ((const struct __wasm_v8x16_load_splat_struct *)__mem)->__v; + return (v128_t)(__u8x16){__v, __v, __v, __v, __v, __v, __v, __v, + __v, __v, __v, __v, __v, __v, __v, __v}; +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_v16x8_load_splat(const void *__mem) { + struct __wasm_v16x8_load_splat_struct { + uint16_t __v; + } __attribute__((__packed__, __may_alias__)); + uint16_t __v = ((const struct __wasm_v16x8_load_splat_struct *)__mem)->__v; + return (v128_t)(__u16x8){__v, __v, __v, __v, __v, __v, __v, __v}; +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_v32x4_load_splat(const void *__mem) { + struct __wasm_v32x4_load_splat_struct { + uint32_t __v; + } __attribute__((__packed__, __may_alias__)); + uint32_t __v = ((const struct __wasm_v32x4_load_splat_struct *)__mem)->__v; + return (v128_t)(__u32x4){__v, __v, __v, __v}; +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_v64x2_load_splat(const void *__mem) { + struct __wasm_v64x2_load_splat_struct { + uint64_t __v; + } __attribute__((__packed__, __may_alias__)); + uint64_t __v = ((const struct __wasm_v64x2_load_splat_struct *)__mem)->__v; + return (v128_t)(__u64x2){__v, __v}; +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i16x8_load_8x8(const void *__mem) { + typedef int8_t __i8x8 __attribute__((__vector_size__(8), __aligned__(8))); + struct __wasm_i16x8_load_8x8_struct { + __i8x8 __v; + } __attribute__((__packed__, __may_alias__)); + __i8x8 __v = ((const struct __wasm_i16x8_load_8x8_struct *)__mem)->__v; + return (v128_t) __builtin_convertvector(__v, __i16x8); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_u16x8_load_8x8(const void *__mem) { + typedef uint8_t __u8x8 __attribute__((__vector_size__(8), __aligned__(8))); + struct __wasm_u16x8_load_8x8_struct { + __u8x8 __v; + } __attribute__((__packed__, __may_alias__)); + __u8x8 __v = ((const struct __wasm_u16x8_load_8x8_struct *)__mem)->__v; + return (v128_t) __builtin_convertvector(__v, __u16x8); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i32x4_load_16x4(const void *__mem) { + typedef int16_t __i16x4 __attribute__((__vector_size__(8), __aligned__(8))); + struct __wasm_i32x4_load_16x4_struct { + __i16x4 __v; + } __attribute__((__packed__, __may_alias__)); + __i16x4 __v = ((const struct __wasm_i32x4_load_16x4_struct *)__mem)->__v; + return (v128_t) __builtin_convertvector(__v, __i32x4); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_u32x4_load_16x4(const void *__mem) { + typedef uint16_t __u16x4 __attribute__((__vector_size__(8), __aligned__(8))); + struct __wasm_u32x4_load_16x4_struct { + __u16x4 __v; + } __attribute__((__packed__, __may_alias__)); + __u16x4 __v = ((const struct __wasm_u32x4_load_16x4_struct *)__mem)->__v; + return (v128_t) __builtin_convertvector(__v, __u32x4); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i64x2_load_32x2(const void *__mem) { + typedef int32_t __i32x2 __attribute__((__vector_size__(8), __aligned__(8))); + struct __wasm_i64x2_load_32x2_struct { + __i32x2 __v; + } __attribute__((__packed__, __may_alias__)); + __i32x2 __v = ((const struct __wasm_i64x2_load_32x2_struct *)__mem)->__v; + return (v128_t) __builtin_convertvector(__v, __i64x2); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_u64x2_load_32x2(const void *__mem) { + typedef uint32_t __u32x2 __attribute__((__vector_size__(8), __aligned__(8))); + struct __wasm_u64x2_load_32x2_struct { + __u32x2 __v; + } __attribute__((__packed__, __may_alias__)); + __u32x2 __v = ((const struct __wasm_u64x2_load_32x2_struct *)__mem)->__v; + return (v128_t) __builtin_convertvector(__v, __u64x2); +} + +#endif // __wasm_unimplemented_simd128__ + +static __inline__ void __DEFAULT_FN_ATTRS wasm_v128_store(void *__mem, + v128_t __a) { + // UB-free unaligned access copied from xmmintrin.h + struct __wasm_v128_store_struct { + __v128_u __v; + } __attribute__((__packed__, __may_alias__)); + ((struct __wasm_v128_store_struct *)__mem)->__v = __a; +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i8x16_make(int8_t __c0, int8_t __c1, int8_t __c2, int8_t __c3, int8_t __c4, + int8_t __c5, int8_t __c6, int8_t __c7, int8_t __c8, int8_t __c9, + int8_t __c10, int8_t __c11, int8_t __c12, int8_t __c13, + int8_t __c14, int8_t __c15) { + return (v128_t)(__i8x16){__c0, __c1, __c2, __c3, __c4, __c5, + __c6, __c7, __c8, __c9, __c10, __c11, + __c12, __c13, __c14, __c15}; +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i16x8_make(int16_t __c0, int16_t __c1, int16_t __c2, int16_t __c3, + int16_t __c4, int16_t __c5, int16_t __c6, int16_t __c7) { + return (v128_t)(__i16x8){__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7}; +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_make(int32_t __c0, + int32_t __c1, + int32_t __c2, + int32_t __c3) { + return (v128_t)(__i32x4){__c0, __c1, __c2, __c3}; +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_make(float __c0, + float __c1, + float __c2, + float __c3) { + return (v128_t)(__f32x4){__c0, __c1, __c2, __c3}; +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_make(int64_t __c0, + int64_t __c1) { + return (v128_t)(__i64x2){__c0, __c1}; +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_make(double __c0, + double __c1) { + return (v128_t)(__f64x2){__c0, __c1}; +} + +#define wasm_i8x16_const(__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7, __c8, \ + __c9, __c10, __c11, __c12, __c13, __c14, __c15) \ + __extension__({ \ + __REQUIRE_CONSTANT(__c0); \ + __REQUIRE_CONSTANT(__c1); \ + __REQUIRE_CONSTANT(__c2); \ + __REQUIRE_CONSTANT(__c3); \ + __REQUIRE_CONSTANT(__c4); \ + __REQUIRE_CONSTANT(__c5); \ + __REQUIRE_CONSTANT(__c6); \ + __REQUIRE_CONSTANT(__c7); \ + __REQUIRE_CONSTANT(__c8); \ + __REQUIRE_CONSTANT(__c9); \ + __REQUIRE_CONSTANT(__c10); \ + __REQUIRE_CONSTANT(__c11); \ + __REQUIRE_CONSTANT(__c12); \ + __REQUIRE_CONSTANT(__c13); \ + __REQUIRE_CONSTANT(__c14); \ + __REQUIRE_CONSTANT(__c15); \ + (v128_t)(__i8x16){__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7, \ + __c8, __c9, __c10, __c11, __c12, __c13, __c14, __c15}; \ + }) + +#define wasm_i16x8_const(__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7) \ + __extension__({ \ + __REQUIRE_CONSTANT(__c0); \ + __REQUIRE_CONSTANT(__c1); \ + __REQUIRE_CONSTANT(__c2); \ + __REQUIRE_CONSTANT(__c3); \ + __REQUIRE_CONSTANT(__c4); \ + __REQUIRE_CONSTANT(__c5); \ + __REQUIRE_CONSTANT(__c6); \ + __REQUIRE_CONSTANT(__c7); \ + (v128_t)(__i16x8){__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7}; \ + }) + +#define wasm_i32x4_const(__c0, __c1, __c2, __c3) \ + __extension__({ \ + __REQUIRE_CONSTANT(__c0); \ + __REQUIRE_CONSTANT(__c1); \ + __REQUIRE_CONSTANT(__c2); \ + __REQUIRE_CONSTANT(__c3); \ + (v128_t)(__i32x4){__c0, __c1, __c2, __c3}; \ + }) + +#define wasm_f32x4_const(__c0, __c1, __c2, __c3) \ + __extension__({ \ + __REQUIRE_CONSTANT(__c0); \ + __REQUIRE_CONSTANT(__c1); \ + __REQUIRE_CONSTANT(__c2); \ + __REQUIRE_CONSTANT(__c3); \ + (v128_t)(__f32x4){__c0, __c1, __c2, __c3}; \ + }) + +#define wasm_i64x2_const(__c0, __c1) \ + __extension__({ \ + __REQUIRE_CONSTANT(__c0); \ + __REQUIRE_CONSTANT(__c1); \ + (v128_t)(__i64x2){__c0, __c1}; \ + }) + +#define wasm_f64x2_const(__c0, __c1) \ + __extension__({ \ + __REQUIRE_CONSTANT(__c0); \ + __REQUIRE_CONSTANT(__c1); \ + (v128_t)(__f64x2){__c0, __c1}; \ + }) + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_splat(int8_t __a) { + return (v128_t)(__i8x16){__a, __a, __a, __a, __a, __a, __a, __a, + __a, __a, __a, __a, __a, __a, __a, __a}; +} + +#define wasm_i8x16_extract_lane(__a, __i) \ + (__builtin_wasm_extract_lane_s_i8x16((__i8x16)(__a), __i)) + +#define wasm_u8x16_extract_lane(__a, __i) \ + (__builtin_wasm_extract_lane_u_i8x16((__i8x16)(__a), __i)) + +#define wasm_i8x16_replace_lane(__a, __i, __b) \ + ((v128_t)__builtin_wasm_replace_lane_i8x16((__i8x16)(__a), __i, __b)) + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_splat(int16_t __a) { + return (v128_t)(__i16x8){__a, __a, __a, __a, __a, __a, __a, __a}; +} + +#define wasm_i16x8_extract_lane(__a, __i) \ + (__builtin_wasm_extract_lane_s_i16x8((__i16x8)(__a), __i)) + +#define wasm_u16x8_extract_lane(__a, __i) \ + (__builtin_wasm_extract_lane_u_i16x8((__i16x8)(__a), __i)) + +#define wasm_i16x8_replace_lane(__a, __i, __b) \ + ((v128_t)__builtin_wasm_replace_lane_i16x8((__i16x8)(__a), __i, __b)) + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_splat(int32_t __a) { + return (v128_t)(__i32x4){__a, __a, __a, __a}; +} + +#define wasm_i32x4_extract_lane(__a, __i) \ + (__builtin_wasm_extract_lane_i32x4((__i32x4)(__a), __i)) + +#define wasm_i32x4_replace_lane(__a, __i, __b) \ + ((v128_t)__builtin_wasm_replace_lane_i32x4((__i32x4)(__a), __i, __b)) + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_splat(int64_t __a) { + return (v128_t)(__i64x2){__a, __a}; +} + +#define wasm_i64x2_extract_lane(__a, __i) \ + (__builtin_wasm_extract_lane_i64x2((__i64x2)(__a), __i)) + +#define wasm_i64x2_replace_lane(__a, __i, __b) \ + ((v128_t)__builtin_wasm_replace_lane_i64x2((__i64x2)(__a), __i, __b)) + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_splat(float __a) { + return (v128_t)(__f32x4){__a, __a, __a, __a}; +} + +#define wasm_f32x4_extract_lane(__a, __i) \ + (__builtin_wasm_extract_lane_f32x4((__f32x4)(__a), __i)) + +#define wasm_f32x4_replace_lane(__a, __i, __b) \ + ((v128_t)__builtin_wasm_replace_lane_f32x4((__f32x4)(__a), __i, __b)) + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_splat(double __a) { + return (v128_t)(__f64x2){__a, __a}; +} + +#define wasm_f64x2_extract_lane(__a, __i) \ + (__builtin_wasm_extract_lane_f64x2((__f64x2)(__a), __i)) + +#define wasm_f64x2_replace_lane(__a, __i, __b) \ + ((v128_t)__builtin_wasm_replace_lane_f64x2((__f64x2)(__a), __i, __b)) + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_eq(v128_t __a, + v128_t __b) { + return (v128_t)((__s8x16)__a == (__s8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_ne(v128_t __a, + v128_t __b) { + return (v128_t)((__s8x16)__a != (__s8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_lt(v128_t __a, + v128_t __b) { + return (v128_t)((__s8x16)__a < (__s8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u8x16_lt(v128_t __a, + v128_t __b) { + return (v128_t)((__u8x16)__a < (__u8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_gt(v128_t __a, + v128_t __b) { + return (v128_t)((__s8x16)__a > (__s8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u8x16_gt(v128_t __a, + v128_t __b) { + return (v128_t)((__u8x16)__a > (__u8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_le(v128_t __a, + v128_t __b) { + return (v128_t)((__s8x16)__a <= (__s8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u8x16_le(v128_t __a, + v128_t __b) { + return (v128_t)((__u8x16)__a <= (__u8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_ge(v128_t __a, + v128_t __b) { + return (v128_t)((__s8x16)__a >= (__s8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u8x16_ge(v128_t __a, + v128_t __b) { + return (v128_t)((__u8x16)__a >= (__u8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_eq(v128_t __a, + v128_t __b) { + return (v128_t)((__i16x8)__a == (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_ne(v128_t __a, + v128_t __b) { + return (v128_t)((__u16x8)__a != (__u16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_lt(v128_t __a, + v128_t __b) { + return (v128_t)((__i16x8)__a < (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u16x8_lt(v128_t __a, + v128_t __b) { + return (v128_t)((__u16x8)__a < (__u16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_gt(v128_t __a, + v128_t __b) { + return (v128_t)((__i16x8)__a > (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u16x8_gt(v128_t __a, + v128_t __b) { + return (v128_t)((__u16x8)__a > (__u16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_le(v128_t __a, + v128_t __b) { + return (v128_t)((__i16x8)__a <= (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u16x8_le(v128_t __a, + v128_t __b) { + return (v128_t)((__u16x8)__a <= (__u16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_ge(v128_t __a, + v128_t __b) { + return (v128_t)((__i16x8)__a >= (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u16x8_ge(v128_t __a, + v128_t __b) { + return (v128_t)((__u16x8)__a >= (__u16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_eq(v128_t __a, + v128_t __b) { + return (v128_t)((__i32x4)__a == (__i32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_ne(v128_t __a, + v128_t __b) { + return (v128_t)((__i32x4)__a != (__i32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_lt(v128_t __a, + v128_t __b) { + return (v128_t)((__i32x4)__a < (__i32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u32x4_lt(v128_t __a, + v128_t __b) { + return (v128_t)((__u32x4)__a < (__u32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_gt(v128_t __a, + v128_t __b) { + return (v128_t)((__i32x4)__a > (__i32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u32x4_gt(v128_t __a, + v128_t __b) { + return (v128_t)((__u32x4)__a > (__u32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_le(v128_t __a, + v128_t __b) { + return (v128_t)((__i32x4)__a <= (__i32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u32x4_le(v128_t __a, + v128_t __b) { + return (v128_t)((__u32x4)__a <= (__u32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_ge(v128_t __a, + v128_t __b) { + return (v128_t)((__i32x4)__a >= (__i32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u32x4_ge(v128_t __a, + v128_t __b) { + return (v128_t)((__u32x4)__a >= (__u32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_eq(v128_t __a, + v128_t __b) { + return (v128_t)((__f32x4)__a == (__f32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_ne(v128_t __a, + v128_t __b) { + return (v128_t)((__f32x4)__a != (__f32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_lt(v128_t __a, + v128_t __b) { + return (v128_t)((__f32x4)__a < (__f32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_gt(v128_t __a, + v128_t __b) { + return (v128_t)((__f32x4)__a > (__f32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_le(v128_t __a, + v128_t __b) { + return (v128_t)((__f32x4)__a <= (__f32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_ge(v128_t __a, + v128_t __b) { + return (v128_t)((__f32x4)__a >= (__f32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_eq(v128_t __a, + v128_t __b) { + return (v128_t)((__f64x2)__a == (__f64x2)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_ne(v128_t __a, + v128_t __b) { + return (v128_t)((__f64x2)__a != (__f64x2)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_lt(v128_t __a, + v128_t __b) { + return (v128_t)((__f64x2)__a < (__f64x2)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_gt(v128_t __a, + v128_t __b) { + return (v128_t)((__f64x2)__a > (__f64x2)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_le(v128_t __a, + v128_t __b) { + return (v128_t)((__f64x2)__a <= (__f64x2)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_ge(v128_t __a, + v128_t __b) { + return (v128_t)((__f64x2)__a >= (__f64x2)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v128_not(v128_t __a) { + return ~__a; +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v128_and(v128_t __a, + v128_t __b) { + return __a & __b; +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v128_or(v128_t __a, + v128_t __b) { + return __a | __b; +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v128_xor(v128_t __a, + v128_t __b) { + return __a ^ __b; +} + +#ifdef __wasm_unimplemented_simd128__ + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v128_andnot(v128_t __a, + v128_t __b) { + return __a & ~__b; +} + +#endif // __wasm_unimplemented_simd128__ + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v128_bitselect(v128_t __a, + v128_t __b, + v128_t __mask) { + return (v128_t)__builtin_wasm_bitselect((__i32x4)__a, (__i32x4)__b, + (__i32x4)__mask); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_abs(v128_t __a) { + return (v128_t)__builtin_wasm_abs_i8x16((__i8x16)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_neg(v128_t __a) { + return (v128_t)(-(__u8x16)__a); +} + +static __inline__ bool __DEFAULT_FN_ATTRS wasm_i8x16_any_true(v128_t __a) { + return __builtin_wasm_any_true_i8x16((__i8x16)__a); +} + +static __inline__ bool __DEFAULT_FN_ATTRS wasm_i8x16_all_true(v128_t __a) { + return __builtin_wasm_all_true_i8x16((__i8x16)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_shl(v128_t __a, + int32_t __b) { + return (v128_t)((__i8x16)__a << __b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_shr(v128_t __a, + int32_t __b) { + return (v128_t)((__s8x16)__a >> __b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u8x16_shr(v128_t __a, + int32_t __b) { + return (v128_t)((__u8x16)__a >> __b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_add(v128_t __a, + v128_t __b) { + return (v128_t)((__u8x16)__a + (__u8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i8x16_add_saturate(v128_t __a, v128_t __b) { + return (v128_t)__builtin_wasm_add_saturate_s_i8x16((__i8x16)__a, + (__i8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_u8x16_add_saturate(v128_t __a, v128_t __b) { + return (v128_t)__builtin_wasm_add_saturate_u_i8x16((__i8x16)__a, + (__i8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_sub(v128_t __a, + v128_t __b) { + return (v128_t)((__u8x16)__a - (__u8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i8x16_sub_saturate(v128_t __a, v128_t __b) { + return (v128_t)__builtin_wasm_sub_saturate_s_i8x16((__i8x16)__a, + (__i8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_u8x16_sub_saturate(v128_t __a, v128_t __b) { + return (v128_t)__builtin_wasm_sub_saturate_u_i8x16((__i8x16)__a, + (__i8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_mul(v128_t __a, + v128_t __b) { + return (v128_t)((__u8x16)__a * (__u8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_min_s(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_min_s_i8x16((__i8x16)__a, (__i8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_min_u(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_min_u_i8x16((__i8x16)__a, (__i8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_max_s(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_max_s_i8x16((__i8x16)__a, (__i8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_max_u(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_max_u_i8x16((__i8x16)__a, (__i8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_avgr_u(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_avgr_u_i8x16((__i8x16)__a, (__i8x16)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_abs(v128_t __a) { + return (v128_t)__builtin_wasm_abs_i16x8((__i16x8)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_neg(v128_t __a) { + return (v128_t)(-(__u16x8)__a); +} + +static __inline__ bool __DEFAULT_FN_ATTRS wasm_i16x8_any_true(v128_t __a) { + return __builtin_wasm_any_true_i16x8((__i16x8)__a); +} + +static __inline__ bool __DEFAULT_FN_ATTRS wasm_i16x8_all_true(v128_t __a) { + return __builtin_wasm_all_true_i16x8((__i16x8)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_shl(v128_t __a, + int32_t __b) { + return (v128_t)((__i16x8)__a << __b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_shr(v128_t __a, + int32_t __b) { + return (v128_t)((__i16x8)__a >> __b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u16x8_shr(v128_t __a, + int32_t __b) { + return (v128_t)((__u16x8)__a >> __b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_add(v128_t __a, + v128_t __b) { + return (v128_t)((__u16x8)__a + (__u16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i16x8_add_saturate(v128_t __a, v128_t __b) { + return (v128_t)__builtin_wasm_add_saturate_s_i16x8((__i16x8)__a, + (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_u16x8_add_saturate(v128_t __a, v128_t __b) { + return (v128_t)__builtin_wasm_add_saturate_u_i16x8((__i16x8)__a, + (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_sub(v128_t __a, + v128_t __b) { + return (v128_t)((__i16x8)__a - (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i16x8_sub_saturate(v128_t __a, v128_t __b) { + return (v128_t)__builtin_wasm_sub_saturate_s_i16x8((__i16x8)__a, + (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_u16x8_sub_saturate(v128_t __a, v128_t __b) { + return (v128_t)__builtin_wasm_sub_saturate_u_i16x8((__i16x8)__a, + (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_mul(v128_t __a, + v128_t __b) { + return (v128_t)((__u16x8)__a * (__u16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_min_s(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_min_s_i16x8((__i16x8)__a, (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_min_u(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_min_u_i16x8((__i16x8)__a, (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_max_s(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_max_s_i16x8((__i16x8)__a, (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_max_u(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_max_u_i16x8((__i16x8)__a, (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_avgr_u(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_avgr_u_i16x8((__i16x8)__a, (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_abs(v128_t __a) { + return (v128_t)__builtin_wasm_abs_i32x4((__i32x4)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_neg(v128_t __a) { + return (v128_t)(-(__u32x4)__a); +} + +static __inline__ bool __DEFAULT_FN_ATTRS wasm_i32x4_any_true(v128_t __a) { + return __builtin_wasm_any_true_i32x4((__i32x4)__a); +} + +static __inline__ bool __DEFAULT_FN_ATTRS wasm_i32x4_all_true(v128_t __a) { + return __builtin_wasm_all_true_i32x4((__i32x4)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_shl(v128_t __a, + int32_t __b) { + return (v128_t)((__i32x4)__a << __b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_shr(v128_t __a, + int32_t __b) { + return (v128_t)((__i32x4)__a >> __b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u32x4_shr(v128_t __a, + int32_t __b) { + return (v128_t)((__u32x4)__a >> __b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_add(v128_t __a, + v128_t __b) { + return (v128_t)((__u32x4)__a + (__u32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_sub(v128_t __a, + v128_t __b) { + return (v128_t)((__u32x4)__a - (__u32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_mul(v128_t __a, + v128_t __b) { + return (v128_t)((__u32x4)__a * (__u32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_min_s(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_min_s_i32x4((__i32x4)__a, (__i32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_min_u(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_min_u_i32x4((__i32x4)__a, (__i32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_max_s(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_max_s_i32x4((__i32x4)__a, (__i32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_max_u(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_max_u_i32x4((__i32x4)__a, (__i32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_neg(v128_t __a) { + return (v128_t)(-(__u64x2)__a); +} + +#ifdef __wasm_unimplemented_simd128__ + +static __inline__ bool __DEFAULT_FN_ATTRS wasm_i64x2_any_true(v128_t __a) { + return __builtin_wasm_any_true_i64x2((__i64x2)__a); +} + +static __inline__ bool __DEFAULT_FN_ATTRS wasm_i64x2_all_true(v128_t __a) { + return __builtin_wasm_all_true_i64x2((__i64x2)__a); +} + +#endif // __wasm_unimplemented_simd128__ + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_shl(v128_t __a, + int32_t __b) { + return (v128_t)((__i64x2)__a << (int64_t)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_shr(v128_t __a, + int32_t __b) { + return (v128_t)((__i64x2)__a >> (int64_t)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u64x2_shr(v128_t __a, + int32_t __b) { + return (v128_t)((__u64x2)__a >> (int64_t)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_add(v128_t __a, + v128_t __b) { + return (v128_t)((__u64x2)__a + (__u64x2)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_sub(v128_t __a, + v128_t __b) { + return (v128_t)((__u64x2)__a - (__u64x2)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_abs(v128_t __a) { + return (v128_t)__builtin_wasm_abs_f32x4((__f32x4)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_neg(v128_t __a) { + return (v128_t)(-(__f32x4)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_sqrt(v128_t __a) { + return (v128_t)__builtin_wasm_sqrt_f32x4((__f32x4)__a); +} + +#ifdef __wasm_unimplemented_simd128__ + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_qfma(v128_t __a, + v128_t __b, + v128_t __c) { + return (v128_t)__builtin_wasm_qfma_f32x4((__f32x4)__a, (__f32x4)__b, + (__f32x4)__c); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_qfms(v128_t __a, + v128_t __b, + v128_t __c) { + return (v128_t)__builtin_wasm_qfms_f32x4((__f32x4)__a, (__f32x4)__b, + (__f32x4)__c); +} + +#endif // __wasm_unimplemented_simd128__ + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_add(v128_t __a, + v128_t __b) { + return (v128_t)((__f32x4)__a + (__f32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_sub(v128_t __a, + v128_t __b) { + return (v128_t)((__f32x4)__a - (__f32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_mul(v128_t __a, + v128_t __b) { + return (v128_t)((__f32x4)__a * (__f32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_div(v128_t __a, + v128_t __b) { + return (v128_t)((__f32x4)__a / (__f32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_min(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_min_f32x4((__f32x4)__a, (__f32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_max(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_max_f32x4((__f32x4)__a, (__f32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_abs(v128_t __a) { + return (v128_t)__builtin_wasm_abs_f64x2((__f64x2)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_neg(v128_t __a) { + return (v128_t)(-(__f64x2)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_sqrt(v128_t __a) { + return (v128_t)__builtin_wasm_sqrt_f64x2((__f64x2)__a); +} + +#ifdef __wasm_unimplemented_simd128__ + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_qfma(v128_t __a, + v128_t __b, + v128_t __c) { + return (v128_t)__builtin_wasm_qfma_f64x2((__f64x2)__a, (__f64x2)__b, + (__f64x2)__c); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_qfms(v128_t __a, + v128_t __b, + v128_t __c) { + return (v128_t)__builtin_wasm_qfms_f64x2((__f64x2)__a, (__f64x2)__b, + (__f64x2)__c); +} + +#endif // __wasm_unimplemented_simd128__ + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_add(v128_t __a, + v128_t __b) { + return (v128_t)((__f64x2)__a + (__f64x2)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_sub(v128_t __a, + v128_t __b) { + return (v128_t)((__f64x2)__a - (__f64x2)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_mul(v128_t __a, + v128_t __b) { + return (v128_t)((__f64x2)__a * (__f64x2)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_div(v128_t __a, + v128_t __b) { + return (v128_t)((__f64x2)__a / (__f64x2)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_min(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_min_f64x2((__f64x2)__a, (__f64x2)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_max(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_max_f64x2((__f64x2)__a, (__f64x2)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i32x4_trunc_saturate_f32x4(v128_t __a) { + return (v128_t)__builtin_wasm_trunc_saturate_s_i32x4_f32x4((__f32x4)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_u32x4_trunc_saturate_f32x4(v128_t __a) { + return (v128_t)__builtin_wasm_trunc_saturate_u_i32x4_f32x4((__f32x4)__a); +} + +#ifdef __wasm_unimplemented_simd128__ + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i64x2_trunc_saturate_f64x2(v128_t __a) { + return (v128_t)__builtin_wasm_trunc_saturate_s_i64x2_f64x2((__f64x2)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_u64x2_trunc_saturate_f64x2(v128_t __a) { + return (v128_t)__builtin_wasm_trunc_saturate_s_i64x2_f64x2((__f64x2)__a); +} + +#endif // __wasm_unimplemented_simd128__ + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_f32x4_convert_i32x4(v128_t __a) { + return (v128_t) __builtin_convertvector((__i32x4)__a, __f32x4); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_f32x4_convert_u32x4(v128_t __a) { + return (v128_t) __builtin_convertvector((__u32x4)__a, __f32x4); +} + +#ifdef __wasm_unimplemented_simd128__ + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_f64x2_convert_i64x2(v128_t __a) { + return (v128_t) __builtin_convertvector((__i64x2)__a, __f64x2); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_f64x2_convert_u64x2(v128_t __a) { + return (v128_t) __builtin_convertvector((__u64x2)__a, __f64x2); +} + +#endif // __wasm_unimplemented_simd128__ + +#define wasm_v8x16_shuffle(__a, __b, __c0, __c1, __c2, __c3, __c4, __c5, __c6, \ + __c7, __c8, __c9, __c10, __c11, __c12, __c13, \ + __c14, __c15) \ + ((v128_t)(__builtin_shufflevector( \ + (__u8x16)(__a), (__u8x16)(__b), __c0, __c1, __c2, __c3, __c4, __c5, \ + __c6, __c7, __c8, __c9, __c10, __c11, __c12, __c13, __c14, __c15))) + +#define wasm_v16x8_shuffle(__a, __b, __c0, __c1, __c2, __c3, __c4, __c5, __c6, \ + __c7) \ + ((v128_t)(__builtin_shufflevector((__u16x8)(__a), (__u16x8)(__b), __c0, \ + __c1, __c2, __c3, __c4, __c5, __c6, \ + __c7))) + +#define wasm_v32x4_shuffle(__a, __b, __c0, __c1, __c2, __c3) \ + ((v128_t)(__builtin_shufflevector((__u32x4)(__a), (__u32x4)(__b), __c0, \ + __c1, __c2, __c3))) + +#define wasm_v64x2_shuffle(__a, __b, __c0, __c1) \ + ((v128_t)( \ + __builtin_shufflevector((__u64x2)(__a), (__u64x2)(__b), __c0, __c1))) + +#ifdef __wasm_unimplemented_simd128__ + +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v8x16_swizzle(v128_t __a, + v128_t __b) { + return (v128_t)__builtin_wasm_swizzle_v8x16((__i8x16)__a, (__i8x16)__b); +} + +#endif // __wasm_unimplemented_simd128__ + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i8x16_narrow_i16x8(v128_t __a, v128_t __b) { + return (v128_t)__builtin_wasm_narrow_s_i8x16_i16x8((__i16x8)__a, + (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_u8x16_narrow_i16x8(v128_t __a, v128_t __b) { + return (v128_t)__builtin_wasm_narrow_u_i8x16_i16x8((__i16x8)__a, + (__i16x8)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i16x8_narrow_i32x4(v128_t __a, v128_t __b) { + return (v128_t)__builtin_wasm_narrow_s_i16x8_i32x4((__i32x4)__a, + (__i32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_u16x8_narrow_i32x4(v128_t __a, v128_t __b) { + return (v128_t)__builtin_wasm_narrow_u_i16x8_i32x4((__i32x4)__a, + (__i32x4)__b); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i16x8_widen_low_i8x16(v128_t __a) { + return (v128_t)__builtin_wasm_widen_low_s_i16x8_i8x16((__i8x16)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i16x8_widen_high_i8x16(v128_t __a) { + return (v128_t)__builtin_wasm_widen_high_s_i16x8_i8x16((__i8x16)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i16x8_widen_low_u8x16(v128_t __a) { + return (v128_t)__builtin_wasm_widen_low_u_i16x8_i8x16((__i8x16)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i16x8_widen_high_u8x16(v128_t __a) { + return (v128_t)__builtin_wasm_widen_high_u_i16x8_i8x16((__i8x16)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i32x4_widen_low_i16x8(v128_t __a) { + return (v128_t)__builtin_wasm_widen_low_s_i32x4_i16x8((__i16x8)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i32x4_widen_high_i16x8(v128_t __a) { + return (v128_t)__builtin_wasm_widen_high_s_i32x4_i16x8((__i16x8)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i32x4_widen_low_u16x8(v128_t __a) { + return (v128_t)__builtin_wasm_widen_low_u_i32x4_i16x8((__i16x8)__a); +} + +static __inline__ v128_t __DEFAULT_FN_ATTRS +wasm_i32x4_widen_high_u16x8(v128_t __a) { + return (v128_t)__builtin_wasm_widen_high_u_i32x4_i16x8((__i16x8)__a); +} + +// Undefine helper macros +#undef __DEFAULT_FN_ATTRS + +#endif // __WASM_SIMD128_H From cfe-commits at lists.llvm.org Mon Mar 30 17:21:54 2020 From: cfe-commits at lists.llvm.org (Richard Smith via cfe-commits) Date: Mon, 30 Mar 2020 17:21:54 -0700 (PDT) Subject: [clang] 3308732 - Fix crash if base specifier parsing hits an invalid type annotation. Message-ID: <5e828d22.1c69fb81.a104a.1609@mx.google.com> Author: Richard Smith Date: 2020-03-30T17:21:40-07:00 New Revision: 330873230071ffc2aebc0fe74db55e7a530c2f1b URL: https://github.com/llvm/llvm-project/commit/330873230071ffc2aebc0fe74db55e7a530c2f1b DIFF: https://github.com/llvm/llvm-project/commit/330873230071ffc2aebc0fe74db55e7a530c2f1b.diff LOG: Fix crash if base specifier parsing hits an invalid type annotation. Also change type annotation representation from ParsedType to TypeResult to make it clearer to consumers that they can represent invalid types. Added: Modified: clang/include/clang/Parse/Parser.h clang/include/clang/Sema/DeclSpec.h clang/lib/Parse/ParseDecl.cpp clang/lib/Parse/ParseDeclCXX.cpp clang/lib/Parse/ParseExpr.cpp clang/lib/Parse/ParseExprCXX.cpp clang/lib/Parse/ParseObjc.cpp clang/lib/Parse/ParseTemplate.cpp clang/lib/Parse/Parser.cpp clang/test/Parser/cxx-class.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index c64a01b73a4a..290da0006116 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -763,13 +763,17 @@ class Parser : public CodeCompletionHandler { } /// getTypeAnnotation - Read a parsed type out of an annotation token. - static ParsedType getTypeAnnotation(const Token &Tok) { + static TypeResult getTypeAnnotation(const Token &Tok) { + if (!Tok.getAnnotationValue()) + return TypeError(); return ParsedType::getFromOpaquePtr(Tok.getAnnotationValue()); } private: - static void setTypeAnnotation(Token &Tok, ParsedType T) { - Tok.setAnnotationValue(T.getAsOpaquePtr()); + static void setTypeAnnotation(Token &Tok, TypeResult T) { + assert((T.isInvalid() || T.get()) && + "produced a valid-but-null type annotation?"); + Tok.setAnnotationValue(T.isInvalid() ? nullptr : T.get().getAsOpaquePtr()); } static NamedDecl *getNonTypeAnnotation(const Token &Tok) { diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index 5a6bedcd6f59..78010b7bb46e 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -667,6 +667,13 @@ class DeclSpec { bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, ParsedType Rep, const PrintingPolicy &Policy); + bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, + unsigned &DiagID, TypeResult Rep, + const PrintingPolicy &Policy) { + if (Rep.isInvalid()) + return SetTypeSpecError(); + return SetTypeSpecType(T, Loc, PrevSpec, DiagID, Rep.get(), Policy); + } bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, Decl *Rep, bool Owned, const PrintingPolicy &Policy); diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 95706fb999c4..e60d1f68fba5 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3217,16 +3217,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, if (Next.is(tok::annot_typename)) { DS.getTypeSpecScope() = SS; ConsumeAnnotationToken(); // The C++ scope. - if (Tok.getAnnotationValue()) { - ParsedType T = getTypeAnnotation(Tok); - isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, - Tok.getAnnotationEndLoc(), - PrevSpec, DiagID, T, Policy); - if (isInvalid) - break; - } - else - DS.SetTypeSpecError(); + TypeResult T = getTypeAnnotation(Tok); + isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, + Tok.getAnnotationEndLoc(), + PrevSpec, DiagID, T, Policy); + if (isInvalid) + break; DS.SetRangeEnd(Tok.getAnnotationEndLoc()); ConsumeAnnotationToken(); // The typename } @@ -3294,13 +3290,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, if (DS.hasTypeSpecifier() && DS.hasTagDefinition()) goto DoneWithDeclSpec; - if (Tok.getAnnotationValue()) { - ParsedType T = getTypeAnnotation(Tok); - isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, - DiagID, T, Policy); - } else - DS.SetTypeSpecError(); - + TypeResult T = getTypeAnnotation(Tok); + isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, + DiagID, T, Policy); if (isInvalid) break; diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 98918efaf295..710632379ace 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1151,13 +1151,10 @@ TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc, AnnotateTemplateIdTokenAsType(SS, /*IsClassName*/true); assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); - ParsedType Type = getTypeAnnotation(Tok); + TypeResult Type = getTypeAnnotation(Tok); EndLocation = Tok.getAnnotationEndLoc(); ConsumeAnnotationToken(); - - if (Type) - return Type; - return true; + return Type; } // Fall through to produce an error below. @@ -1204,7 +1201,7 @@ TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc, // Retrieve the type from the annotation token, consume that token, and // return. EndLocation = Tok.getAnnotationEndLoc(); - ParsedType Type = getTypeAnnotation(Tok); + TypeResult Type = getTypeAnnotation(Tok); ConsumeAnnotationToken(); return Type; } @@ -3510,7 +3507,7 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) { // : declype(...) DeclSpec DS(AttrFactory); // : template_name<...> - ParsedType TemplateTypeTy; + TypeResult TemplateTypeTy; if (Tok.is(tok::identifier)) { // Get the identifier. This may be a member name or a class name, @@ -3532,8 +3529,6 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) { assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); TemplateTypeTy = getTypeAnnotation(Tok); ConsumeAnnotationToken(); - if (!TemplateTypeTy) - return true; } else { Diag(Tok, diag::err_expected_member_or_base_name); return true; @@ -3552,8 +3547,10 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) { SourceLocation EllipsisLoc; TryConsumeToken(tok::ellipsis, EllipsisLoc); + if (TemplateTypeTy.isInvalid()) + return true; return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II, - TemplateTypeTy, DS, IdLoc, + TemplateTypeTy.get(), DS, IdLoc, InitList.get(), EllipsisLoc); } else if(Tok.is(tok::l_paren)) { BalancedDelimiterTracker T(*this, tok::l_paren); @@ -3563,8 +3560,10 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) { ExprVector ArgExprs; CommaLocsTy CommaLocs; auto RunSignatureHelp = [&] { + if (TemplateTypeTy.isInvalid()) + return QualType(); QualType PreferredType = Actions.ProduceCtorInitMemberSignatureHelp( - getCurScope(), ConstructorDecl, SS, TemplateTypeTy, ArgExprs, II, + getCurScope(), ConstructorDecl, SS, TemplateTypeTy.get(), ArgExprs, II, T.getOpenLocation()); CalledSignatureHelp = true; return PreferredType; @@ -3585,12 +3584,17 @@ MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) { SourceLocation EllipsisLoc; TryConsumeToken(tok::ellipsis, EllipsisLoc); + if (TemplateTypeTy.isInvalid()) + return true; return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II, - TemplateTypeTy, DS, IdLoc, + TemplateTypeTy.get(), DS, IdLoc, T.getOpenLocation(), ArgExprs, T.getCloseLocation(), EllipsisLoc); } + if (TemplateTypeTy.isInvalid()) + return true; + if (getLangOpts().CPlusPlus11) return Diag(Tok, diag::err_expected_either) << tok::l_paren << tok::l_brace; else diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 80592671dcd0..9a0f94ae7be5 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1455,7 +1455,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, break; case tok::annot_typename: if (isStartOfObjCClassMessageMissingOpenBracket()) { - ParsedType Type = getTypeAnnotation(Tok); + TypeResult Type = getTypeAnnotation(Tok); // Fake up a Declarator to use with ActOnTypeName. DeclSpec DS(AttrFactory); diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 4389c8777c6d..c5e895d090a5 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -2147,12 +2147,8 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { // type-name case tok::annot_typename: { - if (getTypeAnnotation(Tok)) - DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, - getTypeAnnotation(Tok), Policy); - else - DS.SetTypeSpecError(); - + DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, + getTypeAnnotation(Tok), Policy); DS.SetRangeEnd(Tok.getAnnotationEndLoc()); ConsumeAnnotationToken(); diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index f0a2a482f063..10252b08a8d1 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -2978,7 +2978,7 @@ bool Parser::isStartOfObjCClassMessageMissingOpenBracket() { InMessageExpression) return false; - ParsedType Type; + TypeResult Type; if (Tok.is(tok::annot_typename)) Type = getTypeAnnotation(Tok); @@ -2988,7 +2988,8 @@ bool Parser::isStartOfObjCClassMessageMissingOpenBracket() { else return false; - if (!Type.get().isNull() && Type.get()->isObjCObjectOrInterfaceType()) { + // FIXME: Should not be querying properties of types from the parser. + if (Type.isUsable() && Type.get().get()->isObjCObjectOrInterfaceType()) { const Token &AfterNext = GetLookAheadToken(2); if (AfterNext.isOneOf(tok::colon, tok::r_square)) { if (Tok.is(tok::identifier)) diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index d383839d9231..5025ea5c85fe 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -1321,7 +1321,7 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, LAngleLoc, TemplateArgsPtr, RAngleLoc); Tok.setKind(tok::annot_typename); - setTypeAnnotation(Tok, Type.isInvalid() ? nullptr : Type.get()); + setTypeAnnotation(Tok, Type); if (SS.isNotEmpty()) Tok.setLocation(SS.getBeginLoc()); else if (TemplateKWLoc.isValid()) @@ -1398,7 +1398,7 @@ void Parser::AnnotateTemplateIdTokenAsType(CXXScopeSpec &SS, /*IsCtorOrDtorName*/ false, IsClassName); // Create the new "type" annotation token. Tok.setKind(tok::annot_typename); - setTypeAnnotation(Tok, Type.isInvalid() ? nullptr : Type.get()); + setTypeAnnotation(Tok, Type); if (SS.isNotEmpty()) // it was a C++ qualified type name. Tok.setLocation(SS.getBeginLoc()); // End location stays the same diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index a33e40b8768d..e9dbd50c3ac1 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1902,7 +1902,7 @@ bool Parser::TryAnnotateTypeOrScopeToken() { SourceLocation EndLoc = Tok.getLastLoc(); Tok.setKind(tok::annot_typename); - setTypeAnnotation(Tok, Ty.isInvalid() ? nullptr : Ty.get()); + setTypeAnnotation(Tok, Ty); Tok.setAnnotationEndLoc(EndLoc); Tok.setLocation(TypenameLoc); PP.AnnotateCachedTokens(Tok); diff --git a/clang/test/Parser/cxx-class.cpp b/clang/test/Parser/cxx-class.cpp index ec56d4bee8dd..576c6d7e8b97 100644 --- a/clang/test/Parser/cxx-class.cpp +++ b/clang/test/Parser/cxx-class.cpp @@ -298,6 +298,11 @@ namespace ArrayMemberAccess { } } +namespace UndeclaredBaseTemplate { + template struct imp; + template struct is_member_function_pointer : undeclared::member> {}; // expected-error {{unknown template name 'undeclared'}} +} + // PR11109 must appear at the end of the source file class pr11109r3 { // expected-note{{to match this '{'}} public // expected-error{{expected ':'}} expected-error{{expected '}'}} expected-error{{expected ';' after class}} From cfe-commits at lists.llvm.org Mon Mar 30 17:29:48 2020 From: cfe-commits at lists.llvm.org (Thomas Lively via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 00:29:48 +0000 (UTC) Subject: [PATCH] D76959: [WebAssembly] Import wasm_simd128.h from Emscripten In-Reply-To: References: Message-ID: <52ca27a0d9849873e3d0243df306c361@localhost.localdomain> tlively marked an inline comment as done. tlively added inline comments. ================ Comment at: clang/lib/Headers/wasm_simd128.h:30 +typedef long long __i64x2 __attribute__((__vector_size__(16), __aligned__(16))); +typedef unsigned long long __u64x2 + __attribute__((__vector_size__(16), __aligned__(16))); ---------------- sunfish wrote: > tlively wrote: > > sunfish wrote: > > > Since this file is already including , instead of `char`, `unsigned char`, `short`, `unsigned short`, etc., can these use `int8_t`, `uint8_t`, `int16_t`, `uint16_t`, and so on, for clarity? Also, this would avoid any possible behavior change under `-funsigned-char`. > > Unfortunately not :( This change gives errors like > > > > ``` > > error: cannot initialize a parameter of type '__attribute__((__vector_size__(16 * sizeof(char)))) char' (vector of 16 'char' values) with an rvalue of type '__i8x16' (vector of 16 'int8_t' values) > > return (v128_t)__builtin_wasm_abs_i8x16((__i8x16)a); > > ``` > > > > Even changing `char` to `signed char` doesn't work. I would change the builtins to use the better types, but the builtin definition system does not allow those more interesting types. > > > > This is especially annoying because `-funsigned-char` does indeed change the behavior of the comparison intrinsics. I will have to do extra work in those functions to make it work. > Would changing the clang definitions of the builtins to use signed char (Sc) explicitly fix this, like: > > -TARGET_BUILTIN(__builtin_wasm_swizzle_v8x16, "V16cV16cV16c", "nc", "unimplemented-simd128") > +TARGET_BUILTIN(__builtin_wasm_swizzle_v8x16, "V16ScV16ScV16Sc", "nc", "unimplemented-simd128") > > and so on for all the wasm simd builtins? Neat, I hadn't remembered that those signed and unsigned prefixes existed. Yes, that would enable some simplifications, but I think they would be better done in a follow-on CL. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76959/new/ https://reviews.llvm.org/D76959 From cfe-commits at lists.llvm.org Mon Mar 30 17:29:50 2020 From: cfe-commits at lists.llvm.org (Bhopesh Bassi via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 00:29:50 +0000 (UTC) Subject: [PATCH] D33029: [clang-format] add option for dangling parenthesis In-Reply-To: References: Message-ID: <75a60f5edb0e14ad8c18f705ac2bf2e6@localhost.localdomain> bbassi added a comment. @MyDeveloperDay Can you please share your thoughts on my comment above? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D33029/new/ https://reviews.llvm.org/D33029 From cfe-commits at lists.llvm.org Mon Mar 30 17:30:16 2020 From: cfe-commits at lists.llvm.org (Thomas Lively via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 00:30:16 +0000 (UTC) Subject: [PATCH] D76959: [WebAssembly] Import wasm_simd128.h from Emscripten In-Reply-To: References: Message-ID: <791109f7ada1c694a7f729b555486374@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG5074776de478: [WebAssembly] Import wasm_simd128.h from Emscripten (authored by tlively). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76959/new/ https://reviews.llvm.org/D76959 Files: clang/lib/Headers/CMakeLists.txt clang/lib/Headers/wasm_simd128.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D76959.253744.patch Type: text/x-patch Size: 48377 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 17:41:39 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via cfe-commits) Date: Mon, 30 Mar 2020 17:41:39 -0700 (PDT) Subject: [clang] 764f54b - Rename options --cuda-gpu-arch and --no-cuda-gpu-arch Message-ID: <5e8291c3.1c69fb81.d10e.3895@mx.google.com> Author: Yaxun (Sam) Liu Date: 2020-03-30T20:29:50-04:00 New Revision: 764f54bb857b0fbc6742f306b09f640e0043791d URL: https://github.com/llvm/llvm-project/commit/764f54bb857b0fbc6742f306b09f640e0043791d DIFF: https://github.com/llvm/llvm-project/commit/764f54bb857b0fbc6742f306b09f640e0043791d.diff LOG: Rename options --cuda-gpu-arch and --no-cuda-gpu-arch Per discussion http://lists.llvm.org/pipermail/llvm-dev/2017-February/109930.html Rename -cuda-gpu-arch and --no-cuda-gpu-arch to --offload-arch and --no-offload-arch. The original options will be alias to the new options. Differential Revision: https://reviews.llvm.org/D76987 Added: Modified: clang/include/clang/Driver/Options.td clang/lib/Driver/Driver.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 1358b463eb1a..2e8d4b1d2363 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -571,13 +571,17 @@ def cuda_include_ptx_EQ : Joined<["--"], "cuda-include-ptx=">, Flags<[DriverOpti HelpText<"Include PTX for the following GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">; def no_cuda_include_ptx_EQ : Joined<["--"], "no-cuda-include-ptx=">, Flags<[DriverOption]>, HelpText<"Do not include PTX for the following GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">; +def offload_arch_EQ : Joined<["--"], "offload-arch=">, Flags<[DriverOption]>, + HelpText<"CUDA/HIP offloading device architecture (e.g. sm_35, gfx906). May be specified more than once.">; def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[DriverOption]>, - HelpText<"CUDA GPU architecture (e.g. sm_35). May be specified more than once.">; + Alias; def hip_link : Flag<["--"], "hip-link">, HelpText<"Link clang-offload-bundler bundles for HIP">; -def no_cuda_gpu_arch_EQ : Joined<["--"], "no-cuda-gpu-arch=">, Flags<[DriverOption]>, - HelpText<"Remove GPU architecture (e.g. sm_35) from the list of GPUs to compile for. " +def no_offload_arch_EQ : Joined<["--"], "no-offload-arch=">, Flags<[DriverOption]>, + HelpText<"Remove CUDA/HIP offloading device architecture (e.g. sm_35, gfx906) from the list of devices to compile for. " "'all' resets the list to its default value.">; +def no_cuda_gpu_arch_EQ : Joined<["--"], "no-cuda-gpu-arch=">, Flags<[DriverOption]>, + Alias; def cuda_noopt_device_debug : Flag<["--"], "cuda-noopt-device-debug">, HelpText<"Enable device-side debug info generation. Disables ptxas optimizations.">; def no_cuda_version_check : Flag<["--"], "no-cuda-version-check">, diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 4afe3e635fc8..9e1f41345ea2 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -2526,13 +2526,13 @@ class OffloadingActionBuilder final { std::set GpuArchs; bool Error = false; for (Arg *A : Args) { - if (!(A->getOption().matches(options::OPT_cuda_gpu_arch_EQ) || - A->getOption().matches(options::OPT_no_cuda_gpu_arch_EQ))) + if (!(A->getOption().matches(options::OPT_offload_arch_EQ) || + A->getOption().matches(options::OPT_no_offload_arch_EQ))) continue; A->claim(); const StringRef ArchStr = A->getValue(); - if (A->getOption().matches(options::OPT_no_cuda_gpu_arch_EQ) && + if (A->getOption().matches(options::OPT_no_offload_arch_EQ) && ArchStr == "all") { GpuArchs.clear(); continue; @@ -2541,9 +2541,9 @@ class OffloadingActionBuilder final { if (Arch == CudaArch::UNKNOWN) { C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr; Error = true; - } else if (A->getOption().matches(options::OPT_cuda_gpu_arch_EQ)) + } else if (A->getOption().matches(options::OPT_offload_arch_EQ)) GpuArchs.insert(Arch); - else if (A->getOption().matches(options::OPT_no_cuda_gpu_arch_EQ)) + else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) GpuArchs.erase(Arch); else llvm_unreachable("Unexpected option."); From cfe-commits at lists.llvm.org Mon Mar 30 18:03:07 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 01:03:07 +0000 (UTC) Subject: [PATCH] D76987: Rename options --cuda-gpu-arch and --no-cuda-gpu-arch In-Reply-To: References: Message-ID: yaxunl added a comment. In D76987#1950366 , @gregrodgers wrote: > This was discussed on llvm-dev three years ago. Here is the thread. > > http://lists.llvm.org/pipermail/llvm-dev/2017-February/109930.html > > The last name discussed was "-- offload-arch". I don't believe we need a list option anymore. So ignore the very old request for --offload-archs. > > I am ok with the patch the way it is. In the future, we should consider renaming the CudaArch class to OffloadArch class . Also the GpuArchList is currently only initialized in CudaActionBuilder. Eventually this is will have to be done for HIPActionBuilder and OpenMPActionBuilder. Could you consider creating a function to InitializeGpuArchList ? GpuArchList is initialized by member function initialize() of CudaActionBuilderBase, which is inherited by CudaActionBuilder and HIPActionBuilder, therefore GpuArchList is initialized in both CudaActionBuilder and HIPActionBuilder. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76987/new/ https://reviews.llvm.org/D76987 From cfe-commits at lists.llvm.org Mon Mar 30 18:03:07 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 01:03:07 +0000 (UTC) Subject: [PATCH] D77085: [clang-tidy] Added support for validating configuration options In-Reply-To: References: Message-ID: njames93 updated this revision to Diff 253751. njames93 added a comment. - Fix assertions failing Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77085/new/ https://reviews.llvm.org/D77085 Files: clang-tools-extra/clang-tidy/ClangTidyCheck.cpp clang-tools-extra/clang-tidy/ClangTidyCheck.h clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77085.253751.patch Type: text/x-patch Size: 26968 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 18:03:07 2020 From: cfe-commits at lists.llvm.org (Wei Mi via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 01:03:07 +0000 (UTC) Subject: [PATCH] D73307: Unique Names for Functions with Internal Linkage In-Reply-To: References: Message-ID: <1459ce6d8d06646c7ad217e106e9b69e@localhost.localdomain> wmi added inline comments. ================ Comment at: clang/test/CodeGen/unique-internal-linkage-names.cpp:5 +// RUN: %clang_cc1 -triple x86_64 -x c++ -S -emit-llvm -funique-internal-linkage-names -o - < %s | FileCheck %s --check-prefix=UNIQUE + +static int glob; ---------------- MaskRay wrote: > Might be worth adding a few other internal linkage names. > > * an object in an unnamed namespace > * an extern "C" static function > * a function-local static variable > * `label: &&label` > > Hope @mtrofin and @davidxl can clarify what internal names may benefit AFDO and we can add such internal names specifically. Only internal functions matter for AFDO. Other types of internal names are irrelevant. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73307/new/ https://reviews.llvm.org/D73307 From cfe-commits at lists.llvm.org Mon Mar 30 18:03:08 2020 From: cfe-commits at lists.llvm.org (Jon Chesterfield via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 01:03:08 +0000 (UTC) Subject: [PATCH] D75917: Expose llvm fence instruction as clang intrinsic In-Reply-To: References: Message-ID: JonChesterfield added a comment. Can this be revived? Changing the enum to a string still sounds good to me Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75917/new/ https://reviews.llvm.org/D75917 From cfe-commits at lists.llvm.org Mon Mar 30 18:03:27 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 01:03:27 +0000 (UTC) Subject: [PATCH] D76987: Rename options --cuda-gpu-arch and --no-cuda-gpu-arch In-Reply-To: References: Message-ID: <0d6dce2653759b19b6a04811731160f9@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG764f54bb857b: Rename options --cuda-gpu-arch and --no-cuda-gpu-arch (authored by yaxunl). Herald added a project: clang. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76987/new/ https://reviews.llvm.org/D76987 Files: clang/include/clang/Driver/Options.td clang/lib/Driver/Driver.cpp Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ clang/lib/Driver/Driver.cpp @@ -2526,13 +2526,13 @@ std::set GpuArchs; bool Error = false; for (Arg *A : Args) { - if (!(A->getOption().matches(options::OPT_cuda_gpu_arch_EQ) || - A->getOption().matches(options::OPT_no_cuda_gpu_arch_EQ))) + if (!(A->getOption().matches(options::OPT_offload_arch_EQ) || + A->getOption().matches(options::OPT_no_offload_arch_EQ))) continue; A->claim(); const StringRef ArchStr = A->getValue(); - if (A->getOption().matches(options::OPT_no_cuda_gpu_arch_EQ) && + if (A->getOption().matches(options::OPT_no_offload_arch_EQ) && ArchStr == "all") { GpuArchs.clear(); continue; @@ -2541,9 +2541,9 @@ if (Arch == CudaArch::UNKNOWN) { C.getDriver().Diag(clang::diag::err_drv_cuda_bad_gpu_arch) << ArchStr; Error = true; - } else if (A->getOption().matches(options::OPT_cuda_gpu_arch_EQ)) + } else if (A->getOption().matches(options::OPT_offload_arch_EQ)) GpuArchs.insert(Arch); - else if (A->getOption().matches(options::OPT_no_cuda_gpu_arch_EQ)) + else if (A->getOption().matches(options::OPT_no_offload_arch_EQ)) GpuArchs.erase(Arch); else llvm_unreachable("Unexpected option."); Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -571,13 +571,17 @@ HelpText<"Include PTX for the following GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">; def no_cuda_include_ptx_EQ : Joined<["--"], "no-cuda-include-ptx=">, Flags<[DriverOption]>, HelpText<"Do not include PTX for the following GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">; +def offload_arch_EQ : Joined<["--"], "offload-arch=">, Flags<[DriverOption]>, + HelpText<"CUDA/HIP offloading device architecture (e.g. sm_35, gfx906). May be specified more than once.">; def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[DriverOption]>, - HelpText<"CUDA GPU architecture (e.g. sm_35). May be specified more than once.">; + Alias; def hip_link : Flag<["--"], "hip-link">, HelpText<"Link clang-offload-bundler bundles for HIP">; -def no_cuda_gpu_arch_EQ : Joined<["--"], "no-cuda-gpu-arch=">, Flags<[DriverOption]>, - HelpText<"Remove GPU architecture (e.g. sm_35) from the list of GPUs to compile for. " +def no_offload_arch_EQ : Joined<["--"], "no-offload-arch=">, Flags<[DriverOption]>, + HelpText<"Remove CUDA/HIP offloading device architecture (e.g. sm_35, gfx906) from the list of devices to compile for. " "'all' resets the list to its default value.">; +def no_cuda_gpu_arch_EQ : Joined<["--"], "no-cuda-gpu-arch=">, Flags<[DriverOption]>, + Alias; def cuda_noopt_device_debug : Flag<["--"], "cuda-noopt-device-debug">, HelpText<"Enable device-side debug info generation. Disables ptxas optimizations.">; def no_cuda_version_check : Flag<["--"], "no-cuda-version-check">, -------------- next part -------------- A non-text attachment was scrubbed... Name: D76987.253760.patch Type: text/x-patch Size: 3332 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 18:29:32 2020 From: cfe-commits at lists.llvm.org (Hubert Tong via cfe-commits) Date: Mon, 30 Mar 2020 21:29:32 -0400 Subject: [clang] 499b2a8 - PR45294: Fix handling of assumed template names looked up in the lexical In-Reply-To: <5e7ecedb.1c69fb81.5f293.4dd1@mx.google.com> References: <5e7ecedb.1c69fb81.5f293.4dd1@mx.google.com> Message-ID: I have not found which of the few commits on Friday having to do with template-ids is responsible, but this now produces a crash (trace is below): struct A; struct B : A {}; Richard, would you take a look? Thanks, Hubert Tong :2:12: error: unknown template name 'A' struct B : A {}; ^ PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script. Stack dump: 0. Program arguments: /build/bin/clang++ -cc1 -xc++ - 1. :2:19: current parser token '{' 2. :2:1: parsing struct/union/class body 'B' #0 0x00003fffb2016418 llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/build/bin/../lib/libLLVMSupport.so.11git+0x206418) #1 0x00003fffb2016540 PrintStackTraceSignalHandler(void*) (/build/bin/../lib/libLLVMSupport.so.11git+0x206540) #2 0x00003fffb2013b38 llvm::sys::RunSignalHandlers() (/build/bin/../lib/libLLVMSupport.so.11git+0x203b38) #3 0x00003fffb2013d2c SignalHandler(int) (/build/bin/../lib/libLLVMSupport.so.11git+0x203d2c) #4 0x00003fffb4570478 0x478 clang::Sema::ActOnBaseSpecifier(clang::Decl*, clang::SourceRange, clang::ParsedAttributes&, bool, clang::AccessSpecifier, clang::OpaquePtr, clang::SourceLocation, clang::SourceLocation) #5 0x00003fffb4570478 #6 0x00003fffb4570478 clang::Parser::ParseBaseSpecifier(clang::Decl*) (+0x478) #7 0x0000001c00000017 #8 0x00003fffad949354 clang::Parser::ParseBaseClause(clang::Decl*) (/build/bin/../lib/../lib/libclangSema.so.11git+0x469354) #9 0x00003fffae1b3368 clang::Parser::ParseCXXMemberSpecification(clang::SourceLocation, clang::SourceLocation, clang::Parser::ParsedAttributesWithRange&, unsigned int, clang::Decl*) (/build/bin/../lib/../lib/libclangParse.so.11git+0x73368) #10 0x00003fffae1b3668 clang::Parser::ParseClassSpecifier(clang::tok::TokenKind, clang::SourceLocation, clang::DeclSpec&, clang::Parser::ParsedTemplateInfo const&, clang::AccessSpecifier, bool, clang::Parser::DeclSpecContext, clang::Parser::ParsedAttributesWithRange&) (/build/bin/../lib/../lib/libclangParse.so.11git+0x73668) #11 0x00003fffae1b884c clang::Parser::ParseDeclarationSpecifiers(clang::DeclSpec&, clang::Parser::ParsedTemplateInfo const&, clang::AccessSpecifier, clang::Parser::DeclSpecContext, clang::Parser::LateParsedAttrList*) (/build/bin/../lib/../lib/libclangParse.so.11git+0x7884c) #12 0x00003fffae1ba2ac clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec&, clang::AccessSpecifier) (/build/bin/../lib/../lib/libclangParse.so.11git+0x7a2ac) #13 0x00003fffae19b4f0 clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*, clang::AccessSpecifier) (.part.221) (/build/bin/../lib/../lib/libclangParse.so.11git+0x5b4f0) #14 0x00003fffae248894 clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*) (/build/bin/../lib/../lib/libclangParse.so.11git+0x108894) #15 0x00003fffae249174 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr&, bool) (/build/bin/../lib/../lib/libclangParse.so.11git+0x109174) #16 0x00003fffae24d880 clang::ParseAST(clang::Sema&, bool, bool) (/build/bin/../lib/../lib/libclangParse.so.11git+0x10d880) #17 0x00003fffae24f00c clang::ASTFrontendAction::ExecuteAction() (/build/bin/../lib/../lib/libclangParse.so.11git+0x10f00c) #18 0x00003fffae1743a8 clang::FrontendAction::Execute() (/build/bin/../lib/../lib/libclangParse.so.11git+0x343a8) #19 0x00003fffb07bc5c0 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/build/bin/../lib/libclangFrontend.so.11git+0x11c5c0) #20 0x00003fffb07c100c clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/build/bin/../lib/libclangFrontend.so.11git+0x12100c) #21 0x00003fffb076d900 cc1_main(llvm::ArrayRef, char const*, void*) (/build/bin/../lib/libclangFrontend.so.11git+0xcd900) #22 0x00003fffb06749dc ExecuteCC1Tool(llvm::SmallVectorImpl&) (/build/bin/../lib/libclangFrontendTool.so.11git+0x49dc) #23 0x000000001001635c main (/build/bin/clang+++0x1001635c) #24 0x000000001000f6b8 generic_start_main.isra.0 (/build/bin/clang+++0x1000f6b8) #25 0x000000001000cdcc __libc_start_main (/build/bin/clang+++0x1000cdcc) /build/bin/../lib/libLLVMSupport.so.11git(_ZN4llvm3sys15PrintStackTraceERNS_11raw_ostreamE+0x38)[0x3fffb2016418] /build/bin/../lib/libLLVMSupport.so.11git(+0x206540)[0x3fffb2016540] /build/bin/../lib/libLLVMSupport.so.11git(_ZN4llvm3sys17RunSignalHandlersEv+0x78)[0x3fffb2013b38] /build/bin/../lib/libLLVMSupport.so.11git(+0x203d2c)[0x3fffb2013d2c] [0x3fffb4570478] [0x1c00000017] /build/bin/../lib/../lib/libclangSema.so.11git(_ZN5clang4Sema18ActOnBaseSpecifierEPNS_4DeclENS_11SourceRangeERNS_16ParsedAttributesEbNS_15AccessSpecifierENS_9OpaquePtrINS_8QualTypeEEENS_14SourceLocationESA_+0x234)[0x3fffad949354] /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser18ParseBaseSpecifierEPNS_4DeclE+0x1b8)[0x3fffae1b3368] /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser15ParseBaseClauseEPNS_4DeclE+0x78)[0x3fffae1b3668] /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser27ParseCXXMemberSpecificationENS_14SourceLocationES1_RNS0_25ParsedAttributesWithRangeEjPNS_4DeclE+0x7cc)[0x3fffae1b884c] /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser19ParseClassSpecifierENS_3tok9TokenKindENS_14SourceLocationERNS_8DeclSpecERKNS0_18ParsedTemplateInfoENS_15AccessSpecifierEbNS0_15DeclSpecContextERNS0_25ParsedAttributesWithRangeE+0x15ec)[0x3fffae1ba2ac] /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser26ParseDeclarationSpecifiersERNS_8DeclSpecERKNS0_18ParsedTemplateInfoENS_15AccessSpecifierENS0_15DeclSpecContextEPNS0_18LateParsedAttrListE+0xea0)[0x3fffae19b4f0] /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser30ParseDeclOrFunctionDefInternalERNS0_25ParsedAttributesWithRangeERNS_15ParsingDeclSpecENS_15AccessSpecifierE+0x94)[0x3fffae248894] /build/bin/../lib/../lib/libclangParse.so.11git(+0x109174)[0x3fffae249174] /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser24ParseExternalDeclarationERNS0_25ParsedAttributesWithRangeEPNS_15ParsingDeclSpecE+0x710)[0x3fffae24d880] /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser17ParseTopLevelDeclERNS_9OpaquePtrINS_12DeclGroupRefEEEb+0x12c)[0x3fffae24f00c] /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang8ParseASTERNS_4SemaEbb+0x2c8)[0x3fffae1743a8] /build/bin/../lib/libclangFrontend.so.11git(_ZN5clang17ASTFrontendAction13ExecuteActionEv+0x70)[0x3fffb07bc5c0] /build/bin/../lib/libclangFrontend.so.11git(_ZN5clang14FrontendAction7ExecuteEv+0x10c)[0x3fffb07c100c] /build/bin/../lib/libclangFrontend.so.11git(_ZN5clang16CompilerInstance13ExecuteActionERNS_14FrontendActionE+0x240)[0x3fffb076d900] /build/bin/../lib/libclangFrontendTool.so.11git(_ZN5clang25ExecuteCompilerInvocationEPNS_16CompilerInstanceE+0xb1c)[0x3fffb06749dc] /build/bin/clang++(_Z8cc1_mainN4llvm8ArrayRefIPKcEES2_Pv+0x136c)[0x1001635c] /build/bin/clang++[0x1000f6b8] /build/bin/clang++(main+0xe4c)[0x1000cdcc] /lib64/libc.so.6(+0x25100)[0x3fffaff55100] /lib64/libc.so.6(__libc_start_main+0xc4)[0x3fffaff552f4] On Sat, Mar 28, 2020 at 12:13 AM Richard Smith via cfe-commits < cfe-commits at lists.llvm.org> wrote: > > Author: Richard Smith > Date: 2020-03-27T21:07:06-07:00 > New Revision: 499b2a8d63ca9b319ce3aae462029f37ce7d96dd > > URL: > https://github.com/llvm/llvm-project/commit/499b2a8d63ca9b319ce3aae462029f37ce7d96dd > DIFF: > https://github.com/llvm/llvm-project/commit/499b2a8d63ca9b319ce3aae462029f37ce7d96dd.diff > > LOG: PR45294: Fix handling of assumed template names looked up in the > lexical > scope. > > There are a few contexts in which we assume a name is a template name; > if such a context is one where we should perform an unqualified lookup, > and lookup finds nothing, we would form a dependent template name even > if the name is not dependent. This happens in particular for the lookup > of a pseudo-destructor. > > In passing, rename ActOnDependentTemplateName to just ActOnTemplateName > given that we apply it for non-dependent template names too. > > Added: > > > Modified: > clang/include/clang/Basic/DiagnosticSemaKinds.td > clang/lib/Parse/ParseExprCXX.cpp > clang/lib/Parse/Parser.cpp > clang/lib/Sema/SemaTemplate.cpp > clang/test/Parser/cxx-decl.cpp > clang/test/SemaCXX/literal-operators.cpp > clang/test/SemaCXX/pseudo-destructors.cpp > clang/test/SemaTemplate/nested-name-spec-template.cpp > > Removed: > > > > > ################################################################################ > diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td > b/clang/include/clang/Basic/DiagnosticSemaKinds.td > index d2aa2902bb2a..b48f92f38939 100644 > --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td > +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td > @@ -4919,6 +4919,9 @@ def err_template_kw_refers_to_non_template : Error< > "%0 following the 'template' keyword does not refer to a template">; > def note_template_kw_refers_to_non_template : Note< > "declared as a non-template here">; > +def err_template_kw_refers_to_dependent_non_template : Error< > + "%0%select{| following the 'template' keyword}1 " > + "cannot refer to a dependent template">; > def err_template_kw_refers_to_class_template : Error< > "'%0%1' instantiated to a class template, not a function template">; > def note_referenced_class_template : Note< > > diff --git a/clang/lib/Parse/ParseExprCXX.cpp > b/clang/lib/Parse/ParseExprCXX.cpp > index 985bcf689d21..761fad9456be 100644 > --- a/clang/lib/Parse/ParseExprCXX.cpp > +++ b/clang/lib/Parse/ParseExprCXX.cpp > @@ -1773,6 +1773,12 @@ Parser::ParseCXXPseudoDestructor(Expr *Base, > SourceLocation OpLoc, > > // If there is a '<', the second type name is a template-id. Parse > // it as such. > + // > + // FIXME: This is not a context in which a '<' is assumed to start a > template > + // argument list. This affects examples such as > + // void f(auto *p) { p->~X(); } > + // ... but there's no ambiguity, and nowhere to write 'template' in > such an > + // example, so we accept it anyway. > if (Tok.is(tok::less) && > ParseUnqualifiedIdTemplateId( > SS, ObjectType, Base && Base->containsErrors(), > SourceLocation(), > > diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp > index 47b5de320ebf..a33e40b8768d 100644 > --- a/clang/lib/Parse/Parser.cpp > +++ b/clang/lib/Parse/Parser.cpp > @@ -1878,11 +1878,7 @@ bool Parser::TryAnnotateTypeOrScopeToken() { > Tok.getLocation()); > } else if (Tok.is(tok::annot_template_id)) { > TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); > - if (TemplateId->isInvalid()) > - return true; > - if (TemplateId->Kind != TNK_Type_template && > - TemplateId->Kind != TNK_Dependent_template_name && > - TemplateId->Kind != TNK_Undeclared_template) { > + if (!TemplateId->mightBeType()) { > Diag(Tok, diag::err_typename_refers_to_non_type_template) > << Tok.getAnnotationRange(); > return true; > @@ -1891,14 +1887,13 @@ bool Parser::TryAnnotateTypeOrScopeToken() { > ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), > TemplateId->NumArgs); > > - Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS, > - TemplateId->TemplateKWLoc, > - TemplateId->Template, > - TemplateId->Name, > - TemplateId->TemplateNameLoc, > - TemplateId->LAngleLoc, > - TemplateArgsPtr, > - TemplateId->RAngleLoc); > + Ty = TemplateId->isInvalid() > + ? TypeError() > + : Actions.ActOnTypenameType( > + getCurScope(), TypenameLoc, SS, > TemplateId->TemplateKWLoc, > + TemplateId->Template, TemplateId->Name, > + TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, > + TemplateArgsPtr, TemplateId->RAngleLoc); > } else { > Diag(Tok, diag::err_expected_type_name_after_typename) > << SS.getRange(); > > diff --git a/clang/lib/Sema/SemaTemplate.cpp > b/clang/lib/Sema/SemaTemplate.cpp > index 74d1fbe2ec77..1e2ebc5037bc 100755 > --- a/clang/lib/Sema/SemaTemplate.cpp > +++ b/clang/lib/Sema/SemaTemplate.cpp > @@ -377,6 +377,9 @@ bool Sema::LookupTemplateName(LookupResult &Found, > if (ATK) > *ATK = AssumedTemplateKind::None; > > + if (SS.isInvalid()) > + return true; > + > Found.setTemplateNameLookup(true); > > // Determine where to perform name lookup > @@ -386,7 +389,7 @@ bool Sema::LookupTemplateName(LookupResult &Found, > if (!ObjectType.isNull()) { > // This nested-name-specifier occurs in a member access expression, > e.g., > // x->B::f, and we are looking into the type of the object. > - assert(!SS.isSet() && "ObjectType and scope specifier cannot > coexist"); > + assert(SS.isEmpty() && "ObjectType and scope specifier cannot > coexist"); > LookupCtx = computeDeclContext(ObjectType); > IsDependent = !LookupCtx && ObjectType->isDependentType(); > assert((IsDependent || !ObjectType->isIncompleteType() || > @@ -412,11 +415,11 @@ bool Sema::LookupTemplateName(LookupResult &Found, > Found.clear(); > return false; > } > - } else if (SS.isSet()) { > + } else if (SS.isNotEmpty()) { > // This nested-name-specifier occurs after another > nested-name-specifier, > // so long into the context associated with the prior > nested-name-specifier. > LookupCtx = computeDeclContext(SS, EnteringContext); > - IsDependent = !LookupCtx; > + IsDependent = !LookupCtx && isDependentScopeSpecifier(SS); > > // The declaration context must be complete. > if (LookupCtx && RequireCompleteDeclContext(SS, LookupCtx)) > @@ -443,7 +446,7 @@ bool Sema::LookupTemplateName(LookupResult &Found, > IsDependent |= Found.wasNotFoundInCurrentInstantiation(); > } > > - if (!SS.isSet() && (ObjectType.isNull() || Found.empty())) { > + if (SS.isEmpty() && (ObjectType.isNull() || Found.empty())) { > // C++ [basic.lookup.classref]p1: > // In a class member access expression (5.2.5), if the . or -> > token is > // immediately followed by an identifier followed by a <, the > @@ -470,7 +473,7 @@ bool Sema::LookupTemplateName(LookupResult &Found, > if (Found.isAmbiguous()) > return false; > > - if (ATK && !SS.isSet() && ObjectType.isNull() && > TemplateKWLoc.isInvalid()) { > + if (ATK && SS.isEmpty() && ObjectType.isNull() && > TemplateKWLoc.isInvalid()) { > // C++2a [temp.names]p2: > // A name is also considered to refer to a template if it is an > // unqualified-id followed by a < and name lookup finds either one > or more > @@ -3470,6 +3473,10 @@ QualType Sema::CheckTemplateIdType(TemplateName > Name, > > DTN->getIdentifier(), > TemplateArgs); > > + if (Name.getAsAssumedTemplateName() && > + resolveAssumedTemplateNameAsType(/*Scope*/nullptr, Name, > TemplateLoc)) > + return QualType(); > + > TemplateDecl *Template = Name.getAsTemplateDecl(); > if (!Template || isa(Template) || > isa(Template) || isa(Template)) { > @@ -4652,95 +4659,111 @@ TemplateNameKind Sema::ActOnTemplateName(Scope *S, > diag::ext_template_outside_of_template) > << FixItHint::CreateRemoval(TemplateKWLoc); > > + if (SS.isInvalid()) > + return TNK_Non_template; > + > + // Figure out where isTemplateName is going to look. > DeclContext *LookupCtx = nullptr; > - if (SS.isSet()) > + if (SS.isNotEmpty()) > LookupCtx = computeDeclContext(SS, EnteringContext); > - if (!LookupCtx && ObjectType) > - LookupCtx = computeDeclContext(ObjectType.get()); > - if (LookupCtx) { > - // C++0x [temp.names]p5: > - // If a name prefixed by the keyword template is not the name of > - // a template, the program is ill-formed. [Note: the keyword > - // template may not be applied to non-template members of class > - // templates. -end note ] [ Note: as is the case with the > - // typename prefix, the template prefix is allowed in cases > - // where it is not strictly necessary; i.e., when the > - // nested-name-specifier or the expression on the left of the -> > - // or . is not dependent on a template-parameter, or the use > - // does not appear in the scope of a template. -end note] > - // > - // Note: C++03 was more strict here, because it banned the use of > - // the "template" keyword prior to a template-name that was not a > - // dependent name. C++ DR468 relaxed this requirement (the > - // "template" keyword is now permitted). We follow the C++0x > - // rules, even in C++03 mode with a warning, retroactively applying > the DR. > - bool MemberOfUnknownSpecialization; > - TemplateNameKind TNK = isTemplateName(S, SS, TemplateKWLoc.isValid(), > Name, > - ObjectType, EnteringContext, > Result, > - MemberOfUnknownSpecialization); > - if (TNK == TNK_Non_template && MemberOfUnknownSpecialization) { > - // This is a dependent template. Handle it below. > - } else if (TNK == TNK_Non_template) { > - // Do the lookup again to determine if this is a "nothing found" > case or > - // a "not a template" case. FIXME: Refactor isTemplateName so we > don't > - // need to do this. > - DeclarationNameInfo DNI = GetNameFromUnqualifiedId(Name); > - LookupResult R(*this, DNI.getName(), Name.getBeginLoc(), > - LookupOrdinaryName); > - bool MOUS; > - if (!LookupTemplateName(R, S, SS, ObjectType.get(), EnteringContext, > - MOUS, TemplateKWLoc) && !R.isAmbiguous()) > + else if (ObjectType) > + LookupCtx = computeDeclContext(GetTypeFromParser(ObjectType)); > + > + // C++0x [temp.names]p5: > + // If a name prefixed by the keyword template is not the name of > + // a template, the program is ill-formed. [Note: the keyword > + // template may not be applied to non-template members of class > + // templates. -end note ] [ Note: as is the case with the > + // typename prefix, the template prefix is allowed in cases > + // where it is not strictly necessary; i.e., when the > + // nested-name-specifier or the expression on the left of the -> > + // or . is not dependent on a template-parameter, or the use > + // does not appear in the scope of a template. -end note] > + // > + // Note: C++03 was more strict here, because it banned the use of > + // the "template" keyword prior to a template-name that was not a > + // dependent name. C++ DR468 relaxed this requirement (the > + // "template" keyword is now permitted). We follow the C++0x > + // rules, even in C++03 mode with a warning, retroactively applying the > DR. > + bool MemberOfUnknownSpecialization; > + TemplateNameKind TNK = isTemplateName(S, SS, TemplateKWLoc.isValid(), > Name, > + ObjectType, EnteringContext, > Result, > + MemberOfUnknownSpecialization); > + if (TNK != TNK_Non_template) { > + // We resolved this to a (non-dependent) template name. Return it. > + auto *LookupRD = dyn_cast_or_null(LookupCtx); > + if (!AllowInjectedClassName && SS.isNotEmpty() && LookupRD && > + Name.getKind() == UnqualifiedIdKind::IK_Identifier && > + Name.Identifier && LookupRD->getIdentifier() == Name.Identifier) { > + // C++14 [class.qual]p2: > + // In a lookup in which function names are not ignored and the > + // nested-name-specifier nominates a class C, if the name > specified > + // [...] is the injected-class-name of C, [...] the name is > instead > + // considered to name the constructor > + // > + // We don't get here if naming the constructor would be valid, so we > + // just reject immediately and recover by treating the > + // injected-class-name as naming the template. > + Diag(Name.getBeginLoc(), > + diag::ext_out_of_line_qualified_id_type_names_constructor) > + << Name.Identifier > + << 0 /*injected-class-name used as template name*/ > + << TemplateKWLoc.isValid(); > + } > + return TNK; > + } > + > + if (!MemberOfUnknownSpecialization) { > + // Didn't find a template name, and the lookup wasn't dependent. > + // Do the lookup again to determine if this is a "nothing found" case > or > + // a "not a template" case. FIXME: Refactor isTemplateName so we don't > + // need to do this. > + DeclarationNameInfo DNI = GetNameFromUnqualifiedId(Name); > + LookupResult R(*this, DNI.getName(), Name.getBeginLoc(), > + LookupOrdinaryName); > + bool MOUS; > + // FIXME: If LookupTemplateName fails here, we'll have produced its > + // diagnostics twice. > + if (!LookupTemplateName(R, S, SS, ObjectType.get(), EnteringContext, > + MOUS, TemplateKWLoc) && !R.isAmbiguous()) { > + if (LookupCtx) > Diag(Name.getBeginLoc(), diag::err_no_member) > << DNI.getName() << LookupCtx << SS.getRange(); > - return TNK_Non_template; > - } else { > - // We found something; return it. > - auto *LookupRD = dyn_cast(LookupCtx); > - if (!AllowInjectedClassName && SS.isSet() && LookupRD && > - Name.getKind() == UnqualifiedIdKind::IK_Identifier && > - Name.Identifier && LookupRD->getIdentifier() == > Name.Identifier) { > - // C++14 [class.qual]p2: > - // In a lookup in which function names are not ignored and the > - // nested-name-specifier nominates a class C, if the name > specified > - // [...] is the injected-class-name of C, [...] the name is > instead > - // considered to name the constructor > - // > - // We don't get here if naming the constructor would be valid, so > we > - // just reject immediately and recover by treating the > - // injected-class-name as naming the template. > - Diag(Name.getBeginLoc(), > - diag::ext_out_of_line_qualified_id_type_names_constructor) > - << Name.Identifier > - << 0 /*injected-class-name used as template name*/ > - << 1 /*'template' keyword was used*/; > - } > - return TNK; > + else > + Diag(Name.getBeginLoc(), diag::err_undeclared_use) > + << DNI.getName() << SS.getRange(); > } > + return TNK_Non_template; > } > > NestedNameSpecifier *Qualifier = SS.getScopeRep(); > > switch (Name.getKind()) { > case UnqualifiedIdKind::IK_Identifier: > - Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier, > - > Name.Identifier)); > + Result = TemplateTy::make( > + Context.getDependentTemplateName(Qualifier, Name.Identifier)); > return TNK_Dependent_template_name; > > case UnqualifiedIdKind::IK_OperatorFunctionId: > - Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier, > - > Name.OperatorFunctionId.Operator)); > + Result = TemplateTy::make(Context.getDependentTemplateName( > + Qualifier, Name.OperatorFunctionId.Operator)); > return TNK_Function_template; > > case UnqualifiedIdKind::IK_LiteralOperatorId: > - llvm_unreachable("literal operator id cannot have a dependent scope"); > + // This is a kind of template name, but can never occur in a dependent > + // scope (literal operators can only be declared at namespace scope). > + break; > > default: > break; > } > > - Diag(Name.getBeginLoc(), diag::err_template_kw_refers_to_non_template) > + // This name cannot possibly name a dependent template. Diagnose this > now > + // rather than building a dependent template name that can never be > valid. > + Diag(Name.getBeginLoc(), > + diag::err_template_kw_refers_to_dependent_non_template) > << GetNameFromUnqualifiedId(Name).getName() << Name.getSourceRange() > - << TemplateKWLoc; > + << TemplateKWLoc.isValid() << TemplateKWLoc; > return TNK_Non_template; > } > > > diff --git a/clang/test/Parser/cxx-decl.cpp > b/clang/test/Parser/cxx-decl.cpp > index ba1cce419a46..dbf3a3e70bb0 100644 > --- a/clang/test/Parser/cxx-decl.cpp > +++ b/clang/test/Parser/cxx-decl.cpp > @@ -240,8 +240,7 @@ namespace PR17255 { > void foo() { > typename A::template B<> c; // expected-error {{use of undeclared > identifier 'A'}} > #if __cplusplus <= 199711L > - // expected-error at -2 {{'typename' occurs outside of a template}} > - // expected-error at -3 {{'template' keyword outside of a template}} > + // expected-error at -2 {{'template' keyword outside of a template}} > #endif > } > } > > diff --git a/clang/test/SemaCXX/literal-operators.cpp > b/clang/test/SemaCXX/literal-operators.cpp > index 304aa7cab7f3..834d5ec7923e 100644 > --- a/clang/test/SemaCXX/literal-operators.cpp > +++ b/clang/test/SemaCXX/literal-operators.cpp > @@ -47,3 +47,7 @@ template void operator "" > _invalid(); // expected-error > _Complex float operator""if(long double); // expected-warning {{reserved}} > _Complex float test_if_1() { return 2.0f + 1.5if; }; > void test_if_2() { "foo"if; } // expected-error {{no matching literal > operator for call to 'operator""if'}} > + > +template void dependent_member_template() { > + T().template operator""_foo(); // expected-error > {{'operator""_foo' following the 'template' keyword cannot refer to a > dependent template}} > +} > > diff --git a/clang/test/SemaCXX/pseudo-destructors.cpp > b/clang/test/SemaCXX/pseudo-destructors.cpp > index b71b523de683..292324893dd0 100644 > --- a/clang/test/SemaCXX/pseudo-destructors.cpp > +++ b/clang/test/SemaCXX/pseudo-destructors.cpp > @@ -119,3 +119,54 @@ void test2(Foo d) { > d.~Derived(); // expected-error {{member reference type > 'dotPointerAccess::Foo' (aka 'dotPointerAccess::Derived *') is a pointer; > did you mean to use '->'}} > } > } > + > +int pr45294 = 1 .~undeclared_tempate_name<>(); // expected-error {{use of > undeclared 'undeclared_tempate_name'}} > + > +namespace TwoPhaseLookup { > + namespace NonTemplate { > + struct Y {}; > + using G = Y; > + template void f(T *p) { p->~G(); } // expected-error {{no > member named '~Y'}} > + void h1(Y *p) { p->~G(); } > + void h2(Y *p) { f(p); } > + namespace N { struct G{}; } > + void h3(N::G *p) { p->~G(); } > + void h4(N::G *p) { f(p); } // expected-note {{instantiation of}} > + } > + > + namespace NonTemplateUndeclared { > + struct Y {}; > + template void f(T *p) { p->~G(); } // expected-error > {{undeclared identifier 'G' in destructor name}} > + using G = Y; > + void h1(Y *p) { p->~G(); } > + void h2(Y *p) { f(p); } // expected-note {{instantiation of}} > + namespace N { struct G{}; } > + void h3(N::G *p) { p->~G(); } > + void h4(N::G *p) { f(p); } > + } > + > + namespace Template { > + template struct Y {}; > + template using G = Y; > + template void f(T *p) { p->~G(); } // expected-error > {{no member named '~Y'}} > + void h1(Y *p) { p->~G(); } > + void h2(Y *p) { f(p); } > + namespace N { template struct G {}; } > + void h3(N::G *p) { p->~G(); } > + void h4(N::G *p) { f(p); } // expected-note {{instantiation of}} > + } > + > + namespace TemplateUndeclared { > + template struct Y {}; > + // FIXME: Formally, this is ill-formed before we hit any > instantiation, > + // because we aren't supposed to treat the '<' as introducing a > template > + // name. > + template void f(T *p) { p->~G(); } // expected-error > {{no member named 'G'}} > + template using G = Y; > + void h1(Y *p) { p->~G(); } > + void h2(Y *p) { f(p); } // expected-note {{instantiation of}} > + namespace N { template struct G {}; } > + void h3(N::G *p) { p->~G(); } > + void h4(N::G *p) { f(p); } > + } > +} > > diff --git a/clang/test/SemaTemplate/nested-name-spec-template.cpp > b/clang/test/SemaTemplate/nested-name-spec-template.cpp > index 3e7f506040a6..07dd41bfe27b 100644 > --- a/clang/test/SemaTemplate/nested-name-spec-template.cpp > +++ b/clang/test/SemaTemplate/nested-name-spec-template.cpp > @@ -142,8 +142,7 @@ namespace PR9449 { > > template > void f() { > - int s::template n::* f; // expected-error{{implicit > instantiation of undefined template 'PR9449::s'}} \ > - // expected-error{{no member named 'n'}} > + int s::template n::* f; // expected-error{{implicit > instantiation of undefined template 'PR9449::s'}} > } > > template void f(); // expected-note{{in instantiation of}} > > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cfe-commits at lists.llvm.org Mon Mar 30 18:35:47 2020 From: cfe-commits at lists.llvm.org (Sriraman Tallam via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 01:35:47 +0000 (UTC) Subject: [PATCH] D73307: Unique Names for Functions with Internal Linkage In-Reply-To: References: Message-ID: <1d1bbe363842e4349af856e491b43693@localhost.localdomain> tmsriram marked an inline comment as done. tmsriram added inline comments. ================ Comment at: clang/test/CodeGen/unique-internal-linkage-names.cpp:5 +// RUN: %clang_cc1 -triple x86_64 -x c++ -S -emit-llvm -funique-internal-linkage-names -o - < %s | FileCheck %s --check-prefix=UNIQUE + +static int glob; ---------------- wmi wrote: > MaskRay wrote: > > Might be worth adding a few other internal linkage names. > > > > * an object in an unnamed namespace > > * an extern "C" static function > > * a function-local static variable > > * `label: &&label` > > > > Hope @mtrofin and @davidxl can clarify what internal names may benefit AFDO and we can add such internal names specifically. > Only internal functions matter for AFDO. Other types of internal names are irrelevant. extern "C" static is not very useful as the name is not exposed outside the object file. C++ compiler will still mangle the name. for eg: a.cpp extern "C" { static int bar() { return 0; } } int foo() { printf("%p\n", bar); } $ nm a.o 0000000000000040 t _ZL3barv Also, for label: &&label, it is not preserved in the symbol table as a .L is used which is deleted by the assembler. I can throw a asm("") directive but that will bypass the front-end. Is there anyway to preserve this? I can add the rest of the cases. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73307/new/ https://reviews.llvm.org/D73307 From cfe-commits at lists.llvm.org Mon Mar 30 18:50:02 2020 From: cfe-commits at lists.llvm.org (Richard Smith via cfe-commits) Date: Mon, 30 Mar 2020 18:50:02 -0700 Subject: [clang] 499b2a8 - PR45294: Fix handling of assumed template names looked up in the lexical In-Reply-To: References: <5e7ecedb.1c69fb81.5f293.4dd1@mx.google.com> Message-ID: Already fixed in llvmorg-11-init-7209-g33087323007 :) On Mon, 30 Mar 2020 at 18:30, Hubert Tong via cfe-commits < cfe-commits at lists.llvm.org> wrote: > I have not found which of the few commits on Friday having to do with > template-ids is responsible, but this now produces a crash (trace is below): > struct A; > struct B : A {}; > > Richard, would you take a look? > > Thanks, > > > Hubert Tong > > :2:12: error: unknown template name 'A' > struct B : A {}; > ^ > PLEASE submit a bug report to https://bugs.llvm.org/ and include the > crash backtrace, preprocessed source, and associated run script. > Stack dump: > 0. Program arguments: /build/bin/clang++ -cc1 -xc++ - > 1. :2:19: current parser token '{' > 2. :2:1: parsing struct/union/class body 'B' > #0 0x00003fffb2016418 llvm::sys::PrintStackTrace(llvm::raw_ostream&) > (/build/bin/../lib/libLLVMSupport.so.11git+0x206418) > #1 0x00003fffb2016540 PrintStackTraceSignalHandler(void*) > (/build/bin/../lib/libLLVMSupport.so.11git+0x206540) > #2 0x00003fffb2013b38 llvm::sys::RunSignalHandlers() > (/build/bin/../lib/libLLVMSupport.so.11git+0x203b38) > #3 0x00003fffb2013d2c SignalHandler(int) > (/build/bin/../lib/libLLVMSupport.so.11git+0x203d2c) > #4 0x00003fffb4570478 0x478 > clang::Sema::ActOnBaseSpecifier(clang::Decl*, clang::SourceRange, > clang::ParsedAttributes&, bool, clang::AccessSpecifier, > clang::OpaquePtr, clang::SourceLocation, > clang::SourceLocation) > #5 0x00003fffb4570478 > #6 0x00003fffb4570478 clang::Parser::ParseBaseSpecifier(clang::Decl*) > (+0x478) > #7 0x0000001c00000017 > #8 0x00003fffad949354 clang::Parser::ParseBaseClause(clang::Decl*) > (/build/bin/../lib/../lib/libclangSema.so.11git+0x469354) > #9 0x00003fffae1b3368 > clang::Parser::ParseCXXMemberSpecification(clang::SourceLocation, > clang::SourceLocation, clang::Parser::ParsedAttributesWithRange&, unsigned > int, clang::Decl*) (/build/bin/../lib/../lib/libclangParse.so.11git+0x73368) > #10 0x00003fffae1b3668 > clang::Parser::ParseClassSpecifier(clang::tok::TokenKind, > clang::SourceLocation, clang::DeclSpec&, clang::Parser::ParsedTemplateInfo > const&, clang::AccessSpecifier, bool, clang::Parser::DeclSpecContext, > clang::Parser::ParsedAttributesWithRange&) > (/build/bin/../lib/../lib/libclangParse.so.11git+0x73668) > #11 0x00003fffae1b884c > clang::Parser::ParseDeclarationSpecifiers(clang::DeclSpec&, > clang::Parser::ParsedTemplateInfo const&, clang::AccessSpecifier, > clang::Parser::DeclSpecContext, clang::Parser::LateParsedAttrList*) > (/build/bin/../lib/../lib/libclangParse.so.11git+0x7884c) > #12 0x00003fffae1ba2ac > clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange&, > clang::ParsingDeclSpec&, clang::AccessSpecifier) > (/build/bin/../lib/../lib/libclangParse.so.11git+0x7a2ac) > #13 0x00003fffae19b4f0 > clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange&, > clang::ParsingDeclSpec*, clang::AccessSpecifier) (.part.221) > (/build/bin/../lib/../lib/libclangParse.so.11git+0x5b4f0) > #14 0x00003fffae248894 > clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&, > clang::ParsingDeclSpec*) > (/build/bin/../lib/../lib/libclangParse.so.11git+0x108894) > #15 0x00003fffae249174 > clang::Parser::ParseTopLevelDecl(clang::OpaquePtr&, > bool) (/build/bin/../lib/../lib/libclangParse.so.11git+0x109174) > #16 0x00003fffae24d880 clang::ParseAST(clang::Sema&, bool, bool) > (/build/bin/../lib/../lib/libclangParse.so.11git+0x10d880) > #17 0x00003fffae24f00c clang::ASTFrontendAction::ExecuteAction() > (/build/bin/../lib/../lib/libclangParse.so.11git+0x10f00c) > #18 0x00003fffae1743a8 clang::FrontendAction::Execute() > (/build/bin/../lib/../lib/libclangParse.so.11git+0x343a8) > #19 0x00003fffb07bc5c0 > clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) > (/build/bin/../lib/libclangFrontend.so.11git+0x11c5c0) > #20 0x00003fffb07c100c > clang::ExecuteCompilerInvocation(clang::CompilerInstance*) > (/build/bin/../lib/libclangFrontend.so.11git+0x12100c) > #21 0x00003fffb076d900 cc1_main(llvm::ArrayRef, char const*, > void*) (/build/bin/../lib/libclangFrontend.so.11git+0xcd900) > #22 0x00003fffb06749dc ExecuteCC1Tool(llvm::SmallVectorImpl&) > (/build/bin/../lib/libclangFrontendTool.so.11git+0x49dc) > #23 0x000000001001635c main (/build/bin/clang+++0x1001635c) > #24 0x000000001000f6b8 generic_start_main.isra.0 > (/build/bin/clang+++0x1000f6b8) > #25 0x000000001000cdcc __libc_start_main (/build/bin/clang+++0x1000cdcc) > > /build/bin/../lib/libLLVMSupport.so.11git(_ZN4llvm3sys15PrintStackTraceERNS_11raw_ostreamE+0x38)[0x3fffb2016418] > /build/bin/../lib/libLLVMSupport.so.11git(+0x206540)[0x3fffb2016540] > > /build/bin/../lib/libLLVMSupport.so.11git(_ZN4llvm3sys17RunSignalHandlersEv+0x78)[0x3fffb2013b38] > /build/bin/../lib/libLLVMSupport.so.11git(+0x203d2c)[0x3fffb2013d2c] > [0x3fffb4570478] > [0x1c00000017] > > /build/bin/../lib/../lib/libclangSema.so.11git(_ZN5clang4Sema18ActOnBaseSpecifierEPNS_4DeclENS_11SourceRangeERNS_16ParsedAttributesEbNS_15AccessSpecifierENS_9OpaquePtrINS_8QualTypeEEENS_14SourceLocationESA_+0x234)[0x3fffad949354] > > /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser18ParseBaseSpecifierEPNS_4DeclE+0x1b8)[0x3fffae1b3368] > > /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser15ParseBaseClauseEPNS_4DeclE+0x78)[0x3fffae1b3668] > > /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser27ParseCXXMemberSpecificationENS_14SourceLocationES1_RNS0_25ParsedAttributesWithRangeEjPNS_4DeclE+0x7cc)[0x3fffae1b884c] > > /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser19ParseClassSpecifierENS_3tok9TokenKindENS_14SourceLocationERNS_8DeclSpecERKNS0_18ParsedTemplateInfoENS_15AccessSpecifierEbNS0_15DeclSpecContextERNS0_25ParsedAttributesWithRangeE+0x15ec)[0x3fffae1ba2ac] > > /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser26ParseDeclarationSpecifiersERNS_8DeclSpecERKNS0_18ParsedTemplateInfoENS_15AccessSpecifierENS0_15DeclSpecContextEPNS0_18LateParsedAttrListE+0xea0)[0x3fffae19b4f0] > > /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser30ParseDeclOrFunctionDefInternalERNS0_25ParsedAttributesWithRangeERNS_15ParsingDeclSpecENS_15AccessSpecifierE+0x94)[0x3fffae248894] > /build/bin/../lib/../lib/libclangParse.so.11git(+0x109174)[0x3fffae249174] > > /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser24ParseExternalDeclarationERNS0_25ParsedAttributesWithRangeEPNS_15ParsingDeclSpecE+0x710)[0x3fffae24d880] > > /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang6Parser17ParseTopLevelDeclERNS_9OpaquePtrINS_12DeclGroupRefEEEb+0x12c)[0x3fffae24f00c] > > /build/bin/../lib/../lib/libclangParse.so.11git(_ZN5clang8ParseASTERNS_4SemaEbb+0x2c8)[0x3fffae1743a8] > > /build/bin/../lib/libclangFrontend.so.11git(_ZN5clang17ASTFrontendAction13ExecuteActionEv+0x70)[0x3fffb07bc5c0] > > /build/bin/../lib/libclangFrontend.so.11git(_ZN5clang14FrontendAction7ExecuteEv+0x10c)[0x3fffb07c100c] > > /build/bin/../lib/libclangFrontend.so.11git(_ZN5clang16CompilerInstance13ExecuteActionERNS_14FrontendActionE+0x240)[0x3fffb076d900] > > /build/bin/../lib/libclangFrontendTool.so.11git(_ZN5clang25ExecuteCompilerInvocationEPNS_16CompilerInstanceE+0xb1c)[0x3fffb06749dc] > > /build/bin/clang++(_Z8cc1_mainN4llvm8ArrayRefIPKcEES2_Pv+0x136c)[0x1001635c] > /build/bin/clang++[0x1000f6b8] > /build/bin/clang++(main+0xe4c)[0x1000cdcc] > /lib64/libc.so.6(+0x25100)[0x3fffaff55100] > /lib64/libc.so.6(__libc_start_main+0xc4)[0x3fffaff552f4] > On Sat, Mar 28, 2020 at 12:13 AM Richard Smith via cfe-commits < > cfe-commits at lists.llvm.org> wrote: > >> >> Author: Richard Smith >> Date: 2020-03-27T21:07:06-07:00 >> New Revision: 499b2a8d63ca9b319ce3aae462029f37ce7d96dd >> >> URL: >> https://github.com/llvm/llvm-project/commit/499b2a8d63ca9b319ce3aae462029f37ce7d96dd >> DIFF: >> https://github.com/llvm/llvm-project/commit/499b2a8d63ca9b319ce3aae462029f37ce7d96dd.diff >> >> LOG: PR45294: Fix handling of assumed template names looked up in the >> lexical >> scope. >> >> There are a few contexts in which we assume a name is a template name; >> if such a context is one where we should perform an unqualified lookup, >> and lookup finds nothing, we would form a dependent template name even >> if the name is not dependent. This happens in particular for the lookup >> of a pseudo-destructor. >> >> In passing, rename ActOnDependentTemplateName to just ActOnTemplateName >> given that we apply it for non-dependent template names too. >> >> Added: >> >> >> Modified: >> clang/include/clang/Basic/DiagnosticSemaKinds.td >> clang/lib/Parse/ParseExprCXX.cpp >> clang/lib/Parse/Parser.cpp >> clang/lib/Sema/SemaTemplate.cpp >> clang/test/Parser/cxx-decl.cpp >> clang/test/SemaCXX/literal-operators.cpp >> clang/test/SemaCXX/pseudo-destructors.cpp >> clang/test/SemaTemplate/nested-name-spec-template.cpp >> >> Removed: >> >> >> >> >> ################################################################################ >> diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td >> b/clang/include/clang/Basic/DiagnosticSemaKinds.td >> index d2aa2902bb2a..b48f92f38939 100644 >> --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td >> +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td >> @@ -4919,6 +4919,9 @@ def err_template_kw_refers_to_non_template : Error< >> "%0 following the 'template' keyword does not refer to a template">; >> def note_template_kw_refers_to_non_template : Note< >> "declared as a non-template here">; >> +def err_template_kw_refers_to_dependent_non_template : Error< >> + "%0%select{| following the 'template' keyword}1 " >> + "cannot refer to a dependent template">; >> def err_template_kw_refers_to_class_template : Error< >> "'%0%1' instantiated to a class template, not a function template">; >> def note_referenced_class_template : Note< >> >> diff --git a/clang/lib/Parse/ParseExprCXX.cpp >> b/clang/lib/Parse/ParseExprCXX.cpp >> index 985bcf689d21..761fad9456be 100644 >> --- a/clang/lib/Parse/ParseExprCXX.cpp >> +++ b/clang/lib/Parse/ParseExprCXX.cpp >> @@ -1773,6 +1773,12 @@ Parser::ParseCXXPseudoDestructor(Expr *Base, >> SourceLocation OpLoc, >> >> // If there is a '<', the second type name is a template-id. Parse >> // it as such. >> + // >> + // FIXME: This is not a context in which a '<' is assumed to start a >> template >> + // argument list. This affects examples such as >> + // void f(auto *p) { p->~X(); } >> + // ... but there's no ambiguity, and nowhere to write 'template' in >> such an >> + // example, so we accept it anyway. >> if (Tok.is(tok::less) && >> ParseUnqualifiedIdTemplateId( >> SS, ObjectType, Base && Base->containsErrors(), >> SourceLocation(), >> >> diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp >> index 47b5de320ebf..a33e40b8768d 100644 >> --- a/clang/lib/Parse/Parser.cpp >> +++ b/clang/lib/Parse/Parser.cpp >> @@ -1878,11 +1878,7 @@ bool Parser::TryAnnotateTypeOrScopeToken() { >> Tok.getLocation()); >> } else if (Tok.is(tok::annot_template_id)) { >> TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); >> - if (TemplateId->isInvalid()) >> - return true; >> - if (TemplateId->Kind != TNK_Type_template && >> - TemplateId->Kind != TNK_Dependent_template_name && >> - TemplateId->Kind != TNK_Undeclared_template) { >> + if (!TemplateId->mightBeType()) { >> Diag(Tok, diag::err_typename_refers_to_non_type_template) >> << Tok.getAnnotationRange(); >> return true; >> @@ -1891,14 +1887,13 @@ bool Parser::TryAnnotateTypeOrScopeToken() { >> ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(), >> TemplateId->NumArgs); >> >> - Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS, >> - TemplateId->TemplateKWLoc, >> - TemplateId->Template, >> - TemplateId->Name, >> - TemplateId->TemplateNameLoc, >> - TemplateId->LAngleLoc, >> - TemplateArgsPtr, >> - TemplateId->RAngleLoc); >> + Ty = TemplateId->isInvalid() >> + ? TypeError() >> + : Actions.ActOnTypenameType( >> + getCurScope(), TypenameLoc, SS, >> TemplateId->TemplateKWLoc, >> + TemplateId->Template, TemplateId->Name, >> + TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, >> + TemplateArgsPtr, TemplateId->RAngleLoc); >> } else { >> Diag(Tok, diag::err_expected_type_name_after_typename) >> << SS.getRange(); >> >> diff --git a/clang/lib/Sema/SemaTemplate.cpp >> b/clang/lib/Sema/SemaTemplate.cpp >> index 74d1fbe2ec77..1e2ebc5037bc 100755 >> --- a/clang/lib/Sema/SemaTemplate.cpp >> +++ b/clang/lib/Sema/SemaTemplate.cpp >> @@ -377,6 +377,9 @@ bool Sema::LookupTemplateName(LookupResult &Found, >> if (ATK) >> *ATK = AssumedTemplateKind::None; >> >> + if (SS.isInvalid()) >> + return true; >> + >> Found.setTemplateNameLookup(true); >> >> // Determine where to perform name lookup >> @@ -386,7 +389,7 @@ bool Sema::LookupTemplateName(LookupResult &Found, >> if (!ObjectType.isNull()) { >> // This nested-name-specifier occurs in a member access expression, >> e.g., >> // x->B::f, and we are looking into the type of the object. >> - assert(!SS.isSet() && "ObjectType and scope specifier cannot >> coexist"); >> + assert(SS.isEmpty() && "ObjectType and scope specifier cannot >> coexist"); >> LookupCtx = computeDeclContext(ObjectType); >> IsDependent = !LookupCtx && ObjectType->isDependentType(); >> assert((IsDependent || !ObjectType->isIncompleteType() || >> @@ -412,11 +415,11 @@ bool Sema::LookupTemplateName(LookupResult &Found, >> Found.clear(); >> return false; >> } >> - } else if (SS.isSet()) { >> + } else if (SS.isNotEmpty()) { >> // This nested-name-specifier occurs after another >> nested-name-specifier, >> // so long into the context associated with the prior >> nested-name-specifier. >> LookupCtx = computeDeclContext(SS, EnteringContext); >> - IsDependent = !LookupCtx; >> + IsDependent = !LookupCtx && isDependentScopeSpecifier(SS); >> >> // The declaration context must be complete. >> if (LookupCtx && RequireCompleteDeclContext(SS, LookupCtx)) >> @@ -443,7 +446,7 @@ bool Sema::LookupTemplateName(LookupResult &Found, >> IsDependent |= Found.wasNotFoundInCurrentInstantiation(); >> } >> >> - if (!SS.isSet() && (ObjectType.isNull() || Found.empty())) { >> + if (SS.isEmpty() && (ObjectType.isNull() || Found.empty())) { >> // C++ [basic.lookup.classref]p1: >> // In a class member access expression (5.2.5), if the . or -> >> token is >> // immediately followed by an identifier followed by a <, the >> @@ -470,7 +473,7 @@ bool Sema::LookupTemplateName(LookupResult &Found, >> if (Found.isAmbiguous()) >> return false; >> >> - if (ATK && !SS.isSet() && ObjectType.isNull() && >> TemplateKWLoc.isInvalid()) { >> + if (ATK && SS.isEmpty() && ObjectType.isNull() && >> TemplateKWLoc.isInvalid()) { >> // C++2a [temp.names]p2: >> // A name is also considered to refer to a template if it is an >> // unqualified-id followed by a < and name lookup finds either one >> or more >> @@ -3470,6 +3473,10 @@ QualType Sema::CheckTemplateIdType(TemplateName >> Name, >> >> DTN->getIdentifier(), >> TemplateArgs); >> >> + if (Name.getAsAssumedTemplateName() && >> + resolveAssumedTemplateNameAsType(/*Scope*/nullptr, Name, >> TemplateLoc)) >> + return QualType(); >> + >> TemplateDecl *Template = Name.getAsTemplateDecl(); >> if (!Template || isa(Template) || >> isa(Template) || isa(Template)) { >> @@ -4652,95 +4659,111 @@ TemplateNameKind Sema::ActOnTemplateName(Scope >> *S, >> diag::ext_template_outside_of_template) >> << FixItHint::CreateRemoval(TemplateKWLoc); >> >> + if (SS.isInvalid()) >> + return TNK_Non_template; >> + >> + // Figure out where isTemplateName is going to look. >> DeclContext *LookupCtx = nullptr; >> - if (SS.isSet()) >> + if (SS.isNotEmpty()) >> LookupCtx = computeDeclContext(SS, EnteringContext); >> - if (!LookupCtx && ObjectType) >> - LookupCtx = computeDeclContext(ObjectType.get()); >> - if (LookupCtx) { >> - // C++0x [temp.names]p5: >> - // If a name prefixed by the keyword template is not the name of >> - // a template, the program is ill-formed. [Note: the keyword >> - // template may not be applied to non-template members of class >> - // templates. -end note ] [ Note: as is the case with the >> - // typename prefix, the template prefix is allowed in cases >> - // where it is not strictly necessary; i.e., when the >> - // nested-name-specifier or the expression on the left of the -> >> - // or . is not dependent on a template-parameter, or the use >> - // does not appear in the scope of a template. -end note] >> - // >> - // Note: C++03 was more strict here, because it banned the use of >> - // the "template" keyword prior to a template-name that was not a >> - // dependent name. C++ DR468 relaxed this requirement (the >> - // "template" keyword is now permitted). We follow the C++0x >> - // rules, even in C++03 mode with a warning, retroactively applying >> the DR. >> - bool MemberOfUnknownSpecialization; >> - TemplateNameKind TNK = isTemplateName(S, SS, >> TemplateKWLoc.isValid(), Name, >> - ObjectType, EnteringContext, >> Result, >> - MemberOfUnknownSpecialization); >> - if (TNK == TNK_Non_template && MemberOfUnknownSpecialization) { >> - // This is a dependent template. Handle it below. >> - } else if (TNK == TNK_Non_template) { >> - // Do the lookup again to determine if this is a "nothing found" >> case or >> - // a "not a template" case. FIXME: Refactor isTemplateName so we >> don't >> - // need to do this. >> - DeclarationNameInfo DNI = GetNameFromUnqualifiedId(Name); >> - LookupResult R(*this, DNI.getName(), Name.getBeginLoc(), >> - LookupOrdinaryName); >> - bool MOUS; >> - if (!LookupTemplateName(R, S, SS, ObjectType.get(), >> EnteringContext, >> - MOUS, TemplateKWLoc) && !R.isAmbiguous()) >> + else if (ObjectType) >> + LookupCtx = computeDeclContext(GetTypeFromParser(ObjectType)); >> + >> + // C++0x [temp.names]p5: >> + // If a name prefixed by the keyword template is not the name of >> + // a template, the program is ill-formed. [Note: the keyword >> + // template may not be applied to non-template members of class >> + // templates. -end note ] [ Note: as is the case with the >> + // typename prefix, the template prefix is allowed in cases >> + // where it is not strictly necessary; i.e., when the >> + // nested-name-specifier or the expression on the left of the -> >> + // or . is not dependent on a template-parameter, or the use >> + // does not appear in the scope of a template. -end note] >> + // >> + // Note: C++03 was more strict here, because it banned the use of >> + // the "template" keyword prior to a template-name that was not a >> + // dependent name. C++ DR468 relaxed this requirement (the >> + // "template" keyword is now permitted). We follow the C++0x >> + // rules, even in C++03 mode with a warning, retroactively applying >> the DR. >> + bool MemberOfUnknownSpecialization; >> + TemplateNameKind TNK = isTemplateName(S, SS, TemplateKWLoc.isValid(), >> Name, >> + ObjectType, EnteringContext, >> Result, >> + MemberOfUnknownSpecialization); >> + if (TNK != TNK_Non_template) { >> + // We resolved this to a (non-dependent) template name. Return it. >> + auto *LookupRD = dyn_cast_or_null(LookupCtx); >> + if (!AllowInjectedClassName && SS.isNotEmpty() && LookupRD && >> + Name.getKind() == UnqualifiedIdKind::IK_Identifier && >> + Name.Identifier && LookupRD->getIdentifier() == Name.Identifier) >> { >> + // C++14 [class.qual]p2: >> + // In a lookup in which function names are not ignored and the >> + // nested-name-specifier nominates a class C, if the name >> specified >> + // [...] is the injected-class-name of C, [...] the name is >> instead >> + // considered to name the constructor >> + // >> + // We don't get here if naming the constructor would be valid, so >> we >> + // just reject immediately and recover by treating the >> + // injected-class-name as naming the template. >> + Diag(Name.getBeginLoc(), >> + diag::ext_out_of_line_qualified_id_type_names_constructor) >> + << Name.Identifier >> + << 0 /*injected-class-name used as template name*/ >> + << TemplateKWLoc.isValid(); >> + } >> + return TNK; >> + } >> + >> + if (!MemberOfUnknownSpecialization) { >> + // Didn't find a template name, and the lookup wasn't dependent. >> + // Do the lookup again to determine if this is a "nothing found" >> case or >> + // a "not a template" case. FIXME: Refactor isTemplateName so we >> don't >> + // need to do this. >> + DeclarationNameInfo DNI = GetNameFromUnqualifiedId(Name); >> + LookupResult R(*this, DNI.getName(), Name.getBeginLoc(), >> + LookupOrdinaryName); >> + bool MOUS; >> + // FIXME: If LookupTemplateName fails here, we'll have produced its >> + // diagnostics twice. >> + if (!LookupTemplateName(R, S, SS, ObjectType.get(), EnteringContext, >> + MOUS, TemplateKWLoc) && !R.isAmbiguous()) { >> + if (LookupCtx) >> Diag(Name.getBeginLoc(), diag::err_no_member) >> << DNI.getName() << LookupCtx << SS.getRange(); >> - return TNK_Non_template; >> - } else { >> - // We found something; return it. >> - auto *LookupRD = dyn_cast(LookupCtx); >> - if (!AllowInjectedClassName && SS.isSet() && LookupRD && >> - Name.getKind() == UnqualifiedIdKind::IK_Identifier && >> - Name.Identifier && LookupRD->getIdentifier() == >> Name.Identifier) { >> - // C++14 [class.qual]p2: >> - // In a lookup in which function names are not ignored and the >> - // nested-name-specifier nominates a class C, if the name >> specified >> - // [...] is the injected-class-name of C, [...] the name is >> instead >> - // considered to name the constructor >> - // >> - // We don't get here if naming the constructor would be valid, >> so we >> - // just reject immediately and recover by treating the >> - // injected-class-name as naming the template. >> - Diag(Name.getBeginLoc(), >> - diag::ext_out_of_line_qualified_id_type_names_constructor) >> - << Name.Identifier >> - << 0 /*injected-class-name used as template name*/ >> - << 1 /*'template' keyword was used*/; >> - } >> - return TNK; >> + else >> + Diag(Name.getBeginLoc(), diag::err_undeclared_use) >> + << DNI.getName() << SS.getRange(); >> } >> + return TNK_Non_template; >> } >> >> NestedNameSpecifier *Qualifier = SS.getScopeRep(); >> >> switch (Name.getKind()) { >> case UnqualifiedIdKind::IK_Identifier: >> - Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier, >> - >> Name.Identifier)); >> + Result = TemplateTy::make( >> + Context.getDependentTemplateName(Qualifier, Name.Identifier)); >> return TNK_Dependent_template_name; >> >> case UnqualifiedIdKind::IK_OperatorFunctionId: >> - Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier, >> - >> Name.OperatorFunctionId.Operator)); >> + Result = TemplateTy::make(Context.getDependentTemplateName( >> + Qualifier, Name.OperatorFunctionId.Operator)); >> return TNK_Function_template; >> >> case UnqualifiedIdKind::IK_LiteralOperatorId: >> - llvm_unreachable("literal operator id cannot have a dependent >> scope"); >> + // This is a kind of template name, but can never occur in a >> dependent >> + // scope (literal operators can only be declared at namespace scope). >> + break; >> >> default: >> break; >> } >> >> - Diag(Name.getBeginLoc(), diag::err_template_kw_refers_to_non_template) >> + // This name cannot possibly name a dependent template. Diagnose this >> now >> + // rather than building a dependent template name that can never be >> valid. >> + Diag(Name.getBeginLoc(), >> + diag::err_template_kw_refers_to_dependent_non_template) >> << GetNameFromUnqualifiedId(Name).getName() << >> Name.getSourceRange() >> - << TemplateKWLoc; >> + << TemplateKWLoc.isValid() << TemplateKWLoc; >> return TNK_Non_template; >> } >> >> >> diff --git a/clang/test/Parser/cxx-decl.cpp >> b/clang/test/Parser/cxx-decl.cpp >> index ba1cce419a46..dbf3a3e70bb0 100644 >> --- a/clang/test/Parser/cxx-decl.cpp >> +++ b/clang/test/Parser/cxx-decl.cpp >> @@ -240,8 +240,7 @@ namespace PR17255 { >> void foo() { >> typename A::template B<> c; // expected-error {{use of undeclared >> identifier 'A'}} >> #if __cplusplus <= 199711L >> - // expected-error at -2 {{'typename' occurs outside of a template}} >> - // expected-error at -3 {{'template' keyword outside of a template}} >> + // expected-error at -2 {{'template' keyword outside of a template}} >> #endif >> } >> } >> >> diff --git a/clang/test/SemaCXX/literal-operators.cpp >> b/clang/test/SemaCXX/literal-operators.cpp >> index 304aa7cab7f3..834d5ec7923e 100644 >> --- a/clang/test/SemaCXX/literal-operators.cpp >> +++ b/clang/test/SemaCXX/literal-operators.cpp >> @@ -47,3 +47,7 @@ template void operator "" >> _invalid(); // expected-error >> _Complex float operator""if(long double); // expected-warning >> {{reserved}} >> _Complex float test_if_1() { return 2.0f + 1.5if; }; >> void test_if_2() { "foo"if; } // expected-error {{no matching literal >> operator for call to 'operator""if'}} >> + >> +template void dependent_member_template() { >> + T().template operator""_foo(); // expected-error >> {{'operator""_foo' following the 'template' keyword cannot refer to a >> dependent template}} >> +} >> >> diff --git a/clang/test/SemaCXX/pseudo-destructors.cpp >> b/clang/test/SemaCXX/pseudo-destructors.cpp >> index b71b523de683..292324893dd0 100644 >> --- a/clang/test/SemaCXX/pseudo-destructors.cpp >> +++ b/clang/test/SemaCXX/pseudo-destructors.cpp >> @@ -119,3 +119,54 @@ void test2(Foo d) { >> d.~Derived(); // expected-error {{member reference type >> 'dotPointerAccess::Foo' (aka 'dotPointerAccess::Derived *') is a pointer; >> did you mean to use '->'}} >> } >> } >> + >> +int pr45294 = 1 .~undeclared_tempate_name<>(); // expected-error {{use >> of undeclared 'undeclared_tempate_name'}} >> + >> +namespace TwoPhaseLookup { >> + namespace NonTemplate { >> + struct Y {}; >> + using G = Y; >> + template void f(T *p) { p->~G(); } // expected-error >> {{no member named '~Y'}} >> + void h1(Y *p) { p->~G(); } >> + void h2(Y *p) { f(p); } >> + namespace N { struct G{}; } >> + void h3(N::G *p) { p->~G(); } >> + void h4(N::G *p) { f(p); } // expected-note {{instantiation of}} >> + } >> + >> + namespace NonTemplateUndeclared { >> + struct Y {}; >> + template void f(T *p) { p->~G(); } // expected-error >> {{undeclared identifier 'G' in destructor name}} >> + using G = Y; >> + void h1(Y *p) { p->~G(); } >> + void h2(Y *p) { f(p); } // expected-note {{instantiation of}} >> + namespace N { struct G{}; } >> + void h3(N::G *p) { p->~G(); } >> + void h4(N::G *p) { f(p); } >> + } >> + >> + namespace Template { >> + template struct Y {}; >> + template using G = Y; >> + template void f(T *p) { p->~G(); } // >> expected-error {{no member named '~Y'}} >> + void h1(Y *p) { p->~G(); } >> + void h2(Y *p) { f(p); } >> + namespace N { template struct G {}; } >> + void h3(N::G *p) { p->~G(); } >> + void h4(N::G *p) { f(p); } // expected-note {{instantiation of}} >> + } >> + >> + namespace TemplateUndeclared { >> + template struct Y {}; >> + // FIXME: Formally, this is ill-formed before we hit any >> instantiation, >> + // because we aren't supposed to treat the '<' as introducing a >> template >> + // name. >> + template void f(T *p) { p->~G(); } // >> expected-error {{no member named 'G'}} >> + template using G = Y; >> + void h1(Y *p) { p->~G(); } >> + void h2(Y *p) { f(p); } // expected-note {{instantiation of}} >> + namespace N { template struct G {}; } >> + void h3(N::G *p) { p->~G(); } >> + void h4(N::G *p) { f(p); } >> + } >> +} >> >> diff --git a/clang/test/SemaTemplate/nested-name-spec-template.cpp >> b/clang/test/SemaTemplate/nested-name-spec-template.cpp >> index 3e7f506040a6..07dd41bfe27b 100644 >> --- a/clang/test/SemaTemplate/nested-name-spec-template.cpp >> +++ b/clang/test/SemaTemplate/nested-name-spec-template.cpp >> @@ -142,8 +142,7 @@ namespace PR9449 { >> >> template >> void f() { >> - int s::template n::* f; // expected-error{{implicit >> instantiation of undefined template 'PR9449::s'}} \ >> - // expected-error{{no member named 'n'}} >> + int s::template n::* f; // expected-error{{implicit >> instantiation of undefined template 'PR9449::s'}} >> } >> >> template void f(); // expected-note{{in instantiation of}} >> >> >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits at lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > _______________________________________________ > cfe-commits mailing list > cfe-commits at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cfe-commits at lists.llvm.org Mon Mar 30 19:08:48 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 02:08:48 +0000 (UTC) Subject: [PATCH] D77112: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` Message-ID: jdoerfert created this revision. jdoerfert added reviewers: lebedev.ri, JonChesterfield, ABataev. Herald added subscribers: martong, jfb, arphaman, guansong, bollu, hiraditya, mgorny, jholewinski. Herald added a project: clang. This is a cleanup and normalization patch that also enables reuse with Flang later on. A follow up will clean up and move the directive -> clauses mapping. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77112 Files: clang/include/clang/AST/ASTFwd.h clang/include/clang/AST/ASTTypeTraits.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/Basic/Attr.td clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Basic/OpenMPKinds.h clang/lib/AST/ASTTypeTraits.cpp clang/lib/AST/AttrImpl.cpp clang/lib/AST/OpenMPClause.cpp clang/lib/AST/StmtProfile.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/ASTMatchers/CMakeLists.txt clang/lib/ASTMatchers/Dynamic/Marshallers.h clang/lib/Analysis/CMakeLists.txt clang/lib/Basic/OpenMPKinds.cpp clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt clang/lib/StaticAnalyzer/Core/CMakeLists.txt clang/tools/libclang/CIndex.cpp llvm/include/llvm/Frontend/OpenMP/OMPConstants.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPConstants.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77112.253765.patch Type: text/x-patch Size: 117344 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 19:08:50 2020 From: cfe-commits at lists.llvm.org (Richard Smith - zygoloid via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 02:08:50 +0000 (UTC) Subject: [PATCH] D77081: [MS] Mark vbase dtors ref'd when ref'ing dtor In-Reply-To: References: Message-ID: <6e78032a5c3d389e340fc67da182bcbf@localhost.localdomain> rsmith marked an inline comment as done. rsmith added inline comments. ================ Comment at: clang/lib/Sema/SemaExpr.cpp:16008-16013 + // In the MS ABI, the complete destructor is implicitly defined, + // even if the base destructor is user defined. + CXXRecordDecl *Parent = Destructor->getParent(); + if (Parent->getNumVBases() > 0 && + !Parent->definedImplicitCompleteDestructor()) + DefineImplicitCompleteDestructor(Loc, Destructor); ---------------- rnk wrote: > rsmith wrote: > > Can we avoid doing this when we know the call is to a base subobject destructor or uses virtual dispatch? Should we? (I mean I guess ideally we'd change this function to take a `GlobalDecl` instead of a `FunctionDecl*`, but that seems like a lot of work.) > > > > How does MSVC behave? > I think we can skip this if virtual dispatch is used, but I'm not sure what kinds of devirtualization might break my assumptions. > > For example, uncommenting `final` here causes MSVC to diagnose the error, but it otherwise it compiles: > ``` > struct NoDtor { ~NoDtor() = delete; }; > struct DefaultedDtor : NoDtor { ~DefaultedDtor() = default; }; > struct HasVBases /*final*/ : virtual DefaultedDtor { > virtual ~HasVBases(); > }; > void deleteIt1(HasVBases *p) { delete p; } > ``` > > If the NoDtor destructor is undeleted and the class is made final, then both deleting and complete dtors are emitted for HasVBases. Clang would need to mark DefaultedDtor referenced in this case. > > I think it's OK to "overdiagnose" in this case. It's not possible to emit a vtable here without diagnosing the error. Great, if we're happy to treat all uses of the destructor as using the complete object destructor, then doing this work as part of marking the destructor used seems like it would be the best solution. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77081/new/ https://reviews.llvm.org/D77081 From cfe-commits at lists.llvm.org Mon Mar 30 19:41:20 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 02:41:20 +0000 (UTC) Subject: [PATCH] D77113: [OpenMP][NFC] Move and simplify directive -> allowed clause mapping Message-ID: jdoerfert created this revision. jdoerfert added reviewers: lebedev.ri, JonChesterfield, ABataev. Herald added subscribers: jfb, guansong, bollu, hiraditya. Herald added a project: clang. jdoerfert added a reviewer: fghanim. Move the listing of allowed clauses per OpenMP directive to the new macro file in `llvm/Frontend/OpenMP`. Also, use a single generic macro that specifies the directive and one allowed clause explicitly instead of a dedicated macro per directive. We save 800 loc and boilerplate for all new directives/clauses with no functional change. We also need to include the macro file only once and not once per directive. Depends on D77112 . Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77113 Files: clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Basic/OpenMPKinds.h clang/lib/Basic/OpenMPKinds.cpp llvm/include/llvm/Frontend/OpenMP/OMPConstants.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPConstants.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77113.253770.patch Type: text/x-patch Size: 103093 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 20:13:42 2020 From: cfe-commits at lists.llvm.org (Zarko Todorovski via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 03:13:42 +0000 (UTC) Subject: [PATCH] D76130: [PPC][AIX] Implement variadic function handling in LowerFormalArguments_AIX In-Reply-To: References: Message-ID: <86894fa74cfc5033569a004c86caa1dc@localhost.localdomain> ZarkoCA marked 2 inline comments as done. ZarkoCA added inline comments. ================ Comment at: llvm/test/CodeGen/PowerPC/aix32-cc-abi-vaarg.ll:17 + call void @llvm.va_start(i8* nonnull %0) + call void @llvm.va_copy(i8* nonnull %0, i8* nonnull %0) + %argp.cur = load i8*, i8** %arg, align 4 ---------------- jasonliu wrote: > I think it would be more clear if we actually have another va_list to copy instead of just va_copying itself. The same applies to all the places we call va_copy. > Also it's not very clear to me which part in the check result actually tells me about the effect of the va_copy though. Those are both good points. I'm rewriting the test and adding comments to the IR/assembly to make it clearer. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76130/new/ https://reviews.llvm.org/D76130 From cfe-commits at lists.llvm.org Mon Mar 30 20:46:06 2020 From: cfe-commits at lists.llvm.org (Zarko Todorovski via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 03:46:06 +0000 (UTC) Subject: [PATCH] D76130: [PPC][AIX] Implement variadic function handling in LowerFormalArguments_AIX In-Reply-To: References: Message-ID: <958d85585fb4b8c9edaae5ccb754a748@localhost.localdomain> ZarkoCA updated this revision to Diff 253774. ZarkoCA added a comment. Rebased to include byval changes. Fixed name of array. Fixed up test case as per comment. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76130/new/ https://reviews.llvm.org/D76130 Files: llvm/lib/Target/PowerPC/PPCISelLowering.cpp llvm/test/CodeGen/PowerPC/aix32-cc-abi-vaarg.ll llvm/test/CodeGen/PowerPC/aix64-cc-abi-vaarg.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D76130.253774.patch Type: text/x-patch Size: 41876 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 20:46:07 2020 From: cfe-commits at lists.llvm.org (Zarko Todorovski via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 03:46:07 +0000 (UTC) Subject: [PATCH] D76360: [PPC][AIX] Emit correct Vaarg for 32BIT-AIX in clang In-Reply-To: References: Message-ID: ZarkoCA updated this revision to Diff 253776. ZarkoCA added a comment. Fixed test cases to use builtins again, set no soft float abi for AIX. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76360/new/ https://reviews.llvm.org/D76360 Files: clang/lib/Basic/Targets/PPC.h clang/lib/CodeGen/TargetInfo.cpp clang/test/CodeGen/aix-vararg.c clang/test/CodeGen/aix32-dwarf-error.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D76360.253776.patch Type: text/x-patch Size: 6850 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 20:46:07 2020 From: cfe-commits at lists.llvm.org (Zarko Todorovski via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 03:46:07 +0000 (UTC) Subject: [PATCH] D76360: [PPC][AIX] Emit correct Vaarg for 32BIT-AIX in clang In-Reply-To: References: Message-ID: ZarkoCA marked 4 inline comments as done. ZarkoCA added inline comments. ================ Comment at: clang/lib/CodeGen/TargetInfo.cpp:10019 + return SetCGInfo( + new PPCAIX32TargetCodeGenInfo(Types, CodeGenOpts.FloatABI == "soft")); return SetCGInfo( ---------------- jasonliu wrote: > Does AIX have soft Float? If not, do we want to always pass in 'false'? Thanks, missed changing this. I set it to hard. ================ Comment at: clang/test/CodeGen/aix-vararg.c:4 +// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -emit-llvm -o - %s | FileCheck %s --check-prefix=32BIT +#include + ---------------- jasonliu wrote: > Any reason we don't use __builtin_va... any more? My mistake, I somehow included the old version of the test in the diff. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76360/new/ https://reviews.llvm.org/D76360 From cfe-commits at lists.llvm.org Mon Mar 30 20:46:07 2020 From: cfe-commits at lists.llvm.org (Csaba Dabis via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 03:46:07 +0000 (UTC) Subject: [PATCH] D73521: [analyzer] add-new-checker.py: Introduction In-Reply-To: References: Message-ID: Charusso added a comment. In D73521#1923693 , @NoQ wrote: > Or is each test run updating the repo? Can we simply make the script do `cat DummyChecker.cpp | sed s/DummyChecker/$NAME/g > $NAME.cpp` and store the checker only once? It was updating, yes. The first idea was to copy over the live checker, but I wanted to make it as portable as possible. ================ Comment at: clang/utils/analyzer/add-new-checker.py:714-715 + help='the path to llvm-tblgen') + parser.add_argument('--force-creation', dest='is_force_creation', + action='store_true', help=argparse.SUPPRESS) + parser.add_argument('--test', dest='is_test', ---------------- NoQ wrote: > So, `--overwrite` and add help? It was only made for the test. Removed. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73521/new/ https://reviews.llvm.org/D73521 From cfe-commits at lists.llvm.org Mon Mar 30 20:46:07 2020 From: cfe-commits at lists.llvm.org (Csaba Dabis via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 03:46:07 +0000 (UTC) Subject: [PATCH] D73521: [analyzer] add-new-checker.py: Introduction In-Reply-To: References: Message-ID: Charusso updated this revision to Diff 253777. Charusso marked 3 inline comments as done. Charusso added a comment. Herald added a subscriber: ASDenysPetrov. - Remove the test of creating a live checker, instead copy over the live checker when the script runs. - Simplify the script by adding the new package to the end of the file. - In case of the `checkers.rst` a non-alpha package is going to be added before the alpha packages. - According to this change simplify the tests. - `DummyChecker` -> `ExampleChecker`. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73521/new/ https://reviews.llvm.org/D73521 Files: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt clang/lib/StaticAnalyzer/Checkers/ExampleChecker.cpp clang/test/Analysis/add-new-checker/add-main-package.rst clang/test/Analysis/add-new-checker/add-main-package.td clang/test/Analysis/add-new-checker/add-multiple-packages.rst clang/test/Analysis/add-new-checker/add-multiple-packages.td clang/test/Analysis/add-new-checker/check-add-new-checker.py clang/test/Analysis/add-new-checker/checker-name.rst clang/test/Analysis/add-new-checker/checker-name.td clang/test/Analysis/add-new-checker/flow-package-exist-checker.rst clang/test/Analysis/add-new-checker/flow-package-exist-checker.td clang/test/Analysis/add-new-checker/flow-package-not-exist.rst clang/test/Analysis/add-new-checker/flow-package-not-exist.td clang/test/Analysis/add-new-checker/lit.local.cfg.py clang/test/Analysis/example-checker.cpp clang/utils/analyzer/add-new-checker.py -------------- next part -------------- A non-text attachment was scrubbed... Name: D73521.253777.patch Type: text/x-patch Size: 45796 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 21:18:19 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 04:18:19 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift In-Reply-To: References: Message-ID: <7bd162505a75e7faac371ade81602624@localhost.localdomain> rjmccall added inline comments. ================ Comment at: clang/include/clang/CodeGen/CodeGenABITypes.h:148 + llvm::function_ref + createProtocolReference); } // end namespace CodeGen ---------------- aschwaighofer wrote: > rjmccall wrote: > > I would call this `emitObjCProtocolObject` or something, and maybe say in the comment: > > > > > Get a pointer to a protocol object for the given declaration, emitting it if it hasn't already been emitted in this translation unit. Note that the ABI for emitting a protocol reference in code (e.g. for a `@protocol` expression) in most runtimes is not as simple as just materializing a pointer to this object. > > > > Can you explain the need for the callback? Are you expecting to use this for Swift-declared protocols by synthesizing an ObjC protocol declaration for them? I can see why you'd need a callback in that case. > > Can you explain the need for the callback? Are you expecting to use this for Swift-declared protocols by synthesizing an ObjC protocol declaration for them? I can see why you'd need a callback in that case. > > The objective C protocol references other protocols in its inherited list. Swift has an internal list that keeps track of those protocols references and makes sure to initialized them for the debugger and also makes sure that the underlying protocol structure is emitted. The call back is to keep this list in sync. The problem is that this is really, really intertwined with the ABI logic. This callback basically has to know exactly how the caller is calling it and and what it's expected to build in response. Swift code can use arbitrary inline Objective-C functions and therefore emit arbitrary Objective-C code. Is there an approach that handles that while also being less invasive for Clang IRGen? Can we, e.g., inspect the built llvm::Module to figure out retroactively what protocol refs we need to update dynamically instead of trying to track them during the build? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77077/new/ https://reviews.llvm.org/D77077 From cfe-commits at lists.llvm.org Mon Mar 30 21:50:27 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 04:50:27 +0000 (UTC) Subject: [PATCH] D76937: Fix infinite recursion in deferred diagnostic emitter In-Reply-To: References: Message-ID: <830f4e447b646db311f8bc533abb638f@localhost.localdomain> rjmccall added a comment. In D76937#1950764 , @yaxunl wrote: > In D76937#1950077 , @rjmccall wrote: > > > Can you explain what exactly the emission/semantic model is for variables? Normal code-generation absolutely triggers the emission of many variables lazily (e.g. internal-linkage globals, C++ inline variables); and any variable that's *not* being emitted lazily actually needs to be treated as a potential root into the delayed-diagnostic graph. > > > Currently only in the following case a global variable can change the emission state of a function: > > int foobar3() { return 1; } > #pragma omp declare target > int (*C)() = &foobar3; > #pragma omp end declare target > > > The global variable needs to be in a omp declare target directive. Its initializer references a host function. > > This will cause the function emitted in device compilation. > > This is not transitive for variable declaration/references, e.g. the following case will not cause foobar3 to be emitted in device compilation, unless variable C itself is enclosed in omp declare target directive. > > int foobar3() { return 1; } > int (*C)() = &foobar3; > #pragma omp declare target > int (*D)() = C; > #pragma omp end declare target > > > Since we logged all such variable declarations in DeclsToCheckForDeferredDiags, we only need to check variables decls in DeclsToCheckForDeferredDiags and do not need to check variable decls in DeclRefExpr. Okay. There are other AST nodes besides `DeclRefExpr` that can cause an ODR-use of a `VarDecl`; you could add special cases for them, too, but part of the point of this design is so that you can stop worrying about that kind of thing. I think I've said this before, but you're making things harder for yourself by re-using `visitUsedDecl` as both the "callback" of the `UsedDeclVisitor` and the original method that you call for things from `DeclsToCheckForDeferredDiags`. Just use `visitUsedDecl` for the former, make a new method for the latter, and extract any common logic you want (e.g. for `FunctionDecl`s) into helper methods that both of them can use. That way you can just unconditionally ignore non-functions in `visitUsedDecl`, assert that `DeclsToCheckForDeferredDiags` only contains the kinds of declarations you think it should, and so on. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76937/new/ https://reviews.llvm.org/D76937 From cfe-commits at lists.llvm.org Mon Mar 30 21:50:26 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 04:50:26 +0000 (UTC) Subject: [PATCH] D77028: [NFC] Refactor DeferredDiagsEmitter and skip redundant visit In-Reply-To: References: Message-ID: rjmccall added a comment. I made a suggestion in the other patch about restructuring things out of `visitUsedDecl`. I'll review this when that's done. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77028/new/ https://reviews.llvm.org/D77028 From cfe-commits at lists.llvm.org Mon Mar 30 22:22:35 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 05:22:35 +0000 (UTC) Subject: [PATCH] D74387: [SYCL] Defer __float128 type usage diagnostics In-Reply-To: References: Message-ID: <5108cf09831877a26793706e3bac25a0@localhost.localdomain> rjmccall added inline comments. ================ Comment at: clang/include/clang/Sema/Sema.h:12248 + /// SYCLDiagIfDeviceCode(Loc, diag::err_type_unsupported) << "__float128"; + DeviceDiagBuilder SYCLDiagIfDeviceCode(SourceLocation Loc, unsigned DiagID); + ---------------- Fznamznon wrote: > rjmccall wrote: > > Will this collect notes associated with the diagnostic correctly? > Could you please make your question a bit more concrete? > This function is supposed to work in the same way as `Sema::CUDADiagIfDeviceCode` and `Sema::diagIfOpenMPDeviceCode` . It emits given diagnostic if the current context is known as "device code" and makes this diagnostic deferred otherwise. It uses the `DeviceDiagBuilder` which was implemented earlier. This `DeviceDiagBuilder` also tries to emit callstack notes for the given diagnostics. Do you mean these callstack notes or something else? Logically, notes that are emitted after a warning or error are considered to be part of that diagnostic. A custom `DiagBuilder` that only redirects the main diagnostic but allows the notes to still be emitted will effectively cause those notes to misleadingly follow whatever previous diagnostic might have been emitted. I call this out specifically because some of the places where you're using this still seem to try to emit notes afterwards, at least in some cases. It's possible that `CUDADiagIfDeviceCode` happens to not be used in such a way. Really I'm not sure this conditional `DiagBuilder` approach was a good idea the first time, and I think we should probably reconsider rather than duplicating it. ================ Comment at: clang/lib/Sema/SemaAvailability.cpp:479 + case UnavailableAttr::IR_SYCLForbiddenType: + diag_available_here = diag::err_type_unsupported; + break; ---------------- Fznamznon wrote: > rjmccall wrote: > > All of the other cases are setting this to a note, not an error, so I suspect this will read wrong. > Yes, this is not a note. For such samples: > > ``` > int main() { > __float128 CapturedToDevice = 1; > kernel([=]() { > decltype(CapturedToDevice) D; > }); > } > ``` > It looks like this: > ``` > float128.cpp:63:14: error: 'CapturedToDevice' is unavailable > decltype(CapturedToDevice) D; > ^ > float128.cpp:59:14: error: '__float128' is not supported on this target /// This emitted instead of note > __float128 CapturedToDevice = 1; > ^ > ``` > I had feeling that it should probably be a note. But there is no implemented note for unsupported types. I think I can add a new one if it will make it better. Should I? Yeah, this should be a note, like "note: variable is unavailable because it uses a type '__float128' that is not supported on this target". You should add that. ================ Comment at: clang/lib/Sema/SemaAvailability.cpp:534 + if (S.getLangOpts().SYCLIsDevice) + S.SYCLDiagIfDeviceCode(Loc, diag) << ReferringDecl; + else ---------------- Fznamznon wrote: > rjmccall wrote: > > Are you sure you want to be applying this to all of the possible diagnostics here, rather than just for SYCLForbiddenType unavailable attributes? > I suppose it is reasonable if we want to reuse unavaliable attribute for other SYCL use cases. Plus, In SYCL we don't know where is device code until we instantiate templates, it happens late, so we have to defer any diagnostic while compiling for device, otherwise we can point to host code where much more is allowed. My point is actually the reverse of that. This code path is also used for normal `unavailable` attributes, not just the special ones you're synthesizing. Diagnostics from the use of explicitly-unavailable declarations shouldn't get any special treatment here, no more than you'd give special treatment to a diagnostic arising from an attempt to assign a pointer into a `float`. In the logic above where you recognize `IR_SYCLForbiddenType`, I think you should just check whether you should transitively defer the diagnostic and, if so, do so and then bail out of this function early. That might mean you don't need the custom DiagBuilder, too. ================ Comment at: clang/lib/Sema/SemaDecl.cpp:18030 + if (LangOpts.SYCLIsDevice && FD->hasAttr()) + return FunctionEmissionStatus::Emitted; + ---------------- Fznamznon wrote: > rjmccall wrote: > > So you want to emit it for the definition in addition to emitting it for specific specializations? > Somehow diagnostics are emitted only for the definitions. > Without this change diagnostics aren't emitted at all. Hmm. We might be marking the template pattern invalid; that could result in all sorts of diagnostics being suppressed. We definitely shouldn't be marking things invalid without emitting an eager diagnostic. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D74387/new/ https://reviews.llvm.org/D74387 From cfe-commits at lists.llvm.org Mon Mar 30 22:22:39 2020 From: cfe-commits at lists.llvm.org (Sam Clegg via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 05:22:39 +0000 (UTC) Subject: [PATCH] D77115: [WebAssembly] Emit .llvmcmd and .llvmbc as custom sections Message-ID: sbc100 created this revision. Herald added subscribers: cfe-commits, jfb, sunfish, aheejin, hiraditya, jgravelle-google, dschuff. Herald added a project: clang. sbc100 added reviewers: alexcrichton, sunfish. Fixes: https://bugs.llvm.org/show_bug.cgi?id=45362 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77115 Files: clang/test/Driver/embed-bitcode-wasm.c clang/test/Driver/fembed-bitcode.c llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp llvm/lib/MC/WasmObjectWriter.cpp Index: llvm/lib/MC/WasmObjectWriter.cpp =================================================================== --- llvm/lib/MC/WasmObjectWriter.cpp +++ llvm/lib/MC/WasmObjectWriter.cpp @@ -436,10 +436,6 @@ uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); MCContext &Ctx = Asm.getContext(); - // The .init_array isn't translated as data, so don't do relocations in it. - if (FixupSection.getSectionName().startswith(".init_array")) - return; - if (const MCSymbolRefExpr *RefB = Target.getSymB()) { // To get here the A - B expression must have failed evaluateAsRelocatable. // This means either A or B must be undefined and in WebAssembly we can't @@ -502,6 +498,10 @@ SymA->setUsedInReloc(); } + // The .init_array isn't translated as data, so don't do relocations in it. + if (FixupSection.getSectionName().startswith(".init_array")) + return; + if (RefA->getKind() == MCSymbolRefExpr::VK_GOT) SymA->setUsedInGOT(); @@ -1090,10 +1090,7 @@ if (Sym.isComdat() && !Sym.isDefined()) return false; - if (Sym.isTemporary() && Sym.getName().empty()) - return false; - - if (Sym.isTemporary() && Sym.isData() && !Sym.getSize()) + if (Sym.isTemporary()) return false; if (Sym.isSection()) @@ -1565,7 +1562,7 @@ report_fatal_error("fixups in .init_array should be symbol references"); const auto &TargetSym = cast(SymRef->getSymbol()); if (TargetSym.getIndex() == InvalidIndex) - report_fatal_error("symbols in .init_array should exist in symbtab"); + report_fatal_error("symbols in .init_array should exist in symtab"); if (!TargetSym.isFunction()) report_fatal_error("symbols in .init_array should be for functions"); InitFuncs.push_back( Index: llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp =================================================================== --- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1765,6 +1765,14 @@ StringRef Name = GO->getSection(); + // Certain data sections we treat as custom named section rather than + // segments within the data section. + // This could be avoided if all data segements in (the wasm sense) were + // represented as thier on sections (in the llvm sense). + // TODO(sbc): https://github.com/WebAssembly/tool-conventions/issues/138 + if (Name == ".llvmcmd" || Name == ".llvmbc") + Kind = SectionKind::getMetadata(); + StringRef Group = ""; if (const Comdat *C = getWasmComdat(GO)) { Group = C->getName(); Index: clang/test/Driver/fembed-bitcode.c =================================================================== --- clang/test/Driver/fembed-bitcode.c +++ clang/test/Driver/fembed-bitcode.c @@ -30,3 +30,12 @@ // RUN: | FileCheck --check-prefix=CHECK-HEXAGON %s // CHECK-HEXAGON: "-target-feature" // CHECK-HEXAGON: "+reserved-r19" +// +// RUN: %clang -target wasm32-unknown-unknown -fembed-bitcode=all -pthread -c %s -o /dev/null -### 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-WASM %s + +// CHECK-WASM: "-cc1" +// CHECK-WASM: "-target-feature" "+atomics" + +// CHECK-WASM: "-cc1" +// CHECK-WASM: "-target-feature" "+atomics" Index: clang/test/Driver/embed-bitcode-wasm.c =================================================================== --- /dev/null +++ clang/test/Driver/embed-bitcode-wasm.c @@ -0,0 +1,6 @@ +// REQUIRES: webassembly-registered-target + +// RUN: %clang -c -target wasm32-unknown-unknown %s -fembed-bitcode -o %t.o +// RUN: llvm-readobj -S %t.o | FileCheck --check-prefix=CHECK %s +// CHECK: Name: .llvmbc +// CHECK: Name: .llvmcmd -------------- next part -------------- A non-text attachment was scrubbed... Name: D77115.253780.patch Type: text/x-patch Size: 3698 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 22:55:05 2020 From: cfe-commits at lists.llvm.org (Vy Nguyen via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 05:55:05 +0000 (UTC) Subject: [PATCH] D77116: temp tests Message-ID: oontvoo created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77116 Files: clang/include/clang/Lex/HeaderSearch.h clang/include/clang/Lex/Preprocessor.h clang/include/clang/Serialization/ASTBitCodes.h clang/include/clang/Serialization/ASTReader.h clang/include/clang/Serialization/ASTWriter.h clang/lib/Lex/HeaderSearch.cpp clang/lib/Lex/PPDirectives.cpp clang/lib/Lex/PPLexerChange.cpp clang/lib/Lex/Preprocessor.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/test/Modules/Inputs/dummy_pragma_once.h clang/test/Modules/Inputs/dummy_textual_header.h clang/test/Modules/Inputs/header_in_imported_module.h clang/test/Modules/Inputs/imported_module.cppm clang/test/Modules/Inputs/module.map clang/test/Modules/header-in-imported-module.c clang/test/Modules/import-pragma-once.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77116.253783.patch Type: text/x-patch Size: 30869 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Mon Mar 30 23:25:40 2020 From: cfe-commits at lists.llvm.org (Dylan McKay via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 06:25:40 +0000 (UTC) Subject: [PATCH] D76182: [AVR] Support aliases in non-zero address space In-Reply-To: References: Message-ID: <7c3ab5196f5fda018fc84af6b1eb69c9@localhost.localdomain> dylanmckay added a comment. I think we should add a test, it shouldn't be too hard I think. Look in `clang/tests`, grep for `alias`. Look like it is `extern const int __mod_usb_device_table __attribute__ ((alias("wacom_usb_ids")));`. If you copy paste a new test (use `clang/test/CodeGen/alias.c` as a reference. You can also look for files with `avr` in the name under the `test` folder to see how to add an AVR-specific test. You should be able to 1) define a function alias of another function and 2) `CHECK` that the final IR has address space attributes, even when the alias symbol is used instead of the original symbol. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76182/new/ https://reviews.llvm.org/D76182 From cfe-commits at lists.llvm.org Mon Mar 30 23:25:40 2020 From: cfe-commits at lists.llvm.org (Dylan McKay via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 06:25:40 +0000 (UTC) Subject: [PATCH] D76182: [AVR] Support aliases in non-zero address space In-Reply-To: References: Message-ID: dylanmckay added a comment. Nice patch by the way, the code looks fine, if we can get a basic test in here then it's good to go Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76182/new/ https://reviews.llvm.org/D76182 From cfe-commits at lists.llvm.org Tue Mar 31 00:31:01 2020 From: cfe-commits at lists.llvm.org (Ulrich Weigand via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 07:31:01 +0000 (UTC) Subject: [PATCH] D75914: systemz: allow configuring default CLANG_SYSTEMZ_ARCH In-Reply-To: References: Message-ID: <027950fac282b5a3cdbc66a72a7a8e23@localhost.localdomain> uweigand added a comment. Thanks for working on this, @thakis ! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75914/new/ https://reviews.llvm.org/D75914 From cfe-commits at lists.llvm.org Tue Mar 31 00:31:00 2020 From: cfe-commits at lists.llvm.org (Marcel Hlopko via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 07:31:00 +0000 (UTC) Subject: [PATCH] D76922: [Syntax] Remove delayed folding from tree building. In-Reply-To: References: Message-ID: hlopko updated this revision to Diff 253787. hlopko marked an inline comment as done. hlopko added a comment. Remove unnecessary cast Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76922/new/ https://reviews.llvm.org/D76922 Files: clang/lib/Tooling/Syntax/BuildTree.cpp clang/lib/Tooling/Syntax/Tokens.cpp clang/unittests/Tooling/Syntax/TreeTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76922.253787.patch Type: text/x-patch Size: 23544 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 00:31:01 2020 From: cfe-commits at lists.llvm.org (Marcel Hlopko via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 07:31:01 +0000 (UTC) Subject: [PATCH] D76922: [Syntax] Remove delayed folding from tree building. In-Reply-To: References: Message-ID: <62b08726bc3d36462ae78cf7acca04ec@localhost.localdomain> hlopko added a comment. I propose adding those tests in a separate patch to keep this one focused. Those tests are currently failing, because: - we assume initializer, if present, is extending the declarator range, but `struct P {} p;` has initializer ending where declarator ended already. - UnknownExpressions finds its way inside SimpleDeclarator for p in `struct P {} p, *pp`; - typedefs also fail, unable to find the end of declarator properly. I didn't investigate further. Fixing those seems worthy of a separate patch. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76922/new/ https://reviews.llvm.org/D76922 From cfe-commits at lists.llvm.org Tue Mar 31 00:31:01 2020 From: cfe-commits at lists.llvm.org (Denys Petrov via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 07:31:01 +0000 (UTC) Subject: [PATCH] D73521: [analyzer] add-new-checker.py: Introduction In-Reply-To: References: Message-ID: ASDenysPetrov added a comment. Will this utility affect Visual Studio builds? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73521/new/ https://reviews.llvm.org/D73521 From cfe-commits at lists.llvm.org Tue Mar 31 00:59:04 2020 From: cfe-commits at lists.llvm.org (Dmitri Gribenko via cfe-commits) Date: Tue, 31 Mar 2020 00:59:04 -0700 (PDT) Subject: [clang] cdce2fe - [Syntax] Remove delayed folding from tree building. Message-ID: <5e82f848.1c69fb81.f6ce7.d54b@mx.google.com> Author: Marcel Hlopko Date: 2020-03-31T09:47:50+02:00 New Revision: cdce2fe561eb6e63d77d1d589e521a8e2afb1eef URL: https://github.com/llvm/llvm-project/commit/cdce2fe561eb6e63d77d1d589e521a8e2afb1eef DIFF: https://github.com/llvm/llvm-project/commit/cdce2fe561eb6e63d77d1d589e521a8e2afb1eef.diff LOG: [Syntax] Remove delayed folding from tree building. Summary: This patch removes delayed folding and replaces it with forward peeking. Delayed folding was previously used as a solution to the problem that declaration doesn't have a representation in the AST. For example following code: ``` int a,b; ``` is expressed in the AST as: ``` TranslationUnitDecl |-... |-VarDecl `int a` `-VarDecl `int b` ``` And in the syntax tree we need: ``` *: TranslationUnit `-SimpleDeclaration |-int |-SimpleDeclarator | `-a |-, |-SimpleDeclarator | `-b |-; ``` So in words, we need to create SimpleDeclaration to be a parent of SimpleDeclarator nodes. Previously we used delayed folding to make sure SimpleDeclarations will be eventually created. And in case multiple declarators requested declaration creation, declaration range was extended to cover all declarators. This design started to be hard to reason about, so we decided to replace it with forward peeking. The last declarator node in the chain is responsible for creating SimpleDeclaration for the whole chain. Range of the declaration corresponds to the source range of the declarator node. Declarator decides whether its the last one by peeking to the next AST node (see `isResponsibleForCreatingDeclaration`). This patch does following: * Removed delayed folding logic * Tweaks Token.dumpForTests * Moves getQualifiedNameStart inside BuildTreeVisitor * Extracts BuildTreeVisitor.ProcessDeclaratorAndDeclaration * Renames Builder.getDeclRange to Builder.getDeclarationRange and uses the method in all places. * Adds a bunch of tests Reviewers: gribozavr2 Reviewed By: gribozavr2 Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D76922 Added: Modified: clang/lib/Tooling/Syntax/BuildTree.cpp clang/lib/Tooling/Syntax/Tokens.cpp clang/unittests/Tooling/Syntax/TreeTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp index 82c87ba02b74..11058edec615 100644 --- a/clang/lib/Tooling/Syntax/BuildTree.cpp +++ b/clang/lib/Tooling/Syntax/BuildTree.cpp @@ -44,15 +44,6 @@ using namespace clang; LLVM_ATTRIBUTE_UNUSED static bool isImplicitExpr(clang::Expr *E) { return E->IgnoreImplicit() != E; } -static SourceLocation getQualifiedNameStart(DeclaratorDecl *D) { - auto DN = D->getDeclName(); - bool IsAnonymous = DN.isIdentifier() && !DN.getAsIdentifierInfo(); - if (IsAnonymous) - return SourceLocation(); - return D->getQualifierLoc() ? D->getQualifierLoc().getBeginLoc() - : D->getLocation(); -} - namespace { /// Get start location of the Declarator from the TypeLoc. /// E.g.: @@ -142,8 +133,9 @@ static SourceRange getDeclaratorRange(const SourceManager &SM, TypeLoc T, End = Name; } if (Initializer.isValid()) { - assert(SM.isBeforeInTranslationUnit(End, Initializer.getEnd())); - End = Initializer.getEnd(); + auto InitializerEnd = Initializer.getEnd(); + assert(SM.isBeforeInTranslationUnit(End, InitializerEnd) || End == InitializerEnd); + End = InitializerEnd; } return SourceRange(Start, End); } @@ -212,10 +204,6 @@ class syntax::TreeBuilder { foldNode(Range, New, nullptr); } - /// Must be called with the range of each `DeclaratorDecl`. Ensures the - /// corresponding declarator nodes are covered by `SimpleDeclaration`. - void noticeDeclRange(llvm::ArrayRef Range); - /// Notifies that we should not consume trailing semicolon when computing /// token range of \p D. void noticeDeclWithoutSemicolon(Decl *D); @@ -237,11 +225,6 @@ class syntax::TreeBuilder { void markChild(syntax::Node *N, NodeRole R); /// Set role for the syntax node matching \p N. void markChild(ASTPtr N, NodeRole R); - /// Set role for the delayed node that spans exactly \p Range. - void markDelayedChild(llvm::ArrayRef Range, NodeRole R); - /// Set role for the node that may or may not be delayed. Node must span - /// exactly \p Range. - void markMaybeDelayedChild(llvm::ArrayRef Range, NodeRole R); /// Finish building the tree and consume the root node. syntax::TranslationUnit *finalize() && { @@ -285,7 +268,38 @@ class syntax::TreeBuilder { return maybeAppendSemicolon(Tokens, D); } - llvm::ArrayRef getDeclRange(const Decl *D) const { + /// Returns true if \p D is the last declarator in a chain and is thus + /// reponsible for creating SimpleDeclaration for the whole chain. + template + bool isResponsibleForCreatingDeclaration(const T *D) const { + static_assert((std::is_base_of::value || + std::is_base_of::value), + "only DeclaratorDecl and TypedefNameDecl are supported."); + + const Decl *Next = D->getNextDeclInContext(); + + // There's no next sibling, this one is responsible. + if (Next == nullptr) { + return true; + } + const auto *NextT = llvm::dyn_cast(Next); + + // Next sibling is not the same type, this one is responsible. + if (NextT == nullptr) { + return true; + } + // Next sibling doesn't begin at the same loc, it must be a diff erent + // declaration, so this declarator is responsible. + if (NextT->getBeginLoc() != D->getBeginLoc()) { + return true; + } + + // NextT is a member of the same declaration, and we need the last member to + // create declaration. This one is not responsible. + return false; + } + + llvm::ArrayRef getDeclarationRange(Decl *D) { llvm::ArrayRef Tokens; // We want to drop the template parameters for specializations. if (const auto *S = llvm::dyn_cast(D)) @@ -294,9 +308,11 @@ class syntax::TreeBuilder { Tokens = getRange(D->getSourceRange()); return maybeAppendSemicolon(Tokens, D); } + llvm::ArrayRef getExprRange(const Expr *E) const { return getRange(E->getSourceRange()); } + /// Find the adjusted range for the statement, consuming the trailing /// semicolon when needed. llvm::ArrayRef getStmtRange(const Stmt *S) const { @@ -359,25 +375,6 @@ class syntax::TreeBuilder { } } - ~Forest() { assert(DelayedFolds.empty()); } - - void assignRoleDelayed(llvm::ArrayRef Range, - syntax::NodeRole Role) { - auto It = DelayedFolds.find(Range.begin()); - assert(It != DelayedFolds.end()); - assert(It->second.End == Range.end()); - It->second.Role = Role; - } - - void assignRoleMaybeDelayed(llvm::ArrayRef Range, - syntax::NodeRole Role) { - auto It = DelayedFolds.find(Range.begin()); - if (It == DelayedFolds.end()) - return assignRole(Range, Role); - assert(It->second.End == Range.end()); - It->second.Role = Role; - } - void assignRole(llvm::ArrayRef Range, syntax::NodeRole Role) { assert(!Range.empty()); @@ -396,50 +393,34 @@ class syntax::TreeBuilder { void foldChildren(const syntax::Arena &A, llvm::ArrayRef Tokens, syntax::Tree *Node) { - // Execute delayed folds inside `Tokens`. - auto BeginFolds = DelayedFolds.lower_bound(Tokens.begin()); - auto EndFolds = BeginFolds; - for (; EndFolds != DelayedFolds.end() && - EndFolds->second.End <= Tokens.end(); - ++EndFolds) - ; - // We go in reverse order to ensure we fold deeper nodes first. - for (auto RevIt = EndFolds; RevIt != BeginFolds; --RevIt) { - auto It = std::prev(RevIt); - foldChildrenEager(A, llvm::makeArrayRef(It->first, It->second.End), - It->second.Node); - } - DelayedFolds.erase(BeginFolds, EndFolds); - // Attach children to `Node`. - foldChildrenEager(A, Tokens, Node); - } + assert(Node->firstChild() == nullptr && "node already has children"); - /// Schedule a call to `foldChildren` that will only be executed when - /// containing node is folded. The range of delayed nodes can be extended by - /// calling `extendDelayedFold`. Only one delayed node for each starting - /// token is allowed. - void foldChildrenDelayed(llvm::ArrayRef Tokens, - syntax::Tree *Node) { - assert(!Tokens.empty()); - bool Inserted = - DelayedFolds.insert({Tokens.begin(), DelayedFold{Tokens.end(), Node}}) - .second; - (void)Inserted; - assert(Inserted && "Multiple delayed folds start at the same token"); - } + auto *FirstToken = Tokens.begin(); + auto BeginChildren = Trees.lower_bound(FirstToken); - /// If there a delayed fold, starting at `ExtendedRange.begin()`, extends - /// its endpoint to `ExtendedRange.end()` and returns true. - /// Otherwise, returns false. - bool extendDelayedFold(llvm::ArrayRef ExtendedRange) { - assert(!ExtendedRange.empty()); - auto It = DelayedFolds.find(ExtendedRange.data()); - if (It == DelayedFolds.end()) - return false; - assert(It->second.End <= ExtendedRange.end()); - It->second.End = ExtendedRange.end(); - return true; + assert((BeginChildren == Trees.end() || + BeginChildren->first == FirstToken) && + "fold crosses boundaries of existing subtrees"); + auto EndChildren = Trees.lower_bound(Tokens.end()); + assert( + (EndChildren == Trees.end() || EndChildren->first == Tokens.end()) && + "fold crosses boundaries of existing subtrees"); + + // We need to go in reverse order, because we can only prepend. + for (auto It = EndChildren; It != BeginChildren; --It) { + auto *C = std::prev(It)->second; + if (C->role() == NodeRole::Detached) + C->setRole(NodeRole::Unknown); + Node->prependChildLowLevel(C); + } + + // Mark that this node came from the AST and is backed by the source code. + Node->Original = true; + Node->CanModify = A.tokenBuffer().spelledForExpanded(Tokens).hasValue(); + + Trees.erase(BeginChildren, EndChildren); + Trees.insert({FirstToken, Node}); } // EXPECTS: all tokens were consumed and are owned by a single root node. @@ -467,51 +448,10 @@ class syntax::TreeBuilder { } private: - /// Implementation detail of `foldChildren`, does acutal folding ignoring - /// delayed folds. - void foldChildrenEager(const syntax::Arena &A, - llvm::ArrayRef Tokens, - syntax::Tree *Node) { - assert(Node->firstChild() == nullptr && "node already has children"); - - auto *FirstToken = Tokens.begin(); - auto BeginChildren = Trees.lower_bound(FirstToken); - assert((BeginChildren == Trees.end() || - BeginChildren->first == FirstToken) && - "fold crosses boundaries of existing subtrees"); - auto EndChildren = Trees.lower_bound(Tokens.end()); - assert( - (EndChildren == Trees.end() || EndChildren->first == Tokens.end()) && - "fold crosses boundaries of existing subtrees"); - - // We need to go in reverse order, because we can only prepend. - for (auto It = EndChildren; It != BeginChildren; --It) { - auto *C = std::prev(It)->second; - if (C->role() == NodeRole::Detached) - C->setRole(NodeRole::Unknown); - Node->prependChildLowLevel(C); - } - - // Mark that this node came from the AST and is backed by the source code. - Node->Original = true; - Node->CanModify = A.tokenBuffer().spelledForExpanded(Tokens).hasValue(); - - Trees.erase(BeginChildren, EndChildren); - Trees.insert({FirstToken, Node}); - } - /// Maps from the start token to a subtree starting at that token. /// Keys in the map are pointers into the array of expanded tokens, so /// pointer order corresponds to the order of preprocessor tokens. std::map Trees; - - /// See documentation of `foldChildrenDelayed` for details. - struct DelayedFold { - const syntax::Token *End = nullptr; - syntax::Tree *Node = nullptr; - NodeRole Role = NodeRole::Unknown; - }; - std::map DelayedFolds; }; /// For debugging purposes. @@ -535,47 +475,16 @@ class BuildTreeVisitor : public RecursiveASTVisitor { bool shouldTraversePostOrder() const { return true; } bool WalkUpFromDeclaratorDecl(DeclaratorDecl *DD) { - // Ensure declarators are covered by SimpleDeclaration. - Builder.noticeDeclRange(Builder.getDeclRange(DD)); - - // Build the declarator node. - SourceRange Initializer; - if (auto *V = llvm::dyn_cast(DD)) { - auto *I = V->getInit(); - // Initializers in range-based-for are not part of the declarator - if (I && !V->isCXXForRangeDecl()) - Initializer = I->getSourceRange(); - } - auto Declarator = getDeclaratorRange( - Builder.sourceManager(), DD->getTypeSourceInfo()->getTypeLoc(), - getQualifiedNameStart(DD), Initializer); - if (Declarator.isValid()) { - auto *N = new (allocator()) syntax::SimpleDeclarator; - Builder.foldNode(Builder.getRange(Declarator), N, DD); - Builder.markChild(N, syntax::NodeRole::SimpleDeclaration_declarator); - } - - return true; + return processDeclaratorAndDeclaration(DD); } - bool WalkUpFromTypedefNameDecl(TypedefNameDecl *D) { - // Ensure declarators are covered by SimpleDeclaration. - Builder.noticeDeclRange(Builder.getDeclRange(D)); - - auto R = getDeclaratorRange( - Builder.sourceManager(), D->getTypeSourceInfo()->getTypeLoc(), - /*Name=*/D->getLocation(), /*Initializer=*/SourceRange()); - if (R.isValid()) { - auto *N = new (allocator()) syntax::SimpleDeclarator; - Builder.foldNode(Builder.getRange(R), N, D); - Builder.markChild(N, syntax::NodeRole::SimpleDeclaration_declarator); - } - return true; + bool WalkUpFromTypedefNameDecl(TypedefNameDecl *TD) { + return processDeclaratorAndDeclaration(TD); } bool VisitDecl(Decl *D) { assert(!D->isImplicit()); - Builder.foldNode(Builder.getDeclRange(D), + Builder.foldNode(Builder.getDeclarationRange(D), new (allocator()) syntax::UnknownDeclaration(), D); return true; } @@ -599,9 +508,9 @@ class BuildTreeVisitor : public RecursiveASTVisitor { bool WalkUpFromTemplateDecl(TemplateDecl *S) { foldTemplateDeclaration( - Builder.getDeclRange(S), + Builder.getDeclarationRange(S), Builder.findToken(S->getTemplateParameters()->getTemplateLoc()), - Builder.getDeclRange(S->getTemplatedDecl()), S); + Builder.getDeclarationRange(S->getTemplatedDecl()), S); return true; } @@ -618,7 +527,7 @@ class BuildTreeVisitor : public RecursiveASTVisitor { syntax::Declaration *handleFreeStandingTagDecl(TagDecl *C) { assert(C->isFreeStanding()); // Class is a declaration specifier and needs a spanning declaration node. - auto DeclarationRange = Builder.getDeclRange(C); + auto DeclarationRange = Builder.getDeclarationRange(C); syntax::Declaration *Result = new (allocator()) syntax::SimpleDeclaration; Builder.foldNode(DeclarationRange, Result, nullptr); @@ -702,7 +611,7 @@ class BuildTreeVisitor : public RecursiveASTVisitor { } bool WalkUpFromNamespaceDecl(NamespaceDecl *S) { - auto Tokens = Builder.getDeclRange(S); + auto Tokens = Builder.getDeclarationRange(S); if (Tokens.front().kind() == tok::coloncolon) { // Handle nested namespace definitions. Those start at '::' token, e.g. // namespace a^::b {} @@ -741,10 +650,9 @@ class BuildTreeVisitor : public RecursiveASTVisitor { bool WalkUpFromFunctionTypeLoc(FunctionTypeLoc L) { Builder.markChildToken(L.getLParenLoc(), syntax::NodeRole::OpenParen); - for (auto *P : L.getParams()) - Builder.markDelayedChild( - Builder.getDeclRange(P), - syntax::NodeRole::ParametersAndQualifiers_parameter); + for (auto *P : L.getParams()) { + Builder.markChild(P, syntax::NodeRole::ParametersAndQualifiers_parameter); + } Builder.markChildToken(L.getRParenLoc(), syntax::NodeRole::CloseParen); Builder.foldNode(Builder.getRange(L.getLParenLoc(), L.getEndLoc()), new (allocator()) syntax::ParametersAndQualifiers, L); @@ -755,7 +663,7 @@ class BuildTreeVisitor : public RecursiveASTVisitor { if (!L.getTypePtr()->hasTrailingReturn()) return WalkUpFromFunctionTypeLoc(L); - auto TrailingReturnTokens = BuildTrailingReturn(L); + auto *TrailingReturnTokens = BuildTrailingReturn(L); // Finish building the node for parameters. Builder.markChild(TrailingReturnTokens, syntax::NodeRole::ParametersAndQualifiers_trailingReturn); @@ -877,7 +785,7 @@ class BuildTreeVisitor : public RecursiveASTVisitor { } bool WalkUpFromEmptyDecl(EmptyDecl *S) { - Builder.foldNode(Builder.getDeclRange(S), + Builder.foldNode(Builder.getDeclarationRange(S), new (allocator()) syntax::EmptyDeclaration, S); return true; } @@ -887,55 +795,108 @@ class BuildTreeVisitor : public RecursiveASTVisitor { syntax::NodeRole::StaticAssertDeclaration_condition); Builder.markExprChild(S->getMessage(), syntax::NodeRole::StaticAssertDeclaration_message); - Builder.foldNode(Builder.getDeclRange(S), + Builder.foldNode(Builder.getDeclarationRange(S), new (allocator()) syntax::StaticAssertDeclaration, S); return true; } bool WalkUpFromLinkageSpecDecl(LinkageSpecDecl *S) { - Builder.foldNode(Builder.getDeclRange(S), + Builder.foldNode(Builder.getDeclarationRange(S), new (allocator()) syntax::LinkageSpecificationDeclaration, S); return true; } bool WalkUpFromNamespaceAliasDecl(NamespaceAliasDecl *S) { - Builder.foldNode(Builder.getDeclRange(S), + Builder.foldNode(Builder.getDeclarationRange(S), new (allocator()) syntax::NamespaceAliasDefinition, S); return true; } bool WalkUpFromUsingDirectiveDecl(UsingDirectiveDecl *S) { - Builder.foldNode(Builder.getDeclRange(S), + Builder.foldNode(Builder.getDeclarationRange(S), new (allocator()) syntax::UsingNamespaceDirective, S); return true; } bool WalkUpFromUsingDecl(UsingDecl *S) { - Builder.foldNode(Builder.getDeclRange(S), + Builder.foldNode(Builder.getDeclarationRange(S), new (allocator()) syntax::UsingDeclaration, S); return true; } bool WalkUpFromUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *S) { - Builder.foldNode(Builder.getDeclRange(S), + Builder.foldNode(Builder.getDeclarationRange(S), new (allocator()) syntax::UsingDeclaration, S); return true; } bool WalkUpFromUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *S) { - Builder.foldNode(Builder.getDeclRange(S), + Builder.foldNode(Builder.getDeclarationRange(S), new (allocator()) syntax::UsingDeclaration, S); return true; } bool WalkUpFromTypeAliasDecl(TypeAliasDecl *S) { - Builder.foldNode(Builder.getDeclRange(S), + Builder.foldNode(Builder.getDeclarationRange(S), new (allocator()) syntax::TypeAliasDeclaration, S); return true; } private: + template SourceLocation getQualifiedNameStart(T *D) { + static_assert((std::is_base_of::value || + std::is_base_of::value), + "only DeclaratorDecl and TypedefNameDecl are supported."); + + auto DN = D->getDeclName(); + bool IsAnonymous = DN.isIdentifier() && !DN.getAsIdentifierInfo(); + if (IsAnonymous) + return SourceLocation(); + + if (const auto *DD = llvm::dyn_cast(D)) { + if (DD->getQualifierLoc()) { + return DD->getQualifierLoc().getBeginLoc(); + } + } + + return D->getLocation(); + } + + SourceRange getInitializerRange(Decl *D) { + if (auto *V = llvm::dyn_cast(D)) { + auto *I = V->getInit(); + // Initializers in range-based-for are not part of the declarator + if (I && !V->isCXXForRangeDecl()) + return I->getSourceRange(); + } + + return SourceRange(); + } + + /// Folds SimpleDeclarator node (if present) and in case this is the last + /// declarator in the chain it also folds SimpleDeclaration node. + template bool processDeclaratorAndDeclaration(T *D) { + SourceRange Initializer = getInitializerRange(D); + auto Range = getDeclaratorRange(Builder.sourceManager(), + D->getTypeSourceInfo()->getTypeLoc(), + getQualifiedNameStart(D), Initializer); + + // There doesn't have to be a declarator (e.g. `void foo(int)` only has + // declaration, but no declarator). + if (Range.getBegin().isValid()) { + auto *N = new (allocator()) syntax::SimpleDeclarator; + Builder.foldNode(Builder.getRange(Range), N, nullptr); + Builder.markChild(N, syntax::NodeRole::SimpleDeclaration_declarator); + } + + if (Builder.isResponsibleForCreatingDeclaration(D)) { + Builder.foldNode(Builder.getDeclarationRange(D), + new (allocator()) syntax::SimpleDeclaration, D); + } + return true; + } + /// Returns the range of the built node. syntax::TrailingReturnType *BuildTrailingReturn(FunctionProtoTypeLoc L) { assert(L.getTypePtr()->hasTrailingReturn()); @@ -963,7 +924,7 @@ class BuildTreeVisitor : public RecursiveASTVisitor { Builder.markChild(ReturnDeclarator, syntax::NodeRole::TrailingReturnType_declarator); auto *R = new (allocator()) syntax::TrailingReturnType; - Builder.foldNode(Tokens, R, nullptr); + Builder.foldNode(Tokens, R, L); return R; } @@ -989,12 +950,10 @@ class BuildTreeVisitor : public RecursiveASTVisitor { ArrayRef TemplatedDeclaration, Decl *From) { assert(TemplateKW && TemplateKW->kind() == tok::kw_template); Builder.markChildToken(TemplateKW, syntax::NodeRole::IntroducerKeyword); - Builder.markMaybeDelayedChild( - TemplatedDeclaration, - syntax::NodeRole::TemplateDeclaration_declaration); auto *N = new (allocator()) syntax::TemplateDeclaration; Builder.foldNode(Range, N, From); + Builder.markChild(N, syntax::NodeRole::TemplateDeclaration_declaration); return N; } @@ -1006,13 +965,6 @@ class BuildTreeVisitor : public RecursiveASTVisitor { }; } // namespace -void syntax::TreeBuilder::noticeDeclRange(llvm::ArrayRef Range) { - if (Pending.extendDelayedFold(Range)) - return; - Pending.foldChildrenDelayed(Range, - new (allocator()) syntax::SimpleDeclaration); -} - void syntax::TreeBuilder::noticeDeclWithoutSemicolon(Decl *D) { DeclsWithoutSemicolons.insert(D); } @@ -1040,16 +992,6 @@ void syntax::TreeBuilder::markChild(ASTPtr N, NodeRole R) { setRole(SN, R); } -void syntax::TreeBuilder::markDelayedChild(llvm::ArrayRef Range, - NodeRole R) { - Pending.assignRoleDelayed(Range, R); -} - -void syntax::TreeBuilder::markMaybeDelayedChild( - llvm::ArrayRef Range, NodeRole R) { - Pending.assignRoleMaybeDelayed(Range, R); -} - void syntax::TreeBuilder::markStmtChild(Stmt *Child, NodeRole Role) { if (!Child) return; diff --git a/clang/lib/Tooling/Syntax/Tokens.cpp b/clang/lib/Tooling/Syntax/Tokens.cpp index b3f13a3f6e72..af11f25b1058 100644 --- a/clang/lib/Tooling/Syntax/Tokens.cpp +++ b/clang/lib/Tooling/Syntax/Tokens.cpp @@ -710,8 +710,8 @@ std::string syntax::Token::str() const { } std::string syntax::Token::dumpForTests(const SourceManager &SM) const { - return std::string( - llvm::formatv("{0} {1}", tok::getTokenName(kind()), text(SM))); + return std::string(llvm::formatv("Token(`{0}`, {1}, length = {2})", text(SM), + tok::getTokenName(kind()), length())); } std::string TokenBuffer::dumpForTests() const { diff --git a/clang/unittests/Tooling/Syntax/TreeTest.cpp b/clang/unittests/Tooling/Syntax/TreeTest.cpp index ddd9092d8a76..823045748f99 100644 --- a/clang/unittests/Tooling/Syntax/TreeTest.cpp +++ b/clang/unittests/Tooling/Syntax/TreeTest.cpp @@ -224,6 +224,59 @@ void foo() {} )txt"); } +TEST_F(SyntaxTreeTest, SimpleVariable) { + expectTreeDumpEqual( + R"cpp( +int a; +int b = 42; + )cpp", + R"txt( +*: TranslationUnit +|-SimpleDeclaration +| |-int +| |-SimpleDeclarator +| | `-a +| `-; +`-SimpleDeclaration + |-int + |-SimpleDeclarator + | |-b + | |-= + | `-UnknownExpression + | `-42 + `-; +)txt"); +} + +TEST_F(SyntaxTreeTest, SimpleFunction) { + expectTreeDumpEqual( + R"cpp( +void foo(int a, int b) {} + )cpp", + R"txt( +*: TranslationUnit +`-SimpleDeclaration + |-void + |-SimpleDeclarator + | |-foo + | `-ParametersAndQualifiers + | |-( + | |-SimpleDeclaration + | | |-int + | | `-SimpleDeclarator + | | `-a + | |-, + | |-SimpleDeclaration + | | |-int + | | `-SimpleDeclarator + | | `-b + | `-) + `-CompoundStatement + |-{ + `-} +)txt"); +} + TEST_F(SyntaxTreeTest, If) { expectTreeDumpEqual( R"cpp( @@ -541,20 +594,32 @@ void test() { TEST_F(SyntaxTreeTest, MultipleDeclaratorsGrouping) { expectTreeDumpEqual( R"cpp( - int *a, b; + int *a, b; int *c, d; )cpp", R"txt( *: TranslationUnit +|-SimpleDeclaration +| |-int +| |-SimpleDeclarator +| | |-* +| | `-a +| |-, +| |-SimpleDeclarator +| | `-b +| `-; `-SimpleDeclaration |-int |-SimpleDeclarator | |-* - | `-a + | `-c |-, |-SimpleDeclarator - | `-b + | `-d `-; )txt"); +} + +TEST_F(SyntaxTreeTest, MultipleDeclaratorsGroupingTypedef) { expectTreeDumpEqual( R"cpp( typedef int *a, b; From cfe-commits at lists.llvm.org Tue Mar 31 01:04:10 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 08:04:10 +0000 (UTC) Subject: [PATCH] D76996: [analyzer] Improve PlacementNewChecker In-Reply-To: References: Message-ID: <0852ad6468d8d8ad7925fc71dfd6e9c0@localhost.localdomain> martong added inline comments. ================ Comment at: clang/test/Analysis/placement-new.cpp:265 + + // bad 2(custom align) + 1(index '2' offset) + ::new (&Xi.b[1]) long; // expected-warning{{Storage type is aligned to 3 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}} ---------------- Maybe it is just me, but the contents of the parens here and above seems a bit muddled `(index '2' offset)`. This should be `(index '1' offset)`, shouldn't it? What is the exact meaning of the number in the hyphens (`'2'` in this case), could you please elaborate? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76996/new/ https://reviews.llvm.org/D76996 From cfe-commits at lists.llvm.org Tue Mar 31 01:04:11 2020 From: cfe-commits at lists.llvm.org (Vlastimil Labsky via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 08:04:11 +0000 (UTC) Subject: [PATCH] D77119: [AVR] Fix function pointer address space Message-ID: vlastik created this revision. vlastik added a reviewer: dylanmckay. Herald added subscribers: cfe-commits, Jim. Herald added a project: clang. Function pointers should be created with program address space. This fixes function pointers on AVR. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77119 Files: clang/lib/CodeGen/CodeGenTypes.cpp Index: clang/lib/CodeGen/CodeGenTypes.cpp =================================================================== --- clang/lib/CodeGen/CodeGenTypes.cpp +++ clang/lib/CodeGen/CodeGenTypes.cpp @@ -595,7 +595,11 @@ llvm::Type *PointeeType = ConvertTypeForMem(ETy); if (PointeeType->isVoidTy()) PointeeType = llvm::Type::getInt8Ty(getLLVMContext()); - unsigned AS = Context.getTargetAddressSpace(ETy); + + unsigned AS = PointeeType->isFunctionTy() + ? getDataLayout().getProgramAddressSpace() + : Context.getTargetAddressSpace(ETy); + ResultType = llvm::PointerType::get(PointeeType, AS); break; } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77119.253794.patch Type: text/x-patch Size: 637 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 01:04:23 2020 From: cfe-commits at lists.llvm.org (Dmitri Gribenko via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 08:04:23 +0000 (UTC) Subject: [PATCH] D76922: [Syntax] Remove delayed folding from tree building. In-Reply-To: References: Message-ID: <500b274825cc203a8dbcea6c0009bece@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGcdce2fe561eb: [Syntax] Remove delayed folding from tree building. (authored by hlopko, committed by gribozavr). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76922/new/ https://reviews.llvm.org/D76922 Files: clang/lib/Tooling/Syntax/BuildTree.cpp clang/lib/Tooling/Syntax/Tokens.cpp clang/unittests/Tooling/Syntax/TreeTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76922.253796.patch Type: text/x-patch Size: 23544 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 01:37:09 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Timm_B=C3=A4der_via_Phabricator?= via cfe-commits) Date: Tue, 31 Mar 2020 08:37:09 +0000 (UTC) Subject: [PATCH] D75844: [clang] Set begin loc on GNU attribute parsed attrs In-Reply-To: References: Message-ID: tbaeder added a comment. Sorry for taking so long but it seems like I've went down a rabbit hole a bit. My previous patch sets the range in `parseGNUAttributes()` unconditionally, but that seems to trigger cases such as // FixItLoc = possible correct location for the attributes void ProhibitAttributes(ParsedAttributesWithRange &Attrs, SourceLocation FixItLoc = SourceLocation()) { if (Attrs.Range.isInvalid()) return; DiagnoseProhibitedAttributes(Attrs.Range, FixItLoc); Attrs.clear(); } in Parser.h. Because now the attributes have a valid range, clang emits lots of errors where it previously did not. Do you have a suggestion of what to do here, should I rather go back to a more local fix for the issue? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75844/new/ https://reviews.llvm.org/D75844 From cfe-commits at lists.llvm.org Tue Mar 31 01:37:09 2020 From: cfe-commits at lists.llvm.org (Vlastimil Labsky via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 08:37:09 +0000 (UTC) Subject: [PATCH] D77119: [AVR] Fix function pointer address space In-Reply-To: References: Message-ID: <1dd5735317244a962e93bad04b204dd1@localhost.localdomain> vlastik updated this revision to Diff 253802. vlastik added a comment. Fix formatting CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77119/new/ https://reviews.llvm.org/D77119 Files: clang/lib/CodeGen/CodeGenTypes.cpp Index: clang/lib/CodeGen/CodeGenTypes.cpp =================================================================== --- clang/lib/CodeGen/CodeGenTypes.cpp +++ clang/lib/CodeGen/CodeGenTypes.cpp @@ -595,7 +595,11 @@ llvm::Type *PointeeType = ConvertTypeForMem(ETy); if (PointeeType->isVoidTy()) PointeeType = llvm::Type::getInt8Ty(getLLVMContext()); - unsigned AS = Context.getTargetAddressSpace(ETy); + + unsigned AS = PointeeType->isFunctionTy() + ? getDataLayout().getProgramAddressSpace() + : Context.getTargetAddressSpace(ETy); + ResultType = llvm::PointerType::get(PointeeType, AS); break; } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77119.253802.patch Type: text/x-patch Size: 669 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 01:37:11 2020 From: cfe-commits at lists.llvm.org (Karasev Nikita via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 08:37:11 +0000 (UTC) Subject: [PATCH] D76996: [analyzer] Improve PlacementNewChecker In-Reply-To: References: Message-ID: <9c7ceab55657b332d5408ed9d019d1a0@localhost.localdomain> f00kat updated this revision to Diff 253803. f00kat marked an inline comment as done. f00kat added a comment. Fixed comments in tests Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76996/new/ https://reviews.llvm.org/D76996 Files: clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp clang/test/Analysis/placement-new.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76996.253803.patch Type: text/x-patch Size: 14999 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 02:10:27 2020 From: cfe-commits at lists.llvm.org (Jacek Olesiak via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 09:10:27 +0000 (UTC) Subject: [PATCH] D77039: [clang-format] Don't break multi block parameters on ObjCBreakBeforeNestedBlockParam In-Reply-To: References: Message-ID: <95fb32f390cceac0a4bd0283fa0dab97@localhost.localdomain> jolesiak accepted this revision. jolesiak added a comment. This revision is now accepted and ready to land. Makes sense, thanks for patching this! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77039/new/ https://reviews.llvm.org/D77039 From cfe-commits at lists.llvm.org Tue Mar 31 02:10:27 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 09:10:27 +0000 (UTC) Subject: [PATCH] D77041: [AST] Fix a crash on invalid constexpr Ctorinitializer when building RecoveryExpr. In-Reply-To: References: Message-ID: hokein added a comment. > This makes me nervous, marking the constructor as invalid seems much safer. Can you show tests it regresses? Yeah, the first version of the patch doesn't seem to fix all crashes (X().Y would lead another crash)... so if we mark the CtorDecl as invalid 1. whenever `CtorInitializer->init()->containsError`, we don't have failure tests 2. whenever there is any kind of errors (including the containsError case above) in CtorInitailizer, we have three failing tests (SemaCXX/constant-expression-cxx11.cpp, SemaCXX/constructor-initializer.cpp, SemaTemplate/constexpr-instantiate.cpp). though 1) passes all existing tests, I think it just means current tests don't have enough coverage for recoveryExpr cases. But given the current state, 1) looks most promising -- fixes the crashes, retains broken expressions in CtorInitializer rather than dropping them, doesn't regress the diagnostics a lot (only for CtorInitializer->init()->containsError` case). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77041/new/ https://reviews.llvm.org/D77041 From cfe-commits at lists.llvm.org Tue Mar 31 02:10:33 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 09:10:33 +0000 (UTC) Subject: [PATCH] D77041: [AST] Fix a crash on invalid constexpr Ctorinitializer when building RecoveryExpr. In-Reply-To: References: Message-ID: <89be845582468efe886bd61da00cbf0b@localhost.localdomain> hokein updated this revision to Diff 253809. hokein marked an inline comment as done. hokein added a comment. - mark CtorDecl as invalid when the Initializer init expr contains errors - add a testcase that would crash the previous version of the patch Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77041/new/ https://reviews.llvm.org/D77041 Files: clang/lib/Parse/ParseDeclCXX.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/test/SemaCXX/invalid-constructor-init.cpp Index: clang/test/SemaCXX/invalid-constructor-init.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/invalid-constructor-init.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -frecovery-ast -verify %s + +struct X {// expected-note 2{{candidate constructor }} + int Y; + constexpr X() : Y(foo()) {} // expected-error {{use of undeclared identifier 'foo'}} +}; +// no crash on evaluating the constexpr ctor. +// FIXME: get rid of the bogus diagnostic below. +constexpr int Z = X().Y; // expected-error {{no matching constructor for initialization of 'X'}} + +struct X2 { + int Y = foo(); // expected-error {{use of undeclared identifier 'foo'}} \ + // expected-note {{subexpression not valid in a constant expression}} + constexpr X2() {} // expected-error {{constexpr constructor never produces a constant expression}} +}; + +struct CycleDelegate { + int Y; + CycleDelegate(int) : Y(foo()) {} // expected-error {{use of undeclared identifier 'foo'}} + // FIXME: get rid of the bogus "delegation cycle" diagnostic + // CycleDeclegate(int) is marked as invalid. + CycleDelegate(float) : CycleDelegate(1) {} // expected-error {{creates a delegation cycle}} +}; Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -1685,6 +1685,7 @@ // This implements C++11 [dcl.constexpr]p3,4, as amended by DR1360. bool Sema::CheckConstexprFunctionDefinition(const FunctionDecl *NewFD, CheckConstexprKind Kind) { + assert(!NewFD->isInvalidDecl()); const CXXMethodDecl *MD = dyn_cast(NewFD); if (MD && MD->isInstance()) { // C++11 [dcl.constexpr]p4: @@ -5000,7 +5001,8 @@ for (unsigned i = 0; i < Initializers.size(); i++) { CXXCtorInitializer *Member = Initializers[i]; - + if (Member->getInit() && Member->getInit()->containsErrors()) + Constructor->setInvalidDecl(); if (Member->isBaseInitializer()) Info.AllBaseFields[Member->getBaseClass()->getAs()] = Member; else { Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -45,6 +45,7 @@ #include "clang/Sema/Template.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Triple.h" +#include "llvm/Support/Casting.h" #include #include #include Index: clang/lib/Parse/ParseDeclCXX.cpp =================================================================== --- clang/lib/Parse/ParseDeclCXX.cpp +++ clang/lib/Parse/ParseDeclCXX.cpp @@ -3454,9 +3454,12 @@ } MemInitResult MemInit = ParseMemInitializer(ConstructorDecl); - if (!MemInit.isInvalid()) + if (!MemInit.isInvalid()) { MemInitializers.push_back(MemInit.get()); - else + if (MemInit.get()->getInit() && + MemInit.get()->getInit()->containsErrors()) + AnyErrors = true; + } else AnyErrors = true; if (Tok.is(tok::comma)) -------------- next part -------------- A non-text attachment was scrubbed... Name: D77041.253809.patch Type: text/x-patch Size: 3153 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 02:42:51 2020 From: cfe-commits at lists.llvm.org (Bill Wendling via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 09:42:51 +0000 (UTC) Subject: [PATCH] D62627: [NFC] Do not run CGProfilePass when not using integrated assembler In-Reply-To: References: Message-ID: void edited subscribers, added: manojgupta; removed: cfe-commits. void added a comment. Friendly ping. :-) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D62627/new/ https://reviews.llvm.org/D62627 From cfe-commits at lists.llvm.org Tue Mar 31 02:42:55 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Balogh, _=C3=81d=C3=A1m_via_Phabricator?= via cfe-commits) Date: Tue, 31 Mar 2020 09:42:55 +0000 (UTC) Subject: [PATCH] D77125: [Analyzer] Model return values of container insert and delete operations Message-ID: baloghadamsoftware created this revision. baloghadamsoftware added reviewers: NoQ, Szelethus. baloghadamsoftware added a project: clang. Herald added subscribers: ASDenysPetrov, martong, steakhal, Charusso, gamesh411, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet, xazax.hun, whisperity. Insert and delete operations of `insert()`, `erase()` (plus `insert_after()` and `erase_after()` for `std::forward_list`-like containers were not modeled yet. This patch fixes this issue. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77125 Files: clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp clang/test/Analysis/Inputs/system-header-simulator-cxx.h clang/test/Analysis/diagnostics/explicit-suppression.cpp clang/test/Analysis/iterator-modeling.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77125.253815.patch Type: text/x-patch Size: 42900 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 02:42:56 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 09:42:56 +0000 (UTC) Subject: [PATCH] D76996: [analyzer] Improve PlacementNewChecker In-Reply-To: References: Message-ID: <12c34cf3acc1858f931b47b79e49beae@localhost.localdomain> martong accepted this revision. martong added a comment. This revision is now accepted and ready to land. LGTM! Thanks! But I am not that confident with the element regions and field regions, so @NoQ could you please take another look? ================ Comment at: clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp:82 CharUnits TypeSize = AstContext.getTypeSizeInChars(ElementType); - if (NE->isArray()) { + if (IsArray = NE->isArray()) { const Expr *SizeExpr = *NE->getArraySize(); ---------------- This will break build-bots that run with -Werror. ``` ../../git/llvm-project/clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp:82:15: warning: suggest parentheses around assignment used as truth value [-Wparentheses] if (IsArray = NE->isArray()) { ``` ================ Comment at: clang/test/Analysis/placement-new.cpp:256 + +void f9() { + struct X { ---------------- First I was wondering if we indeed handle correctly structs with nested arrays whose element's type is a structs with nested arrays (... and so on). So, I tried the below test, and it seems okay. Thus I think it might be worth to add something similar to it. ``` void f9_1() { struct Y { char a; alignas(alignof(short)) char b[20]; }; struct X { char e; Y f[20]; } Xi; // expected-note {{'Xi' initialized here}} // ok 2(custom align) + 6*1(index '6' offset) ::new (&Xi.f[6].b[6]) long; // bad 2(custom align) + 1*1(index '1' offset) ::new (&Xi.f[1].b[1]) long; // expected-warning{{Storage type is aligned to 3 bytes but allocated type is aligned to 8 bytes}} expected-note 1 {{}} } ``` Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76996/new/ https://reviews.llvm.org/D76996 From cfe-commits at lists.llvm.org Tue Mar 31 03:51:56 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 10:51:56 +0000 (UTC) Subject: [PATCH] D76663: [clangd] Support new semanticTokens request from LSP 3.16. In-Reply-To: References: Message-ID: <894c01faf58775b679ad3bdf5b725428@localhost.localdomain> hokein accepted this revision. hokein added a comment. This revision is now accepted and ready to land. Thanks! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76663/new/ https://reviews.llvm.org/D76663 From cfe-commits at lists.llvm.org Tue Mar 31 03:51:56 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Bal=C3=A1zs_K=C3=A9ri_via_Phabricator?= via cfe-commits) Date: Tue, 31 Mar 2020 10:51:56 +0000 (UTC) Subject: [PATCH] D72705: [analyzer] Added new checker 'alpha.unix.ErrorReturn'. In-Reply-To: References: Message-ID: <1d18ab1c22bd95674a7b0fedd2ec541e@localhost.localdomain> balazske added a comment. Herald added a subscriber: ASDenysPetrov. ping Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72705/new/ https://reviews.llvm.org/D72705 From cfe-commits at lists.llvm.org Tue Mar 31 03:51:57 2020 From: cfe-commits at lists.llvm.org (Lucas Prates via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 10:51:57 +0000 (UTC) Subject: [PATCH] D75169: [ARM] Enforcing calling convention for half-precision FP arguments and returns for big-endian AArch32 In-Reply-To: References: Message-ID: <9c0645c34904507c26dedd9e2485801a@localhost.localdomain> pratlucas added a comment. > Why not just make half as an argument do the right thing for that case? That would be the ideal approach, but currently there's a limitation on the backend's calling convention lowering that gets in the way. The lowering of calls in `SelectionDAGBuilder` includes a target-independent step that is responsible for spliting or promoting each argument into "legal registers" and takes place before the targets' calling convention lowering. As `f16` is not a legal type on many of the `AAPCS_VFP` targets, it gets promoted to `f32` before the target's lowering code has a chance to define how to handle it. Ideally, this stpe should only take place if lowering calling conventions after type legalization - there's a FIXME there already capturing that -, but that would involve a major rewriting that would impact multiple targets. Inserting a hacky target-dependent fix in this step also didn't look very good. Do you see other alternatives for handling it? If not, which approach would you suggest? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75169/new/ https://reviews.llvm.org/D75169 From cfe-commits at lists.llvm.org Tue Mar 31 04:23:54 2020 From: cfe-commits at lists.llvm.org (Tamas Petz via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 11:23:54 +0000 (UTC) Subject: [PATCH] D77131: [clang] Move branch-protection from CodeGenOptions to LangOptions Message-ID: tamas.petz created this revision. tamas.petz added a reviewer: momchil.velikov. tamas.petz added a project: clang. Herald added a subscriber: cfe-commits. danielkiss added a comment. tamas.petz marked an inline comment as done. just a nit, LGTM otherwise. ================ Comment at: clang/include/clang/Basic/CodeGenOptions.def:402 #undef VALUE_CODEGENOPT - ---------------- is this change necessary? ================ Comment at: clang/include/clang/Basic/CodeGenOptions.def:402 #undef VALUE_CODEGENOPT - ---------------- danielkiss wrote: > is this change necessary? I think there should be one new line at the end of the file, not two. Reason: the option has an effect on preprocessing. Also see thread: http://lists.llvm.org/pipermail/cfe-dev/2020-March/065014.html Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77131 Files: clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Basic/CodeGenOptions.h clang/include/clang/Basic/LangOptions.def clang/include/clang/Basic/LangOptions.h clang/include/clang/Basic/TargetInfo.h clang/lib/Basic/Targets/AArch64.cpp clang/lib/CodeGen/CGDeclCXX.cpp clang/lib/CodeGen/TargetInfo.cpp clang/lib/Frontend/CompilerInvocation.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77131.253829.patch Type: text/x-patch Size: 12287 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 04:23:55 2020 From: cfe-commits at lists.llvm.org (Tamas Petz via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 11:23:55 +0000 (UTC) Subject: [PATCH] D77134: [clang][AARCH64] Add __ARM_FEATURE_{PAC, BTI}_DEFAULT defines Message-ID: tamas.petz created this revision. tamas.petz added a reviewer: momchil.velikov. tamas.petz added a project: clang. Herald added subscribers: cfe-commits, danielkiss. tamas.petz added a comment. Depends on: https://reviews.llvm.org/D77131 As defined by Arm C Language Extensions (ACLE) these macro defines should be set to specific values depending on -mbranch-protection. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77134 Files: clang/include/clang/Basic/LangOptions.h clang/lib/Basic/Targets/AArch64.cpp clang/test/Preprocessor/aarch64-target-features.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77134.253832.patch Type: text/x-patch Size: 6152 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 04:23:57 2020 From: cfe-commits at lists.llvm.org (Tamas Petz via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 11:23:57 +0000 (UTC) Subject: [PATCH] D77134: [clang][AARCH64] Add __ARM_FEATURE_{PAC, BTI}_DEFAULT defines In-Reply-To: References: Message-ID: <499de37dc3e76c200a432eba32c797a6@localhost.localdomain> tamas.petz added a comment. Depends on: https://reviews.llvm.org/D77131 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77134/new/ https://reviews.llvm.org/D77134 From cfe-commits at lists.llvm.org Tue Mar 31 04:23:56 2020 From: cfe-commits at lists.llvm.org (Daniel Kiss via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 11:23:56 +0000 (UTC) Subject: [PATCH] D77131: [clang] Move branch-protection from CodeGenOptions to LangOptions In-Reply-To: References: Message-ID: danielkiss added a comment. just a nit, LGTM otherwise. ================ Comment at: clang/include/clang/Basic/CodeGenOptions.def:402 #undef VALUE_CODEGENOPT - ---------------- is this change necessary? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77131/new/ https://reviews.llvm.org/D77131 From cfe-commits at lists.llvm.org Tue Mar 31 04:23:57 2020 From: cfe-commits at lists.llvm.org (Tamas Petz via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 11:23:57 +0000 (UTC) Subject: [PATCH] D77131: [clang] Move branch-protection from CodeGenOptions to LangOptions In-Reply-To: References: Message-ID: tamas.petz marked an inline comment as done. tamas.petz added inline comments. ================ Comment at: clang/include/clang/Basic/CodeGenOptions.def:402 #undef VALUE_CODEGENOPT - ---------------- danielkiss wrote: > is this change necessary? I think there should be one new line at the end of the file, not two. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77131/new/ https://reviews.llvm.org/D77131 From cfe-commits at lists.llvm.org Tue Mar 31 04:56:42 2020 From: cfe-commits at lists.llvm.org (Diogo N. Sampaio via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 11:56:42 +0000 (UTC) Subject: [PATCH] D77074: [FPEnv][AArch64] Platform-specific builtin constrained FP enablement In-Reply-To: References: Message-ID: dnsampaio added inline comments. ================ Comment at: clang/test/CodeGen/aarch64-neon-intrinsics-constrained.c:288 + +// XXX FIXME do we need to check for both w and x registers? +// COMMON-LABEL: test_vceq_f64 ---------------- kpn wrote: > Anyone? I'm not an ARM expert. The is variants of the `cset` instruction for both `w` and `x`. But I believe that for these tests it should be stable enough to accept only one of them. ================ Comment at: clang/test/CodeGen/aarch64-neon-intrinsics-constrained.c:889 + +// FIXME why the unused bitcast? There are several of them! +// COMMON-LABEL: test_vrnda_f64 ---------------- kpn wrote: > ??? It is a known issue. I believe no-one dug through the neon-emmiter machinery to find out why yet. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77074/new/ https://reviews.llvm.org/D77074 From cfe-commits at lists.llvm.org Tue Mar 31 04:56:45 2020 From: cfe-commits at lists.llvm.org (Csaba Dabis via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 11:56:45 +0000 (UTC) Subject: [PATCH] D73521: [analyzer] add-new-checker.py: Introduction In-Reply-To: References: Message-ID: Charusso added a comment. In D73521#1951776 , @ASDenysPetrov wrote: > Will this utility affect Visual Studio builds? The community owns like 50 build-bots, so it should affect all of them by default. I am hoping it will just work. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73521/new/ https://reviews.llvm.org/D73521 From cfe-commits at lists.llvm.org Tue Mar 31 04:56:46 2020 From: cfe-commits at lists.llvm.org (Dylan McKay via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 11:56:46 +0000 (UTC) Subject: [PATCH] D77119: [AVR] Fix function pointer address space In-Reply-To: References: Message-ID: <400a5b26398b5f94d0056177e610904b@localhost.localdomain> dylanmckay added a comment. Nice work @vlastik, do you need someone to commit this for you? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77119/new/ https://reviews.llvm.org/D77119 From cfe-commits at lists.llvm.org Tue Mar 31 05:27:39 2020 From: cfe-commits at lists.llvm.org (Nathan James via cfe-commits) Date: Tue, 31 Mar 2020 05:27:39 -0700 (PDT) Subject: [clang-tools-extra] 3807079 - [clang-tidy] Fix crash in readability-redundant-string-cstr Message-ID: <5e83373b.1c69fb81.e5dfa.776b@mx.google.com> Author: Nathan James Date: 2020-03-31T13:27:32+01:00 New Revision: 3807079d705fe04c5c3bde8f848ec922b5771f15 URL: https://github.com/llvm/llvm-project/commit/3807079d705fe04c5c3bde8f848ec922b5771f15 DIFF: https://github.com/llvm/llvm-project/commit/3807079d705fe04c5c3bde8f848ec922b5771f15.diff LOG: [clang-tidy] Fix crash in readability-redundant-string-cstr Summary: Addresses [[ https://bugs.llvm.org/show_bug.cgi?id=45286 | clang-tidy-11: Crash in DynTypedMatcher::matches during readability-redundant-string-cstr check ]] Reviewers: aaron.ballman, alexfh, gribozavr2 Reviewed By: gribozavr2 Subscribers: xazax.hun, cfe-commits Tags: #clang, #clang-tools-extra Differential Revision: https://reviews.llvm.org/D76761 Added: Modified: clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-cstr.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp index 8975f294373c..e41cdfcc08d8 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp @@ -61,53 +61,8 @@ formatDereference(const ast_matchers::MatchFinder::MatchResult &Result, return (llvm::Twine("*") + Text).str(); } -// Trying to get CallExpr in which CxxConstructExpr is called. -static const clang::CallExpr * -tryGetCallExprAncestorForCxxConstructExpr(const Expr *TheExpr, - ASTContext &Context) { - // We skip nodes such as CXXBindTemporaryExpr, MaterializeTemporaryExpr. - for (ast_type_traits::DynTypedNode DynParent : Context.getParents(*TheExpr)) { - if (const auto *Parent = DynParent.get()) { - if (const auto *TheCallExpr = dyn_cast(Parent)) - return TheCallExpr; - - if (const clang::CallExpr *TheCallExpr = - tryGetCallExprAncestorForCxxConstructExpr(Parent, Context)) - return TheCallExpr; - } - } - - return nullptr; -} - -// Check that ParamDecl of CallExprDecl has rvalue type. -static bool checkParamDeclOfAncestorCallExprHasRValueRefType( - const Expr *TheCxxConstructExpr, ASTContext &Context) { - if (const clang::CallExpr *TheCallExpr = - tryGetCallExprAncestorForCxxConstructExpr(TheCxxConstructExpr, - Context)) { - for (unsigned i = 0; i < TheCallExpr->getNumArgs(); ++i) { - const Expr *Arg = TheCallExpr->getArg(i); - if (Arg->getSourceRange() == TheCxxConstructExpr->getSourceRange()) { - if (const auto *TheCallExprFuncProto = - TheCallExpr->getCallee() - ->getType() - ->getPointeeType() - ->getAs()) { - if (TheCallExprFuncProto->getParamType(i)->isRValueReferenceType()) - return true; - } - } - } - } - - return false; -} - -AST_MATCHER(CXXConstructExpr, - matchedParamDeclOfAncestorCallExprHasRValueRefType) { - return checkParamDeclOfAncestorCallExprHasRValueRefType( - &Node, Finder->getASTContext()); +AST_MATCHER(MaterializeTemporaryExpr, isBoundToLValue) { + return Node.isBoundToLvalueReference(); } } // end namespace @@ -141,11 +96,11 @@ void RedundantStringCStrCheck::registerMatchers( // Detect redundant 'c_str()' calls through a string constructor. // If CxxConstructExpr is the part of some CallExpr we need to // check that matched ParamDecl of the ancestor CallExpr is not rvalue. - Finder->addMatcher( - cxxConstructExpr( - StringConstructorExpr, hasArgument(0, StringCStrCallExpr), - unless(matchedParamDeclOfAncestorCallExprHasRValueRefType())), - this); + Finder->addMatcher(cxxConstructExpr(StringConstructorExpr, + hasArgument(0, StringCStrCallExpr), + unless(hasParent(materializeTemporaryExpr( + unless(isBoundToLValue()))))), + this); // Detect: 's == str.c_str()' -> 's == str' Finder->addMatcher( diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-cstr.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-cstr.cpp index 1773dc57a8d8..2561b81805bd 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-cstr.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-cstr.cpp @@ -220,3 +220,27 @@ void m1(std::string&&) { m1tp m1p2 = m1; m1p2(s.c_str()); } + +namespace PR45286 { +struct Foo { + void func(const std::string &) {} + void func2(std::string &&) {} +}; + +void bar() { + std::string Str{"aaa"}; + Foo Foo; + Foo.func(Str.c_str()); + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant call to 'c_str' [readability-redundant-string-cstr] + // CHECK-FIXES: {{^ }}Foo.func(Str);{{$}} + + // Ensure it doesn't transform Binding to r values + Foo.func2(Str.c_str()); + + // Ensure its not confused by parens + Foo.func((Str.c_str())); + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant call to 'c_str' [readability-redundant-string-cstr] + // CHECK-FIXES: {{^ }}Foo.func((Str));{{$}} + Foo.func2((Str.c_str())); +} +} // namespace PR45286 From cfe-commits at lists.llvm.org Tue Mar 31 05:32:15 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 12:32:15 +0000 (UTC) Subject: [PATCH] D76761: [clang-tidy] Fix crash in readability-redundant-string-cstr In-Reply-To: References: Message-ID: <25b321111740a3cd73d4a092d292e316@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG3807079d705f: [clang-tidy] Fix crash in readability-redundant-string-cstr (authored by njames93). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76761/new/ https://reviews.llvm.org/D76761 Files: clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-cstr.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76761.253853.patch Type: text/x-patch Size: 4280 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 06:04:39 2020 From: cfe-commits at lists.llvm.org (Vlastimil Labsky via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 13:04:39 +0000 (UTC) Subject: [PATCH] D77119: [AVR] Fix function pointer address space In-Reply-To: References: Message-ID: vlastik added a comment. In D77119#1952293 , @dylanmckay wrote: > Nice work @vlastik, do you need someone to commit this for you? Thanks, yes please I need someone to commit the patch CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77119/new/ https://reviews.llvm.org/D77119 From cfe-commits at lists.llvm.org Tue Mar 31 06:04:40 2020 From: cfe-commits at lists.llvm.org (Michael Kruse via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 13:04:40 +0000 (UTC) Subject: [PATCH] D76342: [OpenMP] Implement '#pragma omp tile' In-Reply-To: References: Message-ID: <94fe239bb2d68b0dc443becc76535688@localhost.localdomain> Meinersbur added a comment. ping Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76342/new/ https://reviews.llvm.org/D76342 From cfe-commits at lists.llvm.org Tue Mar 31 06:04:40 2020 From: cfe-commits at lists.llvm.org (Michael Kruse via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 13:04:40 +0000 (UTC) Subject: [PATCH] D69088: [Lex] #pragma clang transform In-Reply-To: References: Message-ID: Meinersbur added a comment. ping Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D69088/new/ https://reviews.llvm.org/D69088 From cfe-commits at lists.llvm.org Tue Mar 31 06:14:44 2020 From: cfe-commits at lists.llvm.org (Sam McCall via cfe-commits) Date: Tue, 31 Mar 2020 06:14:44 -0700 (PDT) Subject: [clang-tools-extra] 71177ac - [clangd] Support new semanticTokens request from LSP 3.16. Message-ID: <5e834244.1c69fb81.d36eb.7fa9@mx.google.com> Author: Sam McCall Date: 2020-03-31T15:14:35+02:00 New Revision: 71177ac16801ceced4b7dcdd21b05345416f31df URL: https://github.com/llvm/llvm-project/commit/71177ac16801ceced4b7dcdd21b05345416f31df DIFF: https://github.com/llvm/llvm-project/commit/71177ac16801ceced4b7dcdd21b05345416f31df.diff LOG: [clangd] Support new semanticTokens request from LSP 3.16. Summary: This is a simpler request/response protocol. Reference: https://github.com/microsoft/vscode-languageserver-node/blob/master/protocol/src/protocol.semanticTokens.proposed.ts No attempt to support incremental formatting (yet). Reviewers: hokein Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D76663 Added: clang-tools-extra/clangd/test/semantic-tokens.test Modified: clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/ClangdLSPServer.h clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/ClangdServer.h clang-tools-extra/clangd/Protocol.cpp clang-tools-extra/clangd/Protocol.h clang-tools-extra/clangd/SemanticHighlighting.cpp clang-tools-extra/clangd/SemanticHighlighting.h clang-tools-extra/clangd/test/initialize-params.test clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index 9be449660eb0..310c1fec17dd 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -458,6 +458,14 @@ void ClangdLSPServer::notify(llvm::StringRef Method, llvm::json::Value Params) { Transp.notify(Method, std::move(Params)); } +static std::vector semanticTokenTypes() { + std::vector Types; + for (unsigned I = 0; I <= static_cast(HighlightingKind::LastKind); + ++I) + Types.push_back(toSemanticTokenType(static_cast(I))); + return Types; +} + void ClangdLSPServer::onInitialize(const InitializeParams &Params, Callback Reply) { // Determine character encoding first as it affects constructed ClangdServer. @@ -569,6 +577,14 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, // trigger on '->' and '::'. {"triggerCharacters", {".", ">", ":"}}, }}, + {"semanticTokensProvider", + llvm::json::Object{ + {"documentProvider", true}, + {"rangeProvider", false}, + {"legend", + llvm::json::Object{{"tokenTypes", semanticTokenTypes()}, + {"tokenModifiers", llvm::json::Array()}}}, + }}, {"signatureHelpProvider", llvm::json::Object{ {"triggerCharacters", {"(", ","}}, @@ -1220,6 +1236,20 @@ void ClangdLSPServer::onDocumentLink( }); } +void ClangdLSPServer::onSemanticTokens(const SemanticTokensParams &Params, + Callback CB) { + Server->semanticHighlights( + Params.textDocument.uri.file(), + [CB(std::move(CB))]( + llvm::Expected> Toks) mutable { + if (!Toks) + return CB(Toks.takeError()); + SemanticTokens Result; + Result.data = toSemanticTokens(*Toks); + CB(std::move(Result)); + }); +} + ClangdLSPServer::ClangdLSPServer( class Transport &Transp, const FileSystemProvider &FSProvider, const clangd::CodeCompleteOptions &CCOpts, @@ -1267,6 +1297,7 @@ ClangdLSPServer::ClangdLSPServer( MsgHandler->bind("typeHierarchy/resolve", &ClangdLSPServer::onResolveTypeHierarchy); MsgHandler->bind("textDocument/selectionRange", &ClangdLSPServer::onSelectionRange); MsgHandler->bind("textDocument/documentLink", &ClangdLSPServer::onDocumentLink); + MsgHandler->bind("textDocument/semanticTokens", &ClangdLSPServer::onSemanticTokens); // clang-format on } diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h index c4e9e5fb679c..ff67bf772b7f 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.h @@ -119,6 +119,7 @@ class ClangdLSPServer : private ClangdServer::Callbacks { Callback>); void onDocumentLink(const DocumentLinkParams &, Callback>); + void onSemanticTokens(const SemanticTokensParams &, Callback); std::vector getFixes(StringRef File, const clangd::Diagnostic &D); diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index acfaa81dbf29..36af6c98d18b 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -685,6 +685,18 @@ void ClangdServer::documentLinks(PathRef File, TUScheduler::InvalidateOnUpdate); } +void ClangdServer::semanticHighlights( + PathRef File, Callback> CB) { + auto Action = + [CB = std::move(CB)](llvm::Expected InpAST) mutable { + if (!InpAST) + return CB(InpAST.takeError()); + CB(clangd::getSemanticHighlightings(InpAST->AST)); + }; + WorkScheduler.runWithAST("SemanticHighlights", File, std::move(Action), + TUScheduler::InvalidateOnUpdate); +} + std::vector> ClangdServer::getUsedBytesPerFile() const { return WorkScheduler.getUsedBytesPerFile(); diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index 8d9193366d95..a0659c7c3d22 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -297,7 +297,10 @@ class ClangdServer { /// Get all document links in a file. void documentLinks(PathRef File, Callback> CB); - + + void semanticHighlights(PathRef File, + Callback>); + /// Returns estimated memory usage for each of the currently open files. /// The order of results is unspecified. /// Overall memory usage of clangd may be significantly more than reported diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp index 462aebc4b046..9d7c96df02c0 100644 --- a/clang-tools-extra/clangd/Protocol.cpp +++ b/clang-tools-extra/clangd/Protocol.cpp @@ -984,6 +984,29 @@ llvm::json::Value toJSON(const FileStatus &FStatus) { }; } +void SemanticToken::encode(std::vector &Out) const { + Out.push_back(deltaLine); + Out.push_back(deltaStart); + Out.push_back(length); + Out.push_back(tokenType); + Out.push_back(tokenModifiers); +} + +llvm::json::Value toJSON(const SemanticTokens &Tokens) { + std::vector Data; + for (const auto &Tok : Tokens.data) + Tok.encode(Data); + llvm::json::Object Result{{"data", std::move(Data)}}; + if (Tokens.resultId) + Result["resultId"] = *Tokens.resultId; + return Result; +} + +bool fromJSON(const llvm::json::Value &Params, SemanticTokensParams &R) { + llvm::json::ObjectMapper O(Params); + return O && O.map("textDocument", R.textDocument); +} + llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const DocumentHighlight &V) { O << V.range; diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h index d08e546e3ffb..5d0b60d7fe9f 100644 --- a/clang-tools-extra/clangd/Protocol.h +++ b/clang-tools-extra/clangd/Protocol.h @@ -1340,7 +1340,47 @@ struct FileStatus { std::string state; // FIXME: add detail messages. }; -llvm::json::Value toJSON(const FileStatus &FStatus); +llvm::json::Value toJSON(const FileStatus &); + +/// Specifies a single semantic token in the document. +/// This struct is not part of LSP, which just encodes lists of tokens as +/// arrays of numbers directly. +struct SemanticToken { + /// token line number, relative to the previous token + unsigned deltaLine = 0; + /// token start character, relative to the previous token + /// (relative to 0 or the previous token's start if they are on the same line) + unsigned deltaStart = 0; + /// the length of the token. A token cannot be multiline + unsigned length = 0; + /// will be looked up in `SemanticTokensLegend.tokenTypes` + unsigned tokenType = 0; + /// each set bit will be looked up in `SemanticTokensLegend.tokenModifiers` + unsigned tokenModifiers = 0; + + void encode(std::vector &Out) const; +}; + +/// A versioned set of tokens. +struct SemanticTokens { + // An optional result id. If provided and clients support delta updating + // the client will include the result id in the next semantic token request. + // A server can then instead of computing all semantic tokens again simply + // send a delta. + llvm::Optional resultId; + + /// The actual tokens. For a detailed description about how the data is + /// structured pls see + /// https://github.com/microsoft/vscode-extension-samples/blob/5ae1f7787122812dcc84e37427ca90af5ee09f14/semantic-tokens-sample/vscode.proposed.d.ts#L71 + std::vector data; +}; +llvm::json::Value toJSON(const SemanticTokens &); + +struct SemanticTokensParams { + /// The text document. + TextDocumentIdentifier textDocument; +}; +bool fromJSON(const llvm::json::Value &, SemanticTokensParams &); /// Represents a semantic highlighting information that has to be applied on a /// specific line of the text document. diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp index b69f9e8f2710..77b2cbce40d9 100644 --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -445,6 +445,83 @@ bool operator==(const LineHighlightings &L, const LineHighlightings &R) { return std::tie(L.Line, L.Tokens) == std::tie(R.Line, R.Tokens); } +std::vector +toSemanticTokens(llvm::ArrayRef Tokens) { + assert(std::is_sorted(Tokens.begin(), Tokens.end())); + std::vector Result; + const HighlightingToken *Last = nullptr; + for (const HighlightingToken &Tok : Tokens) { + // FIXME: support inactive code - we need to provide the actual bounds. + if (Tok.Kind == HighlightingKind::InactiveCode) + continue; + Result.emplace_back(); + SemanticToken &Out = Result.back(); + // deltaStart/deltaLine are relative if possible. + if (Last) { + assert(Tok.R.start.line >= Last->R.start.line); + Out.deltaLine = Tok.R.start.line - Last->R.start.line; + if (Out.deltaLine == 0) { + assert(Tok.R.start.character >= Last->R.start.character); + Out.deltaStart = Tok.R.start.character - Last->R.start.character; + } else { + Out.deltaStart = Tok.R.start.character; + } + } else { + Out.deltaLine = Tok.R.start.line; + Out.deltaStart = Tok.R.start.character; + } + assert(Tok.R.end.line == Tok.R.start.line); + Out.length = Tok.R.end.character - Tok.R.start.character; + Out.tokenType = static_cast(Tok.Kind); + + Last = &Tok; + } + return Result; +} +llvm::StringRef toSemanticTokenType(HighlightingKind Kind) { + switch (Kind) { + case HighlightingKind::Variable: + case HighlightingKind::LocalVariable: + case HighlightingKind::StaticField: + return "variable"; + case HighlightingKind::Parameter: + return "parameter"; + case HighlightingKind::Function: + return "function"; + case HighlightingKind::Method: + return "member"; + case HighlightingKind::StaticMethod: + // FIXME: better function/member with static modifier? + return "function"; + case HighlightingKind::Field: + return "member"; + case HighlightingKind::Class: + return "class"; + case HighlightingKind::Enum: + return "enum"; + case HighlightingKind::EnumConstant: + return "enumConstant"; // nonstandard + case HighlightingKind::Typedef: + return "type"; + case HighlightingKind::DependentType: + return "dependent"; // nonstandard + case HighlightingKind::DependentName: + return "dependent"; // nonstandard + case HighlightingKind::Namespace: + return "namespace"; + case HighlightingKind::TemplateParameter: + return "typeParameter"; + case HighlightingKind::Concept: + return "concept"; // nonstandard + case HighlightingKind::Primitive: + return "type"; + case HighlightingKind::Macro: + return "macro"; + case HighlightingKind::InactiveCode: + return "comment"; + } +} + std::vector toTheiaSemanticHighlightingInformation( llvm::ArrayRef Tokens) { diff --git a/clang-tools-extra/clangd/SemanticHighlighting.h b/clang-tools-extra/clangd/SemanticHighlighting.h index 31a97b81d6c2..d3b9ddc23a47 100644 --- a/clang-tools-extra/clangd/SemanticHighlighting.h +++ b/clang-tools-extra/clangd/SemanticHighlighting.h @@ -6,8 +6,21 @@ // //===----------------------------------------------------------------------===// // -// An implementation of semantic highlighting based on this proposal: -// https://github.com/microsoft/vscode-languageserver-node/pull/367 in clangd. +// This file supports semantic highlighting: categorizing tokens in the file so +// that the editor can color/style them diff erently. +// +// This is particularly valuable for C++: its complex and context-dependent +// grammar is a challenge for simple syntax-highlighting techniques. +// +// We support two protocols for providing highlights to the client: +// - the `textDocument/semanticTokens` request from LSP 3.16 +// https://github.com/microsoft/vscode-languageserver-node/blob/release/protocol/3.16.0-next.1/protocol/src/protocol.semanticTokens.proposed.ts +// - the earlier proposed `textDocument/semanticHighlighting` notification +// https://github.com/microsoft/vscode-languageserver-node/pull/367 +// This is referred to as "Theia" semantic highlighting in the code. +// It was supported from clangd 9 but should be considered deprecated as of +// clangd 11 and eventually removed. +// // Semantic highlightings are calculated for an AST by visiting every AST node // and classifying nodes that are interesting to highlight (variables/function // calls etc.). @@ -75,6 +88,9 @@ bool operator==(const LineHighlightings &L, const LineHighlightings &R); // main AST. std::vector getSemanticHighlightings(ParsedAST &AST); +std::vector toSemanticTokens(llvm::ArrayRef); +llvm::StringRef toSemanticTokenType(HighlightingKind Kind); + /// Converts a HighlightingKind to a corresponding TextMate scope /// (https://manual.macromates.com/en/language_grammars). llvm::StringRef toTextMateScope(HighlightingKind Kind); diff --git a/clang-tools-extra/clangd/test/initialize-params.test b/clang-tools-extra/clangd/test/initialize-params.test index 2b5c02fc8ce2..9eef5fa68dc9 100644 --- a/clang-tools-extra/clangd/test/initialize-params.test +++ b/clang-tools-extra/clangd/test/initialize-params.test @@ -38,6 +38,16 @@ # CHECK-NEXT: "referencesProvider": true, # CHECK-NEXT: "renameProvider": true, # CHECK-NEXT: "selectionRangeProvider": true, +# CHECK-NEXT: "semanticTokensProvider": { +# CHECK-NEXT: "documentProvider": true, +# CHECK-NEXT: "legend": { +# CHECK-NEXT: "tokenModifiers": [], +# CHECK-NEXT: "tokenTypes": [ +# CHECK-NEXT: "variable", +# CHECK: ] +# CHECK-NEXT: }, +# CHECK-NEXT: "rangeProvider": false +# CHECK-NEXT: }, # CHECK-NEXT: "signatureHelpProvider": { # CHECK-NEXT: "triggerCharacters": [ # CHECK-NEXT: "(", diff --git a/clang-tools-extra/clangd/test/semantic-tokens.test b/clang-tools-extra/clangd/test/semantic-tokens.test new file mode 100644 index 000000000000..1f6b51af84dd --- /dev/null +++ b/clang-tools-extra/clangd/test/semantic-tokens.test @@ -0,0 +1,22 @@ +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.cpp","languageId":"cpp","text":"int x = 2;"}}} +--- +{"jsonrpc":"2.0","id":1,"method":"textDocument/semanticTokens","params":{"textDocument":{"uri":"test:///foo.cpp"}}} +# CHECK: "id": 1, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": { +# CHECK-NEXT: "data": [ +# First line, char 5, variable, no modifiers. +# CHECK-NEXT: 0, +# CHECK-NEXT: 4, +# CHECK-NEXT: 1, +# CHECK-NEXT: 0, +# CHECK-NEXT: 0 +# CHECK-NEXT: ] +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","id":2,"method":"shutdown"} +--- +{"jsonrpc":"2.0","method":"exit"} diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp index 6a7f700e1f49..6c4a4590ab2a 100644 --- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -720,6 +720,41 @@ TEST(SemanticHighlighting, GeneratesHighlightsWhenFileChange) { ASSERT_EQ(Counter.Count, 1); } +TEST(SemanticHighlighting, toSemanticTokens) { + auto CreatePosition = [](int Line, int Character) -> Position { + Position Pos; + Pos.line = Line; + Pos.character = Character; + return Pos; + }; + + std::vector Tokens = { + {HighlightingKind::Variable, + Range{CreatePosition(1, 1), CreatePosition(1, 5)}}, + {HighlightingKind::Function, + Range{CreatePosition(3, 4), CreatePosition(3, 7)}}, + {HighlightingKind::Variable, + Range{CreatePosition(3, 8), CreatePosition(3, 12)}}, + }; + + std::vector Results = toSemanticTokens(Tokens); + EXPECT_EQ(Tokens.size(), Results.size()); + EXPECT_EQ(Results[0].tokenType, unsigned(HighlightingKind::Variable)); + EXPECT_EQ(Results[0].deltaLine, 1u); + EXPECT_EQ(Results[0].deltaStart, 1u); + EXPECT_EQ(Results[0].length, 4u); + + EXPECT_EQ(Results[1].tokenType, unsigned(HighlightingKind::Function)); + EXPECT_EQ(Results[1].deltaLine, 2u); + EXPECT_EQ(Results[1].deltaStart, 4u); + EXPECT_EQ(Results[1].length, 3u); + + EXPECT_EQ(Results[2].tokenType, unsigned(HighlightingKind::Variable)); + EXPECT_EQ(Results[2].deltaLine, 0u); + EXPECT_EQ(Results[2].deltaStart, 4u); + EXPECT_EQ(Results[2].length, 4u); +} + TEST(SemanticHighlighting, toTheiaSemanticHighlightingInformation) { auto CreatePosition = [](int Line, int Character) -> Position { Position Pos; From cfe-commits at lists.llvm.org Tue Mar 31 06:37:13 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 13:37:13 +0000 (UTC) Subject: [PATCH] D77041: [AST] Fix a crash on invalid constexpr Ctorinitializer when building RecoveryExpr. In-Reply-To: References: Message-ID: sammccall accepted this revision. sammccall added inline comments. This revision is now accepted and ready to land. ================ Comment at: clang/lib/Sema/SemaDeclCXX.cpp:5004 CXXCtorInitializer *Member = Initializers[i]; - + if (Member->getInit() && Member->getInit()->containsErrors()) + Constructor->setInvalidDecl(); ---------------- what's the case where this gets hit rather than anyerrors=true? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77041/new/ https://reviews.llvm.org/D77041 From cfe-commits at lists.llvm.org Tue Mar 31 06:37:15 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 13:37:15 +0000 (UTC) Subject: [PATCH] D76831: [AST] Preserve the DeclRefExpr when it refers to an invalid decl. In-Reply-To: References: Message-ID: <78222a2d547293724ec8e1e51b6bf495@localhost.localdomain> sammccall added a comment. I like the idea, but it seems to regress quite a lot of diagnostics... e.g. where we fail to deduce auto and then say it's not a pointer. Also this is regressing things in the -fno-recovery-ast case, because of the changes to CheckDeclInExpr with the existing callsites that allow invalid decls. (I'm not sure what passing AcceptInvalid actually *did* before) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76831/new/ https://reviews.llvm.org/D76831 From cfe-commits at lists.llvm.org Tue Mar 31 06:37:17 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 13:37:17 +0000 (UTC) Subject: [PATCH] D76862: HIP: Ensure new denormal mode attributes are set In-Reply-To: References: Message-ID: <87d54a81c72e7c43a662e7a713d8ecb5@localhost.localdomain> arsenm added a comment. ping CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76862/new/ https://reviews.llvm.org/D76862 From cfe-commits at lists.llvm.org Tue Mar 31 06:37:25 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 13:37:25 +0000 (UTC) Subject: [PATCH] D76663: [clangd] Support new semanticTokens request from LSP 3.16. In-Reply-To: References: Message-ID: <569bb53c9a94df228eefa17f87d03e0c@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG71177ac16801: [clangd] Support new semanticTokens request from LSP 3.16. (authored by sammccall). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76663/new/ https://reviews.llvm.org/D76663 Files: clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/ClangdLSPServer.h clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/ClangdServer.h clang-tools-extra/clangd/Protocol.cpp clang-tools-extra/clangd/Protocol.h clang-tools-extra/clangd/SemanticHighlighting.cpp clang-tools-extra/clangd/SemanticHighlighting.h clang-tools-extra/clangd/test/initialize-params.test clang-tools-extra/clangd/test/semantic-tokens.test clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76663.253865.patch Type: text/x-patch Size: 16653 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 07:09:37 2020 From: cfe-commits at lists.llvm.org (Richard Sandiford via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 14:09:37 +0000 (UTC) Subject: [PATCH] D77056: RFC: [Sema][SVE] Allow non-member operators for SVE types In-Reply-To: References: Message-ID: rsandifo-arm updated this revision to Diff 253867. rsandifo-arm edited the summary of this revision. rsandifo-arm added a comment. Require operators to be defined as static or inside a namespace Also remove redundant brackets and add more tests. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77056/new/ https://reviews.llvm.org/D77056 Files: clang/include/clang/AST/Type.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Basic/Targets/AArch64.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaOverload.cpp clang/test/SemaCXX/sizeless-1.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77056.253867.patch Type: text/x-patch Size: 17849 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 07:12:14 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 14:12:14 +0000 (UTC) Subject: [PATCH] D77142: [clangd] Add a flag to turn on recovery-expr. Message-ID: hokein created this revision. hokein added a reviewer: sammccall. Herald added subscribers: usaxena95, kadircet, arphaman, jkorous, MaskRay, ilya-biryukov. Herald added a project: clang. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77142 Files: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/ClangdServer.h clang-tools-extra/clangd/Compiler.h clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/tool/ClangdMain.cpp clang-tools-extra/clangd/unittests/FindTargetTests.cpp clang-tools-extra/clangd/unittests/TestTU.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77142.253875.patch Type: text/x-patch Size: 6006 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 07:44:42 2020 From: cfe-commits at lists.llvm.org (Zarko Todorovski via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 14:44:42 +0000 (UTC) Subject: [PATCH] D76130: [PPC][AIX] Implement variadic function handling in LowerFormalArguments_AIX In-Reply-To: References: Message-ID: ZarkoCA planned changes to this revision. ZarkoCA added a comment. Fixing test case issues. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76130/new/ https://reviews.llvm.org/D76130 From cfe-commits at lists.llvm.org Tue Mar 31 07:44:43 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 14:44:43 +0000 (UTC) Subject: [PATCH] D77041: [AST] Fix a crash on invalid constexpr Ctorinitializer when building RecoveryExpr. In-Reply-To: References: Message-ID: <1fa59ddd53cabd1876d67f3065fac612@localhost.localdomain> hokein marked an inline comment as done. hokein added inline comments. ================ Comment at: clang/lib/Sema/SemaDeclCXX.cpp:5004 CXXCtorInitializer *Member = Initializers[i]; - + if (Member->getInit() && Member->getInit()->containsErrors()) + Constructor->setInvalidDecl(); ---------------- sammccall wrote: > what's the case where this gets hit rather than anyerrors=true? no cases, if `Member->getInit()->containsErrors()` is true, then `anyerrors` is always true (this is done in `ParseDeclCXX.cpp`). the reason why we added the check here is that we mark the constructor as invalid only for case `Member->getInit()->containsErrors()` (not for other cases leading `anyerrors` to true) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77041/new/ https://reviews.llvm.org/D77041 From cfe-commits at lists.llvm.org Tue Mar 31 07:44:46 2020 From: cfe-commits at lists.llvm.org (Alex Crichton via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 14:44:46 +0000 (UTC) Subject: [PATCH] D77115: [WebAssembly] Emit .llvmcmd and .llvmbc as custom sections In-Reply-To: References: Message-ID: alexcrichton added a comment. Seems reasonable to me! In my testing though if these existed as custom sections they'd still make their way to the final binary through LLD, so could LLD skip over these sectiosn by default? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77115/new/ https://reviews.llvm.org/D77115 From cfe-commits at lists.llvm.org Tue Mar 31 07:44:51 2020 From: cfe-commits at lists.llvm.org (Scott Constable via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 14:44:51 +0000 (UTC) Subject: [PATCH] D76812: [X86] Add Indirect Thunk Support to X86 to mitigate Load Value Injection (LVI) [3/3] In-Reply-To: References: Message-ID: <818c97b8e2bd3a7de1f227f7a0cd2704@localhost.localdomain> sconstab updated this revision to Diff 253888. sconstab added a comment. Added a comment to the header of X86IndirectThunks.cpp to indicate support for LVI thunks. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76812/new/ https://reviews.llvm.org/D76812 Files: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Arch/X86.cpp llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86ISelLowering.cpp llvm/lib/Target/X86/X86IndirectThunks.cpp llvm/lib/Target/X86/X86Subtarget.h llvm/test/CodeGen/X86/lvi-hardening-indirectbr.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D76812.253888.patch Type: text/x-patch Size: 17532 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 08:16:48 2020 From: cfe-commits at lists.llvm.org (Alberto Mardegan via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 15:16:48 +0000 (UTC) Subject: [PATCH] D15469: Expose cxx constructor and method properties through libclang and python bindings. In-Reply-To: References: Message-ID: mardy added a comment. In D15469#396582 , @jbcoe wrote: > I'll submit a new patch for `isDeleted` on its own. The rest of this patch seems uncontentious. > > I hope to find time this week to make the changes. Was the patch for isDeleted ever submitted? If not, I can try to get my hands dirty with it :-) Repository: rL LLVM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D15469/new/ https://reviews.llvm.org/D15469 From cfe-commits at lists.llvm.org Tue Mar 31 08:49:30 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 15:49:30 +0000 (UTC) Subject: [PATCH] D77148: [analyzer] ApiModeling: Add buffer size arg constraint with multiplier involved Message-ID: martong created this revision. martong added reviewers: Szelethus, NoQ, steakhal. Herald added subscribers: cfe-commits, ASDenysPetrov, Charusso, gamesh411, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware, xazax.hun, whisperity. Herald added a project: clang. martong added a parent revision: D77066: [analyzer] ApiModeling: Add buffer size arg constraint. Further develop the buffer size argumentum constraint so it can handle sizes that we can get by multiplying two variables. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77148 Files: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp clang/test/Analysis/std-c-library-functions-arg-constraints.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77148.253899.patch Type: text/x-patch Size: 4923 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 09:22:22 2020 From: cfe-commits at lists.llvm.org (Mariya Podchishchaeva via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 16:22:22 +0000 (UTC) Subject: [PATCH] D74387: [SYCL] Defer __float128 type usage diagnostics In-Reply-To: References: Message-ID: <84659570167e681b85d10491f7dd19cf@localhost.localdomain> Fznamznon updated this revision to Diff 253910. Fznamznon added a comment. Apply comments, rebase. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D74387/new/ https://reviews.llvm.org/D74387 Files: clang/include/clang/Basic/Attr.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Sema/Sema.h clang/lib/Sema/CMakeLists.txt clang/lib/Sema/SemaAvailability.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclAttr.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaSYCL.cpp clang/lib/Sema/SemaType.cpp clang/test/SemaSYCL/float128.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D74387.253910.patch Type: text/x-patch Size: 14163 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 09:22:26 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 16:22:26 +0000 (UTC) Subject: [PATCH] D76725: [clangd] Build ASTs only with fresh preambles or after building a new preamble In-Reply-To: References: Message-ID: <22e865aaaa4314aa7a7ff3457b7eaed3@localhost.localdomain> sammccall added a comment. Had some discussion offline. - having ASTWorker not worry about preamble validity before dispatching to preambleworker seems like a win - for this, preambleworker needs to call preambleReady whether it's new or not, so ASTWorker can produce diagnostics - AST reuse from diagnostics->request seems much more useful than the other way around (e.g. it reduces request latency), so don't bother with the latter. (And we can drop diagnostic computation in some cases) This yields pseudocode like: ASTWorker::update(): enqueue({ currentInputs = inputs preambleworker::update(inputs) }) ASTWorker::runWithAST(): enqueue({ ast = cache.get() if (!ast) patch preamble and build ast action(ast) cache.put(ast) }) PreambleWorker::update(): enqueue({ if (!preamble.compatible(inputs)) build preamble ASTWorker::preambleReady(preamble) }) ASTWorker::preambleReady(): enqueue({ preamble = p build ast publish ast.diagnostics if (inputs == currentInputs) cache.put(ast) else if (preamble != oldPreamble) cache.get() // force next read to use this preamble }) (I'm not sure how simple the actual code can be. I do think defining the methods in that order may help readability) ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:8 //===----------------------------------------------------------------------===// -// For each file, managed by TUScheduler, we create a single ASTWorker that -// manages an AST for that file. All operations that modify or read the AST are -// run on a separate dedicated thread asynchronously in FIFO order. +// TUScheduler stores a worker per active file. This worker is called ASTWorker +// and manages updates(modifications to file contents) and reads(actions ---------------- nit: just "This ASTWorker manages updates..." ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:8 //===----------------------------------------------------------------------===// -// For each file, managed by TUScheduler, we create a single ASTWorker that -// manages an AST for that file. All operations that modify or read the AST are -// run on a separate dedicated thread asynchronously in FIFO order. +// TUScheduler stores a worker per active file. This worker is called ASTWorker +// and manages updates(modifications to file contents) and reads(actions ---------------- sammccall wrote: > nit: just "This ASTWorker manages updates..." uber-nit: I'd say the scheduler *manages* workers and the worker *processes* updates. (Just to avoid mixing metaphors) ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:9 +// TUScheduler stores a worker per active file. This worker is called ASTWorker +// and manages updates(modifications to file contents) and reads(actions +// performed on preamble/AST) to the file. ---------------- nit: space before open parens (not a big deal, but occurs several times) ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:16 // -// The processing thread of the ASTWorker is also responsible for building the -// preamble. However, unlike AST, the same preamble can be read concurrently, so -// we run each of async preamble reads on its own thread. +// An update request changes latest inputs to ensure any subsequent read sees +// the version of the file they were requested. In addition to that it might ---------------- changes latest inputs -> replaces the current parser inputs ("changes" suggests some tricky mutation, and inputs isn't defined here) ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:17 +// An update request changes latest inputs to ensure any subsequent read sees +// the version of the file they were requested. In addition to that it might +// result in publishing diagnostics. ---------------- You need to mention "building an AST" here, as you reference it below. ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:25 // -// Rationale for cancelling updates. -// LSP clients can send updates to clangd on each keystroke. Some files take -// significant time to parse (e.g. a few seconds) and clangd can get starved by -// the updates to those files. Therefore we try to process only the last update, -// if possible. -// Our current strategy to do that is the following: -// - For each update we immediately schedule rebuild of the AST. -// - Rebuild of the AST checks if it was cancelled before doing any actual work. -// If it was, it does not do an actual rebuild, only reports llvm::None to the -// callback -// - When adding an update, we cancel the last update in the queue if it didn't -// have any reads. -// There is probably a optimal ways to do that. One approach we might take is -// the following: -// - For each update we remember the pending inputs, but delay rebuild of the -// AST for some timeout. -// - If subsequent updates come before rebuild was started, we replace the -// pending inputs and reset the timer. -// - If any reads of the AST are scheduled, we start building the AST -// immediately. +// ASTWorker processes the file in two parts, a preamble and a mainfile +// section. A preamble can be reused between multiple versions of the file if it ---------------- nit: we use "main file" or "main-file" much more often than "mainfile". ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:26 +// ASTWorker processes the file in two parts, a preamble and a mainfile +// section. A preamble can be reused between multiple versions of the file if it +// isn't invalidated by a modification to a header, compile commands or ---------------- it it isn't -> until? ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:29 +// modification to relevant part of the current file. Such a preamble is called +// usable. +// In the presence of stale(non-usable) preambles, ASTWorker won't publish ---------------- I don't think "usable" is a good name for this, because we *use* preambles that are not "usable". I think "compatible" or "up-to-date" or "fresh" or so would have enough semantic distance to make this less confusing. ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:37 +// invalidated by an update request, a new build will be requested on +// PreambleThread. PreambleThread serves those requests by building preambles on +// a dedicated thread. Since PreambleThread only receives requests for newer ---------------- Nit: first and third sentences in this paragraph say the same thing, drop the third? ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:43 +// +// Whenever PreambleThread finishes a build, ASTWorker will enqueue a task to +// build a new AST using that preamble, called golden AST to publish ---------------- This gets a bit far into implementation details (uses of queues etc) and is hard to follow. Maybe: When a new preamble is built, a "golden" AST is immediately built from that version of the file. This ensures diagnostics get updated even if the queue is full. ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:48 +// ASTWorker queue is full. +// These golden ASTs also ensures diagnostics are always for newer versions of +// the file. As diagnostics are only published for update requests after a ---------------- This is talking about the subtleties of ordering/version guarantees - not really interesting from the outside, and not enough detail here to avoid reading the code. I'd suggest moving these to preambleReady or so. ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:233 + std::vector CIDiags, WantDiagnostics WantDiags) { // Make possibly expensive copy while not holding the lock. + Request Req = {std::make_unique(CI), std::move(PI), ---------------- Some params get copied explicitly, others get passed by value. Pick one strategy? ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:235 + Request Req = {std::make_unique(CI), std::move(PI), + std::move(CIDiags), std::move(WantDiags), + Context::current().clone()}; ---------------- nit: WantDiags is an enum, no move ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:254 void run() { - dlog("Starting preamble worker for {0}", FileName); + dlog("PreambleThread: Starting worker for {0}", FileName); while (true) { ---------------- The prefix "PreambleThread" implies that there's something in the code called PreambleThread, and that there's one such thing, neither are true. (I also think there's a risk in adding ad-hoc prefixes to things that it adds noise and becomes less readable to people with little context, though at dlog that's less of an issue) ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:322 - /// Builds a preamble for Req and caches it. Might re-use the latest built - /// preamble if it is valid for Req. Also signals waiters about the build. - /// FIXME: We shouldn't cache failed preambles, if we've got a successful - /// build before. - void build(Request Req) { - assert(Req.CI && "Got preamble request with null compiler invocation"); - const ParseInputs &Inputs = Req.Inputs; - std::shared_ptr OldPreamble = - Inputs.ForceRebuild ? nullptr : latest(); - - Status.update([&](TUStatus &Status) { - Status.PreambleActivity = PreambleAction::Building; - }); - - auto Preamble = clang::clangd::buildPreamble( - FileName, std::move(*Req.CI), OldPreamble, Inputs, StoreInMemory, - [this, Version(Inputs.Version)]( - ASTContext &Ctx, std::shared_ptr PP, - const CanonicalIncludes &CanonIncludes) { - Callbacks.onPreambleAST(FileName, Version, Ctx, std::move(PP), - CanonIncludes); - }); - { - std::lock_guard Lock(Mutex); - // LatestBuild might be the last reference to old preamble, do not trigger - // destructor while holding the lock. - std::swap(LatestBuild, Preamble); - } - } + /// Builds a preamble for \p Req will reuse LatestBuild if possible. Notifies + /// ASTWorker. ---------------- this sentence doesn't parse :-) ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:341 SynchronizedTUStatus &Status; + ASTWorker &AW; }; ---------------- Please don't use initialisms like this for members, they're hard to follow out of context. I'd suggest ASTPeer (and PreamblePeer) or just Peer, to indicate these threads are tightly-coupled partners. ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:402 + /// Used to inform ASTWorker about a new preamble build by PreambleThread. + void preambleReady(std::unique_ptr CI, ParseInputs PI, + std::shared_ptr Preamble, ---------------- nit: move somewhere more appropriate (near getCurrentPreamble or update if modelling as public, else into the private section?) ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:402 + /// Used to inform ASTWorker about a new preamble build by PreambleThread. + void preambleReady(std::unique_ptr CI, ParseInputs PI, + std::shared_ptr Preamble, ---------------- sammccall wrote: > nit: move somewhere more appropriate (near getCurrentPreamble or update if modelling as public, else into the private section?) nit: use a verb for mutating operations (updatePreamble)? ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:409 + /// cached one if applicable. Assumes LatestPreamble is usable by \p Inputs. + void publishDiagnostics(std::unique_ptr Invocation, + ParseInputs Inputs, std::vector CIDiags); ---------------- This name is confusing, almost all of its implementation is building AST. generateDiagnostics? ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:481 std::deque Requests; /* GUARDED_BY(Mutex) */ + std::queue ReceivedPreambles; /* GUARDED_BY(Mutex) */ llvm::Optional CurrentRequest; /* GUARDED_BY(Mutex) */ ---------------- PreambleRequests or GoldenASTRequests or so? The queue doens't actually contain preambles. ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:541 +void PreambleThread::build(Request Req) { + assert(Req.CI && "Got preamble request with null compiler invocation"); ---------------- Placing this between ASTWorker and its implementation seems confusing - move it down? ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:554 + LatestBuild->Version, Inputs.Version, FileName); + // We still notify the ASTWorker to make sure diagnostics are updated to + // the latest version of the file without requiring user update. ---------------- This is going to trigger a rebuild of the fileindex - is it really necessary? ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:630 + WantDiagnostics WantDiags) { + std::string TaskName = llvm::formatv("Preamble Update ({0})", PI.Version); + // Store preamble and build diagnostics with new preamble if requested. ---------------- "Golden AST from preamble"? Current text is not terribly descriptive... ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:644 + } + // Give up our ownership to old preamble before starting expensive + Preamble.reset(); ---------------- incomplete comment ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:675 + assert(LatestPreamble); + assert(isPreambleUsable(*LatestPreamble, Inputs, FileName, *Invocation)); + ---------------- this isn't a safe assert - it does IO and could transiently become true/false Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76725/new/ https://reviews.llvm.org/D76725 From cfe-commits at lists.llvm.org Tue Mar 31 09:22:27 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Balogh, _=C3=81d=C3=A1m_via_Phabricator?= via cfe-commits) Date: Tue, 31 Mar 2020 16:22:27 +0000 (UTC) Subject: [PATCH] D77150: [Analyzer] New Option for ContainerModeling: AggressiveEraseModeling Message-ID: baloghadamsoftware created this revision. baloghadamsoftware added reviewers: NoQ, Szelethus. baloghadamsoftware added a project: clang. Herald added subscribers: ASDenysPetrov, martong, steakhal, Charusso, gamesh411, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet, xazax.hun, whisperity. A typical (bad) algorithm for erasing elements of a list is the following: for(auto i = L.begin(); i != L.end(); ++i) { if (condition(*i)) i = L.erase(i); } If `condition()` returns true for the last element, then `erase()` returns the past-the-end iterator which the loop tries to increment which leads to undefined behavior. However, the iterator range checker does not find this bug because the "loop iteration before that last iteration" cannot be recognized by the analyzer. Instead we added an option in this patch to `ContainerModeling` which enables the modeling checker to assume after every erase that the result is the past-the-end iterator (if this case is possible). Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77150 Files: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp clang/test/Analysis/analyzer-config.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77150.253873.patch Type: text/x-patch Size: 5419 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 09:22:28 2020 From: cfe-commits at lists.llvm.org (Mariya Podchishchaeva via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 16:22:28 +0000 (UTC) Subject: [PATCH] D74387: [SYCL] Defer __float128 type usage diagnostics In-Reply-To: References: Message-ID: <31dc877bbcd255892c32f6435a6146e5@localhost.localdomain> Fznamznon marked an inline comment as done. Fznamznon added inline comments. ================ Comment at: clang/include/clang/Sema/Sema.h:12248 + /// SYCLDiagIfDeviceCode(Loc, diag::err_type_unsupported) << "__float128"; + DeviceDiagBuilder SYCLDiagIfDeviceCode(SourceLocation Loc, unsigned DiagID); + ---------------- rjmccall wrote: > Fznamznon wrote: > > rjmccall wrote: > > > Will this collect notes associated with the diagnostic correctly? > > Could you please make your question a bit more concrete? > > This function is supposed to work in the same way as `Sema::CUDADiagIfDeviceCode` and `Sema::diagIfOpenMPDeviceCode` . It emits given diagnostic if the current context is known as "device code" and makes this diagnostic deferred otherwise. It uses the `DeviceDiagBuilder` which was implemented earlier. This `DeviceDiagBuilder` also tries to emit callstack notes for the given diagnostics. Do you mean these callstack notes or something else? > Logically, notes that are emitted after a warning or error are considered to be part of that diagnostic. A custom `DiagBuilder` that only redirects the main diagnostic but allows the notes to still be emitted will effectively cause those notes to misleadingly follow whatever previous diagnostic might have been emitted. > > I call this out specifically because some of the places where you're using this still seem to try to emit notes afterwards, at least in some cases. It's possible that `CUDADiagIfDeviceCode` happens to not be used in such a way. Really I'm not sure this conditional `DiagBuilder` approach was a good idea the first time, and I think we should probably reconsider rather than duplicating it. I think if there are some notes associated with the main diagnostic and we want to make this diagnostic deferred by using `SYCLDiagIfDeviceCode`, we have to use this function `SYCLDiagIfDeviceCode` for notes as well. In my changes I didn't do so because I didn't expect notes emitted after new diagnostic. In our SYCL implementation we find function like `SYCLDiagIfDeviceCode` pretty useful because we don't know where is device code until templates are instantiated. We need some mechanism to defer diagnostics pointing to unsupported features used in device code. Do you have better approach in mind? ================ Comment at: clang/lib/Sema/SemaAvailability.cpp:479 + case UnavailableAttr::IR_SYCLForbiddenType: + diag_available_here = diag::err_type_unsupported; + break; ---------------- rjmccall wrote: > Fznamznon wrote: > > rjmccall wrote: > > > All of the other cases are setting this to a note, not an error, so I suspect this will read wrong. > > Yes, this is not a note. For such samples: > > > > ``` > > int main() { > > __float128 CapturedToDevice = 1; > > kernel([=]() { > > decltype(CapturedToDevice) D; > > }); > > } > > ``` > > It looks like this: > > ``` > > float128.cpp:63:14: error: 'CapturedToDevice' is unavailable > > decltype(CapturedToDevice) D; > > ^ > > float128.cpp:59:14: error: '__float128' is not supported on this target /// This emitted instead of note > > __float128 CapturedToDevice = 1; > > ^ > > ``` > > I had feeling that it should probably be a note. But there is no implemented note for unsupported types. I think I can add a new one if it will make it better. Should I? > Yeah, this should be a note, like "note: variable is unavailable because it uses a type '__float128' that is not supported on this target". You should add that. Okay, done. ================ Comment at: clang/lib/Sema/SemaAvailability.cpp:534 + if (S.getLangOpts().SYCLIsDevice) + S.SYCLDiagIfDeviceCode(Loc, diag) << ReferringDecl; + else ---------------- rjmccall wrote: > Fznamznon wrote: > > rjmccall wrote: > > > Are you sure you want to be applying this to all of the possible diagnostics here, rather than just for SYCLForbiddenType unavailable attributes? > > I suppose it is reasonable if we want to reuse unavaliable attribute for other SYCL use cases. Plus, In SYCL we don't know where is device code until we instantiate templates, it happens late, so we have to defer any diagnostic while compiling for device, otherwise we can point to host code where much more is allowed. > My point is actually the reverse of that. This code path is also used for normal `unavailable` attributes, not just the special ones you're synthesizing. Diagnostics from the use of explicitly-unavailable declarations shouldn't get any special treatment here, no more than you'd give special treatment to a diagnostic arising from an attempt to assign a pointer into a `float`. In the logic above where you recognize `IR_SYCLForbiddenType`, I think you should just check whether you should transitively defer the diagnostic and, if so, do so and then bail out of this function early. That might mean you don't need the custom DiagBuilder, too. Okay, I understand. I was under impression that `unavailable` attributes can appear only for ObjC ARC, so It is safe to defer everything in SYCL, so I moved calls of `SYCLDiagIfDeviceCode` as you requested. It's a bit unclear how to avoid custom `DiagBuilder` here. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D74387/new/ https://reviews.llvm.org/D74387 From cfe-commits at lists.llvm.org Tue Mar 31 09:22:31 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 16:22:31 +0000 (UTC) Subject: [PATCH] D77125: [Analyzer] Model return values of container insert and delete operations In-Reply-To: References: Message-ID: <79cfcedbcf81fd7b90f0967e3eb77161@localhost.localdomain> martong added a comment. It seems like we could model here `emplace` and `emplace_after` exactly the same way we do with `insert` and `insert_after`, couldn't we? Perhaps that could go into this patch too. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77125/new/ https://reviews.llvm.org/D77125 From cfe-commits at lists.llvm.org Tue Mar 31 09:52:17 2020 From: cfe-commits at lists.llvm.org (Sam McCall via cfe-commits) Date: Tue, 31 Mar 2020 09:52:17 -0700 (PDT) Subject: [clang] a76e68c - [CodeComplete] Member completion for concept-constrained types. Message-ID: <5e837541.1c69fb81.eecde.62f7@mx.google.com> Author: Sam McCall Date: 2020-03-31T18:43:24+02:00 New Revision: a76e68c9704fb5b3faf25bb8d51e405b5310ff08 URL: https://github.com/llvm/llvm-project/commit/a76e68c9704fb5b3faf25bb8d51e405b5310ff08 DIFF: https://github.com/llvm/llvm-project/commit/a76e68c9704fb5b3faf25bb8d51e405b5310ff08.diff LOG: [CodeComplete] Member completion for concept-constrained types. Summary: The basic idea is to walk through the concept definition, looking for t.foo() where t has the constrained type. In this patch: - nested types are recognized and offered after :: - variable/function members are recognized and offered after the correct dot/arrow/colon trigger - member functions are recognized (anything directly called). parameter types are presumed to be the argument types. parameters are unnamed. - result types are available when a requirement has a type constraint. These are printed as constraints, except same_as which prints as T. Not in this patch: - support for merging/overloading when two locations describe the same member. The last one wins, for any given name. This is probably important... - support for nested template members (T::x) - support for completing members of (instantiations of) template template parameters Reviewers: nridge, saar.raz Subscribers: mgrang, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D73649 Added: clang/test/CodeCompletion/concepts.cpp Modified: clang/include/clang/Sema/Scope.h clang/lib/Sema/CodeCompleteConsumer.cpp clang/lib/Sema/SemaCodeComplete.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h index 6133425a42a6..169ca175eed2 100644 --- a/clang/include/clang/Sema/Scope.h +++ b/clang/include/clang/Sema/Scope.h @@ -320,9 +320,7 @@ class Scope { /// isDeclScope - Return true if this is the scope that the specified decl is /// declared in. - bool isDeclScope(Decl *D) { - return DeclsInScope.count(D) != 0; - } + bool isDeclScope(const Decl *D) const { return DeclsInScope.count(D) != 0; } DeclContext *getEntity() const { return Entity; } void setEntity(DeclContext *E) { Entity = E; } diff --git a/clang/lib/Sema/CodeCompleteConsumer.cpp b/clang/lib/Sema/CodeCompleteConsumer.cpp index b88ff9dd64cd..2402d896faac 100644 --- a/clang/lib/Sema/CodeCompleteConsumer.cpp +++ b/clang/lib/Sema/CodeCompleteConsumer.cpp @@ -570,29 +570,10 @@ void PrintingCodeCompleteConsumer::ProcessCodeCompleteResults( if (const char *BriefComment = CCS->getBriefComment()) OS << " : " << BriefComment; } - for (const FixItHint &FixIt : Results[I].FixIts) { - const SourceLocation BLoc = FixIt.RemoveRange.getBegin(); - const SourceLocation ELoc = FixIt.RemoveRange.getEnd(); - - SourceManager &SM = SemaRef.SourceMgr; - std::pair BInfo = SM.getDecomposedLoc(BLoc); - std::pair EInfo = SM.getDecomposedLoc(ELoc); - // Adjust for token ranges. - if (FixIt.RemoveRange.isTokenRange()) - EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, SemaRef.LangOpts); - - OS << " (requires fix-it:" - << " {" << SM.getLineNumber(BInfo.first, BInfo.second) << ':' - << SM.getColumnNumber(BInfo.first, BInfo.second) << '-' - << SM.getLineNumber(EInfo.first, EInfo.second) << ':' - << SM.getColumnNumber(EInfo.first, EInfo.second) << "}" - << " to \"" << FixIt.CodeToInsert << "\")"; - } - OS << '\n'; break; case CodeCompletionResult::RK_Keyword: - OS << Results[I].Keyword << '\n'; + OS << Results[I].Keyword; break; case CodeCompletionResult::RK_Macro: @@ -602,13 +583,31 @@ void PrintingCodeCompleteConsumer::ProcessCodeCompleteResults( includeBriefComments())) { OS << " : " << CCS->getAsString(); } - OS << '\n'; break; case CodeCompletionResult::RK_Pattern: - OS << "Pattern : " << Results[I].Pattern->getAsString() << '\n'; + OS << "Pattern : " << Results[I].Pattern->getAsString(); break; } + for (const FixItHint &FixIt : Results[I].FixIts) { + const SourceLocation BLoc = FixIt.RemoveRange.getBegin(); + const SourceLocation ELoc = FixIt.RemoveRange.getEnd(); + + SourceManager &SM = SemaRef.SourceMgr; + std::pair BInfo = SM.getDecomposedLoc(BLoc); + std::pair EInfo = SM.getDecomposedLoc(ELoc); + // Adjust for token ranges. + if (FixIt.RemoveRange.isTokenRange()) + EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, SemaRef.LangOpts); + + OS << " (requires fix-it:" + << " {" << SM.getLineNumber(BInfo.first, BInfo.second) << ':' + << SM.getColumnNumber(BInfo.first, BInfo.second) << '-' + << SM.getLineNumber(EInfo.first, EInfo.second) << ':' + << SM.getColumnNumber(EInfo.first, EInfo.second) << "}" + << " to \"" << FixIt.CodeToInsert << "\")"; + } + OS << '\n'; } } diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 6ba404034a86..00d47faec8a5 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -9,6 +9,7 @@ // This file defines the code-completion semantic actions. // //===----------------------------------------------------------------------===// +#include "clang/AST/ASTConcept.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" @@ -16,8 +17,11 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprObjC.h" +#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/QualTypeNames.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Type.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/Specifiers.h" @@ -4746,6 +4750,369 @@ static RecordDecl *getAsRecordDecl(const QualType BaseType) { return nullptr; } +namespace { +// Collects completion-relevant information about a concept-constrainted type T. +// In particular, examines the constraint expressions to find members of T. +// +// The design is very simple: we walk down each constraint looking for +// expressions of the form T.foo(). +// If we're extra lucky, the return type is specified. +// We don't do any clever handling of && or || in constraint expressions, we +// take members from both branches. +// +// For example, given: +// template concept X = requires (T t, string& s) { t.print(s); }; +// template void foo(U u) { u.^ } +// We want to suggest the inferred member function 'print(string)'. +// We see that u has type U, so X holds. +// X requires t.print(s) to be valid, where t has type U (substituted for T). +// By looking at the CallExpr we find the signature of print(). +// +// While we tend to know in advance which kind of members (access via . -> ::) +// we want, it's simpler just to gather them all and post-filter. +// +// FIXME: some of this machinery could be used for non-concept type-parms too, +// enabling completion for type parameters based on other uses of that param. +// +// FIXME: there are other cases where a type can be constrained by a concept, +// e.g. inside `if constexpr(ConceptSpecializationExpr) { ... }` +class ConceptInfo { +public: + // Describes a likely member of a type, inferred by concept constraints. + // Offered as a code completion for T. T-> and T:: contexts. + struct Member { + // Always non-null: we only handle members with ordinary identifier names. + const IdentifierInfo *Name = nullptr; + // Set for functions we've seen called. + // We don't have the declared parameter types, only the actual types of + // arguments we've seen. These are still valuable, as it's hard to render + // a useful function completion with neither parameter types nor names! + llvm::Optional> ArgTypes; + // Whether this is accessed as T.member, T->member, or T::member. + enum AccessOperator { + Colons, + Arrow, + Dot, + } Operator = Dot; + // What's known about the type of a variable or return type of a function. + const TypeConstraint *ResultType = nullptr; + // FIXME: also track: + // - kind of entity (function/variable/type), to expose structured results + // - template args kinds/types, as a proxy for template params + + // For now we simply return these results as "pattern" strings. + CodeCompletionString *render(Sema &S, CodeCompletionAllocator &Alloc, + CodeCompletionTUInfo &Info) const { + CodeCompletionBuilder B(Alloc, Info); + // Result type + if (ResultType) { + std::string AsString; + { + llvm::raw_string_ostream OS(AsString); + QualType ExactType = deduceType(*ResultType); + if (!ExactType.isNull()) + ExactType.print(OS, getCompletionPrintingPolicy(S)); + else + ResultType->print(OS, getCompletionPrintingPolicy(S)); + } + B.AddResultTypeChunk(Alloc.CopyString(AsString)); + } + // Member name + B.AddTypedTextChunk(Alloc.CopyString(Name->getName())); + // Function argument list + if (ArgTypes) { + B.AddChunk(clang::CodeCompletionString::CK_LeftParen); + bool First = true; + for (QualType Arg : *ArgTypes) { + if (First) + First = false; + else { + B.AddChunk(clang::CodeCompletionString::CK_Comma); + B.AddChunk(clang::CodeCompletionString::CK_HorizontalSpace); + } + B.AddPlaceholderChunk(Alloc.CopyString( + Arg.getAsString(getCompletionPrintingPolicy(S)))); + } + B.AddChunk(clang::CodeCompletionString::CK_RightParen); + } + return B.TakeString(); + } + }; + + // BaseType is the type parameter T to infer members from. + // T must be accessible within S, as we use it to find the template entity + // that T is attached to in order to gather the relevant constraints. + ConceptInfo(const TemplateTypeParmType &BaseType, Scope *S) { + auto *TemplatedEntity = getTemplatedEntity(BaseType.getDecl(), S); + for (const Expr *E : constraintsForTemplatedEntity(TemplatedEntity)) + believe(E, &BaseType); + } + + std::vector members() { + std::vector Results; + for (const auto &E : this->Results) + Results.push_back(E.second); + llvm::sort(Results, [](const Member &L, const Member &R) { + return L.Name->getName() < R.Name->getName(); + }); + return Results; + } + +private: + // Infer members of T, given that the expression E (dependent on T) is true. + void believe(const Expr *E, const TemplateTypeParmType *T) { + if (!E || !T) + return; + if (auto *CSE = dyn_cast(E)) { + // If the concept is + // template concept CD = f(); + // And the concept specialization is + // CD + // Then we're substituting T for B, so we want to make f() true + // by adding members to B - i.e. believe(f(), B); + // + // For simplicity: + // - we don't attempt to substitute int for A + // - when T is used in other ways (like CD) we ignore it + ConceptDecl *CD = CSE->getNamedConcept(); + TemplateParameterList *Params = CD->getTemplateParameters(); + unsigned Index = 0; + for (const auto &Arg : CSE->getTemplateArguments()) { + if (Index >= Params->size()) + break; // Won't happen in valid code. + if (isApprox(Arg, T)) { + auto *TTPD = dyn_cast(Params->getParam(Index)); + if (!TTPD) + continue; + // T was used as an argument, and bound to the parameter TT. + auto *TT = cast(TTPD->getTypeForDecl()); + // So now we know the constraint as a function of TT is true. + believe(CD->getConstraintExpr(), TT); + // (concepts themselves have no associated constraints to require) + } + + ++Index; + } + } else if (auto *BO = dyn_cast(E)) { + // For A && B, we can infer members from both branches. + // For A || B, the union is still more useful than the intersection. + if (BO->getOpcode() == BO_LAnd || BO->getOpcode() == BO_LOr) { + believe(BO->getLHS(), T); + believe(BO->getRHS(), T); + } + } else if (auto *RE = dyn_cast(E)) { + // A requires(){...} lets us infer members from each requirement. + for (const concepts::Requirement *Req : RE->getRequirements()) { + if (!Req->isDependent()) + continue; // Can't tell us anything about T. + // Now Req cannot a substitution-error: those aren't dependent. + + if (auto *TR = dyn_cast(Req)) { + // Do a full traversal so we get `foo` from `typename T::foo::bar`. + QualType AssertedType = TR->getType()->getType(); + ValidVisitor(this, T).TraverseType(AssertedType); + } else if (auto *ER = dyn_cast(Req)) { + ValidVisitor Visitor(this, T); + // If we have a type constraint on the value of the expression, + // AND the whole outer expression describes a member, then we'll + // be able to use the constraint to provide the return type. + if (ER->getReturnTypeRequirement().isTypeConstraint()) { + Visitor.OuterType = + ER->getReturnTypeRequirement().getTypeConstraint(); + Visitor.OuterExpr = ER->getExpr(); + } + Visitor.TraverseStmt(ER->getExpr()); + } else if (auto *NR = dyn_cast(Req)) { + believe(NR->getConstraintExpr(), T); + } + } + } + } + + // This visitor infers members of T based on traversing expressions/types + // that involve T. It is invoked with code known to be valid for T. + class ValidVisitor : public RecursiveASTVisitor { + ConceptInfo *Outer; + const TemplateTypeParmType *T; + + CallExpr *Caller = nullptr; + Expr *Callee = nullptr; + + public: + // If set, OuterExpr is constrained by OuterType. + Expr *OuterExpr = nullptr; + const TypeConstraint *OuterType = nullptr; + + ValidVisitor(ConceptInfo *Outer, const TemplateTypeParmType *T) + : Outer(Outer), T(T) { + assert(T); + } + + // In T.foo or T->foo, `foo` is a member function/variable. + bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) { + const Type *Base = E->getBaseType().getTypePtr(); + bool IsArrow = E->isArrow(); + if (Base->isPointerType() && IsArrow) { + IsArrow = false; + Base = Base->getPointeeType().getTypePtr(); + } + if (isApprox(Base, T)) + addValue(E, E->getMember(), IsArrow ? Member::Arrow : Member::Dot); + return true; + } + + // In T::foo, `foo` is a static member function/variable. + bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { + if (E->getQualifier() && isApprox(E->getQualifier()->getAsType(), T)) + addValue(E, E->getDeclName(), Member::Colons); + return true; + } + + // In T::typename foo, `foo` is a type. + bool VisitDependentNameType(DependentNameType *DNT) { + const auto *Q = DNT->getQualifier(); + if (Q && isApprox(Q->getAsType(), T)) + addType(DNT->getIdentifier()); + return true; + } + + // In T::foo::bar, `foo` must be a type. + // VisitNNS() doesn't exist, and TraverseNNS isn't always called :-( + bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSL) { + if (NNSL) { + NestedNameSpecifier *NNS = NNSL.getNestedNameSpecifier(); + const auto *Q = NNS->getPrefix(); + if (Q && isApprox(Q->getAsType(), T)) + addType(NNS->getAsIdentifier()); + } + // FIXME: also handle T::foo::bar + return RecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNSL); + } + + // FIXME also handle T::foo + + // Track the innermost caller/callee relationship so we can tell if a + // nested expr is being called as a function. + bool VisitCallExpr(CallExpr *CE) { + Caller = CE; + Callee = CE->getCallee(); + return true; + } + + private: + void addResult(Member &&M) { + auto R = Outer->Results.try_emplace(M.Name); + Member &O = R.first->second; + // Overwrite existing if the new member has more info. + // The preference of . vs :: vs -> is fairly arbitrary. + if (/*Inserted*/ R.second || + std::make_tuple(M.ArgTypes.hasValue(), M.ResultType != nullptr, + M.Operator) > std::make_tuple(O.ArgTypes.hasValue(), + O.ResultType != nullptr, + O.Operator)) + O = std::move(M); + } + + void addType(const IdentifierInfo *Name) { + if (!Name) + return; + Member M; + M.Name = Name; + M.Operator = Member::Colons; + addResult(std::move(M)); + } + + void addValue(Expr *E, DeclarationName Name, + Member::AccessOperator Operator) { + if (!Name.isIdentifier()) + return; + Member Result; + Result.Name = Name.getAsIdentifierInfo(); + Result.Operator = Operator; + // If this is the callee of an immediately-enclosing CallExpr, then + // treat it as a method, otherwise it's a variable. + if (Caller != nullptr && Callee == E) { + Result.ArgTypes.emplace(); + for (const auto *Arg : Caller->arguments()) + Result.ArgTypes->push_back(Arg->getType()); + if (Caller == OuterExpr) { + Result.ResultType = OuterType; + } + } else { + if (E == OuterExpr) + Result.ResultType = OuterType; + } + addResult(std::move(Result)); + } + }; + + static bool isApprox(const TemplateArgument &Arg, const Type *T) { + return Arg.getKind() == TemplateArgument::Type && + isApprox(Arg.getAsType().getTypePtr(), T); + } + + static bool isApprox(const Type *T1, const Type *T2) { + return T1 && T2 && + T1->getCanonicalTypeUnqualified() == + T2->getCanonicalTypeUnqualified(); + } + + // Returns the DeclContext immediately enclosed by the template parameter + // scope. For primary templates, this is the templated (e.g.) CXXRecordDecl. + // For specializations, this is e.g. ClassTemplatePartialSpecializationDecl. + static DeclContext *getTemplatedEntity(const TemplateTypeParmDecl *D, + Scope *S) { + if (D == nullptr) + return nullptr; + Scope *Inner = nullptr; + while (S) { + if (S->isTemplateParamScope() && S->isDeclScope(D)) + return Inner ? Inner->getEntity() : nullptr; + Inner = S; + S = S->getParent(); + } + return nullptr; + } + + // Gets all the type constraint expressions that might apply to the type + // variables associated with DC (as returned by getTemplatedEntity()). + static SmallVector + constraintsForTemplatedEntity(DeclContext *DC) { + SmallVector Result; + if (DC == nullptr) + return Result; + // Primary templates can have constraints. + if (const auto *TD = cast(DC)->getDescribedTemplate()) + TD->getAssociatedConstraints(Result); + // Partial specializations may have constraints. + if (const auto *CTPSD = + dyn_cast(DC)) + CTPSD->getAssociatedConstraints(Result); + if (const auto *VTPSD = dyn_cast(DC)) + VTPSD->getAssociatedConstraints(Result); + return Result; + } + + // Attempt to find the unique type satisfying a constraint. + // This lets us show e.g. `int` instead of `std::same_as`. + static QualType deduceType(const TypeConstraint &T) { + // Assume a same_as return type constraint is std::same_as or equivalent. + // In this case the return type is T. + DeclarationName DN = T.getNamedConcept()->getDeclName(); + if (DN.isIdentifier() && DN.getAsIdentifierInfo()->isStr("same_as")) + if (const auto *Args = T.getTemplateArgsAsWritten()) + if (Args->getNumTemplateArgs() == 1) { + const auto &Arg = Args->arguments().front().getArgument(); + if (Arg.getKind() == TemplateArgument::Type) + return Arg.getAsType(); + } + return {}; + } + + llvm::DenseMap Results; +}; +} // namespace + void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, Expr *OtherOpBase, SourceLocation OpLoc, bool IsArrow, @@ -4802,15 +5169,31 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, if (const PointerType *Ptr = BaseType->getAs()) { BaseType = Ptr->getPointeeType(); BaseKind = VK_LValue; - } else if (BaseType->isObjCObjectPointerType()) - /*Do nothing*/; - else + } else if (BaseType->isObjCObjectPointerType() || + BaseType->isTemplateTypeParmType()) { + // Both cases (dot/arrow) handled below. + } else { return false; + } } if (RecordDecl *RD = getAsRecordDecl(BaseType)) { AddRecordMembersCompletionResults(*this, Results, S, BaseType, BaseKind, RD, std::move(AccessOpFixIt)); + } else if (const auto *TTPT = + dyn_cast(BaseType.getTypePtr())) { + auto Operator = + IsArrow ? ConceptInfo::Member::Arrow : ConceptInfo::Member::Dot; + for (const auto &R : ConceptInfo(*TTPT, S).members()) { + if (R.Operator != Operator) + continue; + CodeCompletionResult Result( + R.render(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo())); + if (AccessOpFixIt) + Result.FixIts.push_back(*AccessOpFixIt); + Results.AddResult(std::move(Result)); + } } else if (!IsArrow && BaseType->isObjCObjectPointerType()) { // Objective-C property reference. AddedPropertiesSet AddedProperties; @@ -5446,13 +5829,14 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, // Always pretend to enter a context to ensure that a dependent type // resolves to a dependent record. DeclContext *Ctx = computeDeclContext(SS, /*EnteringContext=*/true); - if (!Ctx) - return; // Try to instantiate any non-dependent declaration contexts before - // we look in them. - if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx)) - return; + // we look in them. Bail out if we fail. + NestedNameSpecifier *NNS = SS.getScopeRep(); + if (NNS != nullptr && SS.isValid() && !NNS->isDependent()) { + if (Ctx == nullptr || RequireCompleteDeclContext(SS, Ctx)) + return; + } ResultBuilder Results(*this, CodeCompleter->getAllocator(), CodeCompleter->getCodeCompletionTUInfo(), CC); @@ -5462,21 +5846,34 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, // The "template" keyword can follow "::" in the grammar, but only // put it into the grammar if the nested-name-specifier is dependent. - NestedNameSpecifier *NNS = SS.getScopeRep(); + // FIXME: results is always empty, this appears to be dead. if (!Results.empty() && NNS->isDependent()) Results.AddResult("template"); + // If the scope is a concept-constrained type parameter, infer nested + // members based on the constraints. + if (const auto *TTPT = + dyn_cast_or_null(NNS->getAsType())) { + for (const auto &R : ConceptInfo(*TTPT, S).members()) { + if (R.Operator != ConceptInfo::Member::Colons) + continue; + Results.AddResult(CodeCompletionResult( + R.render(*this, CodeCompleter->getAllocator(), + CodeCompleter->getCodeCompletionTUInfo()))); + } + } + // Add calls to overridden virtual functions, if there are any. // // FIXME: This isn't wonderful, because we don't know whether we're actually // in a context that permits expressions. This is a general issue with // qualified-id completions. - if (!EnteringContext) + if (Ctx && !EnteringContext) MaybeAddOverrideCalls(*this, Ctx, Results); Results.ExitScope(); - if (CodeCompleter->includeNamespaceLevelDecls() || - (!Ctx->isNamespace() && !Ctx->isTranslationUnit())) { + if (Ctx && + (CodeCompleter->includeNamespaceLevelDecls() || !Ctx->isFileContext())) { CodeCompletionDeclConsumer Consumer(Results, Ctx, BaseType); LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer, /*IncludeGlobalScope=*/true, diff --git a/clang/test/CodeCompletion/concepts.cpp b/clang/test/CodeCompletion/concepts.cpp new file mode 100644 index 000000000000..64aad240c1ec --- /dev/null +++ b/clang/test/CodeCompletion/concepts.cpp @@ -0,0 +1,59 @@ +template concept convertible_to = true; +template concept same_as = true; +template concept integral = true; + +template +concept W = requires(A a, B b) { + { b.www } noexcept -> integral; +}; + +template concept X = requires(T t) { + t.xxx(42); + typename T::xxx_t; + T::xyz::member; +}; + +template +concept Y = requires(T t, U u) { t.yyy(u); }; + +template +concept Z = requires(T t) { + { t.zzz() } -> same_as; + requires W; +}; + +// Concept constraints in all three slots require X, Y, Z, and ad-hoc stuff. +template +requires Y && requires(T *t) { { t->aaa() } -> convertible_to; } +void foo(T t) requires Z || requires(T &t) { t.bbb(); t->bb(); } { + t.x; + t->x; + T::x; + + // RUN: %clang_cc1 -std=c++2a -code-completion-with-fixits -code-completion-at=%s:29:5 %s \ + // RUN: | FileCheck %s -check-prefix=DOT -implicit-check-not=xxx_t + // DOT: Pattern : [#convertible_to#]aaa() + // DOT: Pattern : bb() (requires fix-it: {{.*}} to "->") + // DOT: Pattern : bbb() + // DOT: Pattern : [#integral#]www + // DOT: Pattern : xxx(<#int#>) + // FIXME: it would be nice to have int instead of U here. + // DOT: Pattern : yyy(<#U#>) + // DOT: Pattern : [#int#]zzz() + + // RUN: %clang_cc1 -std=c++2a -code-completion-with-fixits -code-completion-at=%s:30:6 %s \ + // RUN: | FileCheck %s -check-prefix=ARROW -implicit-check-not=xxx_t + // ARROW: Pattern : [#convertible_to#]aaa() (requires fix-it: {{.*}} to ".") + // ARROW: Pattern : bb() + // ARROW: Pattern : bbb() (requires fix-it + // ARROW: Pattern : [#integral#]www (requires fix-it + // ARROW: Pattern : xxx(<#int#>) (requires fix-it + // ARROW: Pattern : yyy(<#U#>) (requires fix-it + // ARROW: Pattern : [#int#]zzz() (requires fix-it + + // RUN: %clang_cc1 -std=c++2a -code-completion-with-fixits -code-completion-at=%s:31:6 %s \ + // RUN: | FileCheck %s -check-prefix=COLONS -implicit-check-not=yyy + // COLONS: Pattern : xxx_t + // COLONS: Pattern : xyz +} + From cfe-commits at lists.llvm.org Tue Mar 31 09:58:01 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 16:58:01 +0000 (UTC) Subject: [PATCH] D77142: [clangd] Add a flag to turn on recovery-expr. In-Reply-To: References: Message-ID: sammccall accepted this revision. sammccall added inline comments. This revision is now accepted and ready to land. ================ Comment at: clang-tools-extra/clangd/Preamble.cpp:135 + CI.getLangOpts()->RecoveryAST = Inputs.Opts.BuildRecoveryAST; + ---------------- There's no prospect of this working for C at the moment. We should make this conditional on C++ (and mention C++ in the desc) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77142/new/ https://reviews.llvm.org/D77142 From cfe-commits at lists.llvm.org Tue Mar 31 09:58:08 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 16:58:08 +0000 (UTC) Subject: [PATCH] D76432: [clangd] Add a tweak for adding "using" statement. In-Reply-To: References: Message-ID: sammccall added a comment. Still LG, should I land this? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76432/new/ https://reviews.llvm.org/D76432 From cfe-commits at lists.llvm.org Tue Mar 31 09:58:10 2020 From: cfe-commits at lists.llvm.org (Daniel Sanders via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 16:58:10 +0000 (UTC) Subject: [PATCH] D77103: Add a new -fglobal-isel option and make -fexperimental-isel an alias for it. In-Reply-To: References: Message-ID: dsanders accepted this revision. dsanders added a comment. This revision is now accepted and ready to land. LGTM Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77103/new/ https://reviews.llvm.org/D77103 From cfe-commits at lists.llvm.org Tue Mar 31 10:01:04 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 17:01:04 +0000 (UTC) Subject: [PATCH] D73649: [CodeComplete] Member completion for concept-constrained types. In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rGa76e68c9704f: [CodeComplete] Member completion for concept-constrained types. (authored by sammccall). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73649/new/ https://reviews.llvm.org/D73649 Files: clang/include/clang/Sema/Scope.h clang/lib/Sema/CodeCompleteConsumer.cpp clang/lib/Sema/SemaCodeComplete.cpp clang/test/CodeCompletion/concepts.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D73649.253921.patch Type: text/x-patch Size: 25600 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 10:12:13 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via cfe-commits) Date: Tue, 31 Mar 2020 10:12:13 -0700 (PDT) Subject: [clang] 753a324 - Make FunctionDecl::isDefined non-virtual, NFC Message-ID: <5e8379ed.1c69fb81.ec05f.9d2a@mx.google.com> Author: Reid Kleckner Date: 2020-03-31T10:12:05-07:00 New Revision: 753a3245f7231ffd86b8af02e57da6ceb2ec5669 URL: https://github.com/llvm/llvm-project/commit/753a3245f7231ffd86b8af02e57da6ceb2ec5669 DIFF: https://github.com/llvm/llvm-project/commit/753a3245f7231ffd86b8af02e57da6ceb2ec5669.diff LOG: Make FunctionDecl::isDefined non-virtual, NFC This convenience wrapper was made virtual when it was introduced. I see no overrides and no reason for it to be virtual, so make it non-virtual. Added: Modified: clang/include/clang/AST/Decl.h Removed: ################################################################################ diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 841e24e527eb..2af1189511a3 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -2030,7 +2030,7 @@ class FunctionDecl : public DeclaratorDecl, /// declaration to the declaration that is a definition (if there is one). bool isDefined(const FunctionDecl *&Definition) const; - virtual bool isDefined() const { + bool isDefined() const { const FunctionDecl* Definition; return isDefined(Definition); } From cfe-commits at lists.llvm.org Tue Mar 31 10:31:44 2020 From: cfe-commits at lists.llvm.org (via cfe-commits) Date: Tue, 31 Mar 2020 10:31:44 -0700 (PDT) Subject: [clang] 94d9122 - [NFC] Do not run CGProfilePass when not using integrated assembler Message-ID: <5e837e80.1c69fb81.19c58.9b60@mx.google.com> Author: zhizhouy Date: 2020-03-31T10:31:31-07:00 New Revision: 94d912296de21e965198ba1ddd1ca6714b3e4722 URL: https://github.com/llvm/llvm-project/commit/94d912296de21e965198ba1ddd1ca6714b3e4722 DIFF: https://github.com/llvm/llvm-project/commit/94d912296de21e965198ba1ddd1ca6714b3e4722.diff LOG: [NFC] Do not run CGProfilePass when not using integrated assembler Summary: CGProfilePass is run by default in certain new pass manager optimization pipeline. Assemblers other than llvm as (such as gnu as) cannot recognize the .cgprofile entries generated and emitted from this pass, causing build time error. This patch adds new options in clang CodeGenOpts and PassBuilder options so that we can turn cgprofile off when not using integrated assembler. Reviewers: Bigcheese, xur, george.burgess.iv, chandlerc, manojgupta Reviewed By: manojgupta Subscribers: manojgupta, void, hiraditya, dexonsmith, llvm-commits, tcwang, llozano Tags: #llvm, #clang Differential Revision: https://reviews.llvm.org/D62627 Added: llvm/test/Other/new-pm-cgprofile.ll Modified: clang/include/clang/Basic/CodeGenOptions.def clang/lib/CodeGen/BackendUtil.cpp clang/lib/Frontend/CompilerInvocation.cpp llvm/include/llvm/Passes/PassBuilder.h llvm/lib/Passes/PassBuilder.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 5b59954fae7b..a62cf5e729db 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -254,6 +254,7 @@ CODEGENOPT(UnwindTables , 1, 0) ///< Emit unwind tables. CODEGENOPT(VectorizeLoop , 1, 0) ///< Run loop vectorizer. CODEGENOPT(VectorizeSLP , 1, 0) ///< Run SLP vectorizer. CODEGENOPT(ProfileSampleAccurate, 1, 0) ///< Sample profile is accurate. +CODEGENOPT(CallGraphProfile , 1, 0) ///< Run call graph profile. /// Attempt to use register sized accesses to bit-fields in structures, when /// possible. diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 97b97276521d..4e8b722eea34 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1108,6 +1108,7 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( PTO.LoopInterleaving = CodeGenOpts.UnrollLoops; PTO.LoopVectorization = CodeGenOpts.VectorizeLoop; PTO.SLPVectorization = CodeGenOpts.VectorizeSLP; + PTO.CallGraphProfile = CodeGenOpts.CallGraphProfile; PTO.Coroutines = LangOpts.Coroutines; PassInstrumentationCallbacks PIC; @@ -1518,6 +1519,7 @@ static void runThinLTOBackend(ModuleSummaryIndex *CombinedIndex, Module *M, Conf.PTO.LoopInterleaving = CGOpts.UnrollLoops; Conf.PTO.LoopVectorization = CGOpts.VectorizeLoop; Conf.PTO.SLPVectorization = CGOpts.VectorizeSLP; + Conf.PTO.CallGraphProfile = CGOpts.CallGraphProfile; // Context sensitive profile. if (CGOpts.hasProfileCSIRInstr()) { diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index dc5e932c9460..46ba46df8999 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -823,6 +823,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.RerollLoops = Args.hasArg(OPT_freroll_loops); Opts.DisableIntegratedAS = Args.hasArg(OPT_fno_integrated_as); + Opts.CallGraphProfile = !Opts.DisableIntegratedAS; Opts.Autolink = !Args.hasArg(OPT_fno_autolink); Opts.SampleProfileFile = std::string(Args.getLastArgValue(OPT_fprofile_sample_use_EQ)); diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h index 38af89622977..12e914d44ba3 100644 --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -105,6 +105,10 @@ class PipelineTuningOptions { /// Tuning option to disable promotion to scalars in LICM with MemorySSA, if /// the number of access is too large. unsigned LicmMssaNoAccForPromotionCap; + + /// Tuning option to enable/disable call graph profile. Its default value is + /// that of the flag: `-enable-npm-call-graph-profile`. + bool CallGraphProfile; }; /// This class provides access to building LLVM's passes. diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 32d0a380ae3a..57c510b8cbfd 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -237,6 +237,10 @@ static cl::opt EnableCHR("enable-chr-npm", cl::init(true), cl::Hidden, cl::desc("Enable control height reduction optimization (CHR)")); +static cl::opt EnableCallGraphProfile( + "enable-npm-call-graph-profile", cl::init(true), cl::Hidden, + cl::desc("Enable call graph profile pass for the new PM (default = on)")); + PipelineTuningOptions::PipelineTuningOptions() { LoopInterleaving = EnableLoopInterleaving; LoopVectorization = EnableLoopVectorization; @@ -246,6 +250,7 @@ PipelineTuningOptions::PipelineTuningOptions() { Coroutines = false; LicmMssaOptCap = SetLicmMssaOptCap; LicmMssaNoAccForPromotionCap = SetLicmMssaNoAccForPromotionCap; + CallGraphProfile = EnableCallGraphProfile; } extern cl::opt EnableHotColdSplit; @@ -1060,7 +1065,8 @@ ModulePassManager PassBuilder::buildModuleOptimizationPipeline( // Add the core optimizing pipeline. MPM.addPass(createModuleToFunctionPassAdaptor(std::move(OptimizePM))); - MPM.addPass(CGProfilePass()); + if (PTO.CallGraphProfile) + MPM.addPass(CGProfilePass()); // Now we need to do some global optimization transforms. // FIXME: It would seem like these should come first in the optimization diff --git a/llvm/test/Other/new-pm-cgprofile.ll b/llvm/test/Other/new-pm-cgprofile.ll new file mode 100644 index 000000000000..c7fe31ab570f --- /dev/null +++ b/llvm/test/Other/new-pm-cgprofile.ll @@ -0,0 +1,11 @@ +; RUN: opt -debug-pass-manager -passes='default' %s 2>&1 |FileCheck %s --check-prefixes=DEFAULT +; RUN: opt -debug-pass-manager -passes='default' -enable-npm-call-graph-profile=0 %s 2>&1 |FileCheck %s --check-prefixes=OFF +; RUN: opt -debug-pass-manager -passes='default' -enable-npm-call-graph-profile=1 %s 2>&1 |FileCheck %s --check-prefixes=ON +; +; DEFAULT: Running pass: CGProfilePass +; OFF-NOT: Running pass: CGProfilePass +; ON: Running pass: CGProfilePass + +define void @foo() { + ret void +} From cfe-commits at lists.llvm.org Tue Mar 31 10:33:37 2020 From: cfe-commits at lists.llvm.org (Sam Clegg via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 17:33:37 +0000 (UTC) Subject: [PATCH] D77115: [WebAssembly] Emit .llvmcmd and .llvmbc as custom sections In-Reply-To: References: Message-ID: <6d166a8f92b453de2409a7fecb5a12a7@localhost.localdomain> sbc100 added a comment. In D77115#1952536 , @alexcrichton wrote: > Seems reasonable to me! In my testing though if these existed as custom sections they'd still make their way to the final binary through LLD, so could LLD skip over these sectiosn by default? I'll take a look at that. Can you confirm that you tools are able to find and use the sections in the same way they do for ELF files? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77115/new/ https://reviews.llvm.org/D77115 From cfe-commits at lists.llvm.org Tue Mar 31 10:33:37 2020 From: cfe-commits at lists.llvm.org (Jason Liu via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 17:33:37 +0000 (UTC) Subject: [PATCH] D76932: [AIX] emit .extern and .weak directive linkage In-Reply-To: References: Message-ID: <24675070133f4accf42d07effd97dfc2@localhost.localdomain> jasonliu added inline comments. ================ Comment at: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:1498 + } + emitLinkage(&F, Name); + continue; ---------------- jasonliu wrote: > I'm surprised we do not enter here for `foo_ext_weak()`. The result of that is we need to do something in `lowerConstant()`, which I would want to avoid if possible. > Should we look into why `isDeclarationForLinker()` returns false for `foo_ext_weak()` here? > My guess is we returned false for `!F->isMaterializable()`. And I'm not sure if `foo_ext_weak` is materializable is the correct answer here. Sorry, ignore the above comment. I think we did entered here for emitLinkage for `foo_ext_weak`. But the hasContainingCsect query blocked the emission there. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76932/new/ https://reviews.llvm.org/D76932 From cfe-commits at lists.llvm.org Tue Mar 31 10:33:40 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 17:33:40 +0000 (UTC) Subject: [PATCH] D77150: [Analyzer] New Option for ContainerModeling: AggressiveEraseModeling In-Reply-To: References: Message-ID: <0ed0667caad80a209a86a319bba6c8a3@localhost.localdomain> martong added a comment. Do you have a lit test as well? It would be useful to have one that is similar to the one you mention in the review's summary. ================ Comment at: clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp:780 + if (AggressiveEraseModeling) { + if (const auto *CData = getContainerData(State, ContReg)) { ---------------- This seems to be very similar to the hunk we have in `handleErase`, so this suggests some unnecessary code duplication. I presume we could create a function which is called from both callers. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77150/new/ https://reviews.llvm.org/D77150 From cfe-commits at lists.llvm.org Tue Mar 31 10:33:42 2020 From: cfe-commits at lists.llvm.org (Jonathan B Coe via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 17:33:42 +0000 (UTC) Subject: [PATCH] D77064: [clang-format] Correct line breaks in C# generic type constraints In-Reply-To: References: Message-ID: jbcoe updated this revision to Diff 253925. jbcoe added a comment. Fix failing test by preventing inconsistent states from being constructed where canBreak is false and mustBreak is true. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77064/new/ https://reviews.llvm.org/D77064 Files: clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/TokenAnnotator.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTestCSharp.cpp Index: clang/unittests/Format/FormatTestCSharp.cpp =================================================================== --- clang/unittests/Format/FormatTestCSharp.cpp +++ clang/unittests/Format/FormatTestCSharp.cpp @@ -564,7 +564,7 @@ TEST_F(FormatTestCSharp, CSharpArrayInitializers) { FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); - + verifyFormat(R"(// private MySet[] setPoints = { new Point(), @@ -710,6 +710,15 @@ IAnotherInterfaceStill {})", Style); + Style.ColumnLimit = 50; // Force lines to be wrapped. + verifyFormat(R"(// +class ItemFactory + where T : new(), + IAnInterface, + IAnotherInterface, + IAnotherInterfaceStill {})", + Style); + // In other languages `where` can be used as a normal identifier. // This example is in C++! verifyFormat(R"(// Index: clang/lib/Format/UnwrappedLineParser.cpp =================================================================== --- clang/lib/Format/UnwrappedLineParser.cpp +++ clang/lib/Format/UnwrappedLineParser.cpp @@ -2340,6 +2340,12 @@ } if (FormatTok->Tok.is(tok::semi)) return; + if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) { + addUnwrappedLine(); + nextToken(); + parseCSharpGenericTypeConstraint(); + break; + } nextToken(); } } Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -1060,15 +1060,20 @@ } void parseCSharpGenericTypeConstraint() { + int OpenAngleBracketsCount = 0; while (CurrentToken) { if (CurrentToken->is(tok::less)) { // parseAngle is too greedy and will consume the whole line. CurrentToken->Type = TT_TemplateOpener; + ++OpenAngleBracketsCount; next(); } else if (CurrentToken->is(tok::greater)) { CurrentToken->Type = TT_TemplateCloser; + --OpenAngleBracketsCount; next(); - } else if (CurrentToken->is(tok::comma)) { + } else if (CurrentToken->is(tok::comma) && OpenAngleBracketsCount == 0) { + // We allow line breaks after GenericTypeConstraintComma's + // so do not flag commas in Generics as GenericTypeConstraintComma's. CurrentToken->Type = TT_CSharpGenericTypeConstraintComma; next(); } else if (CurrentToken->is(Keywords.kw_where)) { Index: clang/lib/Format/ContinuationIndenter.cpp =================================================================== --- clang/lib/Format/ContinuationIndenter.cpp +++ clang/lib/Format/ContinuationIndenter.cpp @@ -346,6 +346,11 @@ Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) { return true; } + // Avoid producing inconsistent states by requiring breaks where they are not + // permitted for C# generic type constraints. + if (State.Stack.back().IsCSharpGenericTypeConstraint && + Previous.isNot(TT_CSharpGenericTypeConstraintComma)) + return false; if ((startsNextParameter(Current, Style) || Previous.is(tok::semi) || (Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) && Style.isCpp() && -------------- next part -------------- A non-text attachment was scrubbed... Name: D77064.253925.patch Type: text/x-patch Size: 3329 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 10:33:42 2020 From: cfe-commits at lists.llvm.org (Jason Liu via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 17:33:42 +0000 (UTC) Subject: [PATCH] D76932: [AIX] emit .extern and .weak directive linkage In-Reply-To: References: Message-ID: <1f7c2f253408c19d5397caba28947923@localhost.localdomain> jasonliu added inline comments. ================ Comment at: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:1492 + + if (MAI->hasDotExternDirective()) { + MCSymbol *Name = getSymbol(&F); ---------------- This query asked if the target supports .extern. However, .extern is not the only directive that could get emitted here. We could also emit .weak. ================ Comment at: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:1498 + } + emitLinkage(&F, Name); + continue; ---------------- I'm surprised we do not enter here for `foo_ext_weak()`. The result of that is we need to do something in `lowerConstant()`, which I would want to avoid if possible. Should we look into why `isDeclarationForLinker()` returns false for `foo_ext_weak()` here? My guess is we returned false for `!F->isMaterializable()`. And I'm not sure if `foo_ext_weak` is materializable is the correct answer here. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76932/new/ https://reviews.llvm.org/D76932 From cfe-commits at lists.llvm.org Tue Mar 31 10:53:00 2020 From: cfe-commits at lists.llvm.org (Aaron Ballman via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 17:53:00 +0000 (UTC) Subject: [PATCH] D76083: [clang-tidy] Expand the list of functions in bugprone-unused-return-value In-Reply-To: References: Message-ID: <60a60adc35f0bdef441e3190924ae7b1@localhost.localdomain> aaron.ballman added inline comments. ================ Comment at: clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp:98 + "::access;" + "::bind;" + "::connect;" ---------------- jranieri-grammatech wrote: > alexfh wrote: > > bind has a side effect and returns a success status. Thus, the result being unused isn't necessarily a bug. Same for `connect`. And probably for `setjmp` as well. > In terms of bind, connect, and setjmp: while I personally would say that code not using the return value is bugprone, the data suggests that the vast majority of developers are using these functions in the intended manner and the false-positive rate should be low. I think we have sufficient statistical data to suggest that these APIs should be on the list because the majority of programmers *do not* use them solely for side effects without using the return value, so my preference is to keep them in the list. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76083/new/ https://reviews.llvm.org/D76083 From cfe-commits at lists.llvm.org Tue Mar 31 10:53:00 2020 From: cfe-commits at lists.llvm.org (Krasimir Georgiev via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 17:53:00 +0000 (UTC) Subject: [PATCH] D77064: [clang-format] Correct line breaks in C# generic type constraints In-Reply-To: References: Message-ID: krasimir accepted this revision. krasimir added a comment. This revision is now accepted and ready to land. Awesome! CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77064/new/ https://reviews.llvm.org/D77064 From cfe-commits at lists.llvm.org Tue Mar 31 10:53:00 2020 From: cfe-commits at lists.llvm.org (Volodymyr Sapsai via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 17:53:00 +0000 (UTC) Subject: [PATCH] D72872: [ObjC generics] Fix not inheriting type bounds in categories/extensions. In-Reply-To: References: Message-ID: <617ebbafbb35f21877f886abbd046afe@localhost.localdomain> vsapsai added a comment. Ping. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72872/new/ https://reviews.llvm.org/D72872 From cfe-commits at lists.llvm.org Tue Mar 31 10:53:01 2020 From: cfe-commits at lists.llvm.org (Jason Liu via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 17:53:01 +0000 (UTC) Subject: [PATCH] D76932: [AIX] emit .extern and .weak directive linkage In-Reply-To: References: Message-ID: jasonliu added inline comments. ================ Comment at: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1548 + + if (XCOFFSym->hasContainingCsect()) { + MCSymbolXCOFF *QualName = ---------------- I hope we can find a better solution here. IMO, we don't even want to override this function in this patch. GVSym should be the right one from what caller passed in. It's caller's responsibility to pass in the right GVSym. When caller calls emitLinkage, we should emitLinkage. It's weird when emitLinkage is called, but none is emitted (when hasContainingCsect() returns false). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76932/new/ https://reviews.llvm.org/D76932 From cfe-commits at lists.llvm.org Tue Mar 31 10:53:00 2020 From: cfe-commits at lists.llvm.org (Raphael Isemann via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 17:53:00 +0000 (UTC) Subject: [PATCH] D75561: Remove const qualifier from Modules returned by ExternalASTSource. (NFC) In-Reply-To: References: Message-ID: teemperor added a comment. I am fine with this if we *really* need it for D75488 . So far the only direct place where we do need the module to be non-const was some redundant assignment for Name (I added a comment in D75488 ), but if that is removed I believe the rest of the code should work with a const Module. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75561/new/ https://reviews.llvm.org/D75561 From cfe-commits at lists.llvm.org Tue Mar 31 11:26:25 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 18:26:25 +0000 (UTC) Subject: [PATCH] D77081: [MS] Mark vbase dtors ref'd when ref'ing dtor In-Reply-To: References: Message-ID: <1c44e24f4ba9fa70b3552ee15630b8db@localhost.localdomain> rnk updated this revision to Diff 253933. rnk added a comment. - Remove definition data bit tracking, use destructor isUsed bit Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77081/new/ https://reviews.llvm.org/D77081 Files: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaExpr.cpp clang/test/CXX/class.access/p4.cpp clang/test/CodeGenCXX/microsoft-abi-vbase-dtor.cpp clang/test/SemaCXX/ms-implicit-complete-dtor.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77081.253933.patch Type: text/x-patch Size: 14881 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 11:26:26 2020 From: cfe-commits at lists.llvm.org (Jason Liu via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 18:26:26 +0000 (UTC) Subject: [PATCH] D76932: [AIX] emit .extern and .weak directive linkage In-Reply-To: References: Message-ID: jasonliu added inline comments. ================ Comment at: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1589 : getObjFileLowering().getSectionForFunctionDescriptor(F, TM)); - + if (F->isDeclaration()) { + MCSymbolXCOFF *FSym = cast(getSymbol(F)); ---------------- If it's possible, I would like to not emitLinkage here. I don't think it's the right place. Could we emitLinkage for the symbols needed in AsmPrinter::doFinalization instead? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76932/new/ https://reviews.llvm.org/D76932 From cfe-commits at lists.llvm.org Tue Mar 31 11:26:27 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 18:26:27 +0000 (UTC) Subject: [PATCH] D77081: [MS] Mark vbase dtors ref'd when ref'ing dtor In-Reply-To: References: Message-ID: rnk added a comment. I'm glad to report that your suggestion worked out well! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77081/new/ https://reviews.llvm.org/D77081 From cfe-commits at lists.llvm.org Tue Mar 31 11:26:32 2020 From: cfe-commits at lists.llvm.org (Sam Clegg via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 18:26:32 +0000 (UTC) Subject: [PATCH] D77115: [WebAssembly] Emit .llvmcmd and .llvmbc as custom sections In-Reply-To: References: Message-ID: sbc100 updated this revision to Diff 253935. sbc100 added a comment. strip in linker Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77115/new/ https://reviews.llvm.org/D77115 Files: clang/test/Driver/embed-bitcode-wasm.c clang/test/Driver/fembed-bitcode.c lld/wasm/Writer.cpp llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp llvm/lib/MC/WasmObjectWriter.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77115.253935.patch Type: text/x-patch Size: 4906 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 11:32:02 2020 From: cfe-commits at lists.llvm.org (Jonathan Coe via cfe-commits) Date: Tue, 31 Mar 2020 11:32:02 -0700 (PDT) Subject: [clang] d1b412a - [clang-format] Correct line breaks in C# generic type constraints Message-ID: <5e838ca2.1c69fb81.91e91.afc9@mx.google.com> Author: Jonathan Coe Date: 2020-03-31T19:27:01+01:00 New Revision: d1b412ae389e4e30706c326ddec192ffb2e272cf URL: https://github.com/llvm/llvm-project/commit/d1b412ae389e4e30706c326ddec192ffb2e272cf DIFF: https://github.com/llvm/llvm-project/commit/d1b412ae389e4e30706c326ddec192ffb2e272cf.diff LOG: [clang-format] Correct line breaks in C# generic type constraints Reviewers: krasimir Reviewed By: krasimir Subscribers: cfe-commits Tags: #clang-format, #clang Differential Revision: https://reviews.llvm.org/D77064 Added: Modified: clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/TokenAnnotator.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTestCSharp.cpp Removed: ################################################################################ diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index d2397dbfeb87..ba42ba0ca050 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -346,6 +346,11 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) { return true; } + // Avoid producing inconsistent states by requiring breaks where they are not + // permitted for C# generic type constraints. + if (State.Stack.back().IsCSharpGenericTypeConstraint && + Previous.isNot(TT_CSharpGenericTypeConstraintComma)) + return false; if ((startsNextParameter(Current, Style) || Previous.is(tok::semi) || (Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) && Style.isCpp() && diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 8f40fc7bdcb6..a3cd4f42f8f8 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1060,15 +1060,20 @@ class AnnotatingParser { } void parseCSharpGenericTypeConstraint() { + int OpenAngleBracketsCount = 0; while (CurrentToken) { if (CurrentToken->is(tok::less)) { // parseAngle is too greedy and will consume the whole line. CurrentToken->Type = TT_TemplateOpener; + ++OpenAngleBracketsCount; next(); } else if (CurrentToken->is(tok::greater)) { CurrentToken->Type = TT_TemplateCloser; + --OpenAngleBracketsCount; next(); - } else if (CurrentToken->is(tok::comma)) { + } else if (CurrentToken->is(tok::comma) && OpenAngleBracketsCount == 0) { + // We allow line breaks after GenericTypeConstraintComma's + // so do not flag commas in Generics as GenericTypeConstraintComma's. CurrentToken->Type = TT_CSharpGenericTypeConstraintComma; next(); } else if (CurrentToken->is(Keywords.kw_where)) { diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index d8202bd61458..18899314512e 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -2340,6 +2340,12 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { } if (FormatTok->Tok.is(tok::semi)) return; + if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) { + addUnwrappedLine(); + nextToken(); + parseCSharpGenericTypeConstraint(); + break; + } nextToken(); } } diff --git a/clang/unittests/Format/FormatTestCSharp.cpp b/clang/unittests/Format/FormatTestCSharp.cpp index f5e0bab1cb31..b0e4e76cefe7 100644 --- a/clang/unittests/Format/FormatTestCSharp.cpp +++ b/clang/unittests/Format/FormatTestCSharp.cpp @@ -564,7 +564,7 @@ var myDict = new Dictionary { TEST_F(FormatTestCSharp, CSharpArrayInitializers) { FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); - + verifyFormat(R"(// private MySet[] setPoints = { new Point(), @@ -710,6 +710,15 @@ class ItemFactory IAnotherInterfaceStill {})", Style); + Style.ColumnLimit = 50; // Force lines to be wrapped. + verifyFormat(R"(// +class ItemFactory + where T : new(), + IAnInterface, + IAnotherInterface, + IAnotherInterfaceStill {})", + Style); + // In other languages `where` can be used as a normal identifier. // This example is in C++! verifyFormat(R"(// From cfe-commits at lists.llvm.org Tue Mar 31 11:35:53 2020 From: cfe-commits at lists.llvm.org (Anna Thomas via cfe-commits) Date: Tue, 31 Mar 2020 11:35:53 -0700 (PDT) Subject: [clang] 28518d9 - [InlineFunction] Handle return attributes on call within inlined body Message-ID: <5e838d89.1c69fb81.90153.424f@mx.google.com> Author: Anna Thomas Date: 2020-03-31T14:35:40-04:00 New Revision: 28518d9ae39ff5c6044e230d58b6ae28b0252cae URL: https://github.com/llvm/llvm-project/commit/28518d9ae39ff5c6044e230d58b6ae28b0252cae DIFF: https://github.com/llvm/llvm-project/commit/28518d9ae39ff5c6044e230d58b6ae28b0252cae.diff LOG: [InlineFunction] Handle return attributes on call within inlined body Consider a callee function that has a call (C) within it which feeds into the return. When we inline that callee into a callsite that has return attributes, we can backward propagate those attributes to the call (C) within that inlined callee body. This is safe to do so only if we can guarantee transfer of execution to successor in the window of instructions between return value (i.e. the call C) and the return instruction. See added test cases. Reviewed-By: reames, jdoerfert Differential Revision: https://reviews.llvm.org/D76140 Added: llvm/test/Transforms/Inline/ret_attr_update.ll Modified: clang/test/CodeGen/builtins-systemz-zvector.c clang/test/CodeGen/builtins-systemz-zvector2.c clang/test/CodeGen/movbe-builtins.c clang/test/CodeGen/rot-intrinsics.c llvm/lib/Transforms/Utils/InlineFunction.cpp Removed: ################################################################################ diff --git a/clang/test/CodeGen/builtins-systemz-zvector.c b/clang/test/CodeGen/builtins-systemz-zvector.c index da0e720c9fae..6cba71098792 100644 --- a/clang/test/CodeGen/builtins-systemz-zvector.c +++ b/clang/test/CodeGen/builtins-systemz-zvector.c @@ -3665,31 +3665,31 @@ void test_integer(void) { // CHECK-ASM: vsumqg idx = vec_test_mask(vsc, vuc); - // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vuc, vuc); - // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vss, vus); - // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vus, vus); - // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vsi, vui); - // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vui, vui); - // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vsl, vul); - // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vul, vul); - // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vd, vul); - // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm } diff --git a/clang/test/CodeGen/builtins-systemz-zvector2.c b/clang/test/CodeGen/builtins-systemz-zvector2.c index a4f791e6019b..1880fed64dbc 100644 --- a/clang/test/CodeGen/builtins-systemz-zvector2.c +++ b/clang/test/CodeGen/builtins-systemz-zvector2.c @@ -654,10 +654,10 @@ void test_integer(void) { // CHECK-ASM: vsrlb idx = vec_test_mask(vf, vui); - // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vd, vul); - // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm vuc = vec_msum_u128(vul, vul, vuc, 0); diff --git a/clang/test/CodeGen/movbe-builtins.c b/clang/test/CodeGen/movbe-builtins.c index 342f66391388..15f49b84ec67 100644 --- a/clang/test/CodeGen/movbe-builtins.c +++ b/clang/test/CodeGen/movbe-builtins.c @@ -7,7 +7,7 @@ short test_loadbe_i16(const short *P) { // CHECK-LABEL: @test_loadbe_i16 // CHECK: [[LOAD:%.*]] = load i16, i16* %{{.*}}, align 1 - // CHECK: call i16 @llvm.bswap.i16(i16 [[LOAD]]) + // CHECK: call signext i16 @llvm.bswap.i16(i16 [[LOAD]]) return _loadbe_i16(P); } diff --git a/clang/test/CodeGen/rot-intrinsics.c b/clang/test/CodeGen/rot-intrinsics.c index dcdc54c4585a..7b1ffb6ae3a6 100644 --- a/clang/test/CodeGen/rot-intrinsics.c +++ b/clang/test/CodeGen/rot-intrinsics.c @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -ffreestanding -triple i686--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -ffreestanding -triple x86_64--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-64BIT-LONG -// RUN: %clang_cc1 -fms-extensions -fms-compatibility -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG +// RUN: %clang_cc1 -ffreestanding -triple i686--linux -emit-llvm -mllvm -update-return-attrs=false %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG +// RUN: %clang_cc1 -ffreestanding -triple x86_64--linux -emit-llvm -mllvm -update-return-attrs=false %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-64BIT-LONG +// RUN: %clang_cc1 -fms-extensions -fms-compatibility -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -mllvm -update-return-attrs=false -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG +// RUN: %clang_cc1 -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -mllvm -update-return-attrs=false -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG +// RUN: %clang_cc1 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -mllvm -update-return-attrs=false -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG +// RUN: %clang_cc1 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -mllvm -update-return-attrs=false -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG #include diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index b8b3d1895093..36d05345f23b 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -80,11 +80,21 @@ EnableNoAliasConversion("enable-noalias-to-md-conversion", cl::init(true), cl::Hidden, cl::desc("Convert noalias attributes to metadata during inlining.")); +static cl::opt UpdateReturnAttributes( + "update-return-attrs", cl::init(true), cl::Hidden, + cl::desc("Update return attributes on calls within inlined body")); + static cl::opt PreserveAlignmentAssumptions("preserve-alignment-assumptions-during-inlining", cl::init(true), cl::Hidden, cl::desc("Convert align attributes to assumptions during inlining.")); +static cl::opt InlinerAttributeWindow( + "inliner-attribute-window", cl::Hidden, + cl::desc("the maximum number of instructions analyzed for may throw during " + "attribute inference in inlined body"), + cl::init(4)); + llvm::InlineResult llvm::InlineFunction(CallBase *CB, InlineFunctionInfo &IFI, AAResults *CalleeAAR, bool InsertLifetime) { @@ -1136,6 +1146,81 @@ static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap, } } +static bool MayContainThrowingOrExitingCall(Instruction *Begin, + Instruction *End) { + + assert(Begin->getParent() == End->getParent() && + "Expected to be in same basic block!"); + unsigned NumInstChecked = 0; + // Check that all instructions in the range [Begin, End) are guaranteed to + // transfer execution to successor. + for (auto &I : make_range(Begin->getIterator(), End->getIterator())) + if (NumInstChecked++ > InlinerAttributeWindow || + !isGuaranteedToTransferExecutionToSuccessor(&I)) + return true; + return false; +} + +static void AddReturnAttributes(CallSite CS, ValueToValueMapTy &VMap) { + if (!UpdateReturnAttributes) + return; + AttrBuilder AB(CS.getAttributes(), AttributeList::ReturnIndex); + if (AB.empty()) + return; + + auto *CalledFunction = CS.getCalledFunction(); + auto &Context = CalledFunction->getContext(); + + for (auto &BB : *CalledFunction) { + auto *RI = dyn_cast(BB.getTerminator()); + if (!RI || !isa(RI->getOperand(0))) + continue; + // Sanity check that the cloned return instruction exists and is a return + // instruction itself. + auto *NewRI = dyn_cast_or_null(VMap.lookup(RI)); + if (!NewRI) + continue; + auto *RetVal = cast(RI->getOperand(0)); + // Sanity check that the cloned RetVal exists and is a call. + // Simplification during inlining could have transformed the cloned + // instruction. + auto *NewRetVal = dyn_cast_or_null(VMap.lookup(RetVal)); + if (!NewRetVal) + continue; + // Backward propagation of attributes to the returned value may be incorrect + // if it is control flow dependent. + // Consider: + // @callee { + // %rv = call @foo() + // %rv2 = call @bar() + // if (%rv2 != null) + // return %rv2 + // if (%rv == null) + // exit() + // return %rv + // } + // caller() { + // %val = call nonnull @callee() + // } + // Here we cannot add the nonnull attribute on either foo or bar. So, we + // limit the check to both NewRetVal and NewRI are in the same basic block + // and there are no throwing/exiting instructions between these + // instructions. + if (NewRI->getParent() != NewRetVal->getParent() || + MayContainThrowingOrExitingCall(NewRetVal, NewRI)) + continue; + // Add to the existing attributes of NewRetVal. + // NB! When we have the same attribute already existing on NewRetVal, but + // with a diff ering value, the AttributeList's merge API honours the already + // existing attribute value (i.e. attributes such as dereferenceable, + // dereferenceable_or_null etc). See AttrBuilder::merge for more details. + AttributeList AL = NewRetVal->getAttributes(); + AttributeList NewAL = + AL.addAttributes(Context, AttributeList::ReturnIndex, AB); + NewRetVal->setAttributes(NewAL); + } +} + /// If the inlined function has non-byval align arguments, then /// add @llvm.assume-based alignment assumptions to preserve this information. static void AddAlignmentAssumptions(CallSite CS, InlineFunctionInfo &IFI) { @@ -1801,6 +1886,10 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, // Add noalias metadata if necessary. AddAliasScopeMetadata(CS, VMap, DL, CalleeAAR); + // Clone return attributes on the callsite into the calls within the inlined + // function which feed into its return value. + AddReturnAttributes(CS, VMap); + // Propagate llvm.mem.parallel_loop_access if necessary. PropagateParallelLoopAccessMetadata(CS, VMap); diff --git a/llvm/test/Transforms/Inline/ret_attr_update.ll b/llvm/test/Transforms/Inline/ret_attr_update.ll new file mode 100644 index 000000000000..2e53540c3fe2 --- /dev/null +++ b/llvm/test/Transforms/Inline/ret_attr_update.ll @@ -0,0 +1,159 @@ +; RUN: opt < %s -inline-threshold=0 -always-inline -S | FileCheck %s +; RUN: opt < %s -passes=always-inline -S | FileCheck %s + +declare i8* @foo(i8*) argmemonly nounwind + +define i8* @callee(i8 *%p) alwaysinline { +; CHECK: @callee( +; CHECK: call i8* @foo(i8* noalias %p) + %r = call i8* @foo(i8* noalias %p) + ret i8* %r +} + +define i8* @caller(i8* %ptr, i64 %x) { +; CHECK-LABEL: @caller +; CHECK: call nonnull i8* @foo(i8* noalias + %gep = getelementptr inbounds i8, i8* %ptr, i64 %x + %p = call nonnull i8* @callee(i8* %gep) + ret i8* %p +} + +declare void @llvm.experimental.guard(i1,...) +; Cannot add nonnull attribute to foo +; because the guard is a throwing call +define internal i8* @callee_with_throwable(i8* %p) alwaysinline { +; CHECK-NOT: callee_with_throwable + %r = call i8* @foo(i8* %p) + %cond = icmp ne i8* %r, null + call void (i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ] + ret i8* %r +} + +declare i8* @bar(i8*) readonly nounwind +; Here also we cannot add nonnull attribute to the call bar. +define internal i8* @callee_with_explicit_control_flow(i8* %p) alwaysinline { +; CHECK-NOT: callee_with_explicit_control_flow + %r = call i8* @bar(i8* %p) + %cond = icmp ne i8* %r, null + br i1 %cond, label %ret, label %orig + +ret: + ret i8* %r + +orig: + ret i8* %p +} + +define i8* @caller2(i8* %ptr, i64 %x, i1 %cond) { +; CHECK-LABEL: @caller2 +; CHECK: call i8* @foo +; CHECK: call i8* @bar + %gep = getelementptr inbounds i8, i8* %ptr, i64 %x + %p = call nonnull i8* @callee_with_throwable(i8* %gep) + %q = call nonnull i8* @callee_with_explicit_control_flow(i8* %gep) + br i1 %cond, label %pret, label %qret + +pret: + ret i8* %p + +qret: + ret i8* %q +} + +define internal i8* @callee3(i8 *%p) alwaysinline { +; CHECK-NOT: callee3 + %r = call noalias i8* @foo(i8* %p) + ret i8* %r +} + +; add the deref attribute to the existing attributes on foo. +define i8* @caller3(i8* %ptr, i64 %x) { +; CHECK-LABEL: caller3 +; CHECK: call noalias dereferenceable_or_null(12) i8* @foo + %gep = getelementptr inbounds i8, i8* %ptr, i64 %x + %p = call dereferenceable_or_null(12) i8* @callee3(i8* %gep) + ret i8* %p +} + +declare i8* @inf_loop_call(i8*) nounwind +; We cannot propagate attributes to foo because we do not know whether inf_loop_call +; will return execution. +define internal i8* @callee_with_sideeffect_callsite(i8* %p) alwaysinline { +; CHECK-NOT: callee_with_sideeffect_callsite + %r = call i8* @foo(i8* %p) + %v = call i8* @inf_loop_call(i8* %p) + ret i8* %r +} + +; do not add deref attribute to foo +define i8* @test4(i8* %ptr, i64 %x) { +; CHECK-LABEL: test4 +; CHECK: call i8* @foo + %gep = getelementptr inbounds i8, i8* %ptr, i64 %x + %p = call dereferenceable_or_null(12) i8* @callee_with_sideeffect_callsite(i8* %gep) + ret i8* %p +} + +declare i8* @baz(i8*) nounwind readonly +define internal i8* @callee5(i8* %p) alwaysinline { +; CHECK-NOT: callee5 + %r = call i8* @foo(i8* %p) + %v = call i8* @baz(i8* %p) + ret i8* %r +} + +; add the deref attribute to foo. +define i8* @test5(i8* %ptr, i64 %x) { +; CHECK-LABEL: test5 +; CHECK: call dereferenceable_or_null(12) i8* @foo + %gep = getelementptr inbounds i8, i8* %ptr, i64 %x + %s = call dereferenceable_or_null(12) i8* @callee5(i8* %gep) + ret i8* %s +} + +; deref attributes have diff erent values on the callee and the call feeding into +; the return. +; AttrBuilder chooses the already existing value and does not overwrite it. +define internal i8* @callee6(i8* %p) alwaysinline { +; CHECK-NOT: callee6 + %r = call dereferenceable_or_null(16) i8* @foo(i8* %p) + %v = call i8* @baz(i8* %p) + ret i8* %r +} + + +define i8* @test6(i8* %ptr, i64 %x) { +; CHECK-LABEL: test6 +; CHECK: call dereferenceable_or_null(16) i8* @foo + %gep = getelementptr inbounds i8, i8* %ptr, i64 %x + %s = call dereferenceable_or_null(12) i8* @callee6(i8* %gep) + ret i8* %s +} + +; We add the attributes from the callee to both the calls below. +define internal i8* @callee7(i8 *%ptr, i1 %cond) alwaysinline { +; CHECK-NOT: @callee7( + br i1 %cond, label %pass, label %fail + +pass: + %r = call i8* @foo(i8* noalias %ptr) + ret i8* %r + +fail: + %s = call i8* @baz(i8* %ptr) + ret i8* %s +} + +define void @test7(i8* %ptr, i64 %x, i1 %cond) { +; CHECK-LABEL: @test7 +; CHECK: call nonnull i8* @foo(i8* noalias +; CHECK: call nonnull i8* @baz +; CHECK: phi i8* +; CHECK: call void @snort + + %gep = getelementptr inbounds i8, i8* %ptr, i64 %x + %t = call nonnull i8* @callee7(i8* %gep, i1 %cond) + call void @snort(i8* %t) + ret void +} +declare void @snort(i8*) From cfe-commits at lists.llvm.org Tue Mar 31 11:58:45 2020 From: cfe-commits at lists.llvm.org (Alex Crichton via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 18:58:45 +0000 (UTC) Subject: [PATCH] D77115: [WebAssembly] Emit .llvmcmd and .llvmbc as custom sections In-Reply-To: References: Message-ID: <3000da99618cfcb706a0e529f77f5e95@localhost.localdomain> alexcrichton accepted this revision. alexcrichton added a comment. This revision is now accepted and ready to land. At least from my POV looks good :) Thanks for the quick patch! Should this link also be updated to handle the special section names? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77115/new/ https://reviews.llvm.org/D77115 From cfe-commits at lists.llvm.org Tue Mar 31 11:58:46 2020 From: cfe-commits at lists.llvm.org (Arnold Schwaighofer via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 18:58:46 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift In-Reply-To: References: Message-ID: aschwaighofer updated this revision to Diff 253938. aschwaighofer added a comment. - Remove callback. Swift can inspect the generated IR and update it. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77077/new/ https://reviews.llvm.org/D77077 Files: clang/include/clang/CodeGen/CodeGenABITypes.h clang/lib/CodeGen/CGObjCGNU.cpp clang/lib/CodeGen/CGObjCMac.cpp clang/lib/CodeGen/CGObjCRuntime.cpp clang/lib/CodeGen/CGObjCRuntime.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D77077.253938.patch Type: text/x-patch Size: 4479 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 11:58:47 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 18:58:47 +0000 (UTC) Subject: [PATCH] D76862: HIP: Ensure new denormal mode attributes are set In-Reply-To: References: Message-ID: <97ad2d38f5680134c77982681bf0ccd8@localhost.localdomain> yaxunl added a comment. Are there any other clang options affecting flushing denormals? If so, are they working properly after this change? Do we need to have tests for them? Thanks. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76862/new/ https://reviews.llvm.org/D76862 From cfe-commits at lists.llvm.org Tue Mar 31 11:58:51 2020 From: cfe-commits at lists.llvm.org (Arnold Schwaighofer via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 18:58:51 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift In-Reply-To: References: Message-ID: <22a7ab88d3396a42818b208b19afa8e8@localhost.localdomain> aschwaighofer marked an inline comment as done. aschwaighofer added inline comments. ================ Comment at: clang/include/clang/CodeGen/CodeGenABITypes.h:148 + llvm::function_ref + createProtocolReference); } // end namespace CodeGen ---------------- rjmccall wrote: > aschwaighofer wrote: > > rjmccall wrote: > > > I would call this `emitObjCProtocolObject` or something, and maybe say in the comment: > > > > > > > Get a pointer to a protocol object for the given declaration, emitting it if it hasn't already been emitted in this translation unit. Note that the ABI for emitting a protocol reference in code (e.g. for a `@protocol` expression) in most runtimes is not as simple as just materializing a pointer to this object. > > > > > > Can you explain the need for the callback? Are you expecting to use this for Swift-declared protocols by synthesizing an ObjC protocol declaration for them? I can see why you'd need a callback in that case. > > > Can you explain the need for the callback? Are you expecting to use this for Swift-declared protocols by synthesizing an ObjC protocol declaration for them? I can see why you'd need a callback in that case. > > > > The objective C protocol references other protocols in its inherited list. Swift has an internal list that keeps track of those protocols references and makes sure to initialized them for the debugger and also makes sure that the underlying protocol structure is emitted. The call back is to keep this list in sync. > The problem is that this is really, really intertwined with the ABI logic. This callback basically has to know exactly how the caller is calling it and and what it's expected to build in response. > > Swift code can use arbitrary inline Objective-C functions and therefore emit arbitrary Objective-C code. Is there an approach that handles that while also being less invasive for Clang IRGen? Can we, e.g., inspect the built llvm::Module to figure out retroactively what protocol refs we need to update dynamically instead of trying to track them during the build? Yes. I think you are right. Swift can inspect the generated IR and update it. https://github.com/aschwaighofer/swift/commit/d29daf41ec3a51405df31591dad6fea97dbc58e0 I have removed the callback. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77077/new/ https://reviews.llvm.org/D77077 From cfe-commits at lists.llvm.org Tue Mar 31 11:58:52 2020 From: cfe-commits at lists.llvm.org (Sam Clegg via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 18:58:52 +0000 (UTC) Subject: [PATCH] D77115: [WebAssembly] Emit .llvmcmd and .llvmbc as custom sections In-Reply-To: References: Message-ID: <464fbb085d599ed1dc01b88eef8d7d97@localhost.localdomain> sbc100 updated this revision to Diff 253941. sbc100 added a comment. Avoid resuing IsUsedInReloc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77115/new/ https://reviews.llvm.org/D77115 Files: clang/test/Driver/embed-bitcode-wasm.c clang/test/Driver/fembed-bitcode.c lld/wasm/Writer.cpp llvm/include/llvm/MC/MCSymbolWasm.h llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp llvm/lib/MC/WasmObjectWriter.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77115.253941.patch Type: text/x-patch Size: 6082 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 11:58:57 2020 From: cfe-commits at lists.llvm.org (Stephen Neuendorffer via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 18:58:57 +0000 (UTC) Subject: [PATCH] D77156: [CMAKE] Plumb include_directories() into tablegen() Message-ID: stephenneuendorffer created this revision. Herald added subscribers: cfe-commits, grosul1, Joonsoo, liufengdb, aartbik, lucyrfox, mgester, arpith-jacob, nicolasvasilache, antiagainst, shauheen, burmako, jpienaar, rriddle, mehdi_amini, mgorny. Herald added a project: clang. stephenneuendorffer added reviewers: mehdi_amini, tstellar. Previously, the tablegen() cmake command, which defines custom commands for running tablegen, included several hardcoded paths. This becomes unwieldy as there are more users for which these paths are insufficient. For most targets, cmake uses include_directories() and the INCLUDE_DIRECTORIES directory property to specify include paths. This change picks up the INCLUDE_DIRECTORIES property and adds it to the include path used when running tablegen. As a side effect, this allows us to remove several hard coded paths to tablegen that are redundant with specified include_directories(). I haven't removed the hardcoded path to CMAKE_CURRENT_SOURCE_DIR, which seems generically useful. There are several users in clang which apparently don't have the current directory as an include_directories(). This could be considered separately. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77156 Files: clang/cmake/modules/AddClang.cmake llvm/cmake/modules/TableGen.cmake mlir/cmake/modules/AddMLIR.cmake mlir/examples/toy/Ch3/CMakeLists.txt mlir/examples/toy/Ch4/CMakeLists.txt mlir/examples/toy/Ch4/include/toy/CMakeLists.txt mlir/examples/toy/Ch5/CMakeLists.txt mlir/examples/toy/Ch5/include/toy/CMakeLists.txt mlir/examples/toy/Ch6/CMakeLists.txt mlir/examples/toy/Ch6/include/toy/CMakeLists.txt mlir/examples/toy/Ch7/CMakeLists.txt mlir/examples/toy/Ch7/include/toy/CMakeLists.txt -------------- next part -------------- A non-text attachment was scrubbed... Name: D77156.253945.patch Type: text/x-patch Size: 8750 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 11:59:20 2020 From: cfe-commits at lists.llvm.org (Phabricator via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 18:59:20 +0000 (UTC) Subject: [PATCH] D77064: [clang-format] Correct line breaks in C# generic type constraints In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rGd1b412ae389e: [clang-format] Correct line breaks in C# generic type constraints (authored by Jonathan Coe <jbcoe at google.com>). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77064/new/ https://reviews.llvm.org/D77064 Files: clang/lib/Format/ContinuationIndenter.cpp clang/lib/Format/TokenAnnotator.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTestCSharp.cpp Index: clang/unittests/Format/FormatTestCSharp.cpp =================================================================== --- clang/unittests/Format/FormatTestCSharp.cpp +++ clang/unittests/Format/FormatTestCSharp.cpp @@ -564,7 +564,7 @@ TEST_F(FormatTestCSharp, CSharpArrayInitializers) { FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); - + verifyFormat(R"(// private MySet[] setPoints = { new Point(), @@ -710,6 +710,15 @@ IAnotherInterfaceStill {})", Style); + Style.ColumnLimit = 50; // Force lines to be wrapped. + verifyFormat(R"(// +class ItemFactory + where T : new(), + IAnInterface, + IAnotherInterface, + IAnotherInterfaceStill {})", + Style); + // In other languages `where` can be used as a normal identifier. // This example is in C++! verifyFormat(R"(// Index: clang/lib/Format/UnwrappedLineParser.cpp =================================================================== --- clang/lib/Format/UnwrappedLineParser.cpp +++ clang/lib/Format/UnwrappedLineParser.cpp @@ -2340,6 +2340,12 @@ } if (FormatTok->Tok.is(tok::semi)) return; + if (Style.isCSharp() && FormatTok->is(Keywords.kw_where)) { + addUnwrappedLine(); + nextToken(); + parseCSharpGenericTypeConstraint(); + break; + } nextToken(); } } Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -1060,15 +1060,20 @@ } void parseCSharpGenericTypeConstraint() { + int OpenAngleBracketsCount = 0; while (CurrentToken) { if (CurrentToken->is(tok::less)) { // parseAngle is too greedy and will consume the whole line. CurrentToken->Type = TT_TemplateOpener; + ++OpenAngleBracketsCount; next(); } else if (CurrentToken->is(tok::greater)) { CurrentToken->Type = TT_TemplateCloser; + --OpenAngleBracketsCount; next(); - } else if (CurrentToken->is(tok::comma)) { + } else if (CurrentToken->is(tok::comma) && OpenAngleBracketsCount == 0) { + // We allow line breaks after GenericTypeConstraintComma's + // so do not flag commas in Generics as GenericTypeConstraintComma's. CurrentToken->Type = TT_CSharpGenericTypeConstraintComma; next(); } else if (CurrentToken->is(Keywords.kw_where)) { Index: clang/lib/Format/ContinuationIndenter.cpp =================================================================== --- clang/lib/Format/ContinuationIndenter.cpp +++ clang/lib/Format/ContinuationIndenter.cpp @@ -346,6 +346,11 @@ Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) { return true; } + // Avoid producing inconsistent states by requiring breaks where they are not + // permitted for C# generic type constraints. + if (State.Stack.back().IsCSharpGenericTypeConstraint && + Previous.isNot(TT_CSharpGenericTypeConstraintComma)) + return false; if ((startsNextParameter(Current, Style) || Previous.is(tok::semi) || (Previous.is(TT_TemplateCloser) && Current.is(TT_StartOfName) && Style.isCpp() && -------------- next part -------------- A non-text attachment was scrubbed... Name: D77064.253948.patch Type: text/x-patch Size: 3329 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 11:59:33 2020 From: cfe-commits at lists.llvm.org (Anna Thomas via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 18:59:33 +0000 (UTC) Subject: [PATCH] D76140: [InlineFunction] update attributes during inlining In-Reply-To: References: Message-ID: <5784c8b458f49065122071af77c9ca98@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG28518d9ae39f: [InlineFunction] Handle return attributes on call within inlined body (authored by anna). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76140/new/ https://reviews.llvm.org/D76140 Files: clang/test/CodeGen/builtins-systemz-zvector.c clang/test/CodeGen/builtins-systemz-zvector2.c clang/test/CodeGen/movbe-builtins.c clang/test/CodeGen/rot-intrinsics.c llvm/lib/Transforms/Utils/InlineFunction.cpp llvm/test/Transforms/Inline/ret_attr_update.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D76140.253950.patch Type: text/x-patch Size: 15788 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 12:01:45 2020 From: cfe-commits at lists.llvm.org (Benjamin Kramer via cfe-commits) Date: Tue, 31 Mar 2020 12:01:45 -0700 (PDT) Subject: [clang] e8f13f4 - Replace std::string::find == 0 with StringRef::startswith Message-ID: <5e839399.1c69fb81.def3c.a414@mx.google.com> Author: Benjamin Kramer Date: 2020-03-31T21:01:09+02:00 New Revision: e8f13f4f62f52067cadb55f3c746ccf9d26ee2ce URL: https://github.com/llvm/llvm-project/commit/e8f13f4f62f52067cadb55f3c746ccf9d26ee2ce DIFF: https://github.com/llvm/llvm-project/commit/e8f13f4f62f52067cadb55f3c746ccf9d26ee2ce.diff LOG: Replace std::string::find == 0 with StringRef::startswith This is both more readable and faster. Found by clang-tidy's abseil-string-find-startswith. Added: Modified: clang/lib/Driver/ToolChains/Arch/AArch64.cpp clang/unittests/Analysis/CloneDetectionTest.cpp lldb/source/Core/Module.cpp lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp lldb/source/Symbol/Variable.cpp Removed: ################################################################################ diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index dc31a5ab7b0f..b21cfac6e7ed 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -140,7 +140,8 @@ getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune, // Handle CPU name is 'native'. if (MtuneLowerCase == "native") MtuneLowerCase = std::string(llvm::sys::getHostCPUName()); - if (MtuneLowerCase == "cyclone" || MtuneLowerCase.find("apple") == 0) { + if (MtuneLowerCase == "cyclone" || + StringRef(MtuneLowerCase).startswith("apple")) { Features.push_back("+zcm"); Features.push_back("+zcz"); } diff --git a/clang/unittests/Analysis/CloneDetectionTest.cpp b/clang/unittests/Analysis/CloneDetectionTest.cpp index 03b63c400434..e09d0733f044 100644 --- a/clang/unittests/Analysis/CloneDetectionTest.cpp +++ b/clang/unittests/Analysis/CloneDetectionTest.cpp @@ -42,7 +42,7 @@ class NoBarFunctionConstraint { for (const StmtSequence &Arg : {A, B}) { if (const auto *D = dyn_cast(Arg.getContainingDecl())) { - if (D->getNameAsString().find("bar") == 0) + if (StringRef(D->getNameAsString()).startswith("bar")) return false; } } diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index cff74dc9d518..fefc23a9b1c5 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -1414,7 +1414,7 @@ void Module::SetSymbolFileFileSpec(const FileSpec &file) { if (FileSystem::Instance().IsDirectory(file)) { std::string new_path(file.GetPath()); std::string old_path(obj_file->GetFileSpec().GetPath()); - if (old_path.find(new_path) == 0) { + if (llvm::StringRef(old_path).startswith(new_path)) { // We specified the same bundle as the symbol file that we already // have return; diff --git a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp index 47c7ae8c8d63..83cf9f8bd269 100644 --- a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp +++ b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp @@ -88,7 +88,7 @@ ObjectContainerBSDArchive::Object::Extract(const DataExtractor &data, return LLDB_INVALID_OFFSET; str.assign((const char *)data.GetData(&offset, 16), 16); - if (str.find("#1/") == 0) { + if (llvm::StringRef(str).startswith("#1/")) { // If the name is longer than 16 bytes, or contains an embedded space then // it will use this format where the length of the name is here and the // name characters are after this header. diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index f5c84c6a6151..5044bed309dc 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -5140,10 +5140,10 @@ uint32_t ObjectFileMachO::GetDependentModules(FileSpecList &files) { std::string loader_path("@loader_path"); std::string executable_path("@executable_path"); for (auto &rpath : rpath_paths) { - if (rpath.find(loader_path) == 0) { + if (llvm::StringRef(rpath).startswith(loader_path)) { rpath.erase(0, loader_path.size()); rpath.insert(0, this_file_spec.GetDirectory().GetCString()); - } else if (rpath.find(executable_path) == 0) { + } else if (llvm::StringRef(rpath).startswith(executable_path)) { rpath.erase(0, executable_path.size()); rpath.insert(0, this_file_spec.GetDirectory().GetCString()); } diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 72907a95f3ab..a3c19f71ce69 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -4418,7 +4418,7 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, }); if (!gdb_type.empty() && !(encoding_set || format_set)) { - if (gdb_type.find("int") == 0) { + if (llvm::StringRef(gdb_type).startswith("int")) { reg_info.format = eFormatHex; reg_info.encoding = eEncodingUint; } else if (gdb_type == "data_ptr" || gdb_type == "code_ptr") { diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp index f1533ef6d4b3..6c18ef15e1a2 100644 --- a/lldb/source/Symbol/Variable.cpp +++ b/lldb/source/Symbol/Variable.cpp @@ -529,7 +529,7 @@ static void PrivateAutoCompleteMembers( i, member_name, nullptr, nullptr, nullptr); if (partial_member_name.empty() || - member_name.find(partial_member_name) == 0) { + llvm::StringRef(member_name).startswith(partial_member_name)) { if (member_name == partial_member_name) { PrivateAutoComplete( frame, partial_path, From cfe-commits at lists.llvm.org Tue Mar 31 12:06:30 2020 From: cfe-commits at lists.llvm.org (Amara Emerson via cfe-commits) Date: Tue, 31 Mar 2020 12:06:30 -0700 (PDT) Subject: [clang] 7f1ea92 - Add a new -fglobal-isel option and make -fexperimental-isel an alias for it. Message-ID: <5e8394b6.1c69fb81.2a0e9.e04b@mx.google.com> Author: Amara Emerson Date: 2020-03-31T12:06:11-07:00 New Revision: 7f1ea924c695f3293ff48f662cd1ec5f44bc1ab6 URL: https://github.com/llvm/llvm-project/commit/7f1ea924c695f3293ff48f662cd1ec5f44bc1ab6 DIFF: https://github.com/llvm/llvm-project/commit/7f1ea924c695f3293ff48f662cd1ec5f44bc1ab6.diff LOG: Add a new -fglobal-isel option and make -fexperimental-isel an alias for it. Since GlobalISel is maturing and is already on at -O0 for AArch64, it's not completely "experimental". Create a more appropriate driver flag and make the older option an alias for it. Differential Revision: https://reviews.llvm.org/D77103 Added: Modified: clang/include/clang/Basic/DiagnosticDriverKinds.td clang/include/clang/Basic/DiagnosticGroups.td clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Clang.cpp clang/test/Driver/global-isel.c Removed: ################################################################################ diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 27ffd562c6de..e35ca843ff56 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -452,13 +452,13 @@ def note_drv_verify_prefix_spelling : Note< "-verify prefixes must start with a letter and contain only alphanumeric" " characters, hyphens, and underscores">; -def warn_drv_experimental_isel_incomplete : Warning< - "-fexperimental-isel support for the '%0' architecture is incomplete">, - InGroup; +def warn_drv_global_isel_incomplete : Warning< + "-fglobal-isel support for the '%0' architecture is incomplete">, + InGroup; -def warn_drv_experimental_isel_incomplete_opt : Warning< - "-fexperimental-isel support is incomplete for this architecture at the current optimization level">, - InGroup; +def warn_drv_global_isel_incomplete_opt : Warning< + "-fglobal-isel support is incomplete for this architecture at the current optimization level">, + InGroup; def warn_drv_moutline_unsupported_opt : Warning< "The '%0' architecture does not support -moutline; flag ignored">, diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index 4d930dcd0462..1175476d609b 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -1154,8 +1154,8 @@ def UnknownArgument : DiagGroup<"unknown-argument">; // compiling OpenCL C/C++ but which is not compatible with the SPIR spec. def SpirCompat : DiagGroup<"spir-compat">; -// Warning for the experimental-isel options. -def ExperimentalISel : DiagGroup<"experimental-isel">; +// Warning for the GlobalISel options. +def GlobalISel : DiagGroup<"global-isel">; // A warning group specifically for warnings related to function // multiversioning. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 2e8d4b1d2363..635fe67095ff 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1249,8 +1249,10 @@ def finline_functions : Flag<["-"], "finline-functions">, Group, def finline_hint_functions: Flag<["-"], "finline-hint-functions">, Group, Flags<[CC1Option]>, HelpText<"Inline functions which are (explicitly or implicitly) marked inline">; def finline : Flag<["-"], "finline">, Group; +def fglobal_isel : Flag<["-"], "fglobal-isel">, Group, + HelpText<"Enables the global instruction selector">; def fexperimental_isel : Flag<["-"], "fexperimental-isel">, Group, - HelpText<"Enables the experimental global instruction selector">; + Alias; def fexperimental_new_pass_manager : Flag<["-"], "fexperimental-new-pass-manager">, Group, Flags<[CC1Option]>, HelpText<"Enables an experimental new pass manager in LLVM.">; @@ -1530,8 +1532,10 @@ def fno_exceptions : Flag<["-"], "fno-exceptions">, Group; def fno_gnu_keywords : Flag<["-"], "fno-gnu-keywords">, Group, Flags<[CC1Option]>; def fno_inline_functions : Flag<["-"], "fno-inline-functions">, Group, Flags<[CC1Option]>; def fno_inline : Flag<["-"], "fno-inline">, Group, Flags<[CC1Option]>; +def fno_global_isel : Flag<["-"], "fno-global-isel">, Group, + HelpText<"Disables the global instruction selector">; def fno_experimental_isel : Flag<["-"], "fno-experimental-isel">, Group, - HelpText<"Disables the experimental global instruction selector">; + Alias; def fno_experimental_new_pass_manager : Flag<["-"], "fno-experimental-new-pass-manager">, Group, Flags<[CC1Option]>, HelpText<"Disables an experimental new pass manager in LLVM.">; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 80a957bf4579..f22e1082357d 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6062,10 +6062,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (SplitLTOUnit) CmdArgs.push_back("-fsplit-lto-unit"); - if (Arg *A = Args.getLastArg(options::OPT_fexperimental_isel, - options::OPT_fno_experimental_isel)) { + if (Arg *A = Args.getLastArg(options::OPT_fglobal_isel, + options::OPT_fno_global_isel)) { CmdArgs.push_back("-mllvm"); - if (A->getOption().matches(options::OPT_fexperimental_isel)) { + if (A->getOption().matches(options::OPT_fglobal_isel)) { CmdArgs.push_back("-global-isel=1"); // GISel is on by default on AArch64 -O0, so don't bother adding @@ -6084,9 +6084,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-global-isel-abort=2"); if (!IsArchSupported) - D.Diag(diag::warn_drv_experimental_isel_incomplete) << Triple.getArchName(); + D.Diag(diag::warn_drv_global_isel_incomplete) << Triple.getArchName(); else - D.Diag(diag::warn_drv_experimental_isel_incomplete_opt); + D.Diag(diag::warn_drv_global_isel_incomplete_opt); } } else { CmdArgs.push_back("-global-isel=0"); diff --git a/clang/test/Driver/global-isel.c b/clang/test/Driver/global-isel.c index f4fc6a758ac2..66f196b03c1e 100644 --- a/clang/test/Driver/global-isel.c +++ b/clang/test/Driver/global-isel.c @@ -1,24 +1,35 @@ // REQUIRES: x86-registered-target,aarch64-registered-target +// RUN: %clang -fglobal-isel -S -### %s 2>&1 | FileCheck --check-prefix=ENABLED %s +// RUN: %clang -fno-global-isel -S -### %s 2>&1 | FileCheck --check-prefix=DISABLED %s + +// RUN: %clang -target aarch64 -fglobal-isel -S %s -### 2>&1 | FileCheck --check-prefix=ARM64-DEFAULT %s +// RUN: %clang -target aarch64 -fglobal-isel -S -O0 %s -### 2>&1 | FileCheck --check-prefix=ARM64-O0 %s +// RUN: %clang -target aarch64 -fglobal-isel -S -O2 %s -### 2>&1 | FileCheck --check-prefix=ARM64-O2 %s +// RUN: %clang -target aarch64 -fglobal-isel -Wno-global-isel -S -O2 %s -### 2>&1 | FileCheck --check-prefix=ARM64-O2-NOWARN %s + +// RUN: %clang -target x86_64 -fglobal-isel -S %s -### 2>&1 | FileCheck --check-prefix=X86_64 %s + +// Now test the aliases. + // RUN: %clang -fexperimental-isel -S -### %s 2>&1 | FileCheck --check-prefix=ENABLED %s // RUN: %clang -fno-experimental-isel -S -### %s 2>&1 | FileCheck --check-prefix=DISABLED %s // RUN: %clang -target aarch64 -fexperimental-isel -S %s -### 2>&1 | FileCheck --check-prefix=ARM64-DEFAULT %s // RUN: %clang -target aarch64 -fexperimental-isel -S -O0 %s -### 2>&1 | FileCheck --check-prefix=ARM64-O0 %s // RUN: %clang -target aarch64 -fexperimental-isel -S -O2 %s -### 2>&1 | FileCheck --check-prefix=ARM64-O2 %s -// RUN: %clang -target aarch64 -fexperimental-isel -Wno-experimental-isel -S -O2 %s -### 2>&1 | FileCheck --check-prefix=ARM64-O2-NOWARN %s // RUN: %clang -target x86_64 -fexperimental-isel -S %s -### 2>&1 | FileCheck --check-prefix=X86_64 %s // ENABLED: "-mllvm" "-global-isel=1" // DISABLED: "-mllvm" "-global-isel=0" -// ARM64-DEFAULT-NOT: warning: -fexperimental-sel +// ARM64-DEFAULT-NOT: warning: -fglobal-isel // ARM64-DEFAULT-NOT: "-global-isel-abort=2" -// ARM64-O0-NOT: warning: -fexperimental-sel -// ARM64-O2: warning: -fexperimental-isel support is incomplete for this architecture at the current optimization level +// ARM64-O0-NOT: warning: -fglobal-isel +// ARM64-O2: warning: -fglobal-isel support is incomplete for this architecture at the current optimization level // ARM64-O2: "-mllvm" "-global-isel-abort=2" -// ARM64-O2-NOWARN-NOT: warning: -fexperimental-isel +// ARM64-O2-NOWARN-NOT: warning: -fglobal-isel -// X86_64: -fexperimental-isel support for the 'x86_64' architecture is incomplete +// X86_64: -fglobal-isel support for the 'x86_64' architecture is incomplete // X86_64: "-mllvm" "-global-isel-abort=2" From cfe-commits at lists.llvm.org Tue Mar 31 12:33:15 2020 From: cfe-commits at lists.llvm.org (Ben Langmuir via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 19:33:15 +0000 (UTC) Subject: [PATCH] D77159: [pch] Honour -fallow-pch-with-compiler-errors for overall compilation status Message-ID: benlangmuir created this revision. benlangmuir added a reviewer: akyrtzi. Herald added subscribers: cfe-commits, arphaman, dexonsmith. Herald added a project: clang. Previously we would emit a PCH with errors, but fail the overall compilation. If run using the driver, that would result in removing the just-produced PCH. Instead, we should have the compilation result match whether we were able to emit the PCH. rdar://61110294 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77159 Files: clang/lib/Serialization/GeneratePCH.cpp clang/test/Index/pch-with-errors.c Index: clang/test/Index/pch-with-errors.c =================================================================== --- clang/test/Index/pch-with-errors.c +++ clang/test/Index/pch-with-errors.c @@ -42,3 +42,6 @@ // RUN: not c-index-test -write-pch %t.pch foobar.c 2>&1 | FileCheck -check-prefix=NONEXISTENT %s // NONEXISTENT: Unable to load translation unit + +// RUN: %clang -x c-header %s -o %t-clang.h.pch -Xclang -detailed-preprocessing-record -Xclang -fallow-pch-with-compiler-errors +// RUN: c-index-test -index-file %s -include %t-clang.h -Xclang -detailed-preprocessing-record | FileCheck -check-prefix=CHECK-INDEX %s Index: clang/lib/Serialization/GeneratePCH.cpp =================================================================== --- clang/lib/Serialization/GeneratePCH.cpp +++ clang/lib/Serialization/GeneratePCH.cpp @@ -57,6 +57,11 @@ } } + // Errors that do not prevent the PCH from being written should not cause the + // overall compilation to fail either. + if (AllowASTWithErrors) + PP.getDiagnostics().getClient()->clear(); + // Emit the PCH file to the Buffer. assert(SemaPtr && "No Sema?"); Buffer->Signature = -------------- next part -------------- A non-text attachment was scrubbed... Name: D77159.253958.patch Type: text/x-patch Size: 1155 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 12:33:17 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 19:33:17 +0000 (UTC) Subject: [PATCH] D76862: HIP: Ensure new denormal mode attributes are set In-Reply-To: References: Message-ID: <0706cfa3a3acd6952673f3f10779bb1a@localhost.localdomain> arsenm added a comment. In D76862#1953013 , @yaxunl wrote: > Are there any other clang options affecting flushing denormals? If so, are they working properly after this change? Do we need to have tests for them? Thanks. I already ensured these are correct for OpenCL, so those already have tests. I didn't realize the HIP toolchain was totally separate, so this fixes it. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76862/new/ https://reviews.llvm.org/D76862 From cfe-commits at lists.llvm.org Tue Mar 31 12:35:22 2020 From: cfe-commits at lists.llvm.org (Amara Emerson via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 19:35:22 +0000 (UTC) Subject: [PATCH] D77103: Add a new -fglobal-isel option and make -fexperimental-isel an alias for it. In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rG7f1ea924c695: Add a new -fglobal-isel option and make -fexperimental-isel an alias for it. (authored by aemerson). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77103/new/ https://reviews.llvm.org/D77103 Files: clang/include/clang/Basic/DiagnosticDriverKinds.td clang/include/clang/Basic/DiagnosticGroups.td clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Clang.cpp clang/test/Driver/global-isel.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77103.253969.patch Type: text/x-patch Size: 7630 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 13:07:36 2020 From: cfe-commits at lists.llvm.org (Anna Thomas via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 20:07:36 +0000 (UTC) Subject: [PATCH] D76140: [InlineFunction] update attributes during inlining In-Reply-To: References: Message-ID: <20776150e30becbc49efed680aef335b@localhost.localdomain> anna added a comment. I got a failure in one of the binaryFormats: lib/BinaryFormat/CMakeFiles/LLVMBinaryFormat.dir/MsgPackReader.cpp Attributes 'zeroext and signext' are incompatible! %rev.i.i.i.i.i.i.i.i = tail call signext zeroext i16 @llvm.bswap.i16(i16 %ret.0.copyload.i.i.i.i) #6 in function _ZN4llvm7msgpack6Reader7readIntIsEENS_8ExpectedIbEERNS0_6ObjectE fatal error: error in backend: Broken function found, compilation aborted! I believe this just showcases undefined behaviour since we were having a returnValue (i.e. call) with an incomptable attribute compared to the return attribute on the callsite. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76140/new/ https://reviews.llvm.org/D76140 From cfe-commits at lists.llvm.org Tue Mar 31 13:07:40 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 20:07:40 +0000 (UTC) Subject: [PATCH] D77081: [MS] Mark vbase dtors ref'd when ref'ing dtor In-Reply-To: References: Message-ID: rnk updated this revision to Diff 253972. rnk added a comment. - finish refactoring, build & test Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77081/new/ https://reviews.llvm.org/D77081 Files: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaExpr.cpp clang/test/CXX/class.access/p4.cpp clang/test/CodeGenCXX/microsoft-abi-vbase-dtor.cpp clang/test/SemaCXX/ms-implicit-complete-dtor.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77081.253972.patch Type: text/x-patch Size: 15184 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 13:07:46 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 20:07:46 +0000 (UTC) Subject: [PATCH] D76862: HIP: Ensure new denormal mode attributes are set In-Reply-To: References: Message-ID: yaxunl accepted this revision. yaxunl added a comment. This revision is now accepted and ready to land. LGTM. Thanks! CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76862/new/ https://reviews.llvm.org/D76862 From cfe-commits at lists.llvm.org Tue Mar 31 13:07:52 2020 From: cfe-commits at lists.llvm.org (Richard Smith - zygoloid via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 20:07:52 +0000 (UTC) Subject: [PATCH] D77041: [AST] Fix a crash on invalid constexpr Ctorinitializer when building RecoveryExpr. In-Reply-To: References: Message-ID: <8980c7238de1e36cada01b5ccfe56053@localhost.localdomain> rsmith added inline comments. ================ Comment at: clang/lib/Parse/ParseDeclCXX.cpp:3459-3461 + if (MemInit.get()->getInit() && + MemInit.get()->getInit()->containsErrors()) + AnyErrors = true; ---------------- The parser should not be inspecting properties of `Expr`s -- that's a layering violation. Can you move this logic into `ActOnMemInitializers` instead? ================ Comment at: clang/lib/Sema/SemaDeclCXX.cpp:1688 CheckConstexprKind Kind) { + assert(!NewFD->isInvalidDecl()); const CXXMethodDecl *MD = dyn_cast(NewFD); ---------------- Instead of asserting this, please just return false on an invalid declaration. There's nothing fundamentally wrong with calling this function on an invalid declaration, but as usual, if we encounter something invalid, we should suppress follow-on diagnostics. ================ Comment at: clang/lib/Sema/SemaDeclCXX.cpp:5005 + if (Member->getInit() && Member->getInit()->containsErrors()) + Constructor->setInvalidDecl(); if (Member->isBaseInitializer()) ---------------- This is inappropriate. The "invalid" bit on a declaration indicates whether the declaration is invalid, not whether the definition is invalid. What we should do is add a "contains errors" bit to `Stmt`, and mark the function body as containing errors if it has an initializer that contains an error. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77041/new/ https://reviews.llvm.org/D77041 From cfe-commits at lists.llvm.org Tue Mar 31 13:07:54 2020 From: cfe-commits at lists.llvm.org (Richard Smith - zygoloid via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 20:07:54 +0000 (UTC) Subject: [PATCH] D77041: [AST] Fix a crash on invalid constexpr Ctorinitializer when building RecoveryExpr. In-Reply-To: References: Message-ID: <762ffb332daccaaaed0813278beaa614@localhost.localdomain> rsmith added inline comments. ================ Comment at: clang/lib/Sema/SemaDeclCXX.cpp:5005 + if (Member->getInit() && Member->getInit()->containsErrors()) + Constructor->setInvalidDecl(); if (Member->isBaseInitializer()) ---------------- rsmith wrote: > This is inappropriate. The "invalid" bit on a declaration indicates whether the declaration is invalid, not whether the definition is invalid. > > What we should do is add a "contains errors" bit to `Stmt`, and mark the function body as containing errors if it has an initializer that contains an error. As an example of why this distinction matters: the "contains errors" bit indicates whether external users of the declaration should ignore it / suppress errors on it, or whether they can still treat it as a regular declaration. It's not ideal for an error in the body of a function to affect the diagnostic behavior of a caller to that function, since the body is (typically) irrelevant to the validity of that caller. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77041/new/ https://reviews.llvm.org/D77041 From cfe-commits at lists.llvm.org Tue Mar 31 13:09:31 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via cfe-commits) Date: Tue, 31 Mar 2020 13:09:31 -0700 (PDT) Subject: [clang] 1ee6ec2 - Remove "mask" operand from shufflevector. Message-ID: <5e83a37b.1c69fb81.d1ccb.951a@mx.google.com> Author: Eli Friedman Date: 2020-03-31T13:08:59-07:00 New Revision: 1ee6ec2bf370fbd1d93f34c8b56741a9d3f22ed2 URL: https://github.com/llvm/llvm-project/commit/1ee6ec2bf370fbd1d93f34c8b56741a9d3f22ed2 DIFF: https://github.com/llvm/llvm-project/commit/1ee6ec2bf370fbd1d93f34c8b56741a9d3f22ed2.diff LOG: Remove "mask" operand from shufflevector. Instead, represent the mask as out-of-line data in the instruction. This should be more efficient in the places that currently use getShuffleVector(), and paves the way for further changes to add new shuffles for scalable vectors. This doesn't change the syntax in textual IR. And I don't currently plan to change the bitcode encoding in this patch, although we'll probably need to do something once we extend shufflevector for scalable types. I expect that once this is finished, we can then replace the raw "mask" with something more appropriate for scalable vectors. Not sure exactly what this looks like at the moment, but there are a few different ways we could handle it. Maybe we could try to describe specific shuffles. Or maybe we could define it in terms of a function to convert a fixed-length array into an appropriate scalable vector, using a "step", or something like that. Differential Revision: https://reviews.llvm.org/D72467 Added: Modified: clang/lib/CodeGen/CGExpr.cpp llvm/include/llvm/ADT/ArrayRef.h llvm/include/llvm/Analysis/ConstantFolding.h llvm/include/llvm/Analysis/InstructionSimplify.h llvm/include/llvm/Analysis/TargetFolder.h llvm/include/llvm/IR/ConstantFolder.h llvm/include/llvm/IR/Constants.h llvm/include/llvm/IR/IRBuilder.h llvm/include/llvm/IR/IRBuilderFolder.h llvm/include/llvm/IR/Instructions.h llvm/include/llvm/IR/NoFolder.h llvm/include/llvm/IR/PatternMatch.h llvm/lib/Analysis/ConstantFolding.cpp llvm/lib/Analysis/InstructionSimplify.cpp llvm/lib/Analysis/TargetTransformInfo.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/Analysis/VectorUtils.cpp llvm/lib/AsmParser/LLParser.cpp llvm/lib/Bitcode/Reader/BitcodeReader.cpp llvm/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/lib/Bitcode/Writer/ValueEnumerator.cpp llvm/lib/CodeGen/CodeGenPrepare.cpp llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/ExecutionEngine/Interpreter/Execution.cpp llvm/lib/IR/AsmWriter.cpp llvm/lib/IR/AutoUpgrade.cpp llvm/lib/IR/ConstantFold.cpp llvm/lib/IR/ConstantFold.h llvm/lib/IR/Constants.cpp llvm/lib/IR/ConstantsContext.h llvm/lib/IR/Core.cpp llvm/lib/IR/Instruction.cpp llvm/lib/IR/Instructions.cpp llvm/lib/IR/Verifier.cpp llvm/lib/Target/AArch64/AArch64ISelLowering.cpp llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp llvm/lib/Target/ARM/ARMISelLowering.cpp llvm/lib/Target/ARM/MVETailPredication.cpp llvm/lib/Target/X86/X86PartialReduction.cpp llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp llvm/lib/Transforms/InstCombine/InstructionCombining.cpp llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp llvm/lib/Transforms/Scalar/GVN.cpp llvm/lib/Transforms/Scalar/GVNSink.cpp llvm/lib/Transforms/Scalar/NewGVN.cpp llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp llvm/lib/Transforms/Vectorize/LoopVectorize.cpp llvm/unittests/IR/PatternMatch.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 671ada019cec..b53b77a819b4 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1675,7 +1675,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile, // Shuffle vector to get vec3. V = Builder.CreateShuffleVector(V, llvm::UndefValue::get(vec4Ty), - {0, 1, 2}, "extractVec"); + ArrayRef{0, 1, 2}, "extractVec"); return EmitFromMemory(V, Ty); } } diff --git a/llvm/include/llvm/ADT/ArrayRef.h b/llvm/include/llvm/ADT/ArrayRef.h index 5cba73e67f04..d11f8b5b44e9 100644 --- a/llvm/include/llvm/ADT/ArrayRef.h +++ b/llvm/include/llvm/ADT/ArrayRef.h @@ -532,11 +532,21 @@ namespace llvm { return LHS.equals(RHS); } - template + template + inline bool operator==(SmallVectorImpl &LHS, ArrayRef RHS) { + return ArrayRef(LHS).equals(RHS); + } + + template inline bool operator!=(ArrayRef LHS, ArrayRef RHS) { return !(LHS == RHS); } + template + inline bool operator!=(SmallVectorImpl &LHS, ArrayRef RHS) { + return !(LHS == RHS); + } + /// @} template hash_code hash_value(ArrayRef S) { diff --git a/llvm/include/llvm/Analysis/ConstantFolding.h b/llvm/include/llvm/Analysis/ConstantFolding.h index 90dc14b0ed9e..68aa1948ab88 100644 --- a/llvm/include/llvm/Analysis/ConstantFolding.h +++ b/llvm/include/llvm/Analysis/ConstantFolding.h @@ -119,10 +119,11 @@ Constant *ConstantFoldInsertElementInstruction(Constant *Val, Constant *ConstantFoldExtractElementInstruction(Constant *Val, Constant *Idx); /// Attempt to constant fold a shufflevector instruction with the -/// specified operands and indices. The constant result is returned if -/// successful; if not, null is returned. +/// specified operands and mask. See class ShuffleVectorInst for a description +/// of the mask representation. The constant result is returned if successful; +/// if not, null is returned. Constant *ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2, - Constant *Mask); + ArrayRef Mask); /// ConstantFoldLoadFromConstPtr - Return the value that a load from C would /// produce if it is constant and determinable. If this is not determinable, diff --git a/llvm/include/llvm/Analysis/InstructionSimplify.h b/llvm/include/llvm/Analysis/InstructionSimplify.h index b661caee6848..7a9a1a81555b 100644 --- a/llvm/include/llvm/Analysis/InstructionSimplify.h +++ b/llvm/include/llvm/Analysis/InstructionSimplify.h @@ -230,7 +230,8 @@ Value *SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q); /// Given operands for a ShuffleVectorInst, fold the result or return null. -Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask, +/// See class ShuffleVectorInst for a description of the mask representation. +Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, ArrayRef Mask, Type *RetTy, const SimplifyQuery &Q); //=== Helper functions for higher up the class hierarchy. diff --git a/llvm/include/llvm/Analysis/TargetFolder.h b/llvm/include/llvm/Analysis/TargetFolder.h index 7277a1230e28..b23316ac3d9b 100644 --- a/llvm/include/llvm/Analysis/TargetFolder.h +++ b/llvm/include/llvm/Analysis/TargetFolder.h @@ -259,7 +259,7 @@ class TargetFolder final : public IRBuilderFolder { } Constant *CreateShuffleVector(Constant *V1, Constant *V2, - Constant *Mask) const override { + ArrayRef Mask) const override { return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask)); } diff --git a/llvm/include/llvm/IR/ConstantFolder.h b/llvm/include/llvm/IR/ConstantFolder.h index 32939e79cd1d..da4a18e3c181 100644 --- a/llvm/include/llvm/IR/ConstantFolder.h +++ b/llvm/include/llvm/IR/ConstantFolder.h @@ -265,7 +265,7 @@ class ConstantFolder final : public IRBuilderFolder { } Constant *CreateShuffleVector(Constant *V1, Constant *V2, - Constant *Mask) const override { + ArrayRef Mask) const override { return ConstantExpr::getShuffleVector(V1, V2, Mask); } diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h index a345795ff54a..868b038b055d 100644 --- a/llvm/include/llvm/IR/Constants.h +++ b/llvm/include/llvm/IR/Constants.h @@ -1206,7 +1206,8 @@ class ConstantExpr : public Constant { Type *OnlyIfReducedTy = nullptr); static Constant *getInsertElement(Constant *Vec, Constant *Elt, Constant *Idx, Type *OnlyIfReducedTy = nullptr); - static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask, + static Constant *getShuffleVector(Constant *V1, Constant *V2, + ArrayRef Mask, Type *OnlyIfReducedTy = nullptr); static Constant *getExtractValue(Constant *Agg, ArrayRef Idxs, Type *OnlyIfReducedTy = nullptr); @@ -1225,6 +1226,16 @@ class ConstantExpr : public Constant { /// expression and return the list of indices. ArrayRef getIndices() const; + /// Assert that this is a shufflevector and return the mask. See class + /// ShuffleVectorInst for a description of the mask representation. + ArrayRef getShuffleMask() const; + + /// Assert that this is a shufflevector and return the mask. + /// + /// TODO: This is a temporary hack until we update the bitcode format for + /// shufflevector. + Constant *getShuffleMaskForBitcode() const; + /// Return a string representation for an opcode. const char *getOpcodeName() const; diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h index 3b0ca0c1ae5c..d4449e196000 100644 --- a/llvm/include/llvm/IR/IRBuilder.h +++ b/llvm/include/llvm/IR/IRBuilder.h @@ -2617,17 +2617,25 @@ class IRBuilderBase { Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name = "") { - if (auto *V1C = dyn_cast(V1)) - if (auto *V2C = dyn_cast(V2)) - if (auto *MC = dyn_cast(Mask)) - return Insert(Folder.CreateShuffleVector(V1C, V2C, MC), Name); - return Insert(new ShuffleVectorInst(V1, V2, Mask), Name); + SmallVector IntMask; + ShuffleVectorInst::getShuffleMask(cast(Mask), IntMask); + return CreateShuffleVector(V1, V2, IntMask, Name); } - Value *CreateShuffleVector(Value *V1, Value *V2, ArrayRef IntMask, + Value *CreateShuffleVector(Value *V1, Value *V2, ArrayRef Mask, const Twine &Name = "") { - Value *Mask = ConstantDataVector::get(Context, IntMask); - return CreateShuffleVector(V1, V2, Mask, Name); + SmallVector IntMask; + IntMask.assign(Mask.begin(), Mask.end()); + return CreateShuffleVector(V1, V2, IntMask, Name); + } + + /// See class ShuffleVectorInst for a description of the mask representation. + Value *CreateShuffleVector(Value *V1, Value *V2, ArrayRef Mask, + const Twine &Name = "") { + if (auto *V1C = dyn_cast(V1)) + if (auto *V2C = dyn_cast(V2)) + return Insert(Folder.CreateShuffleVector(V1C, V2C, Mask), Name); + return Insert(new ShuffleVectorInst(V1, V2, Mask), Name); } Value *CreateExtractValue(Value *Agg, diff --git a/llvm/include/llvm/IR/IRBuilderFolder.h b/llvm/include/llvm/IR/IRBuilderFolder.h index a77a5213dcea..e781e8e094af 100644 --- a/llvm/include/llvm/IR/IRBuilderFolder.h +++ b/llvm/include/llvm/IR/IRBuilderFolder.h @@ -129,7 +129,7 @@ class IRBuilderFolder { virtual Value *CreateInsertElement(Constant *Vec, Constant *NewElt, Constant *Idx) const = 0; virtual Value *CreateShuffleVector(Constant *V1, Constant *V2, - Constant *Mask) const = 0; + ArrayRef Mask) const = 0; virtual Value *CreateExtractValue(Constant *Agg, ArrayRef IdxList) const = 0; virtual Value *CreateInsertValue(Constant *Agg, Constant *Val, diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h index 713624d13bef..857b7374ac47 100644 --- a/llvm/include/llvm/IR/Instructions.h +++ b/llvm/include/llvm/IR/Instructions.h @@ -1988,10 +1988,22 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value) // ShuffleVectorInst Class //===----------------------------------------------------------------------===// +constexpr int UndefMaskElem = -1; + /// This instruction constructs a fixed permutation of two /// input vectors. /// +/// For each element of the result vector, the shuffle mask selects an element +/// from one of the input vectors to copy to the result. Non-negative elements +/// in the mask represent an index into the concatenated pair of input vectors. +/// UndefMaskElem (-1) specifies that the result element is undefined. +/// +/// For scalable vectors, all the elements of the mask must be 0 or -1. This +/// requirement may be relaxed in the future. class ShuffleVectorInst : public Instruction { + SmallVector ShuffleMask; + Constant *ShuffleMaskForBitcode; + protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; @@ -2004,13 +2016,15 @@ class ShuffleVectorInst : public Instruction { Instruction *InsertBefor = nullptr); ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, const Twine &NameStr, BasicBlock *InsertAtEnd); + ShuffleVectorInst(Value *V1, Value *V2, ArrayRef Mask, + const Twine &NameStr = "", + Instruction *InsertBefor = nullptr); + ShuffleVectorInst(Value *V1, Value *V2, ArrayRef Mask, + const Twine &NameStr, BasicBlock *InsertAtEnd); - // allocate space for exactly three operands - void *operator new(size_t s) { - return User::operator new(s, 3); - } + void *operator new(size_t s) { return User::operator new(s, 2); } - /// Swap the first 2 operands and adjust the mask to preserve the semantics + /// Swap the operands and adjust the mask to preserve the semantics /// of the instruction. void commute(); @@ -2018,6 +2032,8 @@ class ShuffleVectorInst : public Instruction { /// formed with the specified operands. static bool isValidOperands(const Value *V1, const Value *V2, const Value *Mask); + static bool isValidOperands(const Value *V1, const Value *V2, + ArrayRef Mask); /// Overload to return most specific vector type. /// @@ -2028,36 +2044,33 @@ class ShuffleVectorInst : public Instruction { /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - Constant *getMask() const { - return cast(getOperand(2)); - } - - /// Return the shuffle mask value for the specified element of the mask. - /// Return -1 if the element is undef. - static int getMaskValue(const Constant *Mask, unsigned Elt); - /// Return the shuffle mask value of this instruction for the given element - /// index. Return -1 if the element is undef. - int getMaskValue(unsigned Elt) const { - return getMaskValue(getMask(), Elt); - } + /// index. Return UndefMaskElem if the element is undef. + int getMaskValue(unsigned Elt) const { return ShuffleMask[Elt]; } /// Convert the input shuffle mask operand to a vector of integers. Undefined - /// elements of the mask are returned as -1. + /// elements of the mask are returned as UndefMaskElem. static void getShuffleMask(const Constant *Mask, SmallVectorImpl &Result); /// Return the mask for this instruction as a vector of integers. Undefined - /// elements of the mask are returned as -1. + /// elements of the mask are returned as UndefMaskElem. void getShuffleMask(SmallVectorImpl &Result) const { - return getShuffleMask(getMask(), Result); + Result.assign(ShuffleMask.begin(), ShuffleMask.end()); } - SmallVector getShuffleMask() const { - SmallVector Mask; - getShuffleMask(Mask); - return Mask; - } + /// Return the mask for this instruction, for use in bitcode. + /// + /// TODO: This is temporary until we decide a new bitcode encoding for + /// shufflevector. + Constant *getShuffleMaskForBitcode() const { return ShuffleMaskForBitcode; } + + static Constant *convertShuffleMaskForBitcode(ArrayRef Mask, + Type *ResultTy); + + void setShuffleMask(ArrayRef Mask); + + ArrayRef getShuffleMask() const { return ShuffleMask; } /// Return true if this shuffle returns a vector with a diff erent number of /// elements than its source vectors. @@ -2065,7 +2078,7 @@ class ShuffleVectorInst : public Instruction { /// shufflevector <4 x n> A, <4 x n> B, <1,2,3,4,5> bool changesLength() const { unsigned NumSourceElts = Op<0>()->getType()->getVectorNumElements(); - unsigned NumMaskElts = getMask()->getType()->getVectorNumElements(); + unsigned NumMaskElts = ShuffleMask.size(); return NumSourceElts != NumMaskElts; } @@ -2074,7 +2087,7 @@ class ShuffleVectorInst : public Instruction { /// Example: shufflevector <2 x n> A, <2 x n> B, <1,2,3> bool increasesLength() const { unsigned NumSourceElts = Op<0>()->getType()->getVectorNumElements(); - unsigned NumMaskElts = getMask()->getType()->getVectorNumElements(); + unsigned NumMaskElts = ShuffleMask.size(); return NumSourceElts < NumMaskElts; } @@ -2095,7 +2108,7 @@ class ShuffleVectorInst : public Instruction { /// Example: shufflevector <4 x n> A, <4 x n> B, <3,0,undef,3> /// TODO: Optionally allow length-changing shuffles. bool isSingleSource() const { - return !changesLength() && isSingleSourceMask(getMask()); + return !changesLength() && isSingleSourceMask(ShuffleMask); } /// Return true if this shuffle mask chooses elements from exactly one source @@ -2116,7 +2129,7 @@ class ShuffleVectorInst : public Instruction { /// from its input vectors. /// Example: shufflevector <4 x n> A, <4 x n> B, <4,undef,6,undef> bool isIdentity() const { - return !changesLength() && isIdentityMask(getShuffleMask()); + return !changesLength() && isIdentityMask(ShuffleMask); } /// Return true if this shuffle lengthens exactly one source vector with @@ -2157,7 +2170,7 @@ class ShuffleVectorInst : public Instruction { /// In that case, the shuffle is better classified as an identity shuffle. /// TODO: Optionally allow length-changing shuffles. bool isSelect() const { - return !changesLength() && isSelectMask(getMask()); + return !changesLength() && isSelectMask(ShuffleMask); } /// Return true if this shuffle mask swaps the order of elements from exactly @@ -2177,7 +2190,7 @@ class ShuffleVectorInst : public Instruction { /// Example: shufflevector <4 x n> A, <4 x n> B, <3,undef,1,undef> /// TODO: Optionally allow length-changing shuffles. bool isReverse() const { - return !changesLength() && isReverseMask(getMask()); + return !changesLength() && isReverseMask(ShuffleMask); } /// Return true if this shuffle mask chooses all elements with the same value @@ -2199,7 +2212,7 @@ class ShuffleVectorInst : public Instruction { /// TODO: Optionally allow length-changing shuffles. /// TODO: Optionally allow splats from other elements. bool isZeroEltSplat() const { - return !changesLength() && isZeroEltSplatMask(getMask()); + return !changesLength() && isZeroEltSplatMask(ShuffleMask); } /// Return true if this shuffle mask is a transpose mask. @@ -2248,7 +2261,7 @@ class ShuffleVectorInst : public Instruction { /// exact specification. /// Example: shufflevector <4 x n> A, <4 x n> B, <0,4,2,6> bool isTranspose() const { - return !changesLength() && isTransposeMask(getMask()); + return !changesLength() && isTransposeMask(ShuffleMask); } /// Return true if this shuffle mask is an extract subvector mask. @@ -2267,7 +2280,7 @@ class ShuffleVectorInst : public Instruction { /// Return true if this shuffle mask is an extract subvector mask. bool isExtractSubvectorMask(int &Index) const { int NumSrcElts = Op<0>()->getType()->getVectorNumElements(); - return isExtractSubvectorMask(getMask(), NumSrcElts, Index); + return isExtractSubvectorMask(ShuffleMask, NumSrcElts, Index); } /// Change values in a shuffle permute mask assuming the two vector operands @@ -2293,9 +2306,8 @@ class ShuffleVectorInst : public Instruction { }; template <> -struct OperandTraits : - public FixedNumOperandTraits { -}; +struct OperandTraits + : public FixedNumOperandTraits {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorInst, Value) diff --git a/llvm/include/llvm/IR/NoFolder.h b/llvm/include/llvm/IR/NoFolder.h index 1e35cfe096eb..dcffa6b2f9da 100644 --- a/llvm/include/llvm/IR/NoFolder.h +++ b/llvm/include/llvm/IR/NoFolder.h @@ -300,7 +300,7 @@ class NoFolder final : public IRBuilderFolder { } Instruction *CreateShuffleVector(Constant *V1, Constant *V2, - Constant *Mask) const override { + ArrayRef Mask) const override { return new ShuffleVectorInst(V1, V2, Mask); } diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index 03b92e524ad5..30c203dedf67 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -50,6 +50,10 @@ template bool match(Val *V, const Pattern &P) { return const_cast(P).match(V); } +template bool match(ArrayRef Mask, const Pattern &P) { + return const_cast(P).match(Mask); +} + template struct OneUse_match { SubPattern_t SubPattern; @@ -1350,12 +1354,69 @@ m_ExtractElement(const Val_t &Val, const Idx_t &Idx) { return TwoOps_match(Val, Idx); } -/// Matches ShuffleVectorInst. +/// Matches shuffle. +template struct Shuffle_match { + T0 Op1; + T1 Op2; + T2 Mask; + + Shuffle_match(const T0 &Op1, const T1 &Op2, const T2 &Mask) + : Op1(Op1), Op2(Op2), Mask(Mask) {} + + template bool match(OpTy *V) { + if (auto *I = dyn_cast(V)) { + return Op1.match(I->getOperand(0)) && Op2.match(I->getOperand(1)) && + Mask.match(I->getShuffleMask()); + } + return false; + } +}; + +struct m_Mask { + ArrayRef &MaskRef; + m_Mask(ArrayRef &MaskRef) : MaskRef(MaskRef) {} + bool match(ArrayRef Mask) { + MaskRef = Mask; + return true; + } +}; + +struct m_ZeroMask { + bool match(ArrayRef Mask) { + return all_of(Mask, [](int Elem) { return Elem == 0 || Elem == -1; }); + } +}; + +struct m_SpecificMask { + ArrayRef &MaskRef; + m_SpecificMask(ArrayRef &MaskRef) : MaskRef(MaskRef) {} + bool match(ArrayRef Mask) { return MaskRef == Mask; } +}; + +struct m_SplatOrUndefMask { + int &SplatIndex; + m_SplatOrUndefMask(int &SplatIndex) : SplatIndex(SplatIndex) {} + bool match(ArrayRef Mask) { + auto First = find_if(Mask, [](int Elem) { return Elem != -1; }); + if (First == Mask.end()) + return false; + SplatIndex = *First; + return all_of(Mask, + [First](int Elem) { return Elem == *First || Elem == -1; }); + } +}; + +/// Matches ShuffleVectorInst independently of mask value. +template +inline TwoOps_match +m_ShuffleVector(const V1_t &v1, const V2_t &v2) { + return TwoOps_match(v1, v2); +} + template -inline ThreeOps_match -m_ShuffleVector(const V1_t &v1, const V2_t &v2, const Mask_t &m) { - return ThreeOps_match(v1, v2, - m); +inline Shuffle_match +m_ShuffleVector(const V1_t &v1, const V2_t &v2, const Mask_t &mask) { + return Shuffle_match(v1, v2, mask); } /// Matches LoadInst. diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index 5efebe2937ed..721ba735e9db 100644 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -1066,7 +1066,8 @@ Constant *ConstantFoldInstOperandsImpl(const Value *InstOrCE, unsigned Opcode, case Instruction::InsertElement: return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]); case Instruction::ShuffleVector: - return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]); + return ConstantExpr::getShuffleVector( + Ops[0], Ops[1], cast(InstOrCE)->getShuffleMask()); } } diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index e62ddf793a13..086ff7433544 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4439,36 +4439,31 @@ static Value *foldIdentityShuffles(int DestElt, Value *Op0, Value *Op1, return RootVec; } -static Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask, - Type *RetTy, const SimplifyQuery &Q, +static Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, + ArrayRef Mask, Type *RetTy, + const SimplifyQuery &Q, unsigned MaxRecurse) { - if (isa(Mask)) + if (all_of(Mask, [](int Elem) { return Elem == UndefMaskElem; })) return UndefValue::get(RetTy); Type *InVecTy = Op0->getType(); - ElementCount MaskEltCount = Mask->getType()->getVectorElementCount(); + unsigned MaskNumElts = Mask.size(); ElementCount InVecEltCount = InVecTy->getVectorElementCount(); - assert(MaskEltCount.Scalable == InVecEltCount.Scalable && - "vscale mismatch between input vector and mask"); - - bool Scalable = MaskEltCount.Scalable; + bool Scalable = InVecEltCount.Scalable; SmallVector Indices; - if (!Scalable) { - ShuffleVectorInst::getShuffleMask(Mask, Indices); - assert(MaskEltCount.Min == Indices.size() && - "Size of Indices not same as number of mask elements?"); - } + Indices.assign(Mask.begin(), Mask.end()); + // Canonicalization: If mask does not select elements from an input vector, + // replace that input vector with undef. if (!Scalable) { - // Canonicalization: If mask does not select elements from an input vector, - // replace that input vector with undef. bool MaskSelects0 = false, MaskSelects1 = false; - for (unsigned i = 0; i != MaskEltCount.Min; ++i) { + unsigned InVecNumElts = InVecEltCount.Min; + for (unsigned i = 0; i != MaskNumElts; ++i) { if (Indices[i] == -1) continue; - if ((unsigned)Indices[i] < InVecEltCount.Min) + if ((unsigned)Indices[i] < InVecNumElts) MaskSelects0 = true; else MaskSelects1 = true; @@ -4514,8 +4509,8 @@ static Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask, assert(isa(Op1) && "Expected undef operand 1 for splat"); // Shuffle mask undefs become undefined constant result elements. - SmallVector VecC(MaskEltCount.Min, C); - for (unsigned i = 0; i != MaskEltCount.Min; ++i) + SmallVector VecC(MaskNumElts, C); + for (unsigned i = 0; i != MaskNumElts; ++i) if (Indices[i] == -1) VecC[i] = UndefValue::get(C->getType()); return ConstantVector::get(VecC); @@ -4526,7 +4521,7 @@ static Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask, // value type is same as the input vectors' type. if (auto *OpShuf = dyn_cast(Op0)) if (isa(Op1) && RetTy == InVecTy && - OpShuf->getMask()->getSplatValue()) + is_splat(OpShuf->getShuffleMask())) return Op0; // All remaining transformation depend on the value of the mask, which is @@ -4545,7 +4540,7 @@ static Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask, // shuffle. This handles simple identity shuffles as well as chains of // shuffles that may widen/narrow and/or move elements across lanes and back. Value *RootVec = nullptr; - for (unsigned i = 0; i != MaskEltCount.Min; ++i) { + for (unsigned i = 0; i != MaskNumElts; ++i) { // Note that recursion is limited for each vector element, so if any element // exceeds the limit, this will fail to simplify. RootVec = @@ -4559,8 +4554,9 @@ static Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask, } /// Given operands for a ShuffleVectorInst, fold the result or return null. -Value *llvm::SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask, - Type *RetTy, const SimplifyQuery &Q) { +Value *llvm::SimplifyShuffleVectorInst(Value *Op0, Value *Op1, + ArrayRef Mask, Type *RetTy, + const SimplifyQuery &Q) { return ::SimplifyShuffleVectorInst(Op0, Op1, Mask, RetTy, Q, RecursionLimit); } @@ -5523,8 +5519,9 @@ Value *llvm::SimplifyInstruction(Instruction *I, const SimplifyQuery &SQ, } case Instruction::ShuffleVector: { auto *SVI = cast(I); - Result = SimplifyShuffleVectorInst(SVI->getOperand(0), SVI->getOperand(1), - SVI->getMask(), SVI->getType(), Q); + Result = + SimplifyShuffleVectorInst(SVI->getOperand(0), SVI->getOperand(1), + SVI->getShuffleMask(), SVI->getType(), Q); break; } case Instruction::PHI: diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp index 89b1783a9a00..2ae44caaaa32 100644 --- a/llvm/lib/Analysis/TargetTransformInfo.cpp +++ b/llvm/lib/Analysis/TargetTransformInfo.cpp @@ -888,7 +888,7 @@ static bool matchPairwiseShuffleMask(ShuffleVectorInst *SI, bool IsLeft, for (unsigned i = 0, e = (1 << Level), val = !IsLeft; i != e; ++i, val += 2) Mask[i] = val; - SmallVector ActualMask = SI->getShuffleMask(); + ArrayRef ActualMask = SI->getShuffleMask(); return Mask == ActualMask; } @@ -1153,7 +1153,7 @@ matchVectorSplittingReduction(const ExtractElementInst *ReduxRoot, // Fill the rest of the mask with -1 for undef. std::fill(&ShuffleMask[MaskStart], ShuffleMask.end(), -1); - SmallVector Mask = Shuffle->getShuffleMask(); + ArrayRef Mask = Shuffle->getShuffleMask(); if (ShuffleMask != Mask) return RK_None; diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 007513020769..6a4d596a3b76 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -168,16 +168,16 @@ static bool getShuffleDemandedElts(const ShuffleVectorInst *Shuf, APInt &DemandedLHS, APInt &DemandedRHS) { // The length of scalable vectors is unknown at compile time, thus we // cannot check their values - if (Shuf->getMask()->getType()->getVectorElementCount().Scalable) + if (Shuf->getType()->getVectorElementCount().Scalable) return false; int NumElts = Shuf->getOperand(0)->getType()->getVectorNumElements(); - int NumMaskElts = Shuf->getMask()->getType()->getVectorNumElements(); + int NumMaskElts = Shuf->getType()->getVectorNumElements(); DemandedLHS = DemandedRHS = APInt::getNullValue(NumElts); if (DemandedElts.isNullValue()) return true; // Simple case of a shuffle with zeroinitializer. - if (isa(Shuf->getMask())) { + if (all_of(Shuf->getShuffleMask(), [](int Elt) { return Elt == 0; })) { DemandedLHS.setBit(0); return true; } diff --git a/llvm/lib/Analysis/VectorUtils.cpp b/llvm/lib/Analysis/VectorUtils.cpp index 532518acc6ad..c8ca2052919c 100644 --- a/llvm/lib/Analysis/VectorUtils.cpp +++ b/llvm/lib/Analysis/VectorUtils.cpp @@ -339,9 +339,9 @@ const llvm::Value *llvm::getSplatValue(const Value *V) { // shuf (inselt ?, Splat, 0), ?, <0, undef, 0, ...> Value *Splat; - if (match(V, m_ShuffleVector(m_InsertElement(m_Value(), m_Value(Splat), - m_ZeroInt()), - m_Value(), m_ZeroInt()))) + if (match(V, m_ShuffleVector( + m_InsertElement(m_Value(), m_Value(Splat), m_ZeroInt()), + m_Value(), m_ZeroMask()))) return Splat; return nullptr; @@ -366,7 +366,7 @@ bool llvm::isSplatValue(const Value *V, int Index, unsigned Depth) { if (auto *Shuf = dyn_cast(V)) { // FIXME: We can safely allow undefs here. If Index was specified, we will // check that the mask elt is defined at the required index. - if (!Shuf->getMask()->getSplatValue()) + if (!is_splat(Shuf->getShuffleMask())) return false; // Match any index. diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index d219f607410b..ebb172048646 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -3636,8 +3636,9 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { return Error(ID.Loc, "expected three operands to shufflevector"); if (!ShuffleVectorInst::isValidOperands(Elts[0], Elts[1], Elts[2])) return Error(ID.Loc, "invalid operands to shufflevector"); - ID.ConstantVal = - ConstantExpr::getShuffleVector(Elts[0], Elts[1],Elts[2]); + SmallVector Mask; + ShuffleVectorInst::getShuffleMask(cast(Elts[2]), Mask); + ID.ConstantVal = ConstantExpr::getShuffleVector(Elts[0], Elts[1], Mask); } else if (Opc == Instruction::ExtractElement) { if (Elts.size() != 2) return Error(ID.Loc, "expected two operands to extractelement"); diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index de2a6b47e6e2..16d3b79598f1 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2337,6 +2337,15 @@ Error BitcodeReader::parseConstants() { Type *CurFullTy = Type::getInt32Ty(Context); unsigned NextCstNo = ValueList.size(); + struct DelayedShufTy { + VectorType *OpTy; + VectorType *RTy; + Type *CurFullTy; + uint64_t Op0Idx; + uint64_t Op1Idx; + uint64_t Op2Idx; + }; + std::vector DelayedShuffles; while (true) { Expected MaybeEntry = Stream.advanceSkippingSubblocks(); if (!MaybeEntry) @@ -2353,6 +2362,29 @@ Error BitcodeReader::parseConstants() { // Once all the constants have been read, go through and resolve forward // references. + // + // We have to treat shuffles specially because they don't have three + // operands anymore. We need to convert the shuffle mask into an array, + // and we can't convert a forward reference. + for (auto &DelayedShuffle : DelayedShuffles) { + VectorType *OpTy = DelayedShuffle.OpTy; + VectorType *RTy = DelayedShuffle.RTy; + uint64_t Op0Idx = DelayedShuffle.Op0Idx; + uint64_t Op1Idx = DelayedShuffle.Op1Idx; + uint64_t Op2Idx = DelayedShuffle.Op2Idx; + Constant *Op0 = ValueList.getConstantFwdRef(Op0Idx, OpTy); + Constant *Op1 = ValueList.getConstantFwdRef(Op1Idx, OpTy); + Type *ShufTy = + VectorType::get(Type::getInt32Ty(Context), RTy->getElementCount()); + Constant *Op2 = ValueList.getConstantFwdRef(Op2Idx, ShufTy); + if (!ShuffleVectorInst::isValidOperands(Op0, Op1, Op2)) + return error("Invalid shufflevector operands"); + SmallVector Mask; + ShuffleVectorInst::getShuffleMask(Op2, Mask); + Value *V = ConstantExpr::getShuffleVector(Op0, Op1, Mask); + ValueList.assignValue(V, NextCstNo, DelayedShuffle.CurFullTy); + ++NextCstNo; + } ValueList.resolveConstantForwardRefs(); return Error::success(); case BitstreamEntry::Record: @@ -2694,13 +2726,9 @@ Error BitcodeReader::parseConstants() { VectorType *OpTy = dyn_cast(CurTy); if (Record.size() < 3 || !OpTy) return error("Invalid record"); - Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy); - Constant *Op1 = ValueList.getConstantFwdRef(Record[1], OpTy); - Type *ShufTy = VectorType::get(Type::getInt32Ty(Context), - OpTy->getElementCount()); - Constant *Op2 = ValueList.getConstantFwdRef(Record[2], ShufTy); - V = ConstantExpr::getShuffleVector(Op0, Op1, Op2); - break; + DelayedShuffles.push_back( + {OpTy, OpTy, CurFullTy, Record[0], Record[1], Record[2]}); + continue; } case bitc::CST_CODE_CE_SHUFVEC_EX: { // [opty, opval, opval, opval] VectorType *RTy = dyn_cast(CurTy); @@ -2708,13 +2736,9 @@ Error BitcodeReader::parseConstants() { dyn_cast_or_null(getTypeByID(Record[0])); if (Record.size() < 4 || !RTy || !OpTy) return error("Invalid record"); - Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy); - Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy); - Type *ShufTy = VectorType::get(Type::getInt32Ty(Context), - RTy->getElementCount()); - Constant *Op2 = ValueList.getConstantFwdRef(Record[3], ShufTy); - V = ConstantExpr::getShuffleVector(Op0, Op1, Op2); - break; + DelayedShuffles.push_back( + {OpTy, RTy, CurFullTy, Record[1], Record[2], Record[3]}); + continue; } case bitc::CST_CODE_CE_CMP: { // CE_CMP: [opty, opval, opval, pred] if (Record.size() < 4) diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index a27eada55d7e..e9ad00d6d4ba 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -2515,7 +2515,7 @@ void ModuleBitcodeWriter::writeConstants(unsigned FirstVal, unsigned LastVal, } Record.push_back(VE.getValueID(C->getOperand(0))); Record.push_back(VE.getValueID(C->getOperand(1))); - Record.push_back(VE.getValueID(C->getOperand(2))); + Record.push_back(VE.getValueID(CE->getShuffleMaskForBitcode())); break; case Instruction::ICmp: case Instruction::FCmp: @@ -2702,7 +2702,8 @@ void ModuleBitcodeWriter::writeInstruction(const Instruction &I, Code = bitc::FUNC_CODE_INST_SHUFFLEVEC; pushValueAndType(I.getOperand(0), InstID, Vals); pushValue(I.getOperand(1), InstID, Vals); - pushValue(I.getOperand(2), InstID, Vals); + pushValue(cast(I).getShuffleMaskForBitcode(), InstID, + Vals); break; case Instruction::ICmp: case Instruction::FCmp: { diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index f59c906c7b75..7419c4687fac 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -88,11 +88,16 @@ static void orderValue(const Value *V, OrderMap &OM) { if (OM.lookup(V).first) return; - if (const Constant *C = dyn_cast(V)) - if (C->getNumOperands() && !isa(C)) + if (const Constant *C = dyn_cast(V)) { + if (C->getNumOperands() && !isa(C)) { for (const Value *Op : C->operands()) if (!isa(Op) && !isa(Op)) orderValue(Op, OM); + if (auto *CE = dyn_cast(C)) + if (CE->getOpcode() == Instruction::ShuffleVector) + orderValue(CE->getShuffleMaskForBitcode(), OM); + } + } // Note: we cannot cache this lookup above, since inserting into the map // changes the map's size, and thus affects the other IDs. @@ -155,11 +160,14 @@ static OrderMap orderModule(const Module &M) { for (const Argument &A : F.args()) orderValue(&A, OM); for (const BasicBlock &BB : F) - for (const Instruction &I : BB) + for (const Instruction &I : BB) { for (const Value *Op : I.operands()) if ((isa(*Op) && !isa(*Op)) || isa(*Op)) orderValue(Op, OM); + if (auto *SVI = dyn_cast(&I)) + orderValue(SVI->getShuffleMaskForBitcode(), OM); + } for (const BasicBlock &BB : F) for (const Instruction &I : BB) orderValue(&I, OM); @@ -250,11 +258,17 @@ static void predictValueUseListOrder(const Value *V, const Function *F, predictValueUseListOrderImpl(V, F, IDPair.first, OM, Stack); // Recursive descent into constants. - if (const Constant *C = dyn_cast(V)) - if (C->getNumOperands()) // Visit GlobalValues. + if (const Constant *C = dyn_cast(V)) { + if (C->getNumOperands()) { // Visit GlobalValues. for (const Value *Op : C->operands()) if (isa(Op)) // Visit GlobalValues. predictValueUseListOrder(Op, F, OM, Stack); + if (auto *CE = dyn_cast(C)) + if (CE->getOpcode() == Instruction::ShuffleVector) + predictValueUseListOrder(CE->getShuffleMaskForBitcode(), F, OM, + Stack); + } + } } static UseListOrderStack predictUseListOrder(const Module &M) { @@ -279,10 +293,14 @@ static UseListOrderStack predictUseListOrder(const Module &M) { for (const Argument &A : F.args()) predictValueUseListOrder(&A, &F, OM, Stack); for (const BasicBlock &BB : F) - for (const Instruction &I : BB) + for (const Instruction &I : BB) { for (const Value *Op : I.operands()) if (isa(*Op) || isa(*Op)) // Visit GlobalValues. predictValueUseListOrder(Op, &F, OM, Stack); + if (auto *SVI = dyn_cast(&I)) + predictValueUseListOrder(SVI->getShuffleMaskForBitcode(), &F, OM, + Stack); + } for (const BasicBlock &BB : F) for (const Instruction &I : BB) predictValueUseListOrder(&I, &F, OM, Stack); @@ -413,6 +431,8 @@ ValueEnumerator::ValueEnumerator(const Module &M, EnumerateMetadata(&F, MD->getMetadata()); } + if (auto *SVI = dyn_cast(&I)) + EnumerateType(SVI->getShuffleMaskForBitcode()->getType()); EnumerateType(I.getType()); if (const auto *Call = dyn_cast(&I)) EnumerateAttributes(Call->getAttributes()); @@ -836,6 +856,9 @@ void ValueEnumerator::EnumerateValue(const Value *V) { I != E; ++I) if (!isa(*I)) // Don't enumerate BB operand to BlockAddress. EnumerateValue(*I); + if (auto *CE = dyn_cast(C)) + if (CE->getOpcode() == Instruction::ShuffleVector) + EnumerateValue(CE->getShuffleMaskForBitcode()); // Finally, add the value. Doing this could make the ValueID reference be // dangling, don't reuse it. @@ -913,6 +936,9 @@ void ValueEnumerator::EnumerateOperandType(const Value *V) { EnumerateOperandType(Op); } + if (auto *CE = dyn_cast(C)) + if (CE->getOpcode() == Instruction::ShuffleVector) + EnumerateOperandType(CE->getShuffleMaskForBitcode()); } void ValueEnumerator::EnumerateAttributes(AttributeList PAL) { @@ -958,11 +984,14 @@ void ValueEnumerator::incorporateFunction(const Function &F) { // Add all function-level constants to the value table. for (const BasicBlock &BB : F) { - for (const Instruction &I : BB) + for (const Instruction &I : BB) { for (const Use &OI : I.operands()) { if ((isa(OI) && !isa(OI)) || isa(OI)) EnumerateValue(OI); } + if (auto *SVI = dyn_cast(&I)) + EnumerateValue(SVI->getShuffleMaskForBitcode()); + } BasicBlocks.push_back(&BB); ValueMap[&BB] = BasicBlocks.size(); } diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 4a416c3c8233..1654eba6bc57 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -6257,7 +6257,7 @@ bool CodeGenPrepare::optimizeSelectInst(SelectInst *SI) { } static bool isBroadcastShuffle(ShuffleVectorInst *SVI) { - SmallVector Mask(SVI->getShuffleMask()); + ArrayRef Mask(SVI->getShuffleMask()); int SplatElem = -1; for (unsigned i = 0; i < Mask.size(); ++i) { if (SplatElem != -1 && Mask[i] != -1 && Mask[i] != SplatElem) @@ -6307,7 +6307,7 @@ bool CodeGenPrepare::optimizeShuffleVectorInst(ShuffleVectorInst *SVI) { assert(InsertPt != UserBB->end()); InsertedShuffle = new ShuffleVectorInst(SVI->getOperand(0), SVI->getOperand(1), - SVI->getOperand(2), "", &*InsertPt); + SVI->getShuffleMask(), "", &*InsertPt); InsertedShuffle->setDebugLoc(SVI->getDebugLoc()); } diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 58888c4dadc7..8135ce86cd22 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1973,8 +1973,11 @@ bool IRTranslator::translateExtractElement(const User &U, bool IRTranslator::translateShuffleVector(const User &U, MachineIRBuilder &MIRBuilder) { - SmallVector Mask; - ShuffleVectorInst::getShuffleMask(cast(U.getOperand(2)), Mask); + ArrayRef Mask; + if (auto *SVI = dyn_cast(&U)) + Mask = SVI->getShuffleMask(); + else + Mask = cast(U).getShuffleMask(); ArrayRef MaskAlloc = MF->allocateShuffleMask(Mask); MIRBuilder .buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {getOrCreateVReg(U)}, diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 26ed6e22af94..ed24e004f908 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -3437,14 +3437,19 @@ void SelectionDAGBuilder::visitExtractElement(const User &I) { void SelectionDAGBuilder::visitShuffleVector(const User &I) { SDValue Src1 = getValue(I.getOperand(0)); SDValue Src2 = getValue(I.getOperand(1)); - Constant *MaskV = cast(I.getOperand(2)); + ArrayRef Mask; + if (auto *SVI = dyn_cast(&I)) + Mask = SVI->getShuffleMask(); + else + Mask = cast(I).getShuffleMask(); SDLoc DL = getCurSDLoc(); const TargetLowering &TLI = DAG.getTargetLoweringInfo(); EVT VT = TLI.getValueType(DAG.getDataLayout(), I.getType()); EVT SrcVT = Src1.getValueType(); unsigned SrcNumElts = SrcVT.getVectorNumElements(); - if (MaskV->isNullValue() && VT.isScalableVector()) { + if (all_of(Mask, [](int Elem) { return Elem == 0; }) && + VT.isScalableVector()) { // Canonical splat form of first element of first input vector. SDValue FirstElt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, SrcVT.getScalarType(), Src1, @@ -3458,8 +3463,6 @@ void SelectionDAGBuilder::visitShuffleVector(const User &I) { // for targets that support a SPLAT_VECTOR for non-scalable vector types. assert(!VT.isScalableVector() && "Unsupported scalable vector shuffle"); - SmallVector Mask; - ShuffleVectorInst::getShuffleMask(MaskV, Mask); unsigned MaskNumElts = Mask.size(); if (SrcNumElts == MaskNumElts) { diff --git a/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp b/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp index 51f31d3d5d8f..4a5fb1feb18f 100644 --- a/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -1868,7 +1868,6 @@ void Interpreter::visitShuffleVectorInst(ShuffleVectorInst &I){ GenericValue Src1 = getOperandValue(I.getOperand(0), SF); GenericValue Src2 = getOperandValue(I.getOperand(1), SF); - GenericValue Src3 = getOperandValue(I.getOperand(2), SF); GenericValue Dest; // There is no need to check types of src1 and src2, because the compiled @@ -1878,7 +1877,7 @@ void Interpreter::visitShuffleVectorInst(ShuffleVectorInst &I){ Type *TyContained = Ty->getElementType(); unsigned src1Size = (unsigned)Src1.AggregateVal.size(); unsigned src2Size = (unsigned)Src2.AggregateVal.size(); - unsigned src3Size = (unsigned)Src3.AggregateVal.size(); + unsigned src3Size = I.getShuffleMask().size(); Dest.AggregateVal.resize(src3Size); @@ -1888,7 +1887,7 @@ void Interpreter::visitShuffleVectorInst(ShuffleVectorInst &I){ break; case Type::IntegerTyID: for( unsigned i=0; i(V) ? GlobalPrefix : LocalPrefix); } +static void PrintShuffleMask(raw_ostream &Out, Type *Ty, ArrayRef Mask) { + Out << ", <"; + if (Ty->getVectorIsScalable()) + Out << "vscale x "; + Out << Mask.size() << " x i32> "; + bool FirstElt = true; + if (all_of(Mask, [](int Elt) { return Elt == 0; })) { + Out << "zeroinitializer"; + } else if (all_of(Mask, [](int Elt) { return Elt == UndefMaskElem; })) { + Out << "undef"; + } else { + Out << "<"; + for (int Elt : Mask) { + if (FirstElt) + FirstElt = false; + else + Out << ", "; + Out << "i32 "; + if (Elt == UndefMaskElem) + Out << "undef"; + else + Out << Elt; + } + Out << ">"; + } +} + namespace { class TypePrinting { @@ -1547,6 +1574,9 @@ static void WriteConstantInternal(raw_ostream &Out, const Constant *CV, TypePrinter.print(CE->getType(), Out); } + if (CE->getOpcode() == Instruction::ShuffleVector) + PrintShuffleMask(Out, CE->getType(), CE->getShuffleMask()); + Out << ')'; return; } @@ -4093,6 +4123,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) { RMWI->getSyncScopeID()); } else if (const FenceInst *FI = dyn_cast(&I)) { writeAtomic(FI->getContext(), FI->getOrdering(), FI->getSyncScopeID()); + } else if (const ShuffleVectorInst *SVI = dyn_cast(&I)) { + PrintShuffleMask(Out, SVI->getType(), SVI->getShuffleMask()); } // Print Metadata info. diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index de5b94403bd7..96021dc1fbd5 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -2335,11 +2335,12 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { PointerType::getUnqual(VT)); Value *Load = Builder.CreateAlignedLoad(VT, Op, Align(1)); if (NumSrcElts == 2) - Rep = Builder.CreateShuffleVector(Load, UndefValue::get(Load->getType()), - { 0, 1, 0, 1 }); + Rep = Builder.CreateShuffleVector( + Load, UndefValue::get(Load->getType()), ArrayRef{0, 1, 0, 1}); else - Rep = Builder.CreateShuffleVector(Load, UndefValue::get(Load->getType()), - { 0, 1, 2, 3, 0, 1, 2, 3 }); + Rep = + Builder.CreateShuffleVector(Load, UndefValue::get(Load->getType()), + ArrayRef{0, 1, 2, 3, 0, 1, 2, 3}); } else if (IsX86 && (Name.startswith("avx512.mask.shuf.i") || Name.startswith("avx512.mask.shuf.f"))) { unsigned Imm = cast(CI->getArgOperand(2))->getZExtValue(); diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp index 07292e50fc8d..c4465d9bfa02 100644 --- a/llvm/lib/IR/ConstantFold.cpp +++ b/llvm/lib/IR/ConstantFold.cpp @@ -876,22 +876,22 @@ Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val, return ConstantVector::get(Result); } -Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1, - Constant *V2, - Constant *Mask) { - ElementCount MaskEltCount = Mask->getType()->getVectorElementCount(); +Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2, + ArrayRef Mask) { + unsigned MaskNumElts = Mask.size(); + ElementCount MaskEltCount = {MaskNumElts, + V1->getType()->getVectorIsScalable()}; Type *EltTy = V1->getType()->getVectorElementType(); // Undefined shuffle mask -> undefined value. - if (isa(Mask)) - return UndefValue::get(VectorType::get(EltTy, MaskEltCount)); - - // Don't break the bitcode reader hack. - if (isa(Mask)) return nullptr; + if (all_of(Mask, [](int Elt) { return Elt == UndefMaskElem; })) { + return UndefValue::get(VectorType::get(EltTy, MaskNumElts)); + } // If the mask is all zeros this is a splat, no need to go through all // elements. - if (isa(Mask) && !MaskEltCount.Scalable) { + if (all_of(Mask, [](int Elt) { return Elt == 0; }) && + !MaskEltCount.Scalable) { Type *Ty = IntegerType::get(V1->getContext(), 32); Constant *Elt = ConstantExpr::getExtractElement(V1, ConstantInt::get(Ty, 0)); @@ -903,13 +903,12 @@ Constant *llvm::ConstantFoldShuffleVectorInstruction(Constant *V1, if (ValTy->isScalable()) return nullptr; - unsigned MaskNumElts = MaskEltCount.Min; unsigned SrcNumElts = V1->getType()->getVectorNumElements(); // Loop over the shuffle mask, evaluating each element. SmallVector Result; for (unsigned i = 0; i != MaskNumElts; ++i) { - int Elt = ShuffleVectorInst::getMaskValue(Mask, i); + int Elt = Mask[i]; if (Elt == -1) { Result.push_back(UndefValue::get(EltTy)); continue; diff --git a/llvm/lib/IR/ConstantFold.h b/llvm/lib/IR/ConstantFold.h index 9ad6e14e9e40..0cdd5cf3cbce 100644 --- a/llvm/lib/IR/ConstantFold.h +++ b/llvm/lib/IR/ConstantFold.h @@ -38,7 +38,7 @@ template class ArrayRef; Constant *ConstantFoldInsertElementInstruction(Constant *Val, Constant *Elt, Constant *Idx); Constant *ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2, - Constant *Mask); + ArrayRef Mask); Constant *ConstantFoldExtractValueInstruction(Constant *Agg, ArrayRef Idxs); Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val, diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index e001b5230751..60ab1a595c34 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -1230,8 +1230,7 @@ Constant *ConstantVector::getSplat(ElementCount EC, Constant *V) { Constant *UndefV = UndefValue::get(VTy); V = ConstantExpr::getInsertElement(UndefV, V, ConstantInt::get(I32Ty, 0)); // Build shuffle mask to perform the splat. - Type *MaskTy = VectorType::get(I32Ty, EC); - Constant *Zeros = ConstantAggregateZero::get(MaskTy); + SmallVector Zeros(EC.Min, 0); // Splat. return ConstantExpr::getShuffleVector(V, UndefV, Zeros); } @@ -1298,6 +1297,14 @@ unsigned ConstantExpr::getPredicate() const { return cast(this)->predicate; } +ArrayRef ConstantExpr::getShuffleMask() const { + return cast(this)->ShuffleMask; +} + +Constant *ConstantExpr::getShuffleMaskForBitcode() const { + return cast(this)->ShuffleMaskForBitcode; +} + Constant * ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const { assert(Op->getType() == getOperand(OpNo)->getType() && @@ -1349,7 +1356,7 @@ Constant *ConstantExpr::getWithOperands(ArrayRef Ops, Type *Ty, case Instruction::ExtractValue: return ConstantExpr::getExtractValue(Ops[0], getIndices(), OnlyIfReducedTy); case Instruction::ShuffleVector: - return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2], + return ConstantExpr::getShuffleVector(Ops[0], Ops[1], getShuffleMask(), OnlyIfReducedTy); case Instruction::GetElementPtr: { auto *GEPO = cast(this); @@ -2152,7 +2159,7 @@ Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C, if (InRangeIndex && *InRangeIndex < 63) SubClassOptionalData |= (*InRangeIndex + 1) << 1; const ConstantExprKeyType Key(Instruction::GetElementPtr, ArgVec, 0, - SubClassOptionalData, None, Ty); + SubClassOptionalData, None, None, Ty); LLVMContextImpl *pImpl = C->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(ReqTy, Key); @@ -2254,23 +2261,25 @@ Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt, } Constant *ConstantExpr::getShuffleVector(Constant *V1, Constant *V2, - Constant *Mask, Type *OnlyIfReducedTy) { + ArrayRef Mask, + Type *OnlyIfReducedTy) { assert(ShuffleVectorInst::isValidOperands(V1, V2, Mask) && "Invalid shuffle vector constant expr operands!"); if (Constant *FC = ConstantFoldShuffleVectorInstruction(V1, V2, Mask)) return FC; // Fold a few common cases. - ElementCount NElts = Mask->getType()->getVectorElementCount(); + unsigned NElts = Mask.size(); Type *EltTy = V1->getType()->getVectorElementType(); - Type *ShufTy = VectorType::get(EltTy, NElts); + bool TypeIsScalable = V1->getType()->getVectorIsScalable(); + Type *ShufTy = VectorType::get(EltTy, NElts, TypeIsScalable); if (OnlyIfReducedTy == ShufTy) return nullptr; // Look up the constant in the table first to ensure uniqueness - Constant *ArgVec[] = { V1, V2, Mask }; - const ConstantExprKeyType Key(Instruction::ShuffleVector, ArgVec); + Constant *ArgVec[] = {V1, V2}; + ConstantExprKeyType Key(Instruction::ShuffleVector, ArgVec, 0, 0, None, Mask); LLVMContextImpl *pImpl = ShufTy->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(ShufTy, Key); @@ -3117,7 +3126,7 @@ Instruction *ConstantExpr::getAsInstruction() const { case Instruction::ExtractValue: return ExtractValueInst::Create(Ops[0], getIndices()); case Instruction::ShuffleVector: - return new ShuffleVectorInst(Ops[0], Ops[1], Ops[2]); + return new ShuffleVectorInst(Ops[0], Ops[1], getShuffleMask()); case Instruction::GetElementPtr: { const auto *GO = cast(this); diff --git a/llvm/lib/IR/ConstantsContext.h b/llvm/lib/IR/ConstantsContext.h index 9ecbb6137836..ad521c8a1bdf 100644 --- a/llvm/lib/IR/ConstantsContext.h +++ b/llvm/lib/IR/ConstantsContext.h @@ -26,6 +26,7 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" #include "llvm/IR/OperandTraits.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Debug.h" @@ -146,21 +147,24 @@ class InsertElementConstantExpr : public ConstantExpr { /// shufflevector constant exprs. class ShuffleVectorConstantExpr : public ConstantExpr { public: - ShuffleVectorConstantExpr(Constant *C1, Constant *C2, Constant *C3) - : ConstantExpr(VectorType::get( - cast(C1->getType())->getElementType(), - cast(C3->getType())->getElementCount()), - Instruction::ShuffleVector, - &Op<0>(), 3) { + ShuffleVectorConstantExpr(Constant *C1, Constant *C2, ArrayRef Mask) + : ConstantExpr( + VectorType::get(cast(C1->getType())->getElementType(), + Mask.size(), C1->getType()->getVectorIsScalable()), + Instruction::ShuffleVector, &Op<0>(), 2) { + assert(ShuffleVectorInst::isValidOperands(C1, C2, Mask) && + "Invalid shuffle vector instruction operands!"); Op<0>() = C1; Op<1>() = C2; - Op<2>() = C3; + ShuffleMask.assign(Mask.begin(), Mask.end()); + ShuffleMaskForBitcode = + ShuffleVectorInst::convertShuffleMaskForBitcode(Mask, getType()); } - // allocate space for exactly three operands - void *operator new(size_t s) { - return User::operator new(s, 3); - } + SmallVector ShuffleMask; + Constant *ShuffleMaskForBitcode; + + void *operator new(size_t s) { return User::operator new(s, 2); } /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -319,7 +323,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementConstantExpr, Value) template <> struct OperandTraits - : public FixedNumOperandTraits {}; + : public FixedNumOperandTraits {}; DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorConstantExpr, Value) template <> @@ -460,36 +464,58 @@ struct InlineAsmKeyType { }; struct ConstantExprKeyType { +private: uint8_t Opcode; uint8_t SubclassOptionalData; uint16_t SubclassData; ArrayRef Ops; ArrayRef Indexes; + ArrayRef ShuffleMask; Type *ExplicitTy; + static ArrayRef getShuffleMaskIfValid(const ConstantExpr *CE) { + if (CE->getOpcode() == Instruction::ShuffleVector) + return CE->getShuffleMask(); + return None; + } + + static ArrayRef getIndicesIfValid(const ConstantExpr *CE) { + if (CE->hasIndices()) + return CE->getIndices(); + return None; + } + + static Type *getSourceElementTypeIfValid(const ConstantExpr *CE) { + if (auto *GEPCE = dyn_cast(CE)) + return GEPCE->getSourceElementType(); + return nullptr; + } + +public: ConstantExprKeyType(unsigned Opcode, ArrayRef Ops, unsigned short SubclassData = 0, unsigned short SubclassOptionalData = 0, ArrayRef Indexes = None, + ArrayRef ShuffleMask = None, Type *ExplicitTy = nullptr) : Opcode(Opcode), SubclassOptionalData(SubclassOptionalData), SubclassData(SubclassData), Ops(Ops), Indexes(Indexes), - ExplicitTy(ExplicitTy) {} + ShuffleMask(ShuffleMask), ExplicitTy(ExplicitTy) {} ConstantExprKeyType(ArrayRef Operands, const ConstantExpr *CE) : Opcode(CE->getOpcode()), SubclassOptionalData(CE->getRawSubclassOptionalData()), SubclassData(CE->isCompare() ? CE->getPredicate() : 0), Ops(Operands), - Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef()), - ExplicitTy(nullptr) {} + Indexes(getIndicesIfValid(CE)), ShuffleMask(getShuffleMaskIfValid(CE)), + ExplicitTy(getSourceElementTypeIfValid(CE)) {} ConstantExprKeyType(const ConstantExpr *CE, SmallVectorImpl &Storage) : Opcode(CE->getOpcode()), SubclassOptionalData(CE->getRawSubclassOptionalData()), SubclassData(CE->isCompare() ? CE->getPredicate() : 0), - Indexes(CE->hasIndices() ? CE->getIndices() : ArrayRef()), - ExplicitTy(nullptr) { + Indexes(getIndicesIfValid(CE)), ShuffleMask(getShuffleMaskIfValid(CE)), + ExplicitTy(getSourceElementTypeIfValid(CE)) { assert(Storage.empty() && "Expected empty storage"); for (unsigned I = 0, E = CE->getNumOperands(); I != E; ++I) Storage.push_back(CE->getOperand(I)); @@ -499,7 +525,8 @@ struct ConstantExprKeyType { bool operator==(const ConstantExprKeyType &X) const { return Opcode == X.Opcode && SubclassData == X.SubclassData && SubclassOptionalData == X.SubclassOptionalData && Ops == X.Ops && - Indexes == X.Indexes; + Indexes == X.Indexes && ShuffleMask == X.ShuffleMask && + ExplicitTy == X.ExplicitTy; } bool operator==(const ConstantExpr *CE) const { @@ -514,15 +541,21 @@ struct ConstantExprKeyType { for (unsigned I = 0, E = Ops.size(); I != E; ++I) if (Ops[I] != CE->getOperand(I)) return false; - if (Indexes != (CE->hasIndices() ? CE->getIndices() : ArrayRef())) + if (Indexes != getIndicesIfValid(CE)) + return false; + if (ShuffleMask != getShuffleMaskIfValid(CE)) + return false; + if (ExplicitTy != getSourceElementTypeIfValid(CE)) return false; return true; } unsigned getHash() const { - return hash_combine(Opcode, SubclassOptionalData, SubclassData, - hash_combine_range(Ops.begin(), Ops.end()), - hash_combine_range(Indexes.begin(), Indexes.end())); + return hash_combine( + Opcode, SubclassOptionalData, SubclassData, + hash_combine_range(Ops.begin(), Ops.end()), + hash_combine_range(Indexes.begin(), Indexes.end()), + hash_combine_range(ShuffleMask.begin(), ShuffleMask.end()), ExplicitTy); } using TypeClass = ConstantInfo::TypeClass; @@ -546,17 +579,14 @@ struct ConstantExprKeyType { case Instruction::InsertElement: return new InsertElementConstantExpr(Ops[0], Ops[1], Ops[2]); case Instruction::ShuffleVector: - return new ShuffleVectorConstantExpr(Ops[0], Ops[1], Ops[2]); + return new ShuffleVectorConstantExpr(Ops[0], Ops[1], ShuffleMask); case Instruction::InsertValue: return new InsertValueConstantExpr(Ops[0], Ops[1], Indexes, Ty); case Instruction::ExtractValue: return new ExtractValueConstantExpr(Ops[0], Indexes, Ty); case Instruction::GetElementPtr: - return GetElementPtrConstantExpr::Create( - ExplicitTy ? ExplicitTy - : cast(Ops[0]->getType()->getScalarType()) - ->getElementType(), - Ops[0], Ops.slice(1), Ty, SubclassOptionalData); + return GetElementPtrConstantExpr::Create(ExplicitTy, Ops[0], Ops.slice(1), + Ty, SubclassOptionalData); case Instruction::ICmp: return new CompareConstantExpr(Ty, Instruction::ICmp, SubclassData, Ops[0], Ops[1]); diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 313bc65e775c..da2e25e77978 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -1781,9 +1781,11 @@ LLVMValueRef LLVMConstInsertElement(LLVMValueRef VectorConstant, LLVMValueRef LLVMConstShuffleVector(LLVMValueRef VectorAConstant, LLVMValueRef VectorBConstant, LLVMValueRef MaskConstant) { + SmallVector IntMask; + ShuffleVectorInst::getShuffleMask(unwrap(MaskConstant), IntMask); return wrap(ConstantExpr::getShuffleVector(unwrap(VectorAConstant), unwrap(VectorBConstant), - unwrap(MaskConstant))); + IntMask)); } LLVMValueRef LLVMConstExtractValue(LLVMValueRef AggConstant, unsigned *IdxList, diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 2ef109067dd6..cd476a360155 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -443,6 +443,9 @@ static bool haveSameSpecialState(const Instruction *I1, const Instruction *I2, RMWI->isVolatile() == cast(I2)->isVolatile() && RMWI->getOrdering() == cast(I2)->getOrdering() && RMWI->getSyncScopeID() == cast(I2)->getSyncScopeID(); + if (const ShuffleVectorInst *SVI = dyn_cast(I1)) + return SVI->getShuffleMask() == + cast(I2)->getShuffleMask(); return true; } diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 3807752eae0d..37e194a0feab 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -1843,57 +1843,109 @@ bool InsertElementInst::isValidOperands(const Value *Vec, const Value *Elt, ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, const Twine &Name, Instruction *InsertBefore) -: Instruction(VectorType::get(cast(V1->getType())->getElementType(), - cast(Mask->getType())->getElementCount()), - ShuffleVector, - OperandTraits::op_begin(this), - OperandTraits::operands(this), - InsertBefore) { + : Instruction( + VectorType::get(cast(V1->getType())->getElementType(), + cast(Mask->getType())->getElementCount()), + ShuffleVector, OperandTraits::op_begin(this), + OperandTraits::operands(this), InsertBefore) { assert(isValidOperands(V1, V2, Mask) && "Invalid shuffle vector instruction operands!"); + Op<0>() = V1; Op<1>() = V2; - Op<2>() = Mask; + SmallVector MaskArr; + getShuffleMask(cast(Mask), MaskArr); + setShuffleMask(MaskArr); setName(Name); } ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, Value *Mask, + const Twine &Name, BasicBlock *InsertAtEnd) + : Instruction( + VectorType::get(cast(V1->getType())->getElementType(), + cast(Mask->getType())->getElementCount()), + ShuffleVector, OperandTraits::op_begin(this), + OperandTraits::operands(this), InsertAtEnd) { + assert(isValidOperands(V1, V2, Mask) && + "Invalid shuffle vector instruction operands!"); + + Op<0>() = V1; + Op<1>() = V2; + SmallVector MaskArr; + getShuffleMask(cast(Mask), MaskArr); + setShuffleMask(MaskArr); + setName(Name); +} + +ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, ArrayRef Mask, const Twine &Name, - BasicBlock *InsertAtEnd) -: Instruction(VectorType::get(cast(V1->getType())->getElementType(), - cast(Mask->getType())->getElementCount()), - ShuffleVector, - OperandTraits::op_begin(this), - OperandTraits::operands(this), - InsertAtEnd) { + Instruction *InsertBefore) + : Instruction( + VectorType::get(cast(V1->getType())->getElementType(), + Mask.size(), V1->getType()->getVectorIsScalable()), + ShuffleVector, OperandTraits::op_begin(this), + OperandTraits::operands(this), InsertBefore) { + assert(isValidOperands(V1, V2, Mask) && + "Invalid shuffle vector instruction operands!"); + Op<0>() = V1; + Op<1>() = V2; + setShuffleMask(Mask); + setName(Name); +} + +ShuffleVectorInst::ShuffleVectorInst(Value *V1, Value *V2, ArrayRef Mask, + const Twine &Name, BasicBlock *InsertAtEnd) + : Instruction( + VectorType::get(cast(V1->getType())->getElementType(), + Mask.size(), V1->getType()->getVectorIsScalable()), + ShuffleVector, OperandTraits::op_begin(this), + OperandTraits::operands(this), InsertAtEnd) { assert(isValidOperands(V1, V2, Mask) && "Invalid shuffle vector instruction operands!"); Op<0>() = V1; Op<1>() = V2; - Op<2>() = Mask; + setShuffleMask(Mask); setName(Name); } void ShuffleVectorInst::commute() { int NumOpElts = Op<0>()->getType()->getVectorNumElements(); - int NumMaskElts = getMask()->getType()->getVectorNumElements(); - SmallVector NewMask(NumMaskElts); - Type *Int32Ty = Type::getInt32Ty(getContext()); + int NumMaskElts = ShuffleMask.size(); + SmallVector NewMask(NumMaskElts); for (int i = 0; i != NumMaskElts; ++i) { int MaskElt = getMaskValue(i); - if (MaskElt == -1) { - NewMask[i] = UndefValue::get(Int32Ty); + if (MaskElt == UndefMaskElem) { + NewMask[i] = UndefMaskElem; continue; } assert(MaskElt >= 0 && MaskElt < 2 * NumOpElts && "Out-of-range mask"); MaskElt = (MaskElt < NumOpElts) ? MaskElt + NumOpElts : MaskElt - NumOpElts; - NewMask[i] = ConstantInt::get(Int32Ty, MaskElt); + NewMask[i] = MaskElt; } - Op<2>() = ConstantVector::get(NewMask); + setShuffleMask(NewMask); Op<0>().swap(Op<1>()); } +bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, + ArrayRef Mask) { + // V1 and V2 must be vectors of the same type. + if (!V1->getType()->isVectorTy() || V1->getType() != V2->getType()) + return false; + + // Make sure the mask elements make sense. + int V1Size = cast(V1->getType())->getNumElements(); + for (int Elem : Mask) + if (Elem != UndefMaskElem && Elem >= V1Size * 2) + return false; + + if (V1->getType()->getVectorIsScalable()) + if ((Mask[0] != 0 && Mask[0] != UndefMaskElem) || !is_splat(Mask)) + return false; + + return true; +} + bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, const Value *Mask) { // V1 and V2 must be vectors of the same type. @@ -1902,7 +1954,8 @@ bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, // Mask must be vector of i32. auto *MaskTy = dyn_cast(Mask->getType()); - if (!MaskTy || !MaskTy->getElementType()->isIntegerTy(32)) + if (!MaskTy || !MaskTy->getElementType()->isIntegerTy(32) || + MaskTy->isScalable() != V1->getType()->getVectorIsScalable()) return false; // Check to see if Mask is valid. @@ -1930,34 +1983,12 @@ bool ShuffleVectorInst::isValidOperands(const Value *V1, const Value *V2, return true; } - // The bitcode reader can create a place holder for a forward reference - // used as the shuffle mask. When this occurs, the shuffle mask will - // fall into this case and fail. To avoid this error, do this bit of - // ugliness to allow such a mask pass. - if (const auto *CE = dyn_cast(Mask)) - if (CE->getOpcode() == Instruction::UserOp1) - return true; - return false; } -int ShuffleVectorInst::getMaskValue(const Constant *Mask, unsigned i) { - assert(i < Mask->getType()->getVectorNumElements() && "Index out of range"); - assert(!Mask->getType()->getVectorElementCount().Scalable && - "Length of scalable vectors unknown at compile time"); - if (auto *CDS = dyn_cast(Mask)) - return CDS->getElementAsInteger(i); - Constant *C = Mask->getAggregateElement(i); - if (isa(C)) - return -1; - return cast(C)->getZExtValue(); -} - void ShuffleVectorInst::getShuffleMask(const Constant *Mask, SmallVectorImpl &Result) { - assert(!Mask->getType()->getVectorElementCount().Scalable && - "Length of scalable vectors unknown at compile time"); - unsigned NumElts = Mask->getType()->getVectorNumElements(); + unsigned NumElts = Mask->getType()->getVectorElementCount().Min; if (isa(Mask)) { Result.resize(NumElts, 0); return; @@ -1975,6 +2006,30 @@ void ShuffleVectorInst::getShuffleMask(const Constant *Mask, } } +void ShuffleVectorInst::setShuffleMask(ArrayRef Mask) { + ShuffleMask.assign(Mask.begin(), Mask.end()); + ShuffleMaskForBitcode = convertShuffleMaskForBitcode(Mask, getType()); +} +Constant *ShuffleVectorInst::convertShuffleMaskForBitcode(ArrayRef Mask, + Type *ResultTy) { + Type *Int32Ty = Type::getInt32Ty(ResultTy->getContext()); + if (ResultTy->getVectorIsScalable()) { + assert(is_splat(Mask) && "Unexpected shuffle"); + Type *VecTy = VectorType::get(Int32Ty, Mask.size(), true); + if (Mask[0] == 0) + return Constant::getNullValue(VecTy); + return UndefValue::get(VecTy); + } + SmallVector MaskConst; + for (int Elem : Mask) { + if (Elem == UndefMaskElem) + MaskConst.push_back(UndefValue::get(Int32Ty)); + else + MaskConst.push_back(ConstantInt::get(Int32Ty, Elem)); + } + return ConstantVector::get(MaskConst); +} + static bool isSingleSourceMaskImpl(ArrayRef Mask, int NumOpElts) { assert(!Mask.empty() && "Shuffle mask must contain elements"); bool UsesLHS = false; @@ -2124,7 +2179,7 @@ bool ShuffleVectorInst::isIdentityWithPadding() const { return false; // The first part of the mask must choose elements from exactly 1 source op. - SmallVector Mask = getShuffleMask(); + ArrayRef Mask = getShuffleMask(); if (!isIdentityMaskImpl(Mask, NumOpElts)) return false; @@ -4298,7 +4353,7 @@ InsertElementInst *InsertElementInst::cloneImpl() const { } ShuffleVectorInst *ShuffleVectorInst::cloneImpl() const { - return new ShuffleVectorInst(getOperand(0), getOperand(1), getOperand(2)); + return new ShuffleVectorInst(getOperand(0), getOperand(1), getShuffleMask()); } PHINode *PHINode::cloneImpl() const { return new PHINode(*this); } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 84364dbb230b..a31a91766ebe 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -3310,7 +3310,7 @@ void Verifier::visitInsertElementInst(InsertElementInst &IE) { void Verifier::visitShuffleVectorInst(ShuffleVectorInst &SV) { Assert(ShuffleVectorInst::isValidOperands(SV.getOperand(0), SV.getOperand(1), - SV.getOperand(2)), + SV.getShuffleMask()), "Invalid shufflevector operands!", &SV); visitInstruction(SV); } diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 149de47e3df8..523ffe993efc 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -9207,10 +9207,10 @@ static bool areExtractShuffleVectors(Value *Op1, Value *Op2) { return FullVT->getNumElements() == 2 * HalfVT->getNumElements(); }; - Constant *M1, *M2; + ArrayRef M1, M2; Value *S1Op1, *S2Op1; - if (!match(Op1, m_ShuffleVector(m_Value(S1Op1), m_Undef(), m_Constant(M1))) || - !match(Op2, m_ShuffleVector(m_Value(S2Op1), m_Undef(), m_Constant(M2)))) + if (!match(Op1, m_ShuffleVector(m_Value(S1Op1), m_Undef(), m_Mask(M1))) || + !match(Op2, m_ShuffleVector(m_Value(S2Op1), m_Undef(), m_Mask(M2)))) return false; // Check that the operands are half as wide as the result and we extract diff --git a/llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp b/llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp index 395c04161ea7..b7baecdec6b6 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp @@ -210,7 +210,7 @@ bool AMDGPULowerKernelArguments::runOnFunction(Function &F) { Arg.replaceAllUsesWith(NewVal); } else if (IsV3) { Value *Shuf = Builder.CreateShuffleVector(Load, UndefValue::get(V4Ty), - {0, 1, 2}, + ArrayRef{0, 1, 2}, Arg.getName() + ".load"); Arg.replaceAllUsesWith(Shuf); } else { diff --git a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp index cf641e3948ac..5a2cd48a81e9 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp @@ -409,7 +409,7 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) { DL->getTypeSizeInBits(Val->getType())) { assert(isVec3ToVec4Shuffle(EffectiveEltTy, Val->getType())); Val = B.CreateShuffleVector(Val, UndefValue::get(Val->getType()), - { 0, 1, 2 }); + ArrayRef{0, 1, 2}); } Val = B.CreateBitCast(Val, EffectiveEltTy); diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index a2de0adb34d7..6d03126b2db0 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -15547,7 +15547,7 @@ bool ARMTargetLowering::shouldSinkOperands(Instruction *I, return false; if (!match(I->getOperand(Op), m_ShuffleVector(m_InsertElement(m_Undef(), m_Value(), m_ZeroInt()), - m_Undef(), m_Zero()))) { + m_Undef(), m_ZeroMask()))) { return false; } Instruction *Shuffle = cast(I->getOperand(Op)); diff --git a/llvm/lib/Target/ARM/MVETailPredication.cpp b/llvm/lib/Target/ARM/MVETailPredication.cpp index dd7867397b45..26b71ba5b600 100644 --- a/llvm/lib/Target/ARM/MVETailPredication.cpp +++ b/llvm/lib/Target/ARM/MVETailPredication.cpp @@ -286,7 +286,7 @@ bool MVETailPredication::isTailPredicate(TripCountPattern &TCP) { Instruction *Insert = nullptr; // The shuffle which broadcasts the index iv into a vector. if (!match(BroadcastSplat, - m_ShuffleVector(m_Instruction(Insert), m_Undef(), m_Zero()))) + m_ShuffleVector(m_Instruction(Insert), m_Undef(), m_ZeroMask()))) return false; // The insert element which initialises a vector with the index iv. @@ -409,7 +409,7 @@ static bool MatchElemCountLoopSetup(Loop *L, Instruction *Shuffle, Instruction *Insert = nullptr; if (!match(Shuffle, - m_ShuffleVector(m_Instruction(Insert), m_Undef(), m_Zero()))) + m_ShuffleVector(m_Instruction(Insert), m_Undef(), m_ZeroMask()))) return false; // Insert the limit into a vector. diff --git a/llvm/lib/Target/X86/X86PartialReduction.cpp b/llvm/lib/Target/X86/X86PartialReduction.cpp index daa293d1e740..26c05eab45b2 100644 --- a/llvm/lib/Target/X86/X86PartialReduction.cpp +++ b/llvm/lib/Target/X86/X86PartialReduction.cpp @@ -384,7 +384,7 @@ bool X86PartialReduction::trySADReplacement(Value *Op, BinaryOperator *Add) { NumElts = OpTy->getVectorNumElements(); if (NumElts == 2) { // Extract down to 2 elements. - Ops[0] = Builder.CreateShuffleVector(Ops[0], Ops[0], {0, 1}); + Ops[0] = Builder.CreateShuffleVector(Ops[0], Ops[0], ArrayRef{0, 1}); } else if (NumElts >= 8) { SmallVector ConcatMask(NumElts); unsigned SubElts = Ops[0]->getType()->getVectorNumElements(); diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 12fb8e9e96f5..6b1824048f75 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -642,12 +642,12 @@ static Instruction *shrinkSplatShuffle(TruncInst &Trunc, InstCombiner::BuilderTy &Builder) { auto *Shuf = dyn_cast(Trunc.getOperand(0)); if (Shuf && Shuf->hasOneUse() && isa(Shuf->getOperand(1)) && - Shuf->getMask()->getSplatValue() && + is_splat(Shuf->getShuffleMask()) && Shuf->getType() == Shuf->getOperand(0)->getType()) { // trunc (shuf X, Undef, SplatMask) --> shuf (trunc X), Undef, SplatMask Constant *NarrowUndef = UndefValue::get(Trunc.getType()); Value *NarrowOp = Builder.CreateTrunc(Shuf->getOperand(0), Trunc.getType()); - return new ShuffleVectorInst(NarrowOp, NarrowUndef, Shuf->getMask()); + return new ShuffleVectorInst(NarrowOp, NarrowUndef, Shuf->getShuffleMask()); } return nullptr; @@ -2553,7 +2553,7 @@ Instruction *InstCombiner::visitBitCast(BitCastInst &CI) { Value *RHS = Builder.CreateBitCast(ShufOp1, DestTy); // Return a new shuffle vector. Use the same element ID's, as we // know the vector types match #elts. - return new ShuffleVectorInst(LHS, RHS, Shuf->getOperand(2)); + return new ShuffleVectorInst(LHS, RHS, Shuf->getShuffleMask()); } } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index c8276c759180..e2c53ae0b31d 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2814,11 +2814,10 @@ static Instruction *foldICmpBitCast(ICmpInst &Cmp, return nullptr; Value *Vec; - Constant *Mask; - if (match(BCSrcOp, - m_ShuffleVector(m_Value(Vec), m_Undef(), m_Constant(Mask)))) { + ArrayRef Mask; + if (match(BCSrcOp, m_ShuffleVector(m_Value(Vec), m_Undef(), m_Mask(Mask)))) { // Check whether every element of Mask is the same constant - if (auto *Elem = dyn_cast_or_null(Mask->getSplatValue())) { + if (is_splat(Mask)) { auto *VecTy = cast(BCSrcOp->getType()); auto *EltTy = cast(VecTy->getElementType()); if (C->isSplat(EltTy->getBitWidth())) { @@ -2827,6 +2826,7 @@ static Instruction *foldICmpBitCast(ICmpInst &Cmp, // then: // => %E = extractelement %vec, i32 Elem // icmp iK %SplatVal, + Value *Elem = Builder.getInt32(Mask[0]); Value *Extract = Builder.CreateExtractElement(Vec, Elem); Value *NewC = ConstantInt::get(EltTy, C->trunc(EltTy->getBitWidth())); return new ICmpInst(Pred, Extract, NewC); @@ -5380,15 +5380,15 @@ static Instruction *foldVectorCmp(CmpInst &Cmp, bool IsFP = isa(Cmp); Value *V1, *V2; - Constant *M; - if (!match(LHS, m_ShuffleVector(m_Value(V1), m_Undef(), m_Constant(M)))) + ArrayRef M; + if (!match(LHS, m_ShuffleVector(m_Value(V1), m_Undef(), m_Mask(M)))) return nullptr; // If both arguments of the cmp are shuffles that use the same mask and // shuffle within a single vector, move the shuffle after the cmp: // cmp (shuffle V1, M), (shuffle V2, M) --> shuffle (cmp V1, V2), M Type *V1Ty = V1->getType(); - if (match(RHS, m_ShuffleVector(m_Value(V2), m_Undef(), m_Specific(M))) && + if (match(RHS, m_ShuffleVector(m_Value(V2), m_Undef(), m_SpecificMask(M))) && V1Ty == V2->getType() && (LHS->hasOneUse() || RHS->hasOneUse())) { Value *NewCmp = IsFP ? Builder.CreateFCmp(Pred, V1, V2) : Builder.CreateICmp(Pred, V1, V2); @@ -5405,16 +5405,16 @@ static Instruction *foldVectorCmp(CmpInst &Cmp, // Length-changing splats are ok, so adjust the constants as needed: // cmp (shuffle V1, M), C --> shuffle (cmp V1, C'), M Constant *ScalarC = C->getSplatValue(/* AllowUndefs */ true); - Constant *ScalarM = M->getSplatValue(/* AllowUndefs */ true); - if (ScalarC && ScalarM) { + int MaskSplatIndex; + if (ScalarC && match(M, m_SplatOrUndefMask(MaskSplatIndex))) { // We allow undefs in matching, but this transform removes those for safety. // Demanded elements analysis should be able to recover some/all of that. C = ConstantVector::getSplat(V1Ty->getVectorElementCount(), ScalarC); - M = ConstantVector::getSplat(M->getType()->getVectorElementCount(), - ScalarM); + SmallVector NewM(M.size(), MaskSplatIndex); Value *NewCmp = IsFP ? Builder.CreateFCmp(Pred, V1, C) : Builder.CreateICmp(Pred, V1, C); - return new ShuffleVectorInst(NewCmp, UndefValue::get(NewCmp->getType()), M); + return new ShuffleVectorInst(NewCmp, UndefValue::get(NewCmp->getType()), + NewM); } return nullptr; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 90b00536b471..6edf11ae6655 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -1389,7 +1389,7 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, Shuffle->getOperand(0)->getType()->getVectorNumElements(); // Handle trivial case of a splat. Only check the first element of LHS // operand. - if (isa(Shuffle->getMask()) && + if (all_of(Shuffle->getShuffleMask(), [](int Elt) { return Elt == 0; }) && DemandedElts.isAllOnesValue()) { if (!isa(I->getOperand(1))) { I->setOperand(1, UndefValue::get(I->getOperand(1)->getType())); @@ -1518,15 +1518,14 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts, } if (NewUndefElts) { // Add additional discovered undefs. - SmallVector Elts; + SmallVector Elts; for (unsigned i = 0; i < VWidth; ++i) { if (UndefElts[i]) - Elts.push_back(UndefValue::get(Type::getInt32Ty(I->getContext()))); + Elts.push_back(UndefMaskElem); else - Elts.push_back(ConstantInt::get(Type::getInt32Ty(I->getContext()), - Shuffle->getMaskValue(i))); + Elts.push_back(Shuffle->getMaskValue(i)); } - I->setOperand(2, ConstantVector::get(Elts)); + Shuffle->setShuffleMask(Elts); MadeChange = true; } break; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index b866f44779eb..2d72696ee531 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -730,7 +730,7 @@ Instruction *InstCombiner::visitInsertValueInst(InsertValueInst &I) { } static bool isShuffleEquivalentToSelect(ShuffleVectorInst &Shuf) { - int MaskSize = Shuf.getMask()->getType()->getVectorNumElements(); + int MaskSize = Shuf.getShuffleMask().size(); int VecSize = Shuf.getOperand(0)->getType()->getVectorNumElements(); // A vector select does not change the size of the operands. @@ -842,13 +842,10 @@ static Instruction *foldInsEltIntoSplat(InsertElementInst &InsElt) { // inselt (shuf (inselt undef, X, 0), undef, <0,undef,0,undef>), X, 1 // --> shuf (inselt undef, X, 0), undef, <0,0,0,undef> unsigned NumMaskElts = Shuf->getType()->getVectorNumElements(); - SmallVector NewMaskVec(NumMaskElts); - Type *I32Ty = IntegerType::getInt32Ty(Shuf->getContext()); - Constant *Zero = ConstantInt::getNullValue(I32Ty); + SmallVector NewMask(NumMaskElts); for (unsigned i = 0; i != NumMaskElts; ++i) - NewMaskVec[i] = i == IdxC ? Zero : Shuf->getMask()->getAggregateElement(i); + NewMask[i] = i == IdxC ? 0 : Shuf->getMaskValue(i); - Constant *NewMask = ConstantVector::get(NewMaskVec); return new ShuffleVectorInst(Op0, UndefValue::get(Op0->getType()), NewMask); } @@ -878,26 +875,23 @@ static Instruction *foldInsEltIntoIdentityShuffle(InsertElementInst &InsElt) { // For example: // inselt (shuf X, IdMask), (extelt X, IdxC), IdxC --> shuf X, IdMask' unsigned NumMaskElts = Shuf->getType()->getVectorNumElements(); - SmallVector NewMaskVec(NumMaskElts); - Type *I32Ty = IntegerType::getInt32Ty(Shuf->getContext()); - Constant *NewMaskEltC = ConstantInt::get(I32Ty, IdxC); - Constant *OldMask = Shuf->getMask(); + SmallVector NewMask(NumMaskElts); + ArrayRef OldMask = Shuf->getShuffleMask(); for (unsigned i = 0; i != NumMaskElts; ++i) { if (i != IdxC) { // All mask elements besides the inserted element remain the same. - NewMaskVec[i] = OldMask->getAggregateElement(i); - } else if (OldMask->getAggregateElement(i) == NewMaskEltC) { + NewMask[i] = OldMask[i]; + } else if (OldMask[i] == (int)IdxC) { // If the mask element was already set, there's nothing to do // (demanded elements analysis may unset it later). return nullptr; } else { - assert(isa(OldMask->getAggregateElement(i)) && + assert(OldMask[i] == UndefMaskElem && "Unexpected shuffle mask element for identity shuffle"); - NewMaskVec[i] = NewMaskEltC; + NewMask[i] = IdxC; } } - Constant *NewMask = ConstantVector::get(NewMaskVec); return new ShuffleVectorInst(X, Shuf->getOperand(1), NewMask); } @@ -965,27 +959,25 @@ static Instruction *foldConstantInsEltIntoShuffle(InsertElementInst &InsElt) { // mask vector with the insertelt index plus the length of the vector // (because the constant vector operand of a shuffle is always the 2nd // operand). - Constant *Mask = Shuf->getMask(); - unsigned NumElts = Mask->getType()->getVectorNumElements(); + ArrayRef Mask = Shuf->getShuffleMask(); + unsigned NumElts = Mask.size(); SmallVector NewShufElts(NumElts); - SmallVector NewMaskElts(NumElts); + SmallVector NewMaskElts(NumElts); for (unsigned I = 0; I != NumElts; ++I) { if (I == InsEltIndex) { NewShufElts[I] = InsEltScalar; - Type *Int32Ty = Type::getInt32Ty(Shuf->getContext()); - NewMaskElts[I] = ConstantInt::get(Int32Ty, InsEltIndex + NumElts); + NewMaskElts[I] = InsEltIndex + NumElts; } else { // Copy over the existing values. NewShufElts[I] = ShufConstVec->getAggregateElement(I); - NewMaskElts[I] = Mask->getAggregateElement(I); + NewMaskElts[I] = Mask[I]; } } // Create new operands for a shuffle that includes the constant of the // original insertelt. The old shuffle will be dead now. return new ShuffleVectorInst(Shuf->getOperand(0), - ConstantVector::get(NewShufElts), - ConstantVector::get(NewMaskElts)); + ConstantVector::get(NewShufElts), NewMaskElts); } else if (auto *IEI = dyn_cast(Inst)) { // Transform sequences of insertelements ops with constant data/indexes into // a single shuffle op. @@ -1305,17 +1297,9 @@ static Value *evaluateInDifferentElementOrder(Value *V, ArrayRef Mask) { if (isa(V)) return ConstantAggregateZero::get(VectorType::get(EltTy, Mask.size())); - if (Constant *C = dyn_cast(V)) { - SmallVector MaskValues; - for (int i = 0, e = Mask.size(); i != e; ++i) { - if (Mask[i] == -1) - MaskValues.push_back(UndefValue::get(I32Ty)); - else - MaskValues.push_back(ConstantInt::get(I32Ty, Mask[i])); - } + if (Constant *C = dyn_cast(V)) return ConstantExpr::getShuffleVector(C, UndefValue::get(C->getType()), - ConstantVector::get(MaskValues)); - } + Mask); Instruction *I = cast(V); switch (I->getOpcode()) { @@ -1404,7 +1388,7 @@ static Value *evaluateInDifferentElementOrder(Value *V, ArrayRef Mask) { // Shuffles to: |EE|FF|GG|HH| // +--+--+--+--+ static bool isShuffleExtractingFromLHS(ShuffleVectorInst &SVI, - SmallVector &Mask) { + ArrayRef Mask) { unsigned LHSElems = SVI.getOperand(0)->getType()->getVectorNumElements(); unsigned MaskElems = Mask.size(); unsigned BegIdx = Mask.front(); @@ -1487,12 +1471,12 @@ static Instruction *foldSelectShuffleWith1Binop(ShuffleVectorInst &Shuf) { // Example: shuf (mul X, {-1,-2,-3,-4}), X, {0,5,6,3} --> mul X, {-1,1,1,-4} // Example: shuf X, (add X, {-1,-2,-3,-4}), {0,1,6,7} --> add X, {0,0,-3,-4} // The existing binop constant vector remains in the same operand position. - Constant *Mask = Shuf.getMask(); + ArrayRef Mask = Shuf.getShuffleMask(); Constant *NewC = Op0IsBinop ? ConstantExpr::getShuffleVector(C, IdC, Mask) : ConstantExpr::getShuffleVector(IdC, C, Mask); bool MightCreatePoisonOrUB = - Mask->containsUndefElement() && + is_contained(Mask, UndefMaskElem) && (Instruction::isIntDivRem(BOpcode) || Instruction::isShift(BOpcode)); if (MightCreatePoisonOrUB) NewC = getSafeVectorConstantForBinop(BOpcode, NewC, true); @@ -1506,7 +1490,7 @@ static Instruction *foldSelectShuffleWith1Binop(ShuffleVectorInst &Shuf) { // An undef shuffle mask element may propagate as an undef constant element in // the new binop. That would produce poison where the original code might not. // If we already made a safe constant, then there's no danger. - if (Mask->containsUndefElement() && !MightCreatePoisonOrUB) + if (is_contained(Mask, UndefMaskElem) && !MightCreatePoisonOrUB) NewBO->dropPoisonGeneratingFlags(); return NewBO; } @@ -1518,14 +1502,14 @@ static Instruction *foldSelectShuffleWith1Binop(ShuffleVectorInst &Shuf) { static Instruction *canonicalizeInsertSplat(ShuffleVectorInst &Shuf, InstCombiner::BuilderTy &Builder) { Value *Op0 = Shuf.getOperand(0), *Op1 = Shuf.getOperand(1); - Constant *Mask = Shuf.getMask(); + ArrayRef Mask = Shuf.getShuffleMask(); Value *X; uint64_t IndexC; // Match a shuffle that is a splat to a non-zero element. if (!match(Op0, m_OneUse(m_InsertElement(m_Undef(), m_Value(X), m_ConstantInt(IndexC)))) || - !match(Op1, m_Undef()) || match(Mask, m_ZeroInt()) || IndexC == 0) + !match(Op1, m_Undef()) || match(Mask, m_ZeroMask()) || IndexC == 0) return nullptr; // Insert into element 0 of an undef vector. @@ -1538,12 +1522,12 @@ static Instruction *canonicalizeInsertSplat(ShuffleVectorInst &Shuf, // shuf (inselt undef, X, 2), undef, <2,2,undef> // --> shuf (inselt undef, X, 0), undef, <0,0,undef> unsigned NumMaskElts = Shuf.getType()->getVectorNumElements(); - SmallVector NewMask(NumMaskElts, Zero); + SmallVector NewMask(NumMaskElts, 0); for (unsigned i = 0; i != NumMaskElts; ++i) - if (isa(Mask->getAggregateElement(i))) - NewMask[i] = Mask->getAggregateElement(i); + if (Mask[i] == UndefMaskElem) + NewMask[i] = Mask[i]; - return new ShuffleVectorInst(NewIns, UndefVec, ConstantVector::get(NewMask)); + return new ShuffleVectorInst(NewIns, UndefVec, NewMask); } /// Try to fold shuffles that are the equivalent of a vector select. @@ -1612,14 +1596,14 @@ static Instruction *foldSelectShuffle(ShuffleVectorInst &Shuf, BinaryOperator::BinaryOps BOpc = Opc0; // Select the constant elements needed for the single binop. - Constant *Mask = Shuf.getMask(); + ArrayRef Mask = Shuf.getShuffleMask(); Constant *NewC = ConstantExpr::getShuffleVector(C0, C1, Mask); // We are moving a binop after a shuffle. When a shuffle has an undefined // mask element, the result is undefined, but it is not poison or undefined // behavior. That is not necessarily true for div/rem/shift. bool MightCreatePoisonOrUB = - Mask->containsUndefElement() && + is_contained(Mask, UndefMaskElem) && (Instruction::isIntDivRem(BOpc) || Instruction::isShift(BOpc)); if (MightCreatePoisonOrUB) NewC = getSafeVectorConstantForBinop(BOpc, NewC, ConstantsAreOp1); @@ -1668,7 +1652,7 @@ static Instruction *foldSelectShuffle(ShuffleVectorInst &Shuf, NewBO->andIRFlags(B1); if (DropNSW) NewBO->setHasNoSignedWrap(false); - if (Mask->containsUndefElement() && !MightCreatePoisonOrUB) + if (is_contained(Mask, UndefMaskElem) && !MightCreatePoisonOrUB) NewBO->dropPoisonGeneratingFlags(); return NewBO; } @@ -1694,8 +1678,7 @@ static Instruction *narrowVectorSelect(ShuffleVectorInst &Shuf, // and have the same number of elements as this shuffle. unsigned NarrowNumElts = Shuf.getType()->getVectorNumElements(); Value *NarrowCond; - if (!match(Cond, m_OneUse(m_ShuffleVector(m_Value(NarrowCond), m_Undef(), - m_Constant()))) || + if (!match(Cond, m_OneUse(m_ShuffleVector(m_Value(NarrowCond), m_Undef()))) || NarrowCond->getType()->getVectorNumElements() != NarrowNumElts || !cast(Cond)->isIdentityWithPadding()) return nullptr; @@ -1703,8 +1686,8 @@ static Instruction *narrowVectorSelect(ShuffleVectorInst &Shuf, // shuf (sel (shuf NarrowCond, undef, WideMask), X, Y), undef, NarrowMask) --> // sel NarrowCond, (shuf X, undef, NarrowMask), (shuf Y, undef, NarrowMask) Value *Undef = UndefValue::get(X->getType()); - Value *NarrowX = Builder.CreateShuffleVector(X, Undef, Shuf.getMask()); - Value *NarrowY = Builder.CreateShuffleVector(Y, Undef, Shuf.getMask()); + Value *NarrowX = Builder.CreateShuffleVector(X, Undef, Shuf.getShuffleMask()); + Value *NarrowY = Builder.CreateShuffleVector(Y, Undef, Shuf.getShuffleMask()); return SelectInst::Create(NarrowCond, NarrowX, NarrowY); } @@ -1715,8 +1698,8 @@ static Instruction *foldIdentityExtractShuffle(ShuffleVectorInst &Shuf) { return nullptr; Value *X, *Y; - Constant *Mask; - if (!match(Op0, m_ShuffleVector(m_Value(X), m_Value(Y), m_Constant(Mask)))) + ArrayRef Mask; + if (!match(Op0, m_ShuffleVector(m_Value(X), m_Value(Y), m_Mask(Mask)))) return nullptr; // Be conservative with shuffle transforms. If we can't kill the 1st shuffle, @@ -1736,16 +1719,16 @@ static Instruction *foldIdentityExtractShuffle(ShuffleVectorInst &Shuf) { // shuf (shuf X, Y, ), undef, <0, undef, 2, 3> --> // shuf X, Y, unsigned NumElts = Shuf.getType()->getVectorNumElements(); - SmallVector NewMask(NumElts); - assert(NumElts < Mask->getType()->getVectorNumElements() && + SmallVector NewMask(NumElts); + assert(NumElts < Mask.size() && "Identity with extract must have less elements than its inputs"); for (unsigned i = 0; i != NumElts; ++i) { - Constant *ExtractMaskElt = Shuf.getMask()->getAggregateElement(i); - Constant *MaskElt = Mask->getAggregateElement(i); - NewMask[i] = isa(ExtractMaskElt) ? ExtractMaskElt : MaskElt; + int ExtractMaskElt = Shuf.getMaskValue(i); + int MaskElt = Mask[i]; + NewMask[i] = ExtractMaskElt == UndefMaskElem ? ExtractMaskElt : MaskElt; } - return new ShuffleVectorInst(X, Y, ConstantVector::get(NewMask)); + return new ShuffleVectorInst(X, Y, NewMask); } /// Try to replace a shuffle with an insertelement or try to replace a shuffle @@ -1753,7 +1736,8 @@ static Instruction *foldIdentityExtractShuffle(ShuffleVectorInst &Shuf) { static Instruction *foldShuffleWithInsert(ShuffleVectorInst &Shuf, InstCombiner &IC) { Value *V0 = Shuf.getOperand(0), *V1 = Shuf.getOperand(1); - SmallVector Mask = Shuf.getShuffleMask(); + SmallVector Mask; + Shuf.getShuffleMask(Mask); // The shuffle must not change vector sizes. // TODO: This restriction could be removed if the insert has only one use @@ -1872,7 +1856,7 @@ static Instruction *foldIdentityPaddedShuffles(ShuffleVectorInst &Shuf) { assert(WideElts > NarrowElts && "Unexpected types for identity with padding"); Type *I32Ty = IntegerType::getInt32Ty(Shuf.getContext()); - SmallVector Mask = Shuf.getShuffleMask(); + ArrayRef Mask = Shuf.getShuffleMask(); SmallVector NewMask(Mask.size(), UndefValue::get(I32Ty)); for (int i = 0, e = Mask.size(); i != e; ++i) { if (Mask[i] == -1) @@ -1905,28 +1889,28 @@ static Instruction *foldIdentityPaddedShuffles(ShuffleVectorInst &Shuf) { Instruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) { Value *LHS = SVI.getOperand(0); Value *RHS = SVI.getOperand(1); - if (auto *V = SimplifyShuffleVectorInst( - LHS, RHS, SVI.getMask(), SVI.getType(), SQ.getWithInstruction(&SVI))) + if (auto *V = + SimplifyShuffleVectorInst(LHS, RHS, SVI.getShuffleMask(), + SVI.getType(), SQ.getWithInstruction(&SVI))) return replaceInstUsesWith(SVI, V); // shuffle x, x, mask --> shuffle x, undef, mask' unsigned VWidth = SVI.getType()->getVectorNumElements(); unsigned LHSWidth = LHS->getType()->getVectorNumElements(); - SmallVector Mask = SVI.getShuffleMask(); + ArrayRef Mask = SVI.getShuffleMask(); Type *Int32Ty = Type::getInt32Ty(SVI.getContext()); if (LHS == RHS) { assert(!isa(RHS) && "Shuffle with 2 undef ops not simplified?"); // Remap any references to RHS to use LHS. - SmallVector Elts; + SmallVector Elts; for (unsigned i = 0; i != VWidth; ++i) { // Propagate undef elements or force mask to LHS. if (Mask[i] < 0) - Elts.push_back(UndefValue::get(Int32Ty)); + Elts.push_back(UndefMaskElem); else - Elts.push_back(ConstantInt::get(Int32Ty, Mask[i] % LHSWidth)); + Elts.push_back(Mask[i] % LHSWidth); } - return new ShuffleVectorInst(LHS, UndefValue::get(RHS->getType()), - ConstantVector::get(Elts)); + return new ShuffleVectorInst(LHS, UndefValue::get(RHS->getType()), Elts); } // shuffle undef, x, mask --> shuffle x, undef, mask' @@ -2151,8 +2135,8 @@ Instruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) { if (newLHS == LHS && newRHS == RHS) return MadeChange ? &SVI : nullptr; - SmallVector LHSMask; - SmallVector RHSMask; + ArrayRef LHSMask; + ArrayRef RHSMask; if (newLHS != LHS) LHSMask = LHSShuffle->getShuffleMask(); if (RHSShuffle && newRHS != RHS) diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 68797662f45e..23370cf21f07 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1534,9 +1534,10 @@ Instruction *InstCombiner::foldVectorBinop(BinaryOperator &Inst) { // narrow binop on each pair of the source operands followed by concatenation // of the results. Value *L0, *L1, *R0, *R1; - Constant *Mask; - if (match(LHS, m_ShuffleVector(m_Value(L0), m_Value(L1), m_Constant(Mask))) && - match(RHS, m_ShuffleVector(m_Value(R0), m_Value(R1), m_Specific(Mask))) && + ArrayRef Mask; + if (match(LHS, m_ShuffleVector(m_Value(L0), m_Value(L1), m_Mask(Mask))) && + match(RHS, + m_ShuffleVector(m_Value(R0), m_Value(R1), m_SpecificMask(Mask))) && LHS->hasOneUse() && RHS->hasOneUse() && cast(LHS)->isConcat() && cast(RHS)->isConcat()) { @@ -1560,7 +1561,7 @@ Instruction *InstCombiner::foldVectorBinop(BinaryOperator &Inst) { if (!isSafeToSpeculativelyExecute(&Inst)) return nullptr; - auto createBinOpShuffle = [&](Value *X, Value *Y, Constant *M) { + auto createBinOpShuffle = [&](Value *X, Value *Y, ArrayRef M) { Value *XY = Builder.CreateBinOp(Opcode, X, Y); if (auto *BO = dyn_cast(XY)) BO->copyIRFlags(&Inst); @@ -1570,8 +1571,9 @@ Instruction *InstCombiner::foldVectorBinop(BinaryOperator &Inst) { // If both arguments of the binary operation are shuffles that use the same // mask and shuffle within a single vector, move the shuffle after the binop. Value *V1, *V2; - if (match(LHS, m_ShuffleVector(m_Value(V1), m_Undef(), m_Constant(Mask))) && - match(RHS, m_ShuffleVector(m_Value(V2), m_Undef(), m_Specific(Mask))) && + if (match(LHS, m_ShuffleVector(m_Value(V1), m_Undef(), m_Mask(Mask))) && + match(RHS, + m_ShuffleVector(m_Value(V2), m_Undef(), m_SpecificMask(Mask))) && V1->getType() == V2->getType() && (LHS->hasOneUse() || RHS->hasOneUse() || LHS == RHS)) { // Op(shuffle(V1, Mask), shuffle(V2, Mask)) -> shuffle(Op(V1, V2), Mask) @@ -1581,17 +1583,19 @@ Instruction *InstCombiner::foldVectorBinop(BinaryOperator &Inst) { // If both arguments of a commutative binop are select-shuffles that use the // same mask with commuted operands, the shuffles are unnecessary. if (Inst.isCommutative() && - match(LHS, m_ShuffleVector(m_Value(V1), m_Value(V2), m_Constant(Mask))) && + match(LHS, m_ShuffleVector(m_Value(V1), m_Value(V2), m_Mask(Mask))) && match(RHS, m_ShuffleVector(m_Specific(V2), m_Specific(V1), - m_Specific(Mask)))) { + m_SpecificMask(Mask)))) { auto *LShuf = cast(LHS); auto *RShuf = cast(RHS); // TODO: Allow shuffles that contain undefs in the mask? // That is legal, but it reduces undef knowledge. // TODO: Allow arbitrary shuffles by shuffling after binop? // That might be legal, but we have to deal with poison. - if (LShuf->isSelect() && !LShuf->getMask()->containsUndefElement() && - RShuf->isSelect() && !RShuf->getMask()->containsUndefElement()) { + if (LShuf->isSelect() && + !is_contained(LShuf->getShuffleMask(), UndefMaskElem) && + RShuf->isSelect() && + !is_contained(RShuf->getShuffleMask(), UndefMaskElem)) { // Example: // LHS = shuffle V1, V2, <0, 5, 6, 3> // RHS = shuffle V2, V1, <0, 5, 6, 3> @@ -1608,9 +1612,9 @@ Instruction *InstCombiner::foldVectorBinop(BinaryOperator &Inst) { // other binops, so they can be folded. It may also enable demanded elements // transforms. Constant *C; - if (match(&Inst, m_c_BinOp( - m_OneUse(m_ShuffleVector(m_Value(V1), m_Undef(), m_Constant(Mask))), - m_Constant(C))) && + if (match(&Inst, m_c_BinOp(m_OneUse(m_ShuffleVector(m_Value(V1), m_Undef(), + m_Mask(Mask))), + m_Constant(C))) && V1->getType()->getVectorNumElements() <= NumElts) { assert(Inst.getType()->getScalarType() == V1->getType()->getScalarType() && "Shuffle should not change scalar type"); @@ -1621,8 +1625,7 @@ Instruction *InstCombiner::foldVectorBinop(BinaryOperator &Inst) { // reorder is not possible. A 1-to-1 mapping is not required. Example: // ShMask = <1,1,2,2> and C = <5,5,6,6> --> NewC = bool ConstOp1 = isa(RHS); - SmallVector ShMask; - ShuffleVectorInst::getShuffleMask(Mask, ShMask); + ArrayRef ShMask = Mask; unsigned SrcVecNumElts = V1->getType()->getVectorNumElements(); UndefValue *UndefScalar = UndefValue::get(C->getType()->getScalarType()); SmallVector NewVecC(SrcVecNumElts, UndefScalar); @@ -1687,12 +1690,12 @@ Instruction *InstCombiner::foldVectorBinop(BinaryOperator &Inst) { std::swap(LHS, RHS); Value *X; - Constant *MaskC; - const APInt *SplatIndex; + ArrayRef MaskC; + int SplatIndex; BinaryOperator *BO; if (!match(LHS, m_OneUse(m_ShuffleVector(m_Value(X), m_Undef(), - m_Constant(MaskC)))) || - !match(MaskC, m_APIntAllowUndef(SplatIndex)) || + m_Mask(MaskC)))) || + !match(MaskC, m_SplatOrUndefMask(SplatIndex)) || X->getType() != Inst.getType() || !match(RHS, m_OneUse(m_BinOp(BO))) || BO->getOpcode() != Opcode) return nullptr; @@ -1701,10 +1704,10 @@ Instruction *InstCombiner::foldVectorBinop(BinaryOperator &Inst) { // moving 'Y' before the splat shuffle, we are implicitly assuming // that it is not undef/poison at the splat index. Value *Y, *OtherOp; - if (isSplatValue(BO->getOperand(0), SplatIndex->getZExtValue())) { + if (isSplatValue(BO->getOperand(0), SplatIndex)) { Y = BO->getOperand(0); OtherOp = BO->getOperand(1); - } else if (isSplatValue(BO->getOperand(1), SplatIndex->getZExtValue())) { + } else if (isSplatValue(BO->getOperand(1), SplatIndex)) { Y = BO->getOperand(1); OtherOp = BO->getOperand(0); } else { @@ -1716,7 +1719,7 @@ Instruction *InstCombiner::foldVectorBinop(BinaryOperator &Inst) { // bo (splat X), (bo Y, OtherOp) --> bo (splat (bo X, Y)), OtherOp Value *NewBO = Builder.CreateBinOp(Opcode, X, Y); UndefValue *Undef = UndefValue::get(Inst.getType()); - Constant *NewMask = ConstantInt::get(MaskC->getType(), *SplatIndex); + SmallVector NewMask(MaskC.size(), SplatIndex); Value *NewSplat = Builder.CreateShuffleVector(NewBO, Undef, NewMask); Instruction *R = BinaryOperator::Create(Opcode, NewSplat, OtherOp); diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index dd892921b62b..ea6156f4c56d 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -1867,10 +1867,9 @@ struct MemorySanitizerVisitor : public InstVisitor { } void visitShuffleVectorInst(ShuffleVectorInst &I) { - insertShadowCheck(I.getOperand(2), &I); IRBuilder<> IRB(&I); setShadow(&I, IRB.CreateShuffleVector(getShadow(&I, 0), getShadow(&I, 1), - I.getOperand(2), "_msprop")); + I.getShuffleMask(), "_msprop")); setOriginForNaryOp(I); } diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index 6b9792aa77b0..d831b0da37a5 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -289,7 +289,7 @@ GVN::Expression GVN::ValueTable::createExpr(Instruction *I) { e.commutative = true; } - if (CmpInst *C = dyn_cast(I)) { + if (auto *C = dyn_cast(I)) { // Sort the operand value numbers so xx get the same value number. CmpInst::Predicate Predicate = C->getPredicate(); if (e.varargs[0] > e.varargs[1]) { @@ -298,10 +298,11 @@ GVN::Expression GVN::ValueTable::createExpr(Instruction *I) { } e.opcode = (C->getOpcode() << 8) | Predicate; e.commutative = true; - } else if (InsertValueInst *E = dyn_cast(I)) { - for (InsertValueInst::idx_iterator II = E->idx_begin(), IE = E->idx_end(); - II != IE; ++II) - e.varargs.push_back(*II); + } else if (auto *E = dyn_cast(I)) { + e.varargs.append(E->idx_begin(), E->idx_end()); + } else if (auto *SVI = dyn_cast(I)) { + ArrayRef ShuffleMask = SVI->getShuffleMask(); + e.varargs.append(ShuffleMask.begin(), ShuffleMask.end()); } return e; @@ -1732,7 +1733,8 @@ uint32_t GVN::ValueTable::phiTranslateImpl(const BasicBlock *Pred, // instead of value numbers. Those index numbers should not be // translated. if ((i > 1 && Exp.opcode == Instruction::InsertValue) || - (i > 0 && Exp.opcode == Instruction::ExtractValue)) + (i > 0 && Exp.opcode == Instruction::ExtractValue) || + (i > 1 && Exp.opcode == Instruction::ShuffleVector)) continue; Exp.varargs[i] = phiTranslate(Pred, PhiBlock, Exp.varargs[i], Gvn); } diff --git a/llvm/lib/Transforms/Scalar/GVNSink.cpp b/llvm/lib/Transforms/Scalar/GVNSink.cpp index 6b9a88d04eda..d0b96218137c 100644 --- a/llvm/lib/Transforms/Scalar/GVNSink.cpp +++ b/llvm/lib/Transforms/Scalar/GVNSink.cpp @@ -350,6 +350,7 @@ using ModelledPHISet = DenseSet>; class InstructionUseExpr : public GVNExpression::BasicExpression { unsigned MemoryUseOrder = -1; bool Volatile = false; + std::vector ShuffleMask; public: InstructionUseExpr(Instruction *I, ArrayRecycler &R, @@ -366,15 +367,18 @@ class InstructionUseExpr : public GVNExpression::BasicExpression { void setMemoryUseOrder(unsigned MUO) { MemoryUseOrder = MUO; } void setVolatile(bool V) { Volatile = V; } + void setShuffleMask(ArrayRef Mask) { + ShuffleMask.assign(Mask.begin(), Mask.end()); + } hash_code getHashValue() const override { return hash_combine(GVNExpression::BasicExpression::getHashValue(), - MemoryUseOrder, Volatile); + MemoryUseOrder, Volatile, ArrayRef(ShuffleMask)); } template hash_code getHashValue(Function MapFn) { - hash_code H = - hash_combine(getOpcode(), getType(), MemoryUseOrder, Volatile); + hash_code H = hash_combine(getOpcode(), getType(), MemoryUseOrder, Volatile, + ArrayRef(ShuffleMask)); for (auto *V : operands()) H = hash_combine(H, MapFn(V)); return H; @@ -402,6 +406,8 @@ class ValueTable { CmpInst::Predicate Predicate = C->getPredicate(); E->setOpcode((C->getOpcode() << 8) | Predicate); } + if (ShuffleVectorInst *SVI = dyn_cast(I)) + E->setShuffleMask(SVI->getShuffleMask()); return E; } diff --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp index 6a643480f312..17b2c534513d 100644 --- a/llvm/lib/Transforms/Scalar/NewGVN.cpp +++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp @@ -2030,10 +2030,12 @@ NewGVN::performSymbolicEvaluation(Value *V, case Instruction::Select: case Instruction::ExtractElement: case Instruction::InsertElement: - case Instruction::ShuffleVector: case Instruction::GetElementPtr: E = createExpression(I); break; + case Instruction::ShuffleVector: + // FIXME: Add support for shufflevector to createExpression. + return nullptr; default: return nullptr; } diff --git a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp index fe344ce5f8db..b8b98d673334 100644 --- a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp +++ b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp @@ -1009,7 +1009,7 @@ static Value *findBasePointer(Value *I, DefiningValueMapTy &Cache) { auto *SV = cast(I); UndefValue *VecUndef = UndefValue::get(SV->getOperand(0)->getType()); std::string Name = suffixed_name_or(I, ".base", "base_sv"); - return new ShuffleVectorInst(VecUndef, VecUndef, SV->getOperand(2), + return new ShuffleVectorInst(VecUndef, VecUndef, SV->getShuffleMask(), Name, SV); } }; diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 3a89fd829384..af51dea002da 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -3405,7 +3405,7 @@ void InnerLoopVectorizer::truncateToMinimalBitwidths() { auto *O1 = B.CreateZExtOrTrunc( SI->getOperand(1), VectorType::get(ScalarTruncatedTy, Elements1)); - NewI = B.CreateShuffleVector(O0, O1, SI->getMask()); + NewI = B.CreateShuffleVector(O0, O1, SI->getShuffleMask()); } else if (isa(I) || isa(I)) { // Don't do anything with the operands, just extend the result. continue; diff --git a/llvm/unittests/IR/PatternMatch.cpp b/llvm/unittests/IR/PatternMatch.cpp index cb11d1ec71f2..186746bca791 100644 --- a/llvm/unittests/IR/PatternMatch.cpp +++ b/llvm/unittests/IR/PatternMatch.cpp @@ -991,31 +991,32 @@ TEST_F(PatternMatchTest, VectorOps) { EXPECT_TRUE(match(EX3, m_ExtractElement(m_Constant(), m_ConstantInt()))); // Test matching shufflevector - EXPECT_TRUE(match(SI1, m_ShuffleVector(m_Value(), m_Undef(), m_Zero()))); - EXPECT_TRUE(match(SI2, m_ShuffleVector(m_Value(A), m_Value(B), m_Value(C)))); + ArrayRef Mask; + EXPECT_TRUE(match(SI1, m_ShuffleVector(m_Value(), m_Undef(), m_ZeroMask()))); + EXPECT_TRUE( + match(SI2, m_ShuffleVector(m_Value(A), m_Value(B), m_Mask(Mask)))); EXPECT_TRUE(A == VI3); EXPECT_TRUE(B == VI4); - EXPECT_TRUE(C == IdxVec); A = B = C = nullptr; // reset // Test matching the vector splat pattern EXPECT_TRUE(match( SI1, m_ShuffleVector(m_InsertElement(m_Undef(), m_SpecificInt(1), m_Zero()), - m_Undef(), m_Zero()))); + m_Undef(), m_ZeroMask()))); EXPECT_FALSE(match( SI3, m_ShuffleVector(m_InsertElement(m_Undef(), m_Value(), m_Zero()), - m_Undef(), m_Zero()))); + m_Undef(), m_ZeroMask()))); EXPECT_FALSE(match( SI4, m_ShuffleVector(m_InsertElement(m_Undef(), m_Value(), m_Zero()), - m_Undef(), m_Zero()))); + m_Undef(), m_ZeroMask()))); EXPECT_TRUE(match( SP1, m_ShuffleVector(m_InsertElement(m_Undef(), m_SpecificInt(2), m_Zero()), - m_Undef(), m_Zero()))); + m_Undef(), m_ZeroMask()))); EXPECT_TRUE(match( SP2, m_ShuffleVector(m_InsertElement(m_Undef(), m_Value(A), m_Zero()), - m_Undef(), m_Zero()))); + m_Undef(), m_ZeroMask()))); EXPECT_TRUE(A == Val); } From cfe-commits at lists.llvm.org Tue Mar 31 13:11:09 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 20:11:09 +0000 (UTC) Subject: [PATCH] D72467: Remove "mask" operand from shufflevector. In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rG1ee6ec2bf370: Remove "mask" operand from shufflevector. (authored by efriedma). Changed prior to commit: https://reviews.llvm.org/D72467?vs=253217&id=253977#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72467/new/ https://reviews.llvm.org/D72467 Files: clang/lib/CodeGen/CGExpr.cpp llvm/include/llvm/ADT/ArrayRef.h llvm/include/llvm/Analysis/ConstantFolding.h llvm/include/llvm/Analysis/InstructionSimplify.h llvm/include/llvm/Analysis/TargetFolder.h llvm/include/llvm/IR/ConstantFolder.h llvm/include/llvm/IR/Constants.h llvm/include/llvm/IR/IRBuilder.h llvm/include/llvm/IR/IRBuilderFolder.h llvm/include/llvm/IR/Instructions.h llvm/include/llvm/IR/NoFolder.h llvm/include/llvm/IR/PatternMatch.h llvm/lib/Analysis/ConstantFolding.cpp llvm/lib/Analysis/InstructionSimplify.cpp llvm/lib/Analysis/TargetTransformInfo.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/Analysis/VectorUtils.cpp llvm/lib/AsmParser/LLParser.cpp llvm/lib/Bitcode/Reader/BitcodeReader.cpp llvm/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/lib/Bitcode/Writer/ValueEnumerator.cpp llvm/lib/CodeGen/CodeGenPrepare.cpp llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/ExecutionEngine/Interpreter/Execution.cpp llvm/lib/IR/AsmWriter.cpp llvm/lib/IR/AutoUpgrade.cpp llvm/lib/IR/ConstantFold.cpp llvm/lib/IR/ConstantFold.h llvm/lib/IR/Constants.cpp llvm/lib/IR/ConstantsContext.h llvm/lib/IR/Core.cpp llvm/lib/IR/Instruction.cpp llvm/lib/IR/Instructions.cpp llvm/lib/IR/Verifier.cpp llvm/lib/Target/AArch64/AArch64ISelLowering.cpp llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp llvm/lib/Target/ARM/ARMISelLowering.cpp llvm/lib/Target/ARM/MVETailPredication.cpp llvm/lib/Target/X86/X86PartialReduction.cpp llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp llvm/lib/Transforms/InstCombine/InstructionCombining.cpp llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp llvm/lib/Transforms/Scalar/GVN.cpp llvm/lib/Transforms/Scalar/GVNSink.cpp llvm/lib/Transforms/Scalar/NewGVN.cpp llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp llvm/lib/Transforms/Vectorize/LoopVectorize.cpp llvm/unittests/IR/PatternMatch.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D72467.253977.patch Type: text/x-patch Size: 110987 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 13:17:46 2020 From: cfe-commits at lists.llvm.org (Anna Thomas via cfe-commits) Date: Tue, 31 Mar 2020 13:17:46 -0700 (PDT) Subject: [clang] 58a0567 - Revert "[InlineFunction] Handle return attributes on call within inlined body" Message-ID: <5e83a56a.1c69fb81.5f293.4d10@mx.google.com> Author: Anna Thomas Date: 2020-03-31T16:16:34-04:00 New Revision: 58a05675daf46b2e9c336dd13ae6ac6dbfdc2c72 URL: https://github.com/llvm/llvm-project/commit/58a05675daf46b2e9c336dd13ae6ac6dbfdc2c72 DIFF: https://github.com/llvm/llvm-project/commit/58a05675daf46b2e9c336dd13ae6ac6dbfdc2c72.diff LOG: Revert "[InlineFunction] Handle return attributes on call within inlined body" This reverts commit 28518d9ae39ff5c6044e230d58b6ae28b0252cae. There is a failure in MsgPackReader.cpp when built with clang. It complains about "signext and zeroext" are incompatible. Investigating offline if it is infact a UB in the MsgPackReader code. Added: Modified: clang/test/CodeGen/builtins-systemz-zvector.c clang/test/CodeGen/builtins-systemz-zvector2.c clang/test/CodeGen/movbe-builtins.c clang/test/CodeGen/rot-intrinsics.c llvm/lib/Transforms/Utils/InlineFunction.cpp Removed: llvm/test/Transforms/Inline/ret_attr_update.ll ################################################################################ diff --git a/clang/test/CodeGen/builtins-systemz-zvector.c b/clang/test/CodeGen/builtins-systemz-zvector.c index 6cba71098792..da0e720c9fae 100644 --- a/clang/test/CodeGen/builtins-systemz-zvector.c +++ b/clang/test/CodeGen/builtins-systemz-zvector.c @@ -3665,31 +3665,31 @@ void test_integer(void) { // CHECK-ASM: vsumqg idx = vec_test_mask(vsc, vuc); - // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vuc, vuc); - // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vss, vus); - // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vus, vus); - // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vsi, vui); - // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vui, vui); - // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vsl, vul); - // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vul, vul); - // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vd, vul); - // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm } diff --git a/clang/test/CodeGen/builtins-systemz-zvector2.c b/clang/test/CodeGen/builtins-systemz-zvector2.c index 1880fed64dbc..a4f791e6019b 100644 --- a/clang/test/CodeGen/builtins-systemz-zvector2.c +++ b/clang/test/CodeGen/builtins-systemz-zvector2.c @@ -654,10 +654,10 @@ void test_integer(void) { // CHECK-ASM: vsrlb idx = vec_test_mask(vf, vui); - // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm idx = vec_test_mask(vd, vul); - // CHECK: call signext i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) + // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) // CHECK-ASM: vtm vuc = vec_msum_u128(vul, vul, vuc, 0); diff --git a/clang/test/CodeGen/movbe-builtins.c b/clang/test/CodeGen/movbe-builtins.c index 15f49b84ec67..342f66391388 100644 --- a/clang/test/CodeGen/movbe-builtins.c +++ b/clang/test/CodeGen/movbe-builtins.c @@ -7,7 +7,7 @@ short test_loadbe_i16(const short *P) { // CHECK-LABEL: @test_loadbe_i16 // CHECK: [[LOAD:%.*]] = load i16, i16* %{{.*}}, align 1 - // CHECK: call signext i16 @llvm.bswap.i16(i16 [[LOAD]]) + // CHECK: call i16 @llvm.bswap.i16(i16 [[LOAD]]) return _loadbe_i16(P); } diff --git a/clang/test/CodeGen/rot-intrinsics.c b/clang/test/CodeGen/rot-intrinsics.c index 7b1ffb6ae3a6..dcdc54c4585a 100644 --- a/clang/test/CodeGen/rot-intrinsics.c +++ b/clang/test/CodeGen/rot-intrinsics.c @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -ffreestanding -triple i686--linux -emit-llvm -mllvm -update-return-attrs=false %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -ffreestanding -triple x86_64--linux -emit-llvm -mllvm -update-return-attrs=false %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-64BIT-LONG -// RUN: %clang_cc1 -fms-extensions -fms-compatibility -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -mllvm -update-return-attrs=false -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -mllvm -update-return-attrs=false -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -mllvm -update-return-attrs=false -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG -// RUN: %clang_cc1 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -mllvm -update-return-attrs=false -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG +// RUN: %clang_cc1 -ffreestanding -triple i686--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG +// RUN: %clang_cc1 -ffreestanding -triple x86_64--linux -emit-llvm %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-64BIT-LONG +// RUN: %clang_cc1 -fms-extensions -fms-compatibility -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG +// RUN: %clang_cc1 -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG +// RUN: %clang_cc1 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=i686-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG +// RUN: %clang_cc1 -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +sse2 -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes CHECK,CHECK-32BIT-LONG #include diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 36d05345f23b..b8b3d1895093 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -80,21 +80,11 @@ EnableNoAliasConversion("enable-noalias-to-md-conversion", cl::init(true), cl::Hidden, cl::desc("Convert noalias attributes to metadata during inlining.")); -static cl::opt UpdateReturnAttributes( - "update-return-attrs", cl::init(true), cl::Hidden, - cl::desc("Update return attributes on calls within inlined body")); - static cl::opt PreserveAlignmentAssumptions("preserve-alignment-assumptions-during-inlining", cl::init(true), cl::Hidden, cl::desc("Convert align attributes to assumptions during inlining.")); -static cl::opt InlinerAttributeWindow( - "inliner-attribute-window", cl::Hidden, - cl::desc("the maximum number of instructions analyzed for may throw during " - "attribute inference in inlined body"), - cl::init(4)); - llvm::InlineResult llvm::InlineFunction(CallBase *CB, InlineFunctionInfo &IFI, AAResults *CalleeAAR, bool InsertLifetime) { @@ -1146,81 +1136,6 @@ static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap, } } -static bool MayContainThrowingOrExitingCall(Instruction *Begin, - Instruction *End) { - - assert(Begin->getParent() == End->getParent() && - "Expected to be in same basic block!"); - unsigned NumInstChecked = 0; - // Check that all instructions in the range [Begin, End) are guaranteed to - // transfer execution to successor. - for (auto &I : make_range(Begin->getIterator(), End->getIterator())) - if (NumInstChecked++ > InlinerAttributeWindow || - !isGuaranteedToTransferExecutionToSuccessor(&I)) - return true; - return false; -} - -static void AddReturnAttributes(CallSite CS, ValueToValueMapTy &VMap) { - if (!UpdateReturnAttributes) - return; - AttrBuilder AB(CS.getAttributes(), AttributeList::ReturnIndex); - if (AB.empty()) - return; - - auto *CalledFunction = CS.getCalledFunction(); - auto &Context = CalledFunction->getContext(); - - for (auto &BB : *CalledFunction) { - auto *RI = dyn_cast(BB.getTerminator()); - if (!RI || !isa(RI->getOperand(0))) - continue; - // Sanity check that the cloned return instruction exists and is a return - // instruction itself. - auto *NewRI = dyn_cast_or_null(VMap.lookup(RI)); - if (!NewRI) - continue; - auto *RetVal = cast(RI->getOperand(0)); - // Sanity check that the cloned RetVal exists and is a call. - // Simplification during inlining could have transformed the cloned - // instruction. - auto *NewRetVal = dyn_cast_or_null(VMap.lookup(RetVal)); - if (!NewRetVal) - continue; - // Backward propagation of attributes to the returned value may be incorrect - // if it is control flow dependent. - // Consider: - // @callee { - // %rv = call @foo() - // %rv2 = call @bar() - // if (%rv2 != null) - // return %rv2 - // if (%rv == null) - // exit() - // return %rv - // } - // caller() { - // %val = call nonnull @callee() - // } - // Here we cannot add the nonnull attribute on either foo or bar. So, we - // limit the check to both NewRetVal and NewRI are in the same basic block - // and there are no throwing/exiting instructions between these - // instructions. - if (NewRI->getParent() != NewRetVal->getParent() || - MayContainThrowingOrExitingCall(NewRetVal, NewRI)) - continue; - // Add to the existing attributes of NewRetVal. - // NB! When we have the same attribute already existing on NewRetVal, but - // with a diff ering value, the AttributeList's merge API honours the already - // existing attribute value (i.e. attributes such as dereferenceable, - // dereferenceable_or_null etc). See AttrBuilder::merge for more details. - AttributeList AL = NewRetVal->getAttributes(); - AttributeList NewAL = - AL.addAttributes(Context, AttributeList::ReturnIndex, AB); - NewRetVal->setAttributes(NewAL); - } -} - /// If the inlined function has non-byval align arguments, then /// add @llvm.assume-based alignment assumptions to preserve this information. static void AddAlignmentAssumptions(CallSite CS, InlineFunctionInfo &IFI) { @@ -1886,10 +1801,6 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, // Add noalias metadata if necessary. AddAliasScopeMetadata(CS, VMap, DL, CalleeAAR); - // Clone return attributes on the callsite into the calls within the inlined - // function which feed into its return value. - AddReturnAttributes(CS, VMap); - // Propagate llvm.mem.parallel_loop_access if necessary. PropagateParallelLoopAccessMetadata(CS, VMap); diff --git a/llvm/test/Transforms/Inline/ret_attr_update.ll b/llvm/test/Transforms/Inline/ret_attr_update.ll deleted file mode 100644 index 2e53540c3fe2..000000000000 --- a/llvm/test/Transforms/Inline/ret_attr_update.ll +++ /dev/null @@ -1,159 +0,0 @@ -; RUN: opt < %s -inline-threshold=0 -always-inline -S | FileCheck %s -; RUN: opt < %s -passes=always-inline -S | FileCheck %s - -declare i8* @foo(i8*) argmemonly nounwind - -define i8* @callee(i8 *%p) alwaysinline { -; CHECK: @callee( -; CHECK: call i8* @foo(i8* noalias %p) - %r = call i8* @foo(i8* noalias %p) - ret i8* %r -} - -define i8* @caller(i8* %ptr, i64 %x) { -; CHECK-LABEL: @caller -; CHECK: call nonnull i8* @foo(i8* noalias - %gep = getelementptr inbounds i8, i8* %ptr, i64 %x - %p = call nonnull i8* @callee(i8* %gep) - ret i8* %p -} - -declare void @llvm.experimental.guard(i1,...) -; Cannot add nonnull attribute to foo -; because the guard is a throwing call -define internal i8* @callee_with_throwable(i8* %p) alwaysinline { -; CHECK-NOT: callee_with_throwable - %r = call i8* @foo(i8* %p) - %cond = icmp ne i8* %r, null - call void (i1, ...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ] - ret i8* %r -} - -declare i8* @bar(i8*) readonly nounwind -; Here also we cannot add nonnull attribute to the call bar. -define internal i8* @callee_with_explicit_control_flow(i8* %p) alwaysinline { -; CHECK-NOT: callee_with_explicit_control_flow - %r = call i8* @bar(i8* %p) - %cond = icmp ne i8* %r, null - br i1 %cond, label %ret, label %orig - -ret: - ret i8* %r - -orig: - ret i8* %p -} - -define i8* @caller2(i8* %ptr, i64 %x, i1 %cond) { -; CHECK-LABEL: @caller2 -; CHECK: call i8* @foo -; CHECK: call i8* @bar - %gep = getelementptr inbounds i8, i8* %ptr, i64 %x - %p = call nonnull i8* @callee_with_throwable(i8* %gep) - %q = call nonnull i8* @callee_with_explicit_control_flow(i8* %gep) - br i1 %cond, label %pret, label %qret - -pret: - ret i8* %p - -qret: - ret i8* %q -} - -define internal i8* @callee3(i8 *%p) alwaysinline { -; CHECK-NOT: callee3 - %r = call noalias i8* @foo(i8* %p) - ret i8* %r -} - -; add the deref attribute to the existing attributes on foo. -define i8* @caller3(i8* %ptr, i64 %x) { -; CHECK-LABEL: caller3 -; CHECK: call noalias dereferenceable_or_null(12) i8* @foo - %gep = getelementptr inbounds i8, i8* %ptr, i64 %x - %p = call dereferenceable_or_null(12) i8* @callee3(i8* %gep) - ret i8* %p -} - -declare i8* @inf_loop_call(i8*) nounwind -; We cannot propagate attributes to foo because we do not know whether inf_loop_call -; will return execution. -define internal i8* @callee_with_sideeffect_callsite(i8* %p) alwaysinline { -; CHECK-NOT: callee_with_sideeffect_callsite - %r = call i8* @foo(i8* %p) - %v = call i8* @inf_loop_call(i8* %p) - ret i8* %r -} - -; do not add deref attribute to foo -define i8* @test4(i8* %ptr, i64 %x) { -; CHECK-LABEL: test4 -; CHECK: call i8* @foo - %gep = getelementptr inbounds i8, i8* %ptr, i64 %x - %p = call dereferenceable_or_null(12) i8* @callee_with_sideeffect_callsite(i8* %gep) - ret i8* %p -} - -declare i8* @baz(i8*) nounwind readonly -define internal i8* @callee5(i8* %p) alwaysinline { -; CHECK-NOT: callee5 - %r = call i8* @foo(i8* %p) - %v = call i8* @baz(i8* %p) - ret i8* %r -} - -; add the deref attribute to foo. -define i8* @test5(i8* %ptr, i64 %x) { -; CHECK-LABEL: test5 -; CHECK: call dereferenceable_or_null(12) i8* @foo - %gep = getelementptr inbounds i8, i8* %ptr, i64 %x - %s = call dereferenceable_or_null(12) i8* @callee5(i8* %gep) - ret i8* %s -} - -; deref attributes have diff erent values on the callee and the call feeding into -; the return. -; AttrBuilder chooses the already existing value and does not overwrite it. -define internal i8* @callee6(i8* %p) alwaysinline { -; CHECK-NOT: callee6 - %r = call dereferenceable_or_null(16) i8* @foo(i8* %p) - %v = call i8* @baz(i8* %p) - ret i8* %r -} - - -define i8* @test6(i8* %ptr, i64 %x) { -; CHECK-LABEL: test6 -; CHECK: call dereferenceable_or_null(16) i8* @foo - %gep = getelementptr inbounds i8, i8* %ptr, i64 %x - %s = call dereferenceable_or_null(12) i8* @callee6(i8* %gep) - ret i8* %s -} - -; We add the attributes from the callee to both the calls below. -define internal i8* @callee7(i8 *%ptr, i1 %cond) alwaysinline { -; CHECK-NOT: @callee7( - br i1 %cond, label %pass, label %fail - -pass: - %r = call i8* @foo(i8* noalias %ptr) - ret i8* %r - -fail: - %s = call i8* @baz(i8* %ptr) - ret i8* %s -} - -define void @test7(i8* %ptr, i64 %x, i1 %cond) { -; CHECK-LABEL: @test7 -; CHECK: call nonnull i8* @foo(i8* noalias -; CHECK: call nonnull i8* @baz -; CHECK: phi i8* -; CHECK: call void @snort - - %gep = getelementptr inbounds i8, i8* %ptr, i64 %x - %t = call nonnull i8* @callee7(i8* %gep, i1 %cond) - call void @snort(i8* %t) - ret void -} -declare void @snort(i8*) From cfe-commits at lists.llvm.org Tue Mar 31 13:36:49 2020 From: cfe-commits at lists.llvm.org (Sergej Jaskiewicz via cfe-commits) Date: Tue, 31 Mar 2020 13:36:49 -0700 (PDT) Subject: [clang] 9a6a696 - [cmake] Link libc++ tests against static libc++/libc++abi in CrossWinToARMLinux.cmake Message-ID: <5e83a9e1.1c69fb81.a7aee.0242@mx.google.com> Author: Sergej Jaskiewicz Date: 2020-03-31T23:36:36+03:00 New Revision: 9a6a696817bd6322d62db21aa17fe395af41f8ae URL: https://github.com/llvm/llvm-project/commit/9a6a696817bd6322d62db21aa17fe395af41f8ae DIFF: https://github.com/llvm/llvm-project/commit/9a6a696817bd6322d62db21aa17fe395af41f8ae.diff LOG: [cmake] Link libc++ tests against static libc++/libc++abi in CrossWinToARMLinux.cmake Summary: Now that D72687 has landed, we can enable this setting in our cache file. Reviewers: vvereschaka Reviewed By: vvereschaka Subscribers: mgorny, kristof.beyls, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D76774 Added: Modified: clang/cmake/caches/CrossWinToARMLinux.cmake Removed: ################################################################################ diff --git a/clang/cmake/caches/CrossWinToARMLinux.cmake b/clang/cmake/caches/CrossWinToARMLinux.cmake index 0d359a1609a5..3d1e961ada8d 100644 --- a/clang/cmake/caches/CrossWinToARMLinux.cmake +++ b/clang/cmake/caches/CrossWinToARMLinux.cmake @@ -86,6 +86,8 @@ set(LIBCXXABI_TARGET_TRIPLE "${CMAKE_C_COMPILER_TARGET}" CACHE S set(LIBCXXABI_SYSROOT "${DEFAULT_SYSROOT}" CACHE STRING "") set(LIBCXXABI_LINK_TESTS_WITH_SHARED_LIBCXXABI OFF CACHE BOOL "") set(LIBCXXABI_LINK_TESTS_WITH_SHARED_LIBCXX OFF CACHE BOOL "") +set(LIBCXX_LINK_TESTS_WITH_SHARED_LIBCXXABI OFF CACHE BOOL "") +set(LIBCXX_LINK_TESTS_WITH_SHARED_LIBCXX OFF CACHE BOOL "") set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") set(LIBCXX_TARGET_TRIPLE "${CMAKE_C_COMPILER_TARGET}" CACHE STRING "") From cfe-commits at lists.llvm.org Tue Mar 31 13:44:43 2020 From: cfe-commits at lists.llvm.org (Csaba Dabis via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 20:44:43 +0000 (UTC) Subject: [PATCH] D77066: [analyzer] ApiModeling: Add buffer size arg constraint In-Reply-To: References: Message-ID: Charusso added a comment. Please avoid to stuff in `CheckerContext` because this facility should be used by ExprEngine/Store as well. Let us reword your API: `getDynamicSizeWithOffset(ProgramStateRef, SVal, SValBuilder &)`. Of course we are trying to obtain some buffer-ish size, that is the purpose of the entire API. I also could imagine something like `getDynamicSizeMul(ProgramStateRef, const MemRegion &, const MemRegion &, SValBuilder &)`, as it is very common. May it would make sense to use the API like: getDynamicSizeWithOffset(State, MR, SVB) { Offset = State->getStoreManager().getStaticOffset(MR, SVB); ... } This idea is similar to `MemRegionManager::getStaticSize(MR, SVB)`. Hopefully no-one needs dynamic offsets. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77066/new/ https://reviews.llvm.org/D77066 From cfe-commits at lists.llvm.org Tue Mar 31 13:44:45 2020 From: cfe-commits at lists.llvm.org (Csaba Dabis via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 20:44:45 +0000 (UTC) Subject: [PATCH] D77022: [analyzer] Use IgnoreImpCasts() instead of reimplementing it. In-Reply-To: References: Message-ID: Charusso accepted this revision. Charusso marked an inline comment as done. Charusso added inline comments. This revision is now accepted and ready to land. ================ Comment at: clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp:512 + return E->IgnoreImpCasts(); } ---------------- thakis wrote: > NoQ wrote: > > Charusso wrote: > > > I think it would make sense to remove the helper-function completely. (Being used 2 times.) > > Yup. > I didn't do that because I liked the comment that this is for the _Nonnull implicit ARC casts – if I inline the function I have to duplicate the comment. Well, if you really like that, sure. I believe it is so common to avoid implicit casts we do not need to express it why. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77022/new/ https://reviews.llvm.org/D77022 From cfe-commits at lists.llvm.org Tue Mar 31 13:44:46 2020 From: cfe-commits at lists.llvm.org (Melanie Blower via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 20:44:46 +0000 (UTC) Subject: [PATCH] D76384: Move FPFeatures from BinaryOperator bitfields to Trailing storage In-Reply-To: References: Message-ID: mibintc updated this revision to Diff 253983. mibintc added a comment. Here's another revision, I believe this handles all of @rjmccall 's requests. Thank you, John, for your review! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76384/new/ https://reviews.llvm.org/D76384 Files: clang/include/clang/AST/Expr.h clang/include/clang/AST/ExprCXX.h clang/include/clang/AST/JSONNodeDumper.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/AST/Stmt.h clang/include/clang/AST/StmtVisitor.h clang/include/clang/AST/TextNodeDumper.h clang/include/clang/Basic/LangOptions.h clang/include/clang/Basic/StmtNodes.td clang/include/clang/Serialization/ASTBitCodes.h clang/lib/AST/ASTImporter.cpp clang/lib/AST/Expr.cpp clang/lib/AST/ExprCXX.cpp clang/lib/AST/ExprClassification.cpp clang/lib/AST/ExprConstant.cpp clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/JSONNodeDumper.cpp clang/lib/AST/StmtPrinter.cpp clang/lib/AST/StmtProfile.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/Analysis/BodyFarm.cpp clang/lib/Analysis/CFG.cpp clang/lib/Analysis/ReachableCode.cpp clang/lib/Analysis/ThreadSafetyCommon.cpp clang/lib/Basic/LangOptions.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprComplex.cpp clang/lib/CodeGen/CGExprScalar.cpp clang/lib/CodeGen/CGObjC.cpp clang/lib/CodeGen/CGStmtOpenMP.cpp clang/lib/CodeGen/CodeGenFunction.h clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp clang/lib/Frontend/Rewrite/RewriteObjC.cpp clang/lib/Index/IndexBody.cpp clang/lib/Sema/AnalysisBasedWarnings.cpp clang/lib/Sema/SemaChecking.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaExceptionSpec.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaExprCXX.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/SemaOverload.cpp clang/lib/Sema/SemaPseudoObject.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/Serialization/ASTWriterStmt.cpp clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp clang/lib/StaticAnalyzer/Core/ExprEngine.cpp clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp clang/test/AST/ast-dump-expr-json.c clang/test/AST/ast-dump-expr.c clang/test/AST/dump.cpp clang/test/Import/compound-assign-op/test.cpp clang/tools/libclang/CXCursor.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76384.253983.patch Type: text/x-patch Size: 88098 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 13:44:47 2020 From: cfe-commits at lists.llvm.org (Jian Cai via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 20:44:47 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization Message-ID: jcai19 created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Add -ftrivial-auto-var-init-stop-after= to limit the number of times stack variables are initialized when -ftrivial-auto-var-init= is used to initialize stack variables to zero or a pattern. This flag can be used to bisect uninitialized uses of a stack variable exposed by automatic variable initialization, such as http://crrev.com/c/2020401. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77168 Files: clang/include/clang/Basic/LangOptions.def clang/include/clang/Driver/Options.td clang/lib/CodeGen/CGDecl.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -3273,6 +3273,11 @@ Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; } + if (Arg *A = Args.getLastArg(OPT_ftrivial_auto_var_init_stop_after)) { + unsigned Val = (unsigned)std::stoi(A->getValue()); + Opts.TrivialAutoVarInitStopAfter = Val; + } + // Parse -fsanitize= arguments. parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ), Diags, Opts.Sanitize); Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -3088,6 +3088,13 @@ CmdArgs.push_back( Args.MakeArgString("-ftrivial-auto-var-init=" + TrivialAutoVarInit)); } + + if (Arg *A = Args.getLastArg(options::OPT_ftrivial_auto_var_init_stop_after)) { + A->claim(); + StringRef Val = A->getValue(); + CmdArgs.push_back( + Args.MakeArgString("-ftrivial-auto-var-init-stop-after=" + Val)); + } } static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs) { Index: clang/lib/CodeGen/CGDecl.cpp =================================================================== --- clang/lib/CodeGen/CGDecl.cpp +++ clang/lib/CodeGen/CGDecl.cpp @@ -1809,6 +1809,19 @@ LangOptions::TrivialAutoVarInitKind::Uninitialized) return; + unsigned StopAfter = getContext().getLangOpts().TrivialAutoVarInitStopAfter; + if (StopAfter) { + static unsigned Counter = 0; + if (Counter >= StopAfter) + return; + if (Counter++ == StopAfter - 1) { + const DeclContext * CD = D.getParentFunctionOrMethod (); + std::string FunctionName = (cast(CD))->getNameInfo().getAsString(); + StringRef SourceFileName = CGM.getModule().getSourceFileName(); + llvm::errs() << "The last variable initialized is " << D.getName() << " of function " << FunctionName << " in " << SourceFileName << "\n"; + } + } + // Only initialize a __block's storage: we always initialize the header. if (emission.IsEscapingByRef && !locIsByrefHeader) Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false); Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -1799,6 +1799,8 @@ def enable_trivial_var_init_zero : Flag<["-"], "enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang">, Flags<[CC1Option, CoreOption]>, HelpText<"Trivial automatic variable initialization to zero is only here for benchmarks, it'll eventually be removed, and I'm OK with that because I'm only using it to benchmark">; +def ftrivial_auto_var_init_stop_after : Joined<["-"], "ftrivial-auto-var-init-stop-after=">, Group, + Flags<[CC1Option, CoreOption]>, HelpText<"Stop initializing trivial automatic stack variables after the specified number of instances">; def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group, Flags<[CoreOption]>, HelpText<"Emit full debug info for all types used by the program">; def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group, Flags<[CoreOption]>, Index: clang/include/clang/Basic/LangOptions.def =================================================================== --- clang/include/clang/Basic/LangOptions.def +++ clang/include/clang/Basic/LangOptions.def @@ -293,6 +293,8 @@ "stack protector mode") ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized, "trivial automatic variable initialization") +VALUE_LANGOPT(TrivialAutoVarInitStopAfter, 32, 0, + "stop trivial automatic variable initialization after the specified number of instances") ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined, "signed integer overflow handling") -------------- next part -------------- A non-text attachment was scrubbed... Name: D77168.253984.patch Type: text/x-patch Size: 4207 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 13:44:48 2020 From: cfe-commits at lists.llvm.org (Duncan P. N. Exon Smith via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 20:44:48 +0000 (UTC) Subject: [PATCH] D77058: [Clang] Add llvm.loop.unroll.disable to loops with -fno-unroll-loops. In-Reply-To: References: Message-ID: dexonsmith added a comment. In D77058#1950019 , @tejohnson wrote: > I think this is a good approach, rather than a per-function attribute, since as mentioned this will be preserved through inlining. > @dexonsmith, does that seem reasonable to you? I missed the original patch and agree with you that we don't want to fix this in LTO by passing the option through to LTO. SGTM! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77058/new/ https://reviews.llvm.org/D77058 From cfe-commits at lists.llvm.org Tue Mar 31 13:48:09 2020 From: cfe-commits at lists.llvm.org (Sergej Jaskiewicz via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 20:48:09 +0000 (UTC) Subject: [PATCH] D76774: [cmake] Link libc++ tests against static libc++/libc++abi in CrossWinToARMLinux.cmake In-Reply-To: References: Message-ID: <60be8411cdcca21bbc46fd0fa9c5e365@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG9a6a696817bd: [cmake] Link libc++ tests against static libc++/libc++abi in CrossWinToARMLinux. (authored by broadwaylamb). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76774/new/ https://reviews.llvm.org/D76774 Files: clang/cmake/caches/CrossWinToARMLinux.cmake Index: clang/cmake/caches/CrossWinToARMLinux.cmake =================================================================== --- clang/cmake/caches/CrossWinToARMLinux.cmake +++ clang/cmake/caches/CrossWinToARMLinux.cmake @@ -86,6 +86,8 @@ set(LIBCXXABI_SYSROOT "${DEFAULT_SYSROOT}" CACHE STRING "") set(LIBCXXABI_LINK_TESTS_WITH_SHARED_LIBCXXABI OFF CACHE BOOL "") set(LIBCXXABI_LINK_TESTS_WITH_SHARED_LIBCXX OFF CACHE BOOL "") +set(LIBCXX_LINK_TESTS_WITH_SHARED_LIBCXXABI OFF CACHE BOOL "") +set(LIBCXX_LINK_TESTS_WITH_SHARED_LIBCXX OFF CACHE BOOL "") set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") set(LIBCXX_TARGET_TRIPLE "${CMAKE_C_COMPILER_TARGET}" CACHE STRING "") -------------- next part -------------- A non-text attachment was scrubbed... Name: D76774.253988.patch Type: text/x-patch Size: 740 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 13:48:20 2020 From: cfe-commits at lists.llvm.org (Erik Pilkington via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 20:48:20 +0000 (UTC) Subject: [PATCH] D76323: [AST] Fix handling of long double and bool in __builtin_bit_cast In-Reply-To: References: Message-ID: erik.pilkington updated this revision to Diff 253986. erik.pilkington marked 5 inline comments as done. erik.pilkington added a comment. Address review comments. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76323/new/ https://reviews.llvm.org/D76323 Files: clang/include/clang/Basic/DiagnosticASTKinds.td clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76323.253986.patch Type: text/x-patch Size: 5999 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 13:48:24 2020 From: cfe-commits at lists.llvm.org (Erik Pilkington via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 20:48:24 +0000 (UTC) Subject: [PATCH] D76323: [AST] Fix handling of long double and bool in __builtin_bit_cast In-Reply-To: References: Message-ID: <937d0784e0e40001a4ff603384be421c@localhost.localdomain> erik.pilkington added inline comments. ================ Comment at: clang/lib/AST/ExprConstant.cpp:6364-6371 + const llvm::fltSemantics &Semantics = Info.Ctx.getFloatTypeSemantics(Ty); + unsigned NumBits = APFloat::semanticsSizeInBits(Semantics); + assert(NumBits % 8 == 0); + CharUnits Width = CharUnits::fromQuantity(NumBits / 8); + SmallVector Bytes(Width.getQuantity()); + llvm::StoreIntToMemory(AsInt, &*Bytes.begin(), Width.getQuantity()); + Buffer.writeObject(Offset, Bytes); ---------------- rsmith wrote: > This appears more complex than necessary. `bitcastToAPInt` already returned the correct number of bits (eg, 80 for x86 fp80) so you don't need to compute that yourself. How about leaving this function alone and changing `visitInt` to store the number of (value representation) bits in the `APSInt` rather than the full (object representation) width of the type? As is, `visitInt` would also be wrong in the same way if the integer type had any full bytes of padding. Sure, this causes us to have to handle `bool` in visitInt, but I think we should have been doing that anyways. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76323/new/ https://reviews.llvm.org/D76323 From cfe-commits at lists.llvm.org Tue Mar 31 13:52:22 2020 From: cfe-commits at lists.llvm.org (Ben Langmuir via cfe-commits) Date: Tue, 31 Mar 2020 13:52:22 -0700 (PDT) Subject: [clang] cc3fddb - [pch] Honour -fallow-pch-with-compiler-errors for overall compilation status Message-ID: <5e83ad86.1c69fb81.31479.039a@mx.google.com> Author: Ben Langmuir Date: 2020-03-31T13:50:12-07:00 New Revision: cc3fddb411d55d4d0902a772a9f3db11fc4f002e URL: https://github.com/llvm/llvm-project/commit/cc3fddb411d55d4d0902a772a9f3db11fc4f002e DIFF: https://github.com/llvm/llvm-project/commit/cc3fddb411d55d4d0902a772a9f3db11fc4f002e.diff LOG: [pch] Honour -fallow-pch-with-compiler-errors for overall compilation status Previously we would emit a PCH with errors, but fail the overall compilation. If run using the driver, that would result in removing the just-produced PCH. Instead, we should have the compilation result match whether we were able to emit the PCH. Differential Revision: https://reviews.llvm.org/D77159 rdar://61110294 Added: Modified: clang/lib/Serialization/GeneratePCH.cpp clang/test/Index/pch-with-errors.c Removed: ################################################################################ diff --git a/clang/lib/Serialization/GeneratePCH.cpp b/clang/lib/Serialization/GeneratePCH.cpp index 002233e49bb0..d869796b82c1 100644 --- a/clang/lib/Serialization/GeneratePCH.cpp +++ b/clang/lib/Serialization/GeneratePCH.cpp @@ -57,6 +57,11 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { } } + // Errors that do not prevent the PCH from being written should not cause the + // overall compilation to fail either. + if (AllowASTWithErrors) + PP.getDiagnostics().getClient()->clear(); + // Emit the PCH file to the Buffer. assert(SemaPtr && "No Sema?"); Buffer->Signature = diff --git a/clang/test/Index/pch-with-errors.c b/clang/test/Index/pch-with-errors.c index 5c94a8a8e4d3..e8711c8e26a9 100644 --- a/clang/test/Index/pch-with-errors.c +++ b/clang/test/Index/pch-with-errors.c @@ -42,3 +42,6 @@ void foo(void) { // RUN: not c-index-test -write-pch %t.pch foobar.c 2>&1 | FileCheck -check-prefix=NONEXISTENT %s // NONEXISTENT: Unable to load translation unit + +// RUN: %clang -x c-header %s -o %t-clang.h.pch -Xclang -detailed-preprocessing-record -Xclang -fallow-pch-with-compiler-errors +// RUN: c-index-test -index-file %s -include %t-clang.h -Xclang -detailed-preprocessing-record | FileCheck -check-prefix=CHECK-INDEX %s From cfe-commits at lists.llvm.org Tue Mar 31 14:10:17 2020 From: cfe-commits at lists.llvm.org (Sam McCall via cfe-commits) Date: Tue, 31 Mar 2020 14:10:17 -0700 (PDT) Subject: [clang-tools-extra] 2dee4d4 - [clangd] Don't build clangdserver for (most) completion tests. NFC Message-ID: <5e83b1b9.1c69fb81.9d3a4.03c6@mx.google.com> Author: Sam McCall Date: 2020-03-31T23:09:36+02:00 New Revision: 2dee4d44297220655786d3fddd471cdf99fa8e5a URL: https://github.com/llvm/llvm-project/commit/2dee4d44297220655786d3fddd471cdf99fa8e5a DIFF: https://github.com/llvm/llvm-project/commit/2dee4d44297220655786d3fddd471cdf99fa8e5a.diff LOG: [clangd] Don't build clangdserver for (most) completion tests. NFC Added: Modified: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp clang-tools-extra/clangd/unittests/FindTargetTests.cpp clang-tools-extra/clangd/unittests/TestTU.cpp clang-tools-extra/clangd/unittests/TestTU.h clang-tools-extra/clangd/unittests/TweakTesting.h Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp index 24197485f68a..06dccfa93956 100644 --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -93,8 +93,9 @@ std::unique_ptr memIndex(std::vector Symbols) { return MemIndex::build(std::move(Slab).build(), RefSlab(), RelationSlab()); } -CodeCompleteResult completions(ClangdServer &Server, llvm::StringRef TestCode, - Position Point, +// Runs code completion. +// If IndexSymbols is non-empty, an index will be built and passed to opts. +CodeCompleteResult completions(const TestTU &TU, Position Point, std::vector IndexSymbols = {}, clangd::CodeCompleteOptions Opts = {}) { std::unique_ptr OverrideIndex; @@ -104,49 +105,35 @@ CodeCompleteResult completions(ClangdServer &Server, llvm::StringRef TestCode, Opts.Index = OverrideIndex.get(); } - auto File = testPath("foo.cpp"); - runAddDocument(Server, File, TestCode); - auto CompletionList = - llvm::cantFail(runCodeComplete(Server, File, Point, Opts)); - return CompletionList; -} - -CodeCompleteResult completions(ClangdServer &Server, llvm::StringRef Text, - std::vector IndexSymbols = {}, - clangd::CodeCompleteOptions Opts = {}, - PathRef FilePath = "foo.cpp") { - std::unique_ptr OverrideIndex; - if (!IndexSymbols.empty()) { - assert(!Opts.Index && "both Index and IndexSymbols given!"); - OverrideIndex = memIndex(std::move(IndexSymbols)); - Opts.Index = OverrideIndex.get(); + auto Inputs = TU.inputs(); + IgnoreDiagnostics Diags; + auto CI = buildCompilerInvocation(Inputs, Diags); + if (!CI) { + ADD_FAILURE() << "Couldn't build CompilerInvocation"; + return {}; } - - auto File = testPath(FilePath); - Annotations Test(Text); - runAddDocument(Server, File, Test.code()); - auto CompletionList = - llvm::cantFail(runCodeComplete(Server, File, Test.point(), Opts)); - return CompletionList; + auto Preamble = + buildPreamble(testPath(TU.Filename), *CI, /*OldPreamble=*/nullptr, Inputs, + /*InMemory=*/true, /*Callback=*/nullptr); + return codeComplete(testPath(TU.Filename), Inputs.CompileCommand, + Preamble.get(), TU.Code, Point, Inputs.FS, Opts); } -// Builds a server and runs code completion. -// If IndexSymbols is non-empty, an index will be built and passed to opts. +// Runs code completion. CodeCompleteResult completions(llvm::StringRef Text, std::vector IndexSymbols = {}, clangd::CodeCompleteOptions Opts = {}, PathRef FilePath = "foo.cpp") { - MockFSProvider FS; - MockCompilationDatabase CDB; + Annotations Test(Text); + auto TU = TestTU::withCode(Test.code()); // To make sure our tests for completiopns inside templates work on Windows. - CDB.ExtraClangFlags = {"-fno-delayed-template-parsing"}; - ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); - return completions(Server, Text, std::move(IndexSymbols), std::move(Opts), - FilePath); + TU.ExtraArgs = {"-fno-delayed-template-parsing"}; + TU.Filename = FilePath.str(); + return completions(TU, Test.point(), std::move(IndexSymbols), + std::move(Opts)); } -// Builds a server and runs code completion. -// If IndexSymbols is non-empty, an index will be built and passed to opts. +// Runs code completion without the clang parser. CodeCompleteResult completionsNoCompile(llvm::StringRef Text, std::vector IndexSymbols = {}, clangd::CodeCompleteOptions Opts = {}, @@ -669,53 +656,38 @@ TEST(CompletionTest, SemaIndexMergeWithLimit) { } TEST(CompletionTest, IncludeInsertionPreprocessorIntegrationTests) { - MockFSProvider FS; - MockCompilationDatabase CDB; - std::string Subdir = testPath("sub"); - std::string SearchDirArg = (Twine("-I") + Subdir).str(); - CDB.ExtraClangFlags = {SearchDirArg.c_str()}; - std::string BarHeader = testPath("sub/bar.h"); - FS.Files[BarHeader] = ""; + TestTU TU; + TU.ExtraArgs.push_back("-I" + testPath("sub")); + TU.AdditionalFiles["sub/bar.h"] = ""; + auto BarURI = URI::create(testPath("sub/bar.h")).toString(); - ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); - auto BarURI = URI::create(BarHeader).toString(); Symbol Sym = cls("ns::X"); Sym.CanonicalDeclaration.FileURI = BarURI.c_str(); Sym.IncludeHeaders.emplace_back(BarURI, 1); // Shoten include path based on search directory and insert. - auto Results = completions(Server, - R"cpp( - int main() { ns::^ } - )cpp", - {Sym}); + Annotations Test("int main() { ns::^ }"); + TU.Code = Test.code().str(); + auto Results = completions(TU, Test.point(), {Sym}); EXPECT_THAT(Results.Completions, ElementsAre(AllOf(Named("X"), InsertInclude("\"bar.h\"")))); // Can be disabled via option. CodeCompleteOptions NoInsertion; NoInsertion.InsertIncludes = CodeCompleteOptions::NeverInsert; - Results = completions(Server, - R"cpp( - int main() { ns::^ } - )cpp", - {Sym}, NoInsertion); + Results = completions(TU, Test.point(), {Sym}, NoInsertion); EXPECT_THAT(Results.Completions, ElementsAre(AllOf(Named("X"), Not(InsertInclude())))); // Duplicate based on inclusions in preamble. - Results = completions(Server, - R"cpp( + Test = Annotations(R"cpp( #include "sub/bar.h" // not shortest, so should only match resolved. int main() { ns::^ } - )cpp", - {Sym}); + )cpp"); + TU.Code = Test.code().str(); + Results = completions(TU, Test.point(), {Sym}); EXPECT_THAT(Results.Completions, ElementsAre(AllOf(Named("X"), Labeled("X"), Not(InsertInclude())))); } TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) { - MockFSProvider FS; - MockCompilationDatabase CDB; - - ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); Symbol SymX = cls("ns::X"); Symbol SymY = cls("ns::Y"); std::string BarHeader = testPath("bar.h"); @@ -725,8 +697,7 @@ TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) { SymX.IncludeHeaders.emplace_back("", 1); SymY.IncludeHeaders.emplace_back("", 1); // Shoten include path based on search directory and insert. - auto Results = completions(Server, - R"cpp( + auto Results = completions(R"cpp( namespace ns { class X; class Y {}; @@ -740,34 +711,27 @@ TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) { } TEST(CompletionTest, IndexSuppressesPreambleCompletions) { - MockFSProvider FS; - MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); - - FS.Files[testPath("bar.h")] = - R"cpp(namespace ns { struct preamble { int member; }; })cpp"; - auto File = testPath("foo.cpp"); Annotations Test(R"cpp( #include "bar.h" namespace ns { int local; } void f() { ns::^; } void f2() { ns::preamble().$2^; } )cpp"); - runAddDocument(Server, File, Test.code()); - clangd::CodeCompleteOptions Opts = {}; + auto TU = TestTU::withCode(Test.code()); + TU.AdditionalFiles["bar.h"] = + R"cpp(namespace ns { struct preamble { int member; }; })cpp"; + clangd::CodeCompleteOptions Opts = {}; auto I = memIndex({var("ns::index")}); Opts.Index = I.get(); - auto WithIndex = cantFail(runCodeComplete(Server, File, Test.point(), Opts)); + auto WithIndex = completions(TU, Test.point(), {}, Opts); EXPECT_THAT(WithIndex.Completions, UnorderedElementsAre(Named("local"), Named("index"))); - auto ClassFromPreamble = - cantFail(runCodeComplete(Server, File, Test.point("2"), Opts)); + auto ClassFromPreamble = completions(TU, Test.point("2"), {}, Opts); EXPECT_THAT(ClassFromPreamble.Completions, Contains(Named("member"))); Opts.Index = nullptr; - auto WithoutIndex = - cantFail(runCodeComplete(Server, File, Test.point(), Opts)); + auto WithoutIndex = completions(TU, Test.point(), {}, Opts); EXPECT_THAT(WithoutIndex.Completions, UnorderedElementsAre(Named("local"), Named("preamble"))); } @@ -811,7 +775,14 @@ TEST(CompletionTest, DynamicIndexIncludeInsertion) { Server.addDocument(testPath("foo_impl.cpp"), FileContent); // Wait for the dynamic index being built. ASSERT_TRUE(Server.blockUntilIdleForTest()); - EXPECT_THAT(completions(Server, "Foo^ foo;").Completions, + + auto File = testPath("foo.cpp"); + Annotations Test("Foo^ foo;"); + runAddDocument(Server, File, Test.code()); + auto CompletionList = + llvm::cantFail(runCodeComplete(Server, File, Test.point(), {})); + + EXPECT_THAT(CompletionList.Completions, ElementsAre(AllOf(Named("Foo"), HasInclude("\"foo_header.h\""), InsertInclude()))); } @@ -892,13 +863,17 @@ TEST(CompletionTest, CommentsFromSystemHeaders) { int foo(); )cpp"; - auto Results = completions(Server, - R"cpp( + auto File = testPath("foo.cpp"); + Annotations Test(R"cpp( #include "foo.h" int x = foo^ )cpp"); + runAddDocument(Server, File, Test.code()); + auto CompletionList = + llvm::cantFail(runCodeComplete(Server, File, Test.point(), {})); + EXPECT_THAT( - Results.Completions, + CompletionList.Completions, Contains(AllOf(Named("foo"), Doc("This comment should be retained!")))); } @@ -1064,15 +1039,19 @@ SignatureHelp signatures(llvm::StringRef Text, Position Point, if (!IndexSymbols.empty()) Index = memIndex(IndexSymbols); - MockFSProvider FS; - MockCompilationDatabase CDB; - ClangdServer::Options Opts = ClangdServer::optsForTest(); - Opts.StaticIndex = Index.get(); - - ClangdServer Server(CDB, FS, Opts); - auto File = testPath("foo.cpp"); - runAddDocument(Server, File, Text); - return llvm::cantFail(runSignatureHelp(Server, File, Point)); + auto TU = TestTU::withCode(Text); + auto Inputs = TU.inputs(); + IgnoreDiagnostics Diags; + auto CI = buildCompilerInvocation(Inputs, Diags); + if (!CI) { + ADD_FAILURE() << "Couldn't build CompilerInvocation"; + return {}; + } + auto Preamble = + buildPreamble(testPath(TU.Filename), *CI, /*OldPreamble=*/nullptr, Inputs, + /*InMemory=*/true, /*Callback=*/nullptr); + return signatureHelp(testPath(TU.Filename), Inputs.CompileCommand, + Preamble.get(), Text, Point, Inputs.FS, Index.get()); } SignatureHelp signatures(llvm::StringRef Text, @@ -1546,14 +1525,7 @@ TEST(CompletionTest, DocumentationFromChangedFileCrash) { } TEST(CompletionTest, NonDocComments) { - MockFSProvider FS; - auto FooCpp = testPath("foo.cpp"); - FS.Files[FooCpp] = ""; - - MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); - - Annotations Source(R"cpp( + const char *Text = R"cpp( // We ignore namespace comments, for rationale see CodeCompletionStrings.h. namespace comments_ns { } @@ -1588,17 +1560,11 @@ TEST(CompletionTest, NonDocComments) { int Struct::comments_quux() { int a = comments^; } - )cpp"); - // FIXME: Auto-completion in a template requires disabling delayed template - // parsing. - CDB.ExtraClangFlags.push_back("-fno-delayed-template-parsing"); - runAddDocument(Server, FooCpp, Source.code(), "null", WantDiagnostics::Yes); - CodeCompleteResult Completions = cantFail(runCodeComplete( - Server, FooCpp, Source.point(), clangd::CodeCompleteOptions())); + )cpp"; // We should not get any of those comments in completion. EXPECT_THAT( - Completions.Completions, + completions(Text).Completions, UnorderedElementsAre(AllOf(Not(IsDocumented()), Named("comments_foo")), AllOf(IsDocumented(), Named("comments_baz")), AllOf(IsDocumented(), Named("comments_quux")), @@ -1740,11 +1706,10 @@ TEST(CompletionTest, CodeCompletionContext) { TEST(CompletionTest, FixItForArrowToDot) { MockFSProvider FS; MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); CodeCompleteOptions Opts; Opts.IncludeFixIts = true; - Annotations TestCode( + const char* Code = R"cpp( class Auxilary { public: @@ -1760,13 +1725,12 @@ TEST(CompletionTest, FixItForArrowToDot) { ClassWithPtr x; x[[->]]^; } - )cpp"); - auto Results = - completions(Server, TestCode.code(), TestCode.point(), {}, Opts); + )cpp"; + auto Results = completions(Code, {}, Opts); EXPECT_EQ(Results.Completions.size(), 3u); TextEdit ReplacementEdit; - ReplacementEdit.range = TestCode.range(); + ReplacementEdit.range = Annotations(Code).range(); ReplacementEdit.newText = "."; for (const auto &C : Results.Completions) { EXPECT_TRUE(C.FixIts.size() == 1u || C.Name == "AuxFunction"); @@ -1777,13 +1741,9 @@ TEST(CompletionTest, FixItForArrowToDot) { } TEST(CompletionTest, FixItForDotToArrow) { - MockFSProvider FS; - MockCompilationDatabase CDB; - ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); - CodeCompleteOptions Opts; Opts.IncludeFixIts = true; - Annotations TestCode( + const char* Code = R"cpp( class Auxilary { public: @@ -1799,13 +1759,12 @@ TEST(CompletionTest, FixItForDotToArrow) { ClassWithPtr x; x[[.]]^; } - )cpp"); - auto Results = - completions(Server, TestCode.code(), TestCode.point(), {}, Opts); + )cpp"; + auto Results = completions(Code, {}, Opts); EXPECT_EQ(Results.Completions.size(), 3u); TextEdit ReplacementEdit; - ReplacementEdit.range = TestCode.range(); + ReplacementEdit.range = Annotations(Code).range(); ReplacementEdit.newText = "->"; for (const auto &C : Results.Completions) { EXPECT_TRUE(C.FixIts.empty() || C.Name == "AuxFunction"); @@ -1858,8 +1817,8 @@ TEST(CompletionTest, RenderWithFixItNonMerged) { TEST(CompletionTest, CompletionTokenRange) { MockFSProvider FS; MockCompilationDatabase CDB; - FS.Files["foo/abc/foo.h"] = ""; - ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); + TestTU TU; + TU.AdditionalFiles["foo/abc/foo.h"] = ""; constexpr const char *TestCodes[] = { R"cpp( @@ -1891,10 +1850,10 @@ TEST(CompletionTest, CompletionTokenRange) { }; for (const auto &Text : TestCodes) { Annotations TestCode(Text); - auto Results = completions(Server, TestCode.code(), TestCode.point()); - + TU.Code = TestCode.code().str(); + auto Results = completions(TU, TestCode.point()); if (Results.Completions.size() != 1) { - ADD_FAILURE() << "Results.Completions.size() != 1"; + ADD_FAILURE() << "Results.Completions.size() != 1" << Text; continue; } EXPECT_THAT(Results.Completions.front().CompletionTokenRange, @@ -2247,13 +2206,12 @@ TEST(CompletionTest, InsertTheMostPopularHeader) { } TEST(CompletionTest, NoInsertIncludeIfOnePresent) { - MockFSProvider FS; - MockCompilationDatabase CDB; - - std::string FooHeader = testPath("foo.h"); - FS.Files[FooHeader] = ""; - - ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); + Annotations Test(R"cpp( + #include "foo.h" + Fun^ + )cpp"); + auto TU = TestTU::withCode(Test.code()); + TU.AdditionalFiles["foo.h"] = ""; std::string DeclFile = URI::create(testPath("foo")).toString(); Symbol Sym = func("Func"); @@ -2262,7 +2220,7 @@ TEST(CompletionTest, NoInsertIncludeIfOnePresent) { Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000); EXPECT_THAT( - completions(Server, "#include \"foo.h\"\nFun^", {Sym}).Completions, + completions(TU, Test.point(), {Sym}).Completions, UnorderedElementsAre( AllOf(Named("Func"), HasInclude("\"foo.h\""), Not(InsertInclude())))); } @@ -2279,20 +2237,15 @@ TEST(CompletionTest, MergeMacrosFromIndexAndSema) { } TEST(CompletionTest, MacroFromPreamble) { - MockFSProvider FS; - MockCompilationDatabase CDB; - std::string FooHeader = testPath("foo.h"); - FS.Files[FooHeader] = "#define CLANGD_PREAMBLE_HEADER x\n"; - ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); - auto Results = completions( - R"cpp(#include "foo.h" - #define CLANGD_PREAMBLE_MAIN x + Annotations Test(R"cpp(#define CLANGD_PREAMBLE_MAIN x int x = 0; #define CLANGD_MAIN x void f() { CLANGD_^ } - )cpp", - {func("CLANGD_INDEX")}); + )cpp"); + auto TU = TestTU::withCode(Test.code()); + TU.HeaderCode = "#define CLANGD_PREAMBLE_HEADER x"; + auto Results = completions(TU, Test.point(), {func("CLANGD_INDEX")}); // We should get results from the main file, including the preamble section. // However no results from included files (the index should cover them). EXPECT_THAT(Results.Completions, @@ -2405,29 +2358,22 @@ TEST(SignatureHelpTest, ConstructorInitializeFields) { } TEST(CompletionTest, IncludedCompletionKinds) { - MockFSProvider FS; - MockCompilationDatabase CDB; - std::string Subdir = testPath("sub"); - std::string SearchDirArg = (Twine("-I") + Subdir).str(); - CDB.ExtraClangFlags = {SearchDirArg.c_str()}; - std::string BarHeader = testPath("sub/bar.h"); - FS.Files[BarHeader] = ""; - ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); - auto Results = completions(Server, - R"cpp( - #include "^" - )cpp"); + Annotations Test(R"cpp(#include "^")cpp"); + auto TU = TestTU::withCode(Test.code()); + TU.AdditionalFiles["sub/bar.h"] = ""; + TU.ExtraArgs.push_back("-I" + testPath("sub")); + + auto Results = completions(TU, Test.point()); EXPECT_THAT(Results.Completions, AllOf(Has("sub/", CompletionItemKind::Folder), Has("bar.h\"", CompletionItemKind::File))); } TEST(CompletionTest, NoCrashAtNonAlphaIncludeHeader) { - auto Results = completions( + completions( R"cpp( #include "./^" )cpp"); - EXPECT_TRUE(Results.Completions.empty()); } TEST(CompletionTest, NoAllScopesCompletionWhenQualified) { diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp index c38ccc3f9441..53d29a236a07 100644 --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -65,7 +65,7 @@ class TargetDeclTest : public ::testing::Test { protected: using Rel = DeclRelation; std::string Code; - std::vector Flags; + std::vector Flags; // Asserts that `Code` has a marked selection of a node `NodeType`, // and returns allTargetDecls() as PrintedDecl structs. diff --git a/clang-tools-extra/clangd/unittests/TestTU.cpp b/clang-tools-extra/clangd/unittests/TestTU.cpp index 909c125aed2e..dfcdb0884e27 100644 --- a/clang-tools-extra/clangd/unittests/TestTU.cpp +++ b/clang-tools-extra/clangd/unittests/TestTU.cpp @@ -20,7 +20,7 @@ namespace clang { namespace clangd { -ParsedAST TestTU::build() const { +ParseInputs TestTU::inputs() const { std::string FullFilename = testPath(Filename), FullHeaderName = testPath(HeaderFilename), ImportThunk = testPath("import_thunk.h"); @@ -34,25 +34,24 @@ ParsedAST TestTU::build() const { Files[FullHeaderName] = HeaderCode; Files[ImportThunk] = ThunkContents; - std::vector Cmd = {"clang"}; + ParseInputs Inputs; + auto& Argv = Inputs.CompileCommand.CommandLine; + Argv = {"clang"}; // FIXME: this shouldn't need to be conditional, but it breaks a // GoToDefinition test for some reason (getMacroArgExpandedLocation fails). if (!HeaderCode.empty()) { - Cmd.push_back("-include"); - Cmd.push_back(ImplicitHeaderGuard ? ImportThunk.c_str() - : FullHeaderName.c_str()); + Argv.push_back("-include"); + Argv.push_back(ImplicitHeaderGuard ? ImportThunk : FullHeaderName); // ms-compatibility changes the meaning of #import. // The default is OS-dependent (on on windows), ensure it's off. if (ImplicitHeaderGuard) - Cmd.push_back("-fno-ms-compatibility"); + Inputs.CompileCommand.CommandLine.push_back("-fno-ms-compatibility"); } - Cmd.insert(Cmd.end(), ExtraArgs.begin(), ExtraArgs.end()); + Argv.insert(Argv.end(), ExtraArgs.begin(), ExtraArgs.end()); // Put the file name at the end -- this allows the extra arg (-xc++) to // override the language setting. - Cmd.push_back(FullFilename.c_str()); - ParseInputs Inputs; + Argv.push_back(FullFilename); Inputs.CompileCommand.Filename = FullFilename; - Inputs.CompileCommand.CommandLine = {Cmd.begin(), Cmd.end()}; Inputs.CompileCommand.Directory = testRoot(); Inputs.Contents = Code; Inputs.FS = buildTestFS(Files); @@ -62,15 +61,20 @@ ParsedAST TestTU::build() const { Inputs.Index = ExternalIndex; if (Inputs.Index) Inputs.Opts.SuggestMissingIncludes = true; + return Inputs; +} + +ParsedAST TestTU::build() const { + auto Inputs = inputs(); StoreDiags Diags; auto CI = buildCompilerInvocation(Inputs, Diags); assert(CI && "Failed to build compilation invocation."); auto Preamble = - buildPreamble(FullFilename, *CI, + buildPreamble(testPath(Filename), *CI, /*OldPreamble=*/nullptr, Inputs, /*StoreInMemory=*/true, /*PreambleCallback=*/nullptr); - auto AST = - buildAST(FullFilename, std::move(CI), Diags.take(), Inputs, Preamble); + auto AST = buildAST(testPath(Filename), std::move(CI), Diags.take(), Inputs, + Preamble); if (!AST.hasValue()) { ADD_FAILURE() << "Failed to build code:\n" << Code; llvm_unreachable("Failed to build TestTU!"); @@ -79,9 +83,17 @@ ParsedAST TestTU::build() const { // This guards against accidental syntax errors silently subverting tests. // error-ok is awfully primitive - using clang -verify would be nicer. // Ownership and layering makes it pretty hard. - if (llvm::none_of(Files, [](const auto &KV) { - return llvm::StringRef(KV.second).contains("error-ok"); - })) { + bool ErrorOk = [&, this] { + llvm::StringLiteral Marker = "error-ok"; + if (llvm::StringRef(Code).contains(Marker) || + llvm::StringRef(HeaderCode).contains(Marker)) + return true; + for (const auto& KV : this->AdditionalFiles) + if (llvm::StringRef(KV.second).contains(Marker)) + return true; + return false; + }(); + if (!ErrorOk) { for (const auto &D : AST->getDiagnostics()) if (D.Severity >= DiagnosticsEngine::Error) { ADD_FAILURE() diff --git a/clang-tools-extra/clangd/unittests/TestTU.h b/clang-tools-extra/clangd/unittests/TestTU.h index 4668543d5b4d..229f65a4b95c 100644 --- a/clang-tools-extra/clangd/unittests/TestTU.h +++ b/clang-tools-extra/clangd/unittests/TestTU.h @@ -17,6 +17,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TESTTU_H #define LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TESTTU_H +#include "Compiler.h" #include "ParsedAST.h" #include "Path.h" #include "index/Index.h" @@ -54,7 +55,7 @@ struct TestTU { llvm::StringMap AdditionalFiles; // Extra arguments for the compiler invocation. - std::vector ExtraArgs; + std::vector ExtraArgs; llvm::Optional ClangTidyChecks; llvm::Optional ClangTidyWarningsAsErrors; @@ -67,6 +68,7 @@ struct TestTU { // By default, build() will report Error diagnostics as GTest errors. // Suppress this behavior by adding an 'error-ok' comment to the code. ParsedAST build() const; + ParseInputs inputs() const; SymbolSlab headerSymbols() const; std::unique_ptr index() const; }; diff --git a/clang-tools-extra/clangd/unittests/TweakTesting.h b/clang-tools-extra/clangd/unittests/TweakTesting.h index 10186f859bae..c771149a72fc 100644 --- a/clang-tools-extra/clangd/unittests/TweakTesting.h +++ b/clang-tools-extra/clangd/unittests/TweakTesting.h @@ -66,7 +66,7 @@ class TweakTest : public ::testing::Test { llvm::StringRef FileName = "TestTU.cpp"; // Extra flags passed to the compilation in apply(). - std::vector ExtraArgs; + std::vector ExtraArgs; // Context in which snippets of code should be placed to run tweaks. CodeContext Context = File; From cfe-commits at lists.llvm.org Tue Mar 31 14:17:18 2020 From: cfe-commits at lists.llvm.org (Roman Lebedev via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 21:17:18 +0000 (UTC) Subject: [PATCH] D70265: [clang-tidy] Add CppCoreGuidelines I.2 "Avoid non-const global variables" check In-Reply-To: References: Message-ID: <11d0d9f8694b5fdb465dbe1cd93fe96c@localhost.localdomain> lebedev.ri added a comment. Hello. 2 points: rG512767eb3fe9c34c655a480d034147c54f1d4f85 doesn't reference this review, so it's a bit hard to find. Please try to reference it next time. Is this check really intentionally complaining about function-scope static variables? How are they global? https://godbolt.org/z/2QMemL void bar(int*); void foo() { static int a; bar(&a); } :4:14: warning: variable 'a' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables] static int a; ^ Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70265/new/ https://reviews.llvm.org/D70265 From cfe-commits at lists.llvm.org Tue Mar 31 14:17:27 2020 From: cfe-commits at lists.llvm.org (Anna Thomas via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 21:17:27 +0000 (UTC) Subject: [PATCH] D76140: [InlineFunction] update attributes during inlining In-Reply-To: References: Message-ID: <2d9f1c99a44dc2ab0fb025ea4784ef08@localhost.localdomain> anna reopened this revision. anna added a comment. This revision is now accepted and ready to land. In D76140#1953201 , @anna wrote: > I got a failure in one of the binaryFormats: > lib/BinaryFormat/CMakeFiles/LLVMBinaryFormat.dir/MsgPackReader.cpp > > Attributes 'zeroext and signext' are incompatible! > %rev.i.i.i.i.i.i.i.i = tail call signext zeroext i16 @llvm.bswap.i16(i16 %ret.0.copyload.i.i.i.i) #6 > in function _ZN4llvm7msgpack6Reader7readIntIsEENS_8ExpectedIbEERNS0_6ObjectE > fatal error: error in backend: Broken function found, compilation aborted! > > > I believe this just showcases undefined behaviour since we were having a returnValue (i.e. call) with an incomptable attribute compared to the return attribute on the callsite. The last statement is not true. Had a discussion offline with Philip and he pointed out that we missed the fact that attributes such as `signext` and `zeroext` are part of the *call* itself. We cannot propagate these attributes into the callee since such attributes are part of the ABI for the call it is attached to. I'm reopening this review to fix this issue. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76140/new/ https://reviews.llvm.org/D76140 From cfe-commits at lists.llvm.org Tue Mar 31 14:17:28 2020 From: cfe-commits at lists.llvm.org (Anna Thomas via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 21:17:28 +0000 (UTC) Subject: [PATCH] D76140: [InlineFunction] update attributes during inlining In-Reply-To: References: Message-ID: <9f988d193568dafa42dd4355228c8828@localhost.localdomain> anna planned changes to this revision. anna added a comment. see above comment. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76140/new/ https://reviews.llvm.org/D76140 From cfe-commits at lists.llvm.org Tue Mar 31 14:17:39 2020 From: cfe-commits at lists.llvm.org (Anna Thomas via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 21:17:39 +0000 (UTC) Subject: [PATCH] D76140: [InlineFunction] update attributes during inlining In-Reply-To: References: Message-ID: <7c3ba3965855bcc288cd1611eb7b22da@localhost.localdomain> anna marked an inline comment as done. anna added inline comments. ================ Comment at: llvm/lib/Transforms/Utils/InlineFunction.cpp:1175 + continue; + // Sanity check that the cloned return instruction exists and is a return + // instruction itself. ---------------- anna wrote: > anna wrote: > > reames wrote: > > > Ok, after staring at it a bit, I've convinced myself the code here is correct, just needlessly conservative. > > > > > > What you're doing is: > > > If the callees return instruction and returned call both map to the same instructions once inlined, determine whether there's a possible exit between the inlined copy. > > > > > > What you could be doing: > > > If the callee returns a call, check if *in the callee* there's a possible exit between call and return, then apply attribute to cloned call. > > > > > > The key difference is when the caller directly returns the result vs uses it locally. The result here is that your transform is much more narrow in applicability than it first appears. > > yes, thanks for pointing it out. I realized it after our offline discussion :) > > For now, I will add a FIXME testcase which showcases the difference in code and handle that testcase in a followon change. > > The key difference is when the caller directly returns the result vs uses it locally. The result here is that your transform is much more narrow in applicability than it first appears. > I tried multiple test cases to showcase the difference between the two ideas above but failed. Specifically, `simplifyInstruction` used during inlining the callee is not too great at optimizing the body. For example, see added testcase `test7`. > > I also tried the less restrictive version (check the safety of the optimization in the callee itself, and do the attribute update on the cloned instruction), but didn't see any testcases in clang that needed update. Of course, that doesn't mean anything :) > > Clarified this with Philip offline. The current patch is not restrictive. In fact, now that I think of it, sometimes, it may be better - `simplifyInstruction` can fold away instructions and reduce the "window size" between the RV and the ReturnInst. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76140/new/ https://reviews.llvm.org/D76140 From cfe-commits at lists.llvm.org Tue Mar 31 14:17:42 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 21:17:42 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift In-Reply-To: References: Message-ID: <9cf7df0e9413405e2b4b9873e4cc3d2e@localhost.localdomain> rjmccall added inline comments. ================ Comment at: clang/lib/CodeGen/CGObjCGNU.cpp:623 + llvm_unreachable("not implemented"); + } + ---------------- I think this is just the (unfortunately-named) `GenerateProtocolRef` (the one that just takes a protocol and not a CGF). ================ Comment at: clang/lib/CodeGen/CGObjCRuntime.h:217 + /// ProtocolPtrTy. + virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) = 0; + ---------------- Can this name more closely parallel the "external" name, like `getOrEmitProtocolObject`? Also, I think we're incrementally lowercasing new method names. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77077/new/ https://reviews.llvm.org/D77077 From cfe-commits at lists.llvm.org Tue Mar 31 14:18:27 2020 From: cfe-commits at lists.llvm.org (Alexey Bataev via cfe-commits) Date: Tue, 31 Mar 2020 14:18:27 -0700 (PDT) Subject: [clang] 9b3bf72 - [OPENMP50]Allow use of array shaping expression in a list. Message-ID: <5e83b3a3.1c69fb81.960be.049c@mx.google.com> Author: Alexey Bataev Date: 2020-03-31T17:15:31-04:00 New Revision: 9b3bf72a0d7918601e8005554592fcb4949a822e URL: https://github.com/llvm/llvm-project/commit/9b3bf72a0d7918601e8005554592fcb4949a822e DIFF: https://github.com/llvm/llvm-project/commit/9b3bf72a0d7918601e8005554592fcb4949a822e.diff LOG: [OPENMP50]Allow use of array shaping expression in a list. Need to allow arrayshaping expression in a list of expressions, so use ParseAssignmentExpression() when try to parse the base of the shaping operation. Added: Modified: clang/lib/Parse/ParseExpr.cpp clang/test/OpenMP/task_ast_print.cpp Removed: ################################################################################ diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 9a0f94ae7be5..fc07cfe5ad03 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -3001,7 +3001,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, // Match the ')'. T.consumeClose(); RParenLoc = T.getCloseLocation(); - Result = Actions.CorrectDelayedTyposInExpr(ParseExpression()); + Result = Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); if (ErrorFound) { Result = ExprError(); } else if (!Result.isInvalid()) { diff --git a/clang/test/OpenMP/task_ast_print.cpp b/clang/test/OpenMP/task_ast_print.cpp index 0f11b390f7fa..1da6c5045934 100644 --- a/clang/test/OpenMP/task_ast_print.cpp +++ b/clang/test/OpenMP/task_ast_print.cpp @@ -164,8 +164,8 @@ int main(int argc, char **argv) { #pragma omp threadprivate(a) Enum ee; // CHECK: Enum ee; -#pragma omp task untied mergeable depend(out:argv[:a][1], (arr)[0:],([argc][10])argv) if(task: argc > 0) priority(f) depend(depobj:y) - // CHECK-NEXT: #pragma omp task untied mergeable depend(out : argv[:a][1],(arr)[0:],([argc][10])argv) if(task: argc > 0) priority(f) depend(depobj : y) +#pragma omp task untied mergeable depend(out:argv[:a][1], (arr)[0:],([argc][10])argv,b) if(task: argc > 0) priority(f) depend(depobj:y) + // CHECK-NEXT: #pragma omp task untied mergeable depend(out : argv[:a][1],(arr)[0:],([argc][10])argv,b) if(task: argc > 0) priority(f) depend(depobj : y) a = 2; // CHECK-NEXT: a = 2; #pragma omp taskgroup task_reduction(min: arr1) From cfe-commits at lists.llvm.org Tue Mar 31 14:19:44 2020 From: cfe-commits at lists.llvm.org (Ben Langmuir via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 21:19:44 +0000 (UTC) Subject: [PATCH] D77159: [pch] Honour -fallow-pch-with-compiler-errors for overall compilation status In-Reply-To: References: Message-ID: <97f96bf5951bc488c953ca14c5f6f59a@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGcc3fddb411d5: [pch] Honour -fallow-pch-with-compiler-errors for overall compilation status (authored by benlangmuir). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77159/new/ https://reviews.llvm.org/D77159 Files: clang/lib/Serialization/GeneratePCH.cpp clang/test/Index/pch-with-errors.c Index: clang/test/Index/pch-with-errors.c =================================================================== --- clang/test/Index/pch-with-errors.c +++ clang/test/Index/pch-with-errors.c @@ -42,3 +42,6 @@ // RUN: not c-index-test -write-pch %t.pch foobar.c 2>&1 | FileCheck -check-prefix=NONEXISTENT %s // NONEXISTENT: Unable to load translation unit + +// RUN: %clang -x c-header %s -o %t-clang.h.pch -Xclang -detailed-preprocessing-record -Xclang -fallow-pch-with-compiler-errors +// RUN: c-index-test -index-file %s -include %t-clang.h -Xclang -detailed-preprocessing-record | FileCheck -check-prefix=CHECK-INDEX %s Index: clang/lib/Serialization/GeneratePCH.cpp =================================================================== --- clang/lib/Serialization/GeneratePCH.cpp +++ clang/lib/Serialization/GeneratePCH.cpp @@ -57,6 +57,11 @@ } } + // Errors that do not prevent the PCH from being written should not cause the + // overall compilation to fail either. + if (AllowASTWithErrors) + PP.getDiagnostics().getClient()->clear(); + // Emit the PCH file to the Buffer. assert(SemaPtr && "No Sema?"); Buffer->Signature = -------------- next part -------------- A non-text attachment was scrubbed... Name: D77159.254000.patch Type: text/x-patch Size: 1155 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 14:53:12 2020 From: cfe-commits at lists.llvm.org (Digger via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 21:53:12 +0000 (UTC) Subject: [PATCH] D76932: [AIX] emit .extern and .weak directive linkage In-Reply-To: References: Message-ID: DiggerLin marked 3 inline comments as done. DiggerLin added inline comments. ================ Comment at: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1548 + + if (XCOFFSym->hasContainingCsect()) { + MCSymbolXCOFF *QualName = ---------------- jasonliu wrote: > I hope we can find a better solution here. IMO, we don't even want to override this function in this patch. > GVSym should be the right one from what caller passed in. It's caller's responsibility to pass in the right GVSym. > When caller calls emitLinkage, we should emitLinkage. It's weird when emitLinkage is called, but none is emitted (when hasContainingCsect() returns false). In the function ``` bool AsmPrinter::doFinalization(Module &M) { // Emit remaining GOT equivalent globals. emitGlobalGOTEquivs(); // Emit visibility info for declarations for (const Function &F : M) { .... } ``` there is function name .llvm.stackprotector in the M. the function is declared . it go to emitLinkage(); we need if (XCOFFSym->hasContainingCsect()) { } to exclude emit linkage for function .llvm.stackprotector I think over it , do you have any good suggestion to distinguish .llvm.stackprotector from other extern declared function. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76932/new/ https://reviews.llvm.org/D76932 From cfe-commits at lists.llvm.org Tue Mar 31 14:53:14 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 21:53:14 +0000 (UTC) Subject: [PATCH] D77176: [clangd] Force delayed-template-parsing off in code completion. Message-ID: sammccall created this revision. sammccall added a reviewer: kadircet. Herald added subscribers: cfe-commits, usaxena95, arphaman, jkorous, MaskRay, ilya-biryukov. Herald added a project: clang. It prevents code completion entirely in affected method bodies. The main reason it's turned on is for compatibility with headers, so we turn it off for the main file only. This is allowed because it's a compatible langopt. Fixes https://github.com/clangd/clangd/issues/302 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77176 Files: clang-tools-extra/clangd/CodeComplete.cpp clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp Index: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -127,7 +127,6 @@ Annotations Test(Text); auto TU = TestTU::withCode(Test.code()); // To make sure our tests for completiopns inside templates work on Windows. - TU.ExtraArgs = {"-fno-delayed-template-parsing"}; TU.Filename = FilePath.str(); return completions(TU, Test.point(), std::move(IndexSymbols), std::move(Opts)); @@ -2660,6 +2659,20 @@ EXPECT_THAT(Signatures, Contains(Sig("x() -> auto"))); } +TEST(CompletionTest, DelayedTemplateParsing) { + Annotations Test(R"cpp( + int xxx; + template int foo() { return xx^; } + )cpp"); + auto TU = TestTU::withCode(Test.code()); + // Even though delayed-template-parsing is on, we will disable it to provide + // completion in templates. + TU.ExtraArgs.push_back("-fdelayed-template-parsing"); + + EXPECT_THAT(completions(TU, Test.point()).Completions, + Contains(Named("xxx"))); +} + TEST(CompletionTest, CompletionRange) { const char *WithRange = "auto x = [[abc]]^"; auto Completions = completions(WithRange); Index: clang-tools-extra/clangd/CodeComplete.cpp =================================================================== --- clang-tools-extra/clangd/CodeComplete.cpp +++ clang-tools-extra/clangd/CodeComplete.cpp @@ -1072,6 +1072,10 @@ FrontendOpts.SkipFunctionBodies = true; // Disable typo correction in Sema. CI->getLangOpts()->SpellChecking = false; + // Code completion won't trigger in delayed template bodies. + // This is on-by-default in windows to allow parsing SDK headers; we're only + // disabling it for the main-file (not preamble). + CI->getLangOpts()->DelayedTemplateParsing = false; // Setup code completion. FrontendOpts.CodeCompleteOpts = Options; FrontendOpts.CodeCompletionAt.FileName = std::string(Input.FileName); -------------- next part -------------- A non-text attachment was scrubbed... Name: D77176.254005.patch Type: text/x-patch Size: 2063 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 14:53:15 2020 From: cfe-commits at lists.llvm.org (Fady Ghanim via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 21:53:15 +0000 (UTC) Subject: [PATCH] D77112: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` In-Reply-To: References: Message-ID: <7dcd09db0049a63da110a0290d461446@localhost.localdomain> fghanim added a comment. Thanks for doing this. I looked at all of it, and the changes seem to be you just moved things to llvm/Frontend, and fixed namespaces/includes to work correctly with the new location. Is there here anything else I am missing? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77112/new/ https://reviews.llvm.org/D77112 From cfe-commits at lists.llvm.org Tue Mar 31 14:53:19 2020 From: cfe-commits at lists.llvm.org (Manoj Gupta via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 21:53:19 +0000 (UTC) Subject: [PATCH] D71082: Allow system header to provide their own implementation of some builtin In-Reply-To: References: Message-ID: manojgupta added a comment. We believe this change (relanded as https://reviews.llvm.org/rGd437fba8ef626b6d8b7928540f630163a9b04021) is causing a mis-compile in Linux kernel 4.4 builds resulting in local test failures. Chrome OS bug: https://bugs.chromium.org/p/chromium/issues/detail?id=1066638 I will try to see if I can reduce it further but will it be ok to revert this change meanwhile? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71082/new/ https://reviews.llvm.org/D71082 From cfe-commits at lists.llvm.org Tue Mar 31 14:55:03 2020 From: cfe-commits at lists.llvm.org (Fady Ghanim via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 21:55:03 +0000 (UTC) Subject: [PATCH] D77113: [OpenMP][NFC] Move and simplify directive -> allowed clause mapping In-Reply-To: References: Message-ID: fghanim added a comment. Thanks for working on this as well. As an aside, I like the new allowed clause implementation much better. it is much simpler and cleaner than the previous one. I'll wait to see if anyone else has comments, but if not, then it LGTM. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77113/new/ https://reviews.llvm.org/D77113 From cfe-commits at lists.llvm.org Tue Mar 31 15:00:47 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via cfe-commits) Date: Tue, 31 Mar 2020 15:00:47 -0700 (PDT) Subject: [clang] c9d65a4 - HIP: Ensure new denormal mode attributes are set Message-ID: <5e83bd8f.1c69fb81.1fd26.085e@mx.google.com> Author: Matt Arsenault Date: 2020-03-31T18:00:37-04:00 New Revision: c9d65a48af1d7bbfed7e785613cc9d9acf71821b URL: https://github.com/llvm/llvm-project/commit/c9d65a48af1d7bbfed7e785613cc9d9acf71821b DIFF: https://github.com/llvm/llvm-project/commit/c9d65a48af1d7bbfed7e785613cc9d9acf71821b.diff LOG: HIP: Ensure new denormal mode attributes are set Apparently HIPToolChain does not subclass from AMDGPUToolChain, so this was not applying the new denormal attributes. I'm not sure why this doesn't subclass. Just copy the implementation for now. Added: Modified: clang/lib/Driver/ToolChains/AMDGPU.cpp clang/lib/Driver/ToolChains/AMDGPU.h clang/lib/Driver/ToolChains/HIP.cpp clang/lib/Driver/ToolChains/HIP.h clang/test/Driver/cuda-flush-denormals-to-zero.cu Removed: ################################################################################ diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index 06e4686ac2b9..e6a5af99b203 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -103,6 +103,19 @@ AMDGPUToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch, return DAL; } +bool AMDGPUToolChain::getDefaultDenormsAreZeroForTarget( + llvm::AMDGPU::GPUKind Kind) { + const unsigned ArchAttr = llvm::AMDGPU::getArchAttrAMDGCN(Kind); + + // Default to enabling f32 denormals by default on subtargets where fma is + // fast with denormals + const bool DefaultDenormsAreZeroForTarget = + (ArchAttr & llvm::AMDGPU::FEATURE_FAST_FMA_F32) && + (ArchAttr & llvm::AMDGPU::FEATURE_FAST_DENORMAL_F32); + + return DefaultDenormsAreZeroForTarget; +} + llvm::DenormalMode AMDGPUToolChain::getDefaultDenormalModeForType( const llvm::opt::ArgList &DriverArgs, Action::OffloadKind DeviceOffloadKind, const llvm::fltSemantics *FPType) const { @@ -121,18 +134,10 @@ llvm::DenormalMode AMDGPUToolChain::getDefaultDenormalModeForType( const StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_mcpu_EQ); auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch); - // Default to enabling f32 denormals by default on subtargets where fma is - // fast with denormals - - const unsigned ArchAttr = llvm::AMDGPU::getArchAttrAMDGCN(Kind); - const bool DefaultDenormsAreZeroForTarget = - (ArchAttr & llvm::AMDGPU::FEATURE_FAST_FMA_F32) && - (ArchAttr & llvm::AMDGPU::FEATURE_FAST_DENORMAL_F32); - // TODO: There are way too many flags that change this. Do we need to check // them all? bool DAZ = DriverArgs.hasArg(options::OPT_cl_denorms_are_zero) || - !DefaultDenormsAreZeroForTarget; + !getDefaultDenormsAreZeroForTarget(Kind); // Outputs are flushed to zero, preserving sign return DAZ ? llvm::DenormalMode::getPreserveSign() : llvm::DenormalMode::getIEEE(); diff --git a/clang/lib/Driver/ToolChains/AMDGPU.h b/clang/lib/Driver/ToolChains/AMDGPU.h index 78c40580b302..e7a873efb008 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.h +++ b/clang/lib/Driver/ToolChains/AMDGPU.h @@ -13,6 +13,8 @@ #include "clang/Driver/Options.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" +#include "llvm/Support/TargetParser.h" + #include namespace clang { @@ -67,6 +69,10 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUToolChain : public Generic_ELF { llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const override; + /// Return whether denormals should be flushed, and treated as 0 by default + /// for the subtarget. + static bool getDefaultDenormsAreZeroForTarget(llvm::AMDGPU::GPUKind GPUKind); + llvm::DenormalMode getDefaultDenormalModeForType( const llvm::opt::ArgList &DriverArgs, Action::OffloadKind DeviceOffloadKind, diff --git a/clang/lib/Driver/ToolChains/HIP.cpp b/clang/lib/Driver/ToolChains/HIP.cpp index 157dca7e0c8d..0a9ec68e13e4 100644 --- a/clang/lib/Driver/ToolChains/HIP.cpp +++ b/clang/lib/Driver/ToolChains/HIP.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "HIP.h" +#include "AMDGPU.h" #include "CommonArgs.h" #include "InputInfo.h" #include "clang/Basic/Cuda.h" @@ -16,6 +17,7 @@ #include "clang/Driver/Options.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" +#include "llvm/Support/TargetParser.h" using namespace clang::driver; using namespace clang::driver::toolchains; @@ -272,6 +274,34 @@ HIPToolChain::HIPToolChain(const Driver &D, const llvm::Triple &Triple, getProgramPaths().push_back(getDriver().Dir); } +// FIXME: Duplicated in AMDGPUToolChain +llvm::DenormalMode HIPToolChain::getDefaultDenormalModeForType( + const llvm::opt::ArgList &DriverArgs, Action::OffloadKind DeviceOffloadKind, + const llvm::fltSemantics *FPType) const { + // Denormals should always be enabled for f16 and f64. + if (!FPType || FPType != &llvm::APFloat::IEEEsingle()) + return llvm::DenormalMode::getIEEE(); + + if (DeviceOffloadKind == Action::OFK_Cuda) { + if (FPType && FPType == &llvm::APFloat::IEEEsingle() && + DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero, + options::OPT_fno_cuda_flush_denormals_to_zero, + false)) + return llvm::DenormalMode::getPreserveSign(); + } + + const StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_mcpu_EQ); + auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch); + + // TODO: There are way too many flags that change this. Do we need to check + // them all? + bool DAZ = DriverArgs.hasArg(options::OPT_cl_denorms_are_zero) || + !AMDGPUToolChain::getDefaultDenormsAreZeroForTarget(Kind); + // Outputs are flushed to zero, preserving sign + return DAZ ? llvm::DenormalMode::getPreserveSign() : + llvm::DenormalMode::getIEEE(); +} + void HIPToolChain::addClangTargetOptions( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, diff --git a/clang/lib/Driver/ToolChains/HIP.h b/clang/lib/Driver/ToolChains/HIP.h index c4f944e458bf..32eb8704feb5 100644 --- a/clang/lib/Driver/ToolChains/HIP.h +++ b/clang/lib/Driver/ToolChains/HIP.h @@ -115,6 +115,11 @@ class LLVM_LIBRARY_VISIBILITY HIPToolChain : public ToolChain { unsigned GetDefaultDwarfVersion() const override { return 4; } + llvm::DenormalMode getDefaultDenormalModeForType( + const llvm::opt::ArgList &DriverArgs, + Action::OffloadKind DeviceOffloadKind, + const llvm::fltSemantics *FPType = nullptr) const override; + const ToolChain &HostTC; protected: diff --git a/clang/test/Driver/cuda-flush-denormals-to-zero.cu b/clang/test/Driver/cuda-flush-denormals-to-zero.cu index 74f4bbc1585e..5b1046b0cb12 100644 --- a/clang/test/Driver/cuda-flush-denormals-to-zero.cu +++ b/clang/test/Driver/cuda-flush-denormals-to-zero.cu @@ -7,6 +7,16 @@ // RUN: %clang -no-canonical-prefixes -### -target x86_64-linux-gnu -c -march=haswell --cuda-gpu-arch=sm_70 -fcuda-flush-denormals-to-zero -nocudainc -nocudalib %s 2>&1 | FileCheck -check-prefix=FTZ %s // RUN: %clang -no-canonical-prefixes -### -target x86_64-linux-gnu -c -march=haswell --cuda-gpu-arch=sm_70 -fno-cuda-flush-denormals-to-zero -nocudainc -nocudalib %s 2>&1 | FileCheck -check-prefix=NOFTZ %s +// Test explicit argument. +// RUN: %clang -no-canonical-prefixes -### -target x86_64-linux-gnu -c -march=haswell --cuda-gpu-arch=gfx803 -fcuda-flush-denormals-to-zero -nocudainc -nogpulib %s 2>&1 | FileCheck -check-prefix=FTZ %s +// RUN: %clang -no-canonical-prefixes -### -target x86_64-linux-gnu -c -march=haswell --cuda-gpu-arch=gfx803 -fno-cuda-flush-denormals-to-zero -nocudainc -nogpulib %s 2>&1 | FileCheck -check-prefix=NOFTZ %s +// RUN: %clang -x hip -no-canonical-prefixes -### -target x86_64-linux-gnu -c -march=haswell --cuda-gpu-arch=gfx900 -fcuda-flush-denormals-to-zero -nocudainc -nogpulib %s 2>&1 | FileCheck -check-prefix=FTZ %s +// RUN: %clang -x hip -no-canonical-prefixes -### -target x86_64-linux-gnu -c -march=haswell --cuda-gpu-arch=gfx900 -fno-cuda-flush-denormals-to-zero -nocudainc -nogpulib %s 2>&1 | FileCheck -check-prefix=NOFTZ %s + +// Test the default changing with no argument based on the subtarget. +// RUN: %clang -x hip -no-canonical-prefixes -### -target x86_64-linux-gnu -c -march=haswell --cuda-gpu-arch=gfx803 -nocudainc -nogpulib %s 2>&1 | FileCheck -check-prefix=FTZ %s +// RUN: %clang -x hip -no-canonical-prefixes -### -target x86_64-linux-gnu -c -march=haswell --cuda-gpu-arch=gfx900 -nocudainc -nogpulib %s 2>&1 | FileCheck -check-prefix=NOFTZ %s + // CPUFTZ-NOT: -fdenormal-fp-math // FTZ-NOT: -fdenormal-fp-math-f32= From cfe-commits at lists.llvm.org Tue Mar 31 15:22:54 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via cfe-commits) Date: Tue, 31 Mar 2020 15:22:54 -0700 (PDT) Subject: [clang] 175e423 - AMDGPU: Make HIPToolChain a subclass of AMDGPUToolChain Message-ID: <5e83c2be.1c69fb81.45882.0c36@mx.google.com> Author: Matt Arsenault Date: 2020-03-31T18:22:46-04:00 New Revision: 175e42303bb2a4253c65126666b1ae05b32b0004 URL: https://github.com/llvm/llvm-project/commit/175e42303bb2a4253c65126666b1ae05b32b0004 DIFF: https://github.com/llvm/llvm-project/commit/175e42303bb2a4253c65126666b1ae05b32b0004.diff LOG: AMDGPU: Make HIPToolChain a subclass of AMDGPUToolChain This fixes some code duplication. This is also a step towards consolidating builtin library handling. Added: Modified: clang/lib/Driver/ToolChains/HIP.cpp clang/lib/Driver/ToolChains/HIP.h Removed: ################################################################################ diff --git a/clang/lib/Driver/ToolChains/HIP.cpp b/clang/lib/Driver/ToolChains/HIP.cpp index 0a9ec68e13e4..d21b3f5f0b19 100644 --- a/clang/lib/Driver/ToolChains/HIP.cpp +++ b/clang/lib/Driver/ToolChains/HIP.cpp @@ -268,40 +268,12 @@ void AMDGCN::Linker::ConstructJob(Compilation &C, const JobAction &JA, HIPToolChain::HIPToolChain(const Driver &D, const llvm::Triple &Triple, const ToolChain &HostTC, const ArgList &Args) - : ToolChain(D, Triple, Args), HostTC(HostTC) { + : AMDGPUToolChain(D, Triple, Args), HostTC(HostTC) { // Lookup binaries into the driver directory, this is used to // discover the clang-offload-bundler executable. getProgramPaths().push_back(getDriver().Dir); } -// FIXME: Duplicated in AMDGPUToolChain -llvm::DenormalMode HIPToolChain::getDefaultDenormalModeForType( - const llvm::opt::ArgList &DriverArgs, Action::OffloadKind DeviceOffloadKind, - const llvm::fltSemantics *FPType) const { - // Denormals should always be enabled for f16 and f64. - if (!FPType || FPType != &llvm::APFloat::IEEEsingle()) - return llvm::DenormalMode::getIEEE(); - - if (DeviceOffloadKind == Action::OFK_Cuda) { - if (FPType && FPType == &llvm::APFloat::IEEEsingle() && - DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero, - options::OPT_fno_cuda_flush_denormals_to_zero, - false)) - return llvm::DenormalMode::getPreserveSign(); - } - - const StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_mcpu_EQ); - auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch); - - // TODO: There are way too many flags that change this. Do we need to check - // them all? - bool DAZ = DriverArgs.hasArg(options::OPT_cl_denorms_are_zero) || - !AMDGPUToolChain::getDefaultDenormsAreZeroForTarget(Kind); - // Outputs are flushed to zero, preserving sign - return DAZ ? llvm::DenormalMode::getPreserveSign() : - llvm::DenormalMode::getIEEE(); -} - void HIPToolChain::addClangTargetOptions( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, diff --git a/clang/lib/Driver/ToolChains/HIP.h b/clang/lib/Driver/ToolChains/HIP.h index 32eb8704feb5..b6a3a2718635 100644 --- a/clang/lib/Driver/ToolChains/HIP.h +++ b/clang/lib/Driver/ToolChains/HIP.h @@ -11,6 +11,7 @@ #include "clang/Driver/ToolChain.h" #include "clang/Driver/Tool.h" +#include "AMDGPU.h" namespace clang { namespace driver { @@ -72,7 +73,7 @@ class LLVM_LIBRARY_VISIBILITY Linker : public Tool { namespace toolchains { -class LLVM_LIBRARY_VISIBILITY HIPToolChain : public ToolChain { +class LLVM_LIBRARY_VISIBILITY HIPToolChain final : public AMDGPUToolChain { public: HIPToolChain(const Driver &D, const llvm::Triple &Triple, const ToolChain &HostTC, const llvm::opt::ArgList &Args); @@ -115,11 +116,6 @@ class LLVM_LIBRARY_VISIBILITY HIPToolChain : public ToolChain { unsigned GetDefaultDwarfVersion() const override { return 4; } - llvm::DenormalMode getDefaultDenormalModeForType( - const llvm::opt::ArgList &DriverArgs, - Action::OffloadKind DeviceOffloadKind, - const llvm::fltSemantics *FPType = nullptr) const override; - const ToolChain &HostTC; protected: From cfe-commits at lists.llvm.org Tue Mar 31 15:27:20 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 22:27:20 +0000 (UTC) Subject: [PATCH] D71082: Allow system header to provide their own implementation of some builtin In-Reply-To: References: Message-ID: <09f0aed5cf5883ad55e0efa4162f8192@localhost.localdomain> efriedma added a comment. I'd prefer not to revert a change that's three months old without some sort of evidence the issue is actually the compiler's fault. If nobody else has seen an issue, it's probably okay to let it sit for a day or two. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71082/new/ https://reviews.llvm.org/D71082 From cfe-commits at lists.llvm.org Tue Mar 31 15:27:25 2020 From: cfe-commits at lists.llvm.org (Kanglei Fang via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 22:27:25 +0000 (UTC) Subject: [PATCH] D77039: [clang-format] Don't break multi block parameters on ObjCBreakBeforeNestedBlockParam In-Reply-To: References: Message-ID: <9eb7a0646a5c276ed9b4f90c88d4cb91@localhost.localdomain> ghvg1313 updated this revision to Diff 254014. ghvg1313 added a comment. - Fix documentation formatting Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77039/new/ https://reviews.llvm.org/D77039 Files: clang/docs/ClangFormatStyleOptions.rst Index: clang/docs/ClangFormatStyleOptions.rst =================================================================== --- clang/docs/ClangFormatStyleOptions.rst +++ clang/docs/ClangFormatStyleOptions.rst @@ -2072,8 +2072,8 @@ - (void)_aMethod { [self.test1 t:self - w:self - callback:^(typeof(self) self, NSNumber *u, NSNumber *v) { + w:self + callback:^(typeof(self) self, NSNumber *u, NSNumber *v) { u = c; }] } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77039.254014.patch Type: text/x-patch Size: 531 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 15:27:26 2020 From: cfe-commits at lists.llvm.org (Kanglei Fang via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 22:27:26 +0000 (UTC) Subject: [PATCH] D77039: [clang-format] Don't break multi block parameters on ObjCBreakBeforeNestedBlockParam In-Reply-To: References: Message-ID: <48f33a240023719ca62c077c69d90996@localhost.localdomain> ghvg1313 updated this revision to Diff 254015. ghvg1313 added a comment. reset diff's base Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77039/new/ https://reviews.llvm.org/D77039 Files: clang/docs/ClangFormatStyleOptions.rst clang/lib/Format/ContinuationIndenter.cpp clang/unittests/Format/FormatTestObjC.cpp Index: clang/unittests/Format/FormatTestObjC.cpp =================================================================== --- clang/unittests/Format/FormatTestObjC.cpp +++ clang/unittests/Format/FormatTestObjC.cpp @@ -1420,6 +1420,10 @@ "*b, NSNumber *c) {\n" " b = c;\n" "}]"); + verifyFormat("[self.test1 t:self w:self callback:^(typeof(self) self, " + "NSNumber *u, NSNumber *v) {\n" + " u = v;\n" + "} z:self]"); Style.ColumnLimit = 80; verifyFormat( Index: clang/lib/Format/ContinuationIndenter.cpp =================================================================== --- clang/lib/Format/ContinuationIndenter.cpp +++ clang/lib/Format/ContinuationIndenter.cpp @@ -342,6 +342,7 @@ if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection) return true; if (Style.Language == FormatStyle::LK_ObjC && + Style.ObjCBreakBeforeNestedBlockParam && Current.ObjCSelectorNameParts > 1 && Current.startsSequence(TT_SelectorName, tok::colon, tok::caret)) { return true; Index: clang/docs/ClangFormatStyleOptions.rst =================================================================== --- clang/docs/ClangFormatStyleOptions.rst +++ clang/docs/ClangFormatStyleOptions.rst @@ -2072,8 +2072,8 @@ - (void)_aMethod { [self.test1 t:self - w:self - callback:^(typeof(self) self, NSNumber *u, NSNumber *v) { + w:self + callback:^(typeof(self) self, NSNumber *u, NSNumber *v) { u = c; }] } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77039.254015.patch Type: text/x-patch Size: 1638 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 15:27:27 2020 From: cfe-commits at lists.llvm.org (Kanglei Fang via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 22:27:27 +0000 (UTC) Subject: [PATCH] D77039: [clang-format] Don't break multi block parameters on ObjCBreakBeforeNestedBlockParam In-Reply-To: References: Message-ID: <0f3b61bfdd5a8ce904b05e80db1ce844@localhost.localdomain> ghvg1313 added a comment. @jolesiak I don't yet have the commit access, do you mind help merging this diff? Thanks Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77039/new/ https://reviews.llvm.org/D77039 From cfe-commits at lists.llvm.org Tue Mar 31 15:27:30 2020 From: cfe-commits at lists.llvm.org (Jon Chesterfield via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 22:27:30 +0000 (UTC) Subject: [PATCH] D77113: [OpenMP][NFC] Move and simplify directive -> allowed clause mapping In-Reply-To: References: Message-ID: <1f77934039e92a0a7e727261ef515a09@localhost.localdomain> JonChesterfield accepted this revision. JonChesterfield added a comment. This revision is now accepted and ready to land. LGTM too. Non functional change, clearer code. Thanks Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77113/new/ https://reviews.llvm.org/D77113 From cfe-commits at lists.llvm.org Tue Mar 31 15:27:31 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 22:27:31 +0000 (UTC) Subject: [PATCH] D77112: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` In-Reply-To: References: Message-ID: jdoerfert added a comment. In D77112#1953471 , @fghanim wrote: > Thanks for doing this. I looked at all of it, and the changes seem to be you just moved things to llvm/Frontend, and fixed namespaces/includes to work correctly with the new location. Is there here anything else I am missing? Not really. This moves the macros and the two helper functions (string -> enum, enum -> string) into lib/Frontend and adjusts everything to work again. No functional change was intended and no tests output changed. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77112/new/ https://reviews.llvm.org/D77112 From cfe-commits at lists.llvm.org Tue Mar 31 15:27:38 2020 From: cfe-commits at lists.llvm.org (Jian Cai via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 22:27:38 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: <7d7d0995154c9f3ec33e9a7ec3a65410@localhost.localdomain> jcai19 updated this revision to Diff 254019. jcai19 added a comment. Add test cases. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 Files: clang/include/clang/Basic/LangOptions.def clang/include/clang/Driver/Options.td clang/lib/CodeGen/CGDecl.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGenCXX/auto-var-init-stop-after.cpp clang/test/Driver/clang_f_opts.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77168.254019.patch Type: text/x-patch Size: 6948 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 15:27:41 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 22:27:41 +0000 (UTC) Subject: [PATCH] D76887: AMDGPU: Make HIPToolChain a subclass of ROCMToolChain In-Reply-To: References: Message-ID: <607acf5e6fc9c8fb468dfd84b619e571@localhost.localdomain> arsenm closed this revision. arsenm added a comment. 175e42303bb2a4253c65126666b1ae05b32b0004 , rebased to avoid dependence on ROCM toolchain patch CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76887/new/ https://reviews.llvm.org/D76887 From cfe-commits at lists.llvm.org Tue Mar 31 15:27:42 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 22:27:42 +0000 (UTC) Subject: [PATCH] D76862: HIP: Ensure new denormal mode attributes are set In-Reply-To: References: Message-ID: arsenm closed this revision. arsenm added a comment. c9d65a48af1d7bbfed7e785613cc9d9acf71821b CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76862/new/ https://reviews.llvm.org/D76862 From cfe-commits at lists.llvm.org Tue Mar 31 15:28:48 2020 From: cfe-commits at lists.llvm.org (Ben Langmuir via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 22:28:48 +0000 (UTC) Subject: [PATCH] D77180: Forward WrapperFrontendAction::shouldEraseOutputFiles() Message-ID: benlangmuir created this revision. benlangmuir added a reviewer: akyrtzi. Herald added subscribers: cfe-commits, dexonsmith. Herald added a project: clang. Per the documentation, this class is supposed to forward every virtual method, but we had missed on (shouldEraseOutputFiles). This fixes using a wrapped frontend action over the PCH generator when using -fallow-pch-with-compiler-errors. I do not think any upstream wrapper actions can test this. rdar://61110294 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77180 Files: clang/include/clang/Frontend/FrontendAction.h clang/lib/Frontend/FrontendAction.cpp Index: clang/lib/Frontend/FrontendAction.cpp =================================================================== --- clang/lib/Frontend/FrontendAction.cpp +++ clang/lib/Frontend/FrontendAction.cpp @@ -1081,6 +1081,9 @@ void WrapperFrontendAction::EndSourceFileAction() { WrappedAction->EndSourceFileAction(); } +bool WrapperFrontendAction::shouldEraseOutputFiles() { + return WrappedAction->shouldEraseOutputFiles(); +} bool WrapperFrontendAction::usesPreprocessorOnly() const { return WrappedAction->usesPreprocessorOnly(); Index: clang/include/clang/Frontend/FrontendAction.h =================================================================== --- clang/include/clang/Frontend/FrontendAction.h +++ clang/include/clang/Frontend/FrontendAction.h @@ -312,6 +312,7 @@ bool BeginSourceFileAction(CompilerInstance &CI) override; void ExecuteAction() override; void EndSourceFileAction() override; + bool shouldEraseOutputFiles() override; public: /// Construct a WrapperFrontendAction from an existing action, taking -------------- next part -------------- A non-text attachment was scrubbed... Name: D77180.254021.patch Type: text/x-patch Size: 1041 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 15:30:07 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 22:30:07 +0000 (UTC) Subject: [PATCH] D76950: HIP: Link correct denormal mode library In-Reply-To: References: Message-ID: <7a783cc2d7d4be1833f734ab70a86ee3@localhost.localdomain> arsenm added a comment. ping CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76950/new/ https://reviews.llvm.org/D76950 From cfe-commits at lists.llvm.org Tue Mar 31 15:45:38 2020 From: cfe-commits at lists.llvm.org (Alexey Bataev via cfe-commits) Date: Tue, 31 Mar 2020 15:45:38 -0700 (PDT) Subject: [clang] e094dd5 - [OPENMP50]Fix size calculation for array shaping expression in the Message-ID: <5e83c812.1c69fb81.5b6cf.0cf6@mx.google.com> Author: Alexey Bataev Date: 2020-03-31T18:45:21-04:00 New Revision: e094dd5adcbdd7f49226d93c3964f99bf5a25ba6 URL: https://github.com/llvm/llvm-project/commit/e094dd5adcbdd7f49226d93c3964f99bf5a25ba6 DIFF: https://github.com/llvm/llvm-project/commit/e094dd5adcbdd7f49226d93c3964f99bf5a25ba6.diff LOG: [OPENMP50]Fix size calculation for array shaping expression in the codegen. Need to include the size of the pointee type when trying to calculate the total size of the array shaping expression. Added: Modified: clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/CodeGen/CGOpenMPRuntime.cpp clang/lib/Sema/SemaExpr.cpp clang/test/OpenMP/depobj_codegen.cpp clang/test/OpenMP/task_codegen.c clang/test/OpenMP/task_depend_messages.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 26a9cabfc741..61bf2535e127 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10203,7 +10203,8 @@ def warn_nested_declare_variant "nested context ignored">, InGroup; def err_omp_non_pointer_type_array_shaping_base : Error< - "expected pointer type expression as a base of an array shaping operation">; + "expected expression with a pointer to a complete type as a base of an array " + "shaping operation">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index ae98433acb48..31fdc320d698 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -5374,7 +5374,7 @@ std::pair CGOpenMPRuntime::emitDependClause( llvm::Value *Size; QualType Ty = E->getType(); if (OASE) { - Size = llvm::ConstantInt::get(CGF.SizeTy,/*V=*/1); + Size = CGF.getTypeSize(OASE->getBase()->getType()->getPointeeType()); for (const Expr *SE : OASE->getDimensions()) { llvm::Value *Sz = CGF.EmitScalarExpr(SE); Sz = CGF.EmitScalarConversion(Sz, SE->getType(), diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 1a18eab72527..c0f8600aa0cc 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4817,10 +4817,13 @@ ExprResult Sema::ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, if (!BaseTy->isPointerType() && Base->isTypeDependent()) return OMPArrayShapingExpr::Create(Context, Context.DependentTy, Base, LParenLoc, RParenLoc, Dims, Brackets); - if (!BaseTy->isPointerType()) + if (!BaseTy->isPointerType() || + (!Base->isTypeDependent() && + BaseTy->getPointeeType()->isIncompleteType())) return ExprError(Diag(Base->getExprLoc(), diag::err_omp_non_pointer_type_array_shaping_base) << Base->getSourceRange()); + SmallVector NewDims; bool ErrorFound = false; for (Expr *Dim : Dims) { diff --git a/clang/test/OpenMP/depobj_codegen.cpp b/clang/test/OpenMP/depobj_codegen.cpp index 2c7509babc17..e51c607ac55a 100644 --- a/clang/test/OpenMP/depobj_codegen.cpp +++ b/clang/test/OpenMP/depobj_codegen.cpp @@ -21,7 +21,7 @@ void foo() {} template T tmain(T argc) { static T a; - void *argv; + int *argv; #pragma omp depobj(a) depend(in:argv, ([3][*(int*)argv][4])argv) #pragma omp depobj(argc) destroy #pragma omp depobj(argc) update(inout) @@ -99,12 +99,12 @@ int main(int argc, char **argv) { // CHECK: store i64 8, i64* [[SZ_ADDR]], // CHECK: [[FLAGS_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 2 // CHECK: store i8 1, i8* [[FLAGS_ADDR]], -// CHECK: [[SHAPE_ADDR:%.+]] = load i8*, i8** [[ARGV_ADDR:%.+]], -// CHECK: [[SZ1:%.+]] = mul nuw i64 3, %{{.+}} +// CHECK: [[SHAPE_ADDR:%.+]] = load i32*, i32** [[ARGV_ADDR:%.+]], +// CHECK: [[SZ1:%.+]] = mul nuw i64 12, %{{.+}} // CHECK: [[SZ:%.+]] = mul nuw i64 [[SZ1]], 4 // CHECK: [[BASE_ADDR:%.+]] = getelementptr inbounds [3 x %struct.kmp_depend_info], [3 x %struct.kmp_depend_info]* [[DEP_ADDR]], i{{.+}} 0, i{{.+}} 2 // CHECK: [[ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 0 -// CHECK: [[SHAPE:%.+]] = ptrtoint i8* [[SHAPE_ADDR]] to i64 +// CHECK: [[SHAPE:%.+]] = ptrtoint i32* [[SHAPE_ADDR]] to i64 // CHECK: store i64 [[SHAPE]], i64* [[ADDR]], // CHECK: [[SZ_ADDR:%.+]] = getelementptr inbounds %struct.kmp_depend_info, %struct.kmp_depend_info* [[BASE_ADDR]], i{{.+}} 0, i{{.+}} 1 // CHECK: store i64 [[SZ]], i64* [[SZ_ADDR]], diff --git a/clang/test/OpenMP/task_codegen.c b/clang/test/OpenMP/task_codegen.c index 9e4b3b59d6d5..0f01f11be8b3 100644 --- a/clang/test/OpenMP/task_codegen.c +++ b/clang/test/OpenMP/task_codegen.c @@ -58,7 +58,7 @@ int main() { // CHECK: store i8 1, i8* [[FLAGS_ADDR]], // CHECK: [[A:%.+]] = load i32, i32* [[A_ADDR]], // CHECK: [[A_CAST:%.+]] = sext i32 [[A]] to i64 - // CHECK: [[SZ1:%.+]] = mul nuw i64 3, [[A_CAST]] + // CHECK: [[SZ1:%.+]] = mul nuw i64 24, [[A_CAST]] // CHECK: [[A:%.+]] = load i32, i32* [[A_ADDR]], // CHECK: [[A_CAST:%.+]] = sext i32 [[A]] to i64 // CHECK: [[SZ:%.+]] = mul nuw i64 [[SZ1]], [[A_CAST]] diff --git a/clang/test/OpenMP/task_depend_messages.cpp b/clang/test/OpenMP/task_depend_messages.cpp index 7d976eca2ec1..f04c167cbdcc 100644 --- a/clang/test/OpenMP/task_depend_messages.cpp +++ b/clang/test/OpenMP/task_depend_messages.cpp @@ -67,8 +67,8 @@ int main(int argc, char **argv, char *env[]) { #pragma omp task depend(in : ([]) // omp45-error {{expected body of lambda expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error 2 {{expected expression}} #pragma omp task depend(in : ([])a // omp45-error {{expected body of lambda expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error {{expected expression}} #pragma omp task depend(in : ([])a) // omp45-error {{expected body of lambda expression}} omp50-error {{expected expression}} - #pragma omp task depend(in : ([a])a) // omp45-error {{expected body of lambda expression}} omp50-error {{expected pointer type expression as a base of an array shaping operation}} - #pragma omp task depend(in : ([a])argc) // omp45-error {{expected body of lambda expression}} omp50-error {{expected pointer type expression as a base of an array shaping operation}} + #pragma omp task depend(in : ([a])a) // omp45-error {{expected body of lambda expression}} omp50-error {{expected expression with a pointer to a complete type as a base of an array shaping operation}} + #pragma omp task depend(in : ([a])argc) // omp45-error {{expected body of lambda expression}} omp50-error {{expected expression with a pointer to a complete type as a base of an array shaping operation}} #pragma omp task depend(in : ([-1][0])argv) // omp45-error {{expected variable name or 'this' in lambda capture list}} omp45-error {{expected ')'}} omp45-note {{to match this '('}} omp50-error {{array shaping dimension is evaluated to a non-positive value -1}} omp50-error {{array shaping dimension is evaluated to a non-positive value 0}} foo(); From cfe-commits at lists.llvm.org Tue Mar 31 15:59:57 2020 From: cfe-commits at lists.llvm.org (Fangrui Song via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 22:59:57 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: <5e8075b6698fe90503ea0063c1e6c8dc@localhost.localdomain> MaskRay added inline comments. ================ Comment at: clang/lib/CodeGen/CGDecl.cpp:1814 + if (StopAfter) { + static unsigned Counter = 0; + if (Counter >= StopAfter) ---------------- I am a bit worried about the static variable. This makes CodeGen not reusable. ================ Comment at: clang/test/CodeGenCXX/auto-var-init-stop-after.cpp:1 +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern -ftrivial-auto-var-init-stop-after=2 %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN-STOP-AFTER-2 +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fblocks -ftrivial-auto-var-init=pattern -ftrivial-auto-var-init-stop-after=3 %s -emit-llvm -o - | FileCheck %s -check-prefix=PATTERN-STOP-AFTER-3 ---------------- You can drop `-fblocks`, because the test has nothing to do with the Blocks extension. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 From cfe-commits at lists.llvm.org Tue Mar 31 15:59:58 2020 From: cfe-commits at lists.llvm.org (Manoj Gupta via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 22:59:58 +0000 (UTC) Subject: [PATCH] D71082: Allow system header to provide their own implementation of some builtin In-Reply-To: References: Message-ID: <8bd731c684babdd4f4411fc59c658cfc@localhost.localdomain> manojgupta added a comment. Sure, I am trying to root cause the issue. Will report back hopefully soon. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71082/new/ https://reviews.llvm.org/D71082 From cfe-commits at lists.llvm.org Tue Mar 31 15:59:59 2020 From: cfe-commits at lists.llvm.org (Fady Ghanim via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 22:59:59 +0000 (UTC) Subject: [PATCH] D77112: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` In-Reply-To: References: Message-ID: <07f73cd434febefe2e076209c4374f9a@localhost.localdomain> fghanim added a comment. Figured as much, just wanted to be sure. Anyways, this one also LGTM I'll wait a couple of days in case any one has comments, if not I'll approve it Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77112/new/ https://reviews.llvm.org/D77112 From cfe-commits at lists.llvm.org Tue Mar 31 15:59:59 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 22:59:59 +0000 (UTC) Subject: [PATCH] D76950: HIP: Link correct denormal mode library In-Reply-To: References: Message-ID: <4201e60b93e32b2b80b53da1d107d75e@localhost.localdomain> yaxunl accepted this revision. yaxunl added a comment. This revision is now accepted and ready to land. LGTM. Thanks! ================ Comment at: clang/test/Driver/hip-device-libs.hip:5 -// Test flush-denormals-to-zero enabled uses oclc_daz_opt_on +// Test if if oclc_daz_opt_on or if oclc_daz_opt_off is linked depending on +// expected denormal mode. ---------------- dup if CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76950/new/ https://reviews.llvm.org/D76950 From cfe-commits at lists.llvm.org Tue Mar 31 16:00:01 2020 From: cfe-commits at lists.llvm.org (JF Bastien via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 23:00:01 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: <17eca56c410843158c510040937bceba@localhost.localdomain> jfb added a comment. I'm not sure this is a good idea at all. We want to keep the codepath as simple as possible to avoid introducing bugs. If a codebase sees a crash then it's easier to bisect one function at a time than doing something like this. I'd much rather see bisection using pragma to apply the `uninitialized` attribute to multiple declarations. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 From cfe-commits at lists.llvm.org Tue Mar 31 16:11:34 2020 From: cfe-commits at lists.llvm.org (Alexey Bataev via cfe-commits) Date: Tue, 31 Mar 2020 16:11:34 -0700 (PDT) Subject: [clang] c2aa543 - [OPENMP50]Codegen for array shaping expression in map clauses. Message-ID: <5e83ce26.1c69fb81.9d3a4.0f7c@mx.google.com> Author: Alexey Bataev Date: 2020-03-31T19:06:49-04:00 New Revision: c2aa543237843fa7b7c0191b6685062b3512f245 URL: https://github.com/llvm/llvm-project/commit/c2aa543237843fa7b7c0191b6685062b3512f245 DIFF: https://github.com/llvm/llvm-project/commit/c2aa543237843fa7b7c0191b6685062b3512f245.diff LOG: [OPENMP50]Codegen for array shaping expression in map clauses. Added codegen support for array shaping operations in map/to/from clauses. Added: Modified: clang/lib/CodeGen/CGOpenMPRuntime.cpp clang/lib/Sema/SemaOpenMP.cpp clang/test/OpenMP/target_data_ast_print.cpp clang/test/OpenMP/target_map_codegen.cpp clang/test/OpenMP/target_map_messages.cpp clang/test/OpenMP/target_update_ast_print.cpp clang/test/OpenMP/target_update_codegen.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 31fdc320d698..6642851a56bc 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -7448,6 +7448,20 @@ class MappableExprsHandler { llvm::Value *getExprTypeSize(const Expr *E) const { QualType ExprTy = E->getType().getCanonicalType(); + // Calculate the size for array shaping expression. + if (const auto *OAE = dyn_cast(E)) { + llvm::Value *Size = + CGF.getTypeSize(OAE->getBase()->getType()->getPointeeType()); + for (const Expr *SE : OAE->getDimensions()) { + llvm::Value *Sz = CGF.EmitScalarExpr(SE); + Sz = CGF.EmitScalarConversion(Sz, SE->getType(), + CGF.getContext().getSizeType(), + SE->getExprLoc()); + Size = CGF.Builder.CreateNUWMul(Size, Sz); + } + return Size; + } + // Reference types are ignored for mapping purposes. if (const auto *RefTy = ExprTy->getAs()) ExprTy = RefTy->getPointeeType().getCanonicalType(); @@ -7779,6 +7793,7 @@ class MappableExprsHandler { const Expr *AssocExpr = I->getAssociatedExpression(); const auto *AE = dyn_cast(AssocExpr); const auto *OASE = dyn_cast(AssocExpr); + const auto *OAShE = dyn_cast(AssocExpr); if (isa(AssocExpr)) { // The base is the 'this' pointer. The content of the pointer is going @@ -7788,6 +7803,11 @@ class MappableExprsHandler { (OASE && isa(OASE->getBase()->IgnoreParenImpCasts()))) { BP = CGF.EmitOMPSharedLValue(AssocExpr).getAddress(CGF); + } else if (OAShE && + isa(OAShE->getBase()->IgnoreParenCasts())) { + BP = Address( + CGF.EmitScalarExpr(OAShE->getBase()), + CGF.getContext().getTypeAlignInChars(OAShE->getBase()->getType())); } else { // The base is the reference to the variable. // BP = &Var. @@ -7870,9 +7890,12 @@ class MappableExprsHandler { // types. const auto *OASE = dyn_cast(I->getAssociatedExpression()); + const auto *OAShE = + dyn_cast(I->getAssociatedExpression()); const auto *UO = dyn_cast(I->getAssociatedExpression()); const auto *BO = dyn_cast(I->getAssociatedExpression()); bool IsPointer = + OAShE || (OASE && OMPArraySectionExpr::getBaseOriginalType(OASE) .getCanonicalType() ->isAnyPointerType()) || @@ -7890,8 +7913,15 @@ class MappableExprsHandler { isa(Next->getAssociatedExpression())) && "Unexpected expression"); - Address LB = CGF.EmitOMPSharedLValue(I->getAssociatedExpression()) - .getAddress(CGF); + Address LB = Address::invalid(); + if (OAShE) { + LB = Address(CGF.EmitScalarExpr(OAShE->getBase()), + CGF.getContext().getTypeAlignInChars( + OAShE->getBase()->getType())); + } else { + LB = CGF.EmitOMPSharedLValue(I->getAssociatedExpression()) + .getAddress(CGF); + } // If this component is a pointer inside the base struct then we don't // need to create any entry for it - it will be combined with the object diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index f9e8e3d6ccc8..7d2ae172fe4d 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -1943,7 +1943,8 @@ bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, if (isa(EI->getAssociatedExpression()) || isa(EI->getAssociatedExpression()) || - isa(EI->getAssociatedExpression())) { + isa(EI->getAssociatedExpression()) || + isa(EI->getAssociatedExpression())) { IsVariableAssociatedWithSection = true; // There is nothing more we need to know about this variable. return true; @@ -3225,7 +3226,7 @@ class DSAAttrChecker final : public StmtVisitor { StackComponents, OpenMPClauseKind) { // Variable is used if it has been marked as an array, array - // section or the variable iself. + // section, array shaping or the variable iself. return StackComponents.size() == 1 || std::all_of( std::next(StackComponents.rbegin()), @@ -3236,6 +3237,8 @@ class DSAAttrChecker final : public StmtVisitor { nullptr && (isa( MC.getAssociatedExpression()) || + isa( + MC.getAssociatedExpression()) || isa( MC.getAssociatedExpression())); }); @@ -3393,8 +3396,10 @@ class DSAAttrChecker final : public StmtVisitor { // Do both expressions have the same kind? if (CCI->getAssociatedExpression()->getStmtClass() != SC.getAssociatedExpression()->getStmtClass()) - if (!(isa( - SC.getAssociatedExpression()) && + if (!((isa( + SC.getAssociatedExpression()) || + isa( + SC.getAssociatedExpression())) && isa( CCI->getAssociatedExpression()))) return false; @@ -16284,6 +16289,15 @@ class MapBaseChecker final : public StmtVisitor { Components.emplace_back(OASE, nullptr); return RelevantExpr || Visit(E); } + bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { + Expr *Base = E->getBase(); + + // Record the component - we don't have any declaration associated. + Components.emplace_back(E, nullptr); + + return Visit(Base->IgnoreParenImpCasts()); + } + bool VisitUnaryOperator(UnaryOperator *UO) { if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || UO->getOpcode() != UO_Deref) { @@ -16409,9 +16423,11 @@ static bool checkMapConflicts( // variable in map clauses of the same construct. if (CurrentRegionOnly && (isa(CI->getAssociatedExpression()) || - isa(CI->getAssociatedExpression())) && + isa(CI->getAssociatedExpression()) || + isa(CI->getAssociatedExpression())) && (isa(SI->getAssociatedExpression()) || - isa(SI->getAssociatedExpression()))) { + isa(SI->getAssociatedExpression()) || + isa(SI->getAssociatedExpression()))) { SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), diag::err_omp_multiple_array_items_in_map_clause) << CI->getAssociatedExpression()->getSourceRange(); @@ -16443,6 +16459,9 @@ static bool checkMapConflicts( const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); Type = OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); + } else if (const auto *OASE = dyn_cast( + SI->getAssociatedExpression())) { + Type = OASE->getBase()->getType()->getPointeeType(); } if (Type.isNull() || Type->isAnyPointerType() || checkArrayExpressionDoesNotReferToWholeSize( @@ -16905,6 +16924,7 @@ static void checkMappableExpressionList( QualType Type; auto *ASE = dyn_cast(VE->IgnoreParens()); auto *OASE = dyn_cast(VE->IgnoreParens()); + auto *OAShE = dyn_cast(VE->IgnoreParens()); if (ASE) { Type = ASE->getType().getNonReferenceType(); } else if (OASE) { @@ -16915,6 +16935,8 @@ static void checkMappableExpressionList( else Type = BaseType->getPointeeType(); Type = Type.getNonReferenceType(); + } else if (OAShE) { + Type = OAShE->getBase()->getType()->getPointeeType(); } else { Type = VE->getType(); } diff --git a/clang/test/OpenMP/target_data_ast_print.cpp b/clang/test/OpenMP/target_data_ast_print.cpp index fa67c1834aa4..fcd6e928655c 100644 --- a/clang/test/OpenMP/target_data_ast_print.cpp +++ b/clang/test/OpenMP/target_data_ast_print.cpp @@ -1,10 +1,10 @@ -// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ast-print %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s -// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -ast-print %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s // expected-no-diagnostics #ifndef HEADER @@ -139,6 +139,8 @@ int main (int argc, char **argv) { static int a; // CHECK: static int a; +#pragma omp target data map(to: ([argc][3][a])argv) + // CHECK: #pragma omp target data map(to: ([argc][3][a])argv) #pragma omp target data map(to: c) // CHECK: #pragma omp target data map(to: c) a=2; diff --git a/clang/test/OpenMP/target_map_codegen.cpp b/clang/test/OpenMP/target_map_codegen.cpp index b9766e82ce03..ecfe50c01ea6 100644 --- a/clang/test/OpenMP/target_map_codegen.cpp +++ b/clang/test/OpenMP/target_map_codegen.cpp @@ -5353,5 +5353,81 @@ void explicit_maps_single (int ii){ // CK31: define {{.+}}[[CALL00]] // CK31: define {{.+}}[[CALL01]] +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK32 -verify -fopenmp -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK32 --check-prefix CK32-64 +// RUN: %clang_cc1 -DCK32 -fopenmp -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK32 --check-prefix CK32-64 +// RUN: %clang_cc1 -DCK32 -verify -fopenmp -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK32 --check-prefix CK32-32 +// RUN: %clang_cc1 -DCK32 -fopenmp -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK32 --check-prefix CK32-32 + +// RUN: %clang_cc1 -DCK32 -verify -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY32 %s +// RUN: %clang_cc1 -DCK32 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY32 %s +// RUN: %clang_cc1 -DCK32 -verify -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY32 %s +// RUN: %clang_cc1 -DCK32 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY32 %s +// SIMD-ONLY32-NOT: {{__kmpc|__tgt}} +#ifdef CK32 + +// CK32-DAG: [[MTYPE_TO:@.+]] = {{.+}}constant [1 x i64] [i64 33] +// CK32-DAG: [[MTYPE_FROM:@.+]] = {{.+}}constant [1 x i64] [i64 34] + +void array_shaping(float *f, int sa) { + + // CK32-DAG: call i32 @__tgt_target(i64 -1, i8* @{{.+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i64* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE_TO]]{{.+}}) + // CK32-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK32-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK32-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // CK32-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK32-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK32-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + + // CK32-DAG: [[BPC0:%.+]] = bitcast i8** [[BP0]] to float** + // CK32-DAG: [[PC0:%.+]] = bitcast i8** [[P0]] to float** + + // CK32-DAG: store float* [[F1:%.+]], float** [[BPC0]], + // CK32-DAG: store float* [[F2:%.+]], float** [[PC0]], + // CK32-DAG: store i64 [[SIZE:%.+]], i64* [[S0]], + + // CK32-DAG: [[F1]] = load float*, float** [[F_ADDR:%.+]], + // CK32-DAG: [[F2]] = load float*, float** [[F_ADDR]], + // CK32-64-DAG: [[SIZE]] = mul nuw i64 [[SZ1:%.+]], 4 + // CK32-64-DAG: [[SZ1]] = mul nuw i64 12, %{{.+}} + // CK32-32-DAG: [[SIZE]] = sext i32 [[SZ1:%.+]] to i64 + // CK32-32-DAG: [[SZ1]] = mul nuw i32 [[SZ2:%.+]], 4 + // CK32-32-DAG: [[SZ2]] = mul nuw i32 12, %{{.+}} + #pragma omp target map(to:([3][sa][4])f) + f[0] = 1; + sa = 1; + // CK32-DAG: call i32 @__tgt_target(i64 -1, i8* @{{.+}}, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i64* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE_FROM]]{{.+}}) + // CK32-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK32-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK32-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // CK32-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK32-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK32-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + + // CK32-DAG: [[BPC0:%.+]] = bitcast i8** [[BP0]] to float** + // CK32-DAG: [[PC0:%.+]] = bitcast i8** [[P0]] to float** + + // CK32-DAG: store float* [[F1:%.+]], float** [[BPC0]], + // CK32-DAG: store float* [[F2:%.+]], float** [[PC0]], + // CK32-DAG: store i64 [[SIZE:%.+]], i64* [[S0]], + + // CK32-DAG: [[F1]] = load float*, float** [[F_ADDR:%.+]], + // CK32-DAG: [[F2]] = load float*, float** [[F_ADDR]], + // CK32-64-DAG: [[SIZE]] = mul nuw i64 [[SZ1:%.+]], 5 + // CK32-64-DAG: [[SZ1]] = mul nuw i64 4, %{{.+}} + // CK32-32-DAG: [[SIZE]] = sext i32 [[SZ1:%.+]] to i64 + // CK32-32-DAG: [[SZ1]] = mul nuw i32 [[SZ2:%.+]], 5 + // CK32-32-DAG: [[SZ2]] = mul nuw i32 4, %{{.+}} + #pragma omp target map(from: ([sa][5])f) + f[0] = 1; +} + #endif #endif diff --git a/clang/test/OpenMP/target_map_messages.cpp b/clang/test/OpenMP/target_map_messages.cpp index 96932af6a04c..a18590fc85fe 100644 --- a/clang/test/OpenMP/target_map_messages.cpp +++ b/clang/test/OpenMP/target_map_messages.cpp @@ -140,6 +140,8 @@ struct SA { {} #pragma omp target map(close bf: a) // expected-error {{incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'}} {} + #pragma omp target map(([b[I]][bf])f) // le45-error {{expected ',' or ']' in lambda capture list}} le45-error {{expected ')'}} le45-note {{to match this '('}} + {} return; } }; @@ -189,203 +191,209 @@ void SAclient(int arg) { SD u; SC r(p),t(p); - #pragma omp target map(r) +#pragma omp target map(r) {} - #pragma omp target map(marr[2][0:2][0:2]) // expected-error {{array section does not specify contiguous storage}} +#pragma omp target map(marr[2] [0:2] [0:2]) // expected-error {{array section does not specify contiguous storage}} {} - #pragma omp target map(marr[:][0:2][0:2]) // expected-error {{array section does not specify contiguous storage}} +#pragma omp target map(marr[:] [0:2] [0:2]) // expected-error {{array section does not specify contiguous storage}} {} - #pragma omp target map(marr[2][3][0:2]) +#pragma omp target map(marr[2][3] [0:2]) {} - #pragma omp target map(marr[:][:][:]) +#pragma omp target map(marr[:][:][:]) {} - #pragma omp target map(marr[:2][:][:]) +#pragma omp target map(marr[:2][:][:]) {} - #pragma omp target map(marr[arg:][:][:]) +#pragma omp target map(marr [arg:][:][:]) {} - #pragma omp target map(marr[arg:]) +#pragma omp target map(marr [arg:]) {} - #pragma omp target map(marr[arg:][:arg][:]) // correct if arg is the size of dimension 2 +#pragma omp target map(marr [arg:][:arg][:]) // correct if arg is the size of dimension 2 {} - #pragma omp target map(marr[:arg][:]) +#pragma omp target map(marr[:arg][:]) {} - #pragma omp target map(marr[:arg][n:]) +#pragma omp target map(marr[:arg] [n:]) {} - #pragma omp target map(marr[:][:arg][n:]) // correct if arg is the size of dimension 2 +#pragma omp target map(marr[:][:arg] [n:]) // correct if arg is the size of dimension 2 {} - #pragma omp target map(marr[:][:m][n:]) // expected-error {{array section does not specify contiguous storage}} +#pragma omp target map(marr[:][:m] [n:]) // expected-error {{array section does not specify contiguous storage}} {} - #pragma omp target map(marr[n:m][:arg][n:]) +#pragma omp target map(marr [n:m][:arg] [n:]) {} - #pragma omp target map(marr[:2][:1][:]) // expected-error {{array section does not specify contiguous storage}} +#pragma omp target map(marr[:2][:1][:]) // expected-error {{array section does not specify contiguous storage}} {} - #pragma omp target map(marr[:2][1:][:]) // expected-error {{array section does not specify contiguous storage}} +#pragma omp target map(marr[:2] [1:][:]) // expected-error {{array section does not specify contiguous storage}} {} - #pragma omp target map(marr[:2][:][:1]) // expected-error {{array section does not specify contiguous storage}} +#pragma omp target map(marr[:2][:][:1]) // expected-error {{array section does not specify contiguous storage}} {} - #pragma omp target map(marr[:2][:][1:]) // expected-error {{array section does not specify contiguous storage}} +#pragma omp target map(marr[:2][:] [1:]) // expected-error {{array section does not specify contiguous storage}} {} - #pragma omp target map(marr[:1][:2][:]) +#pragma omp target map(marr[:1][:2][:]) {} - #pragma omp target map(marr[:1][0][:]) +#pragma omp target map(marr[:1][0][:]) {} - #pragma omp target map(marr[:arg][:2][:]) // correct if arg is 1 +#pragma omp target map(marr[:arg][:2][:]) // correct if arg is 1 {} - #pragma omp target map(marr[:1][3:1][:2]) +#pragma omp target map(marr[:1] [3:1][:2]) {} - #pragma omp target map(marr[:1][3:arg][:2]) // correct if arg is 1 +#pragma omp target map(marr[:1] [3:arg][:2]) // correct if arg is 1 {} - #pragma omp target map(marr[:1][3:2][:2]) // expected-error {{array section does not specify contiguous storage}} +#pragma omp target map(marr[:1] [3:2][:2]) // expected-error {{array section does not specify contiguous storage}} {} - #pragma omp target map(marr[:2][:10][:]) +#pragma omp target map(marr[:2][:10][:]) {} - #pragma omp target map(marr[:2][:][:5+5]) +#pragma omp target map(marr[:2][:][:5 + 5]) {} - #pragma omp target map(marr[:2][2+2-4:][0:5+5]) +#pragma omp target map(marr[:2] [2 + 2 - 4:] [0:5 + 5]) {} - #pragma omp target map(marr[:1][:2][0]) // expected-error {{array section does not specify contiguous storage}} +#pragma omp target map(marr[:1][:2][0]) // expected-error {{array section does not specify contiguous storage}} {} - #pragma omp target map(marr2[:1][:2][0]) +#pragma omp target map(marr2[:1][:2][0]) {} - #pragma omp target map(mvla[:1][:][0]) // correct if the size of dimension 2 is 1. +#pragma omp target map(mvla[:1][:][0]) // correct if the size of dimension 2 is 1. {} - #pragma omp target map(mvla[:2][:arg][:]) // correct if arg is the size of dimension 2. +#pragma omp target map(mvla[:2][:arg][:]) // correct if arg is the size of dimension 2. {} - #pragma omp target map(mvla[:1][:2][0]) // expected-error {{array section does not specify contiguous storage}} +#pragma omp target map(mvla[:1][:2][0]) // expected-error {{array section does not specify contiguous storage}} {} - #pragma omp target map(mvla[1][2:arg][:]) +#pragma omp target map(mvla[1] [2:arg][:]) {} - #pragma omp target map(mvla[:1][:][:]) +#pragma omp target map(mvla[:1][:][:]) {} - #pragma omp target map(mvla2[:1][:2][:11]) +#pragma omp target map(mvla2[:1][:2][:11]) {} - #pragma omp target map(mvla2[:1][:2][:10]) // expected-error {{array section does not specify contiguous storage}} +#pragma omp target map(mvla2[:1][:2][:10]) // expected-error {{array section does not specify contiguous storage}} {} - #pragma omp target map(mptr[:2][2+2-4:1][0:5+5]) // expected-error {{array section does not specify contiguous storage}} +#pragma omp target map(mptr[:2] [2 + 2 - 4:1] [0:5 + 5]) // expected-error {{array section does not specify contiguous storage}} {} - #pragma omp target map(mptr[:1][:2-1][2:4-3]) +#pragma omp target map(mptr[:1][:2 - 1] [2:4 - 3]) {} - #pragma omp target map(mptr[:1][:arg][2:4-3]) // correct if arg is 1. +#pragma omp target map(mptr[:1][:arg] [2:4 - 3]) // correct if arg is 1. {} - #pragma omp target map(mptr[:1][:2-1][0:2]) +#pragma omp target map(mptr[:1][:2 - 1] [0:2]) {} - #pragma omp target map(mptr[:1][:2][0:2]) // expected-error {{array section does not specify contiguous storage}} +#pragma omp target map(mptr[:1][:2] [0:2]) // expected-error {{array section does not specify contiguous storage}} {} - #pragma omp target map(mptr[:1][:][0:2]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} +#pragma omp target map(mptr[:1][:] [0:2]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} {} - #pragma omp target map(mptr[:2][:1][0:2]) // expected-error {{array section does not specify contiguous storage}} +#pragma omp target map(mptr[:2][:1] [0:2]) // expected-error {{array section does not specify contiguous storage}} {} - #pragma omp target map(r.ArrS[0].B) +#pragma omp target map(r.ArrS[0].B) {} - #pragma omp target map(r.ArrS[:1].B) // expected-error {{OpenMP array section is not allowed here}} +#pragma omp target map(r.ArrS[:1].B) // expected-error {{OpenMP array section is not allowed here}} {} - #pragma omp target map(r.ArrS[:arg].B) // expected-error {{OpenMP array section is not allowed here}} +#pragma omp target map(r.ArrS[:arg].B) // expected-error {{OpenMP array section is not allowed here}} {} - #pragma omp target map(r.ArrS[0].Arr[1:23]) +#pragma omp target map(r.ArrS[0].Arr [1:23]) {} - #pragma omp target map(r.ArrS[0].Arr[1:arg]) +#pragma omp target map(r.ArrS[0].Arr [1:arg]) {} - #pragma omp target map(r.ArrS[0].Arr[arg:23]) +#pragma omp target map(r.ArrS[0].Arr [arg:23]) {} - #pragma omp target map(r.ArrS[0].Error) // expected-error {{no member named 'Error' in 'SB'}} +#pragma omp target map(r.ArrS[0].Error) // expected-error {{no member named 'Error' in 'SB'}} {} - #pragma omp target map(r.ArrS[0].A, r.ArrS[1].A) // expected-error {{multiple array elements associated with the same variable are not allowed in map clauses of the same construct}} expected-note {{used here}} +#pragma omp target map(r.ArrS[0].A, r.ArrS[1].A) // expected-error {{multiple array elements associated with the same variable are not allowed in map clauses of the same construct}} expected-note {{used here}} {} - #pragma omp target map(r.ArrS[0].A, t.ArrS[1].A) +#pragma omp target map(r.ArrS[0].A, t.ArrS[1].A) {} - #pragma omp target map(r.PtrS[0], r.PtrS->B) // expected-error {{same pointer dereferenced in multiple diff erent ways in map clause expressions}} expected-note {{used here}} +#pragma omp target map(r.PtrS[0], r.PtrS->B) // expected-error {{same pointer dereferenced in multiple diff erent ways in map clause expressions}} expected-note {{used here}} {} - #pragma omp target map(r.PtrS, r.PtrS->B) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}} +#pragma omp target map(r.PtrS, r.PtrS->B) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}} {} - #pragma omp target map(r.PtrS->A, r.PtrS->B) +#pragma omp target map(r.PtrS->A, r.PtrS->B) {} - #pragma omp target map(r.RPtrS[0], r.RPtrS->B) // expected-error {{same pointer dereferenced in multiple diff erent ways in map clause expressions}} expected-note {{used here}} +#pragma omp target map(r.RPtrS[0], r.RPtrS->B) // expected-error {{same pointer dereferenced in multiple diff erent ways in map clause expressions}} expected-note {{used here}} {} - #pragma omp target map(r.RPtrS, r.RPtrS->B) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}} +#pragma omp target map(r.RPtrS, r.RPtrS->B) // expected-error {{pointer cannot be mapped along with a section derived from itself}} expected-note {{used here}} {} - #pragma omp target map(r.RPtrS->A, r.RPtrS->B) +#pragma omp target map(r.RPtrS->A, r.RPtrS->B) {} - #pragma omp target map(r.S.Arr[:12]) +#pragma omp target map(r.S.Arr[:12]) {} - #pragma omp target map(r.S.foo()[:12]) // le45-error {{expected expression containing only member accesses and/or array sections based on named variables}} le50-error {{expected addressable lvalue in 'map' clause}} +#pragma omp target map(r.S.foo() [:12]) // le45-error {{expected expression containing only member accesses and/or array sections based on named variables}} le50-error {{expected addressable lvalue in 'map' clause}} {} - #pragma omp target map(r.C, r.D) +#pragma omp target map(r.C, r.D) {} - #pragma omp target map(r.C, r.C) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} +#pragma omp target map(r.C, r.C) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} {} - #pragma omp target map(r.C) map(r.C) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} +#pragma omp target map(r.C) map(r.C) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} {} - #pragma omp target map(r.C, r.S) // this would be an error only caught at runtime - Sema would have to make sure there is not way for the missing data between fields to be mapped somewhere else. +#pragma omp target map(r.C, r.S) // this would be an error only caught at runtime - Sema would have to make sure there is not way for the missing data between fields to be mapped somewhere else. {} - #pragma omp target map(r, r.S) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} +#pragma omp target map(r, r.S) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}} {} - #pragma omp target map(r.C, t.C) +#pragma omp target map(r.C, t.C) {} - #pragma omp target map(r.A) // expected-error {{bit fields cannot be used to specify storage in a 'map' clause}} +#pragma omp target map(r.A) // expected-error {{bit fields cannot be used to specify storage in a 'map' clause}} {} - #pragma omp target map(r.Arr) +#pragma omp target map(r.Arr) {} - #pragma omp target map(r.Arr[3:5]) +#pragma omp target map(r.Arr [3:5]) {} - #pragma omp target map(r.Ptr[3:5]) +#pragma omp target map(r.Ptr [3:5]) {} - #pragma omp target map(r.ArrS[3:5].A) // expected-error {{OpenMP array section is not allowed here}} +#pragma omp target map(r.ArrS [3:5].A) // expected-error {{OpenMP array section is not allowed here}} {} - #pragma omp target map(r.ArrS[3:5].Arr[6:7]) // expected-error {{OpenMP array section is not allowed here}} +#pragma omp target map(r.ArrS [3:5].Arr [6:7]) // expected-error {{OpenMP array section is not allowed here}} {} - #pragma omp target map(r.ArrS[3].Arr[6:7]) +#pragma omp target map(r.ArrS[3].Arr [6:7]) {} - #pragma omp target map(r.S.Arr[4:5]) +#pragma omp target map(r.S.Arr [4:5]) {} - #pragma omp target map(r.S.Ptr[4:5]) +#pragma omp target map(r.S.Ptr [4:5]) {} - #pragma omp target map(r.S.Ptr[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} +#pragma omp target map(r.S.Ptr[:]) // expected-error {{section length is unspecified and cannot be inferred because subscripted value is not an array}} {} - #pragma omp target map((p+1)->A) // le45-error {{expected expression containing only member accesses and/or array sections based on named variables}} +#pragma omp target map((p + 1)->A) // le45-error {{expected expression containing only member accesses and/or array sections based on named variables}} {} - #pragma omp target map(u.B) // expected-error {{mapping of union members is not allowed}} +#pragma omp target map(u.B) // expected-error {{mapping of union members is not allowed}} {} - #pragma omp target +#pragma omp target { u.B = 0; r.S.foo(); } - #pragma omp target data map(to: r.C) //expected-note {{used here}} +#pragma omp target data map(to \ + : r.C) //expected-note {{used here}} { - #pragma omp target map(r.D) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} +#pragma omp target map(r.D) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}} {} } - #pragma omp target data map(to: t.Ptr) //expected-note {{used here}} +#pragma omp target data map(to \ + : t.Ptr) //expected-note {{used here}} { - #pragma omp target map(t.Ptr[:23]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} +#pragma omp target map(t.Ptr[:23]) // expected-error {{pointer cannot be mapped along with a section derived from itself}} {} } - #pragma omp target data map(to: t.C, t.D) +#pragma omp target data map(to \ + : t.C, t.D) { - #pragma omp target data map(to: t.C) +#pragma omp target data map(to \ + : t.C) { - #pragma omp target map(t.D) +#pragma omp target map(t.D) {} } } - #pragma omp target data map(marr[:][:][:]) +#pragma omp target data map(marr[:][:][:]) { - #pragma omp target data map(marr) +#pragma omp target data map(marr) {} } - #pragma omp target data map(to: t) +#pragma omp target data map(to \ + : t) { - #pragma omp target data map(to: t.C) +#pragma omp target data map(to \ + : t.C) { - #pragma omp target map(t.D) +#pragma omp target map(t.D) {} } } diff --git a/clang/test/OpenMP/target_update_ast_print.cpp b/clang/test/OpenMP/target_update_ast_print.cpp index e60e081b3210..fb6440b87cea 100644 --- a/clang/test/OpenMP/target_update_ast_print.cpp +++ b/clang/test/OpenMP/target_update_ast_print.cpp @@ -1,10 +1,10 @@ -// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s -// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s // expected-no-diagnostics #ifndef HEADER @@ -14,29 +14,29 @@ void foo() {} template T foo(T targ, U uarg) { - static T a; + static T a, *p; U b; int l; -#pragma omp target update to(a) if(l>5) device(l) nowait depend(inout:l) +#pragma omp target update to(([a][targ])p, a) if(l>5) device(l) nowait depend(inout:l) -#pragma omp target update from(b) if(l<5) device(l-1) nowait depend(inout:l) +#pragma omp target update from(b, ([a][targ])p) if(l<5) device(l-1) nowait depend(inout:l) return a + targ + (T)b; } -// CHECK: static T a; +// CHECK: static T a, *p; // CHECK-NEXT: U b; // CHECK-NEXT: int l; -// CHECK-NEXT: #pragma omp target update to(a) if(l > 5) device(l) nowait depend(inout : l){{$}} -// CHECK-NEXT: #pragma omp target update from(b) if(l < 5) device(l - 1) nowait depend(inout : l) -// CHECK: static int a; +// CHECK-NEXT: #pragma omp target update to(([a][targ])p,a) if(l > 5) device(l) nowait depend(inout : l){{$}} +// CHECK-NEXT: #pragma omp target update from(b,([a][targ])p) if(l < 5) device(l - 1) nowait depend(inout : l) +// CHECK: static int a, *p; // CHECK-NEXT: float b; // CHECK-NEXT: int l; -// CHECK-NEXT: #pragma omp target update to(a) if(l > 5) device(l) nowait depend(inout : l) -// CHECK-NEXT: #pragma omp target update from(b) if(l < 5) device(l - 1) nowait depend(inout : l) -// CHECK: static char a; +// CHECK-NEXT: #pragma omp target update to(([a][targ])p,a) if(l > 5) device(l) nowait depend(inout : l) +// CHECK-NEXT: #pragma omp target update from(b,([a][targ])p) if(l < 5) device(l - 1) nowait depend(inout : l) +// CHECK: static char a, *p; // CHECK-NEXT: float b; // CHECK-NEXT: int l; -// CHECK-NEXT: #pragma omp target update to(a) if(l > 5) device(l) nowait depend(inout : l) -// CHECK-NEXT: #pragma omp target update from(b) if(l < 5) device(l - 1) nowait depend(inout : l) +// CHECK-NEXT: #pragma omp target update to(([a][targ])p,a) if(l > 5) device(l) nowait depend(inout : l) +// CHECK-NEXT: #pragma omp target update from(b,([a][targ])p) if(l < 5) device(l - 1) nowait depend(inout : l) int main(int argc, char **argv) { static int a; diff --git a/clang/test/OpenMP/target_update_codegen.cpp b/clang/test/OpenMP/target_update_codegen.cpp index 479461e7ca80..fd5a62a8067c 100644 --- a/clang/test/OpenMP/target_update_codegen.cpp +++ b/clang/test/OpenMP/target_update_codegen.cpp @@ -984,5 +984,80 @@ void lvalue_find_base(float **f, SSA *sa) { #pragma omp target update from(*(sa->sa->i+*(1+sa->i+f))) } +#endif +///==========================================================================/// +// RUN: %clang_cc1 -DCK18 -verify -fopenmp -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-64 +// RUN: %clang_cc1 -DCK18 -fopenmp -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-64 +// RUN: %clang_cc1 -DCK18 -verify -fopenmp -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-32 +// RUN: %clang_cc1 -DCK18 -fopenmp -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK18 --check-prefix CK18-32 + +// RUN: %clang_cc1 -DCK18 -verify -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY18 %s +// RUN: %clang_cc1 -DCK18 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY18 %s +// RUN: %clang_cc1 -DCK18 -verify -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY18 %s +// RUN: %clang_cc1 -DCK18 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY18 %s +// SIMD-ONLY18-NOT: {{__kmpc|__tgt}} +#ifdef CK18 + +// CK18-DAG: [[MTYPE_TO:@.+]] = {{.+}}constant [1 x i64] [i64 33] +// CK18-DAG: [[MTYPE_FROM:@.+]] = {{.+}}constant [1 x i64] [i64 34] + +//CK18-LABEL: array_shaping +void array_shaping(float *f, int sa) { + + // CK18-DAG: call void @__tgt_target_data_update(i64 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i64* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE_TO]]{{.+}}) + // CK18-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK18-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK18-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // CK18-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK18-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK18-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + + // CK18-DAG: [[BPC0:%.+]] = bitcast i8** [[BP0]] to float** + // CK18-DAG: [[PC0:%.+]] = bitcast i8** [[P0]] to float** + + // CK18-DAG: store float* [[F1:%.+]], float** [[BPC0]], + // CK18-DAG: store float* [[F2:%.+]], float** [[PC0]], + // CK18-DAG: store i64 [[SIZE:%.+]], i64* [[S0]], + + // CK18-DAG: [[F1]] = load float*, float** [[F_ADDR:%.+]], + // CK18-DAG: [[F2]] = load float*, float** [[F_ADDR]], + // CK18-64-DAG: [[SIZE]] = mul nuw i64 [[SZ1:%.+]], 4 + // CK18-64-DAG: [[SZ1]] = mul nuw i64 12, %{{.+}} + // CK18-32-DAG: [[SIZE]] = sext i32 [[SZ1:%.+]] to i64 + // CK18-32-DAG: [[SZ1]] = mul nuw i32 [[SZ2:%.+]], 4 + // CK18-32-DAG: [[SZ2]] = mul nuw i32 12, %{{.+}} + #pragma omp target update to(([3][sa][4])f) + sa = 1; + // CK18-DAG: call void @__tgt_target_data_update(i64 -1, i32 1, i8** [[GEPBP:%.+]], i8** [[GEPP:%.+]], i64* [[GEPS:%.+]], {{.+}}getelementptr {{.+}}[1 x i{{.+}}]* [[MTYPE_FROM]]{{.+}}) + // CK18-DAG: [[GEPBP]] = getelementptr inbounds {{.+}}[[BP:%[^,]+]] + // CK18-DAG: [[GEPP]] = getelementptr inbounds {{.+}}[[P:%[^,]+]] + // CK18-DAG: [[GEPS]] = getelementptr inbounds {{.+}}[[S:%[^,]+]] + + // CK18-DAG: [[BP0:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 0 + // CK18-DAG: [[P0:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 0 + // CK18-DAG: [[S0:%.+]] = getelementptr inbounds {{.+}}[[S]], i{{.+}} 0, i{{.+}} 0 + + // CK18-DAG: [[BPC0:%.+]] = bitcast i8** [[BP0]] to float** + // CK18-DAG: [[PC0:%.+]] = bitcast i8** [[P0]] to float** + + // CK18-DAG: store float* [[F1:%.+]], float** [[BPC0]], + // CK18-DAG: store float* [[F2:%.+]], float** [[PC0]], + // CK18-DAG: store i64 [[SIZE:%.+]], i64* [[S0]], + + // CK18-DAG: [[F1]] = load float*, float** [[F_ADDR:%.+]], + // CK18-DAG: [[F2]] = load float*, float** [[F_ADDR]], + // CK18-64-DAG: [[SIZE]] = mul nuw i64 [[SZ1:%.+]], 5 + // CK18-64-DAG: [[SZ1]] = mul nuw i64 4, %{{.+}} + // CK18-32-DAG: [[SIZE]] = sext i32 [[SZ1:%.+]] to i64 + // CK18-32-DAG: [[SZ1]] = mul nuw i32 [[SZ2:%.+]], 5 + // CK18-32-DAG: [[SZ2]] = mul nuw i32 4, %{{.+}} + #pragma omp target update from(([sa][5])f) +} + #endif #endif From cfe-commits at lists.llvm.org Tue Mar 31 16:13:29 2020 From: cfe-commits at lists.llvm.org (Alexey Bataev via cfe-commits) Date: Tue, 31 Mar 2020 16:13:29 -0700 (PDT) Subject: [clang] 39ada46 - [OPENMP][DOCS]Mark array shaping as done, NFC. Message-ID: <5e83ce99.1c69fb81.35aea.0dff@mx.google.com> Author: Alexey Bataev Date: 2020-03-31T19:12:52-04:00 New Revision: 39ada4688936d165adf1a3c22b250034bab8f8a3 URL: https://github.com/llvm/llvm-project/commit/39ada4688936d165adf1a3c22b250034bab8f8a3 DIFF: https://github.com/llvm/llvm-project/commit/39ada4688936d165adf1a3c22b250034bab8f8a3.diff LOG: [OPENMP][DOCS]Mark array shaping as done, NFC. Added: Modified: clang/docs/OpenMPSupport.rst Removed: ################################################################################ diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst index 209a77440537..7fef9e867885 100644 --- a/clang/docs/OpenMPSupport.rst +++ b/clang/docs/OpenMPSupport.rst @@ -229,7 +229,7 @@ implementation. +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | base language | lambda support | :good:`done` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| misc extension | array shaping | :part:`worked on` | D74144 | +| misc extension | array shaping | :good:`done` | D74144 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | misc extension | library shutdown (omp_pause_resource[_all]) | :none:`unclaimed parts` | D55078 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ From cfe-commits at lists.llvm.org Tue Mar 31 16:20:46 2020 From: cfe-commits at lists.llvm.org (Ben Langmuir via cfe-commits) Date: Tue, 31 Mar 2020 16:20:46 -0700 (PDT) Subject: [clang] c322d32 - Forward WrapperFrontendAction::shouldEraseOutputFiles() Message-ID: <5e83d04e.1c69fb81.b122b.074b@mx.google.com> Author: Ben Langmuir Date: 2020-03-31T16:20:23-07:00 New Revision: c322d328aa331639f647711aee44c5dddfadd337 URL: https://github.com/llvm/llvm-project/commit/c322d328aa331639f647711aee44c5dddfadd337 DIFF: https://github.com/llvm/llvm-project/commit/c322d328aa331639f647711aee44c5dddfadd337.diff LOG: Forward WrapperFrontendAction::shouldEraseOutputFiles() Per the documentation, this class is supposed to forward every virtual method, but we had missed on (shouldEraseOutputFiles). This fixes using a wrapped frontend action over the PCH generator when using -fallow-pch-with-compiler-errors. I do not think any upstream wrapper actions can test this. Differential Revision: https://reviews.llvm.org/D77180 rdar://61110294 Added: Modified: clang/include/clang/Frontend/FrontendAction.h clang/lib/Frontend/FrontendAction.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Frontend/FrontendAction.h b/clang/include/clang/Frontend/FrontendAction.h index e994e24cf5af..c9f9f080c141 100644 --- a/clang/include/clang/Frontend/FrontendAction.h +++ b/clang/include/clang/Frontend/FrontendAction.h @@ -312,6 +312,7 @@ class WrapperFrontendAction : public FrontendAction { bool BeginSourceFileAction(CompilerInstance &CI) override; void ExecuteAction() override; void EndSourceFileAction() override; + bool shouldEraseOutputFiles() override; public: /// Construct a WrapperFrontendAction from an existing action, taking diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index 1dc85d967ca0..0155238dd0a8 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -1081,6 +1081,9 @@ void WrapperFrontendAction::ExecuteAction() { void WrapperFrontendAction::EndSourceFileAction() { WrappedAction->EndSourceFileAction(); } +bool WrapperFrontendAction::shouldEraseOutputFiles() { + return WrappedAction->shouldEraseOutputFiles(); +} bool WrapperFrontendAction::usesPreprocessorOnly() const { return WrappedAction->usesPreprocessorOnly(); From cfe-commits at lists.llvm.org Tue Mar 31 16:33:10 2020 From: cfe-commits at lists.llvm.org (Nico Weber via cfe-commits) Date: Tue, 31 Mar 2020 16:33:10 -0700 (PDT) Subject: [clang] 7ea64ae - [analyzer] Use IgnoreImpCasts() instead of reimplementing it. Message-ID: <5e83d336.1c69fb81.1e3bf.126b@mx.google.com> Author: Nico Weber Date: 2020-03-31T19:32:55-04:00 New Revision: 7ea64ae3afe4ad98e6753b9f74b30019113f719c URL: https://github.com/llvm/llvm-project/commit/7ea64ae3afe4ad98e6753b9f74b30019113f719c DIFF: https://github.com/llvm/llvm-project/commit/7ea64ae3afe4ad98e6753b9f74b30019113f719c.diff LOG: [analyzer] Use IgnoreImpCasts() instead of reimplementing it. No intended behavior change. Differential Revision: https://reviews.llvm.org/D77022 Added: Modified: clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp Removed: ################################################################################ diff --git a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp index e4b720df6b11..0b8d100992a2 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -508,13 +508,7 @@ void NullabilityChecker::checkEvent(ImplicitNullDerefEvent Event) const { /// return expressions of ObjC types when the return type of the function or /// method is non-null but the express is not. static const Expr *lookThroughImplicitCasts(const Expr *E) { - assert(E); - - while (auto *ICE = dyn_cast(E)) { - E = ICE->getSubExpr(); - } - - return E; + return E->IgnoreImpCasts(); } /// This method check when nullable pointer or null value is returned from a From cfe-commits at lists.llvm.org Tue Mar 31 16:34:01 2020 From: cfe-commits at lists.llvm.org (Arnold Schwaighofer via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 23:34:01 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift In-Reply-To: References: Message-ID: <65616a364ad2ff6783bae95a2c10f97d@localhost.localdomain> aschwaighofer marked an inline comment as done. aschwaighofer added inline comments. ================ Comment at: clang/lib/CodeGen/CGObjCRuntime.h:217 + /// ProtocolPtrTy. + virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) = 0; + ---------------- rjmccall wrote: > Can this name more closely parallel the "external" name, like `getOrEmitProtocolObject`? > > Also, I think we're incrementally lowercasing new method names. This is an already existing method. I just moved it higher in the class hierarchy to CGObjCRuntime from CGObjCMac so that it is callable from getOrEmitProtocolObject. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77077/new/ https://reviews.llvm.org/D77077 From cfe-commits at lists.llvm.org Tue Mar 31 16:34:06 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 23:34:06 +0000 (UTC) Subject: [PATCH] D76384: Move FPFeatures from BinaryOperator bitfields to Trailing storage In-Reply-To: References: Message-ID: rjmccall added inline comments. ================ Comment at: clang/include/clang/AST/Expr.h:3474 + static unsigned sizeOfTrailingObjects(bool hasFP, bool isCompound) { + return (hasFP ? 1 : 0) * sizeof(unsigned) + + (isCompound ? 2 : 0) * sizeof(QualType); ---------------- Sorry, I wasn't trying to say you need this here! Since you can use TrailingObjects for BinaryOperator, you absolutely should take advantage of what it does. I was just pointing you at the CallExpr stuff so that you can see the places you'll need to update when you add this storage to CallExpr. ================ Comment at: clang/include/clang/AST/Expr.h:3679 + return *getTrailingObjects(); + } + FPOptions getFPFeatures(const ASTContext &C) const { ---------------- I'm not sure it's a good idea to have this accessor, at least not with such a tempting name. Maybe `getStoredFPFeatures()` and `hasStoredFPFeatures()`? ================ Comment at: clang/include/clang/AST/Expr.h:3695 // operations on floating point types. bool isFEnvAccessOn() const { return getFPFeatures().allowFEnvAccess(); } ---------------- These two accessors will need to take `ASTContext`s eventually. Are you planning to do that in a follow-up patch? ================ Comment at: clang/include/clang/AST/JSONNodeDumper.h:265 void VisitBinaryOperator(const BinaryOperator *BO); - void VisitCompoundAssignOperator(const CompoundAssignOperator *CAO); + void VisitCompoundAssignOperator(const BinaryOperator *CAO); void VisitMemberExpr(const MemberExpr *ME); ---------------- What actually calls this? `StmtVisitor` as written doesn't fall back on a VisitCompoundAssignOperator. You could *make* it fall back on one, of course. ================ Comment at: clang/include/clang/AST/RecursiveASTVisitor.h:427 // CompoundAssignOperator) but do have visitors. -#define OPERATOR(NAME) \ - GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator) +#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME##Assign, BinaryOperator) ---------------- Comment needs updating. ================ Comment at: clang/include/clang/AST/StmtVisitor.h:146 + RetTy VisitBin##NAME(PTR(BinaryOperator) S, ParamTys... P) { \ + DISPATCH(BinAssign, BinaryOperator); \ } ---------------- Comment needs updating, but more importantly, you're making all of these fall back on `VisitBinAssign`, which is definitely not correct. ================ Comment at: clang/include/clang/Basic/LangOptions.h:394 + return true; + } + ---------------- The problem with having both functions that take `ASTContext`s and functions that don't is that it's easy to mix them, so they either need to have the same behavior (in which case it's pointless to have an overload that takes the `ASTContext`) or you're making something really error-prone. I would feel a lot more confident that you were designing and using these APIs correctly if you actually took advantage of the ability to not store trailing FPOptions in some case, like when they match the global settings in the ASTContext. That way you'll actually be verifying that everything behaves correctly if nodes don't store FPOptions. If you do that, I think you'll see my point about not having all these easily-confusable functions that do or do not take `ASTContext`s.. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76384/new/ https://reviews.llvm.org/D76384 From cfe-commits at lists.llvm.org Tue Mar 31 16:34:06 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 23:34:06 +0000 (UTC) Subject: [PATCH] D72467: Remove "mask" operand from shufflevector. In-Reply-To: References: Message-ID: <96c863ead117b27d0fe3eda008584e46@localhost.localdomain> efriedma added a comment. (Also merged followup https://github.com/llvm/llvm-project/commit/ba4764c2cc14b0b495af539a913de10cf8268420 to fix a memory leak caught by the bots.) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72467/new/ https://reviews.llvm.org/D72467 From cfe-commits at lists.llvm.org Tue Mar 31 16:34:10 2020 From: cfe-commits at lists.llvm.org (Jian Cai via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 23:34:10 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: jcai19 added a comment. Agreed, but having this option may save quite some time when bisecting files with many functions and stack variables, like this one . It will be much easier to write a script that automates the bisection process. What do you think? Thanks. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 From cfe-commits at lists.llvm.org Tue Mar 31 16:34:11 2020 From: cfe-commits at lists.llvm.org (Arnold Schwaighofer via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 23:34:11 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift In-Reply-To: References: Message-ID: aschwaighofer marked an inline comment as done. aschwaighofer added inline comments. ================ Comment at: clang/lib/CodeGen/CGObjCRuntime.h:217 + /// ProtocolPtrTy. + virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) = 0; + ---------------- aschwaighofer wrote: > rjmccall wrote: > > Can this name more closely parallel the "external" name, like `getOrEmitProtocolObject`? > > > > Also, I think we're incrementally lowercasing new method names. > This is an already existing method. I just moved it higher in the class hierarchy to CGObjCRuntime from CGObjCMac so that it is callable from getOrEmitProtocolObject. s/getOrEmitProtocolObject/emitObjCProtocolObject Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77077/new/ https://reviews.llvm.org/D77077 From cfe-commits at lists.llvm.org Tue Mar 31 16:35:09 2020 From: cfe-commits at lists.llvm.org (Ben Langmuir via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 23:35:09 +0000 (UTC) Subject: [PATCH] D77180: Forward WrapperFrontendAction::shouldEraseOutputFiles() In-Reply-To: References: Message-ID: <5e792ffaeda05d10ca23f338594ec38c@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGc322d328aa33: Forward WrapperFrontendAction::shouldEraseOutputFiles() (authored by benlangmuir). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77180/new/ https://reviews.llvm.org/D77180 Files: clang/include/clang/Frontend/FrontendAction.h clang/lib/Frontend/FrontendAction.cpp Index: clang/lib/Frontend/FrontendAction.cpp =================================================================== --- clang/lib/Frontend/FrontendAction.cpp +++ clang/lib/Frontend/FrontendAction.cpp @@ -1081,6 +1081,9 @@ void WrapperFrontendAction::EndSourceFileAction() { WrappedAction->EndSourceFileAction(); } +bool WrapperFrontendAction::shouldEraseOutputFiles() { + return WrappedAction->shouldEraseOutputFiles(); +} bool WrapperFrontendAction::usesPreprocessorOnly() const { return WrappedAction->usesPreprocessorOnly(); Index: clang/include/clang/Frontend/FrontendAction.h =================================================================== --- clang/include/clang/Frontend/FrontendAction.h +++ clang/include/clang/Frontend/FrontendAction.h @@ -312,6 +312,7 @@ bool BeginSourceFileAction(CompilerInstance &CI) override; void ExecuteAction() override; void EndSourceFileAction() override; + bool shouldEraseOutputFiles() override; public: /// Construct a WrapperFrontendAction from an existing action, taking -------------- next part -------------- A non-text attachment was scrubbed... Name: D77180.254042.patch Type: text/x-patch Size: 1041 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 16:35:26 2020 From: cfe-commits at lists.llvm.org (Nico Weber via Phabricator via cfe-commits) Date: Tue, 31 Mar 2020 23:35:26 +0000 (UTC) Subject: [PATCH] D77022: [analyzer] Use IgnoreImpCasts() instead of reimplementing it. In-Reply-To: References: Message-ID: <66dd9e4bacc94f28755d7ab163366f01@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG7ea64ae3afe4: [analyzer] Use IgnoreImpCasts() instead of reimplementing it. (authored by thakis). Herald added a project: clang. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77022/new/ https://reviews.llvm.org/D77022 Files: clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp Index: clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -508,13 +508,7 @@ /// return expressions of ObjC types when the return type of the function or /// method is non-null but the express is not. static const Expr *lookThroughImplicitCasts(const Expr *E) { - assert(E); - - while (auto *ICE = dyn_cast(E)) { - E = ICE->getSubExpr(); - } - - return E; + return E->IgnoreImpCasts(); } /// This method check when nullable pointer or null value is returned from a -------------- next part -------------- A non-text attachment was scrubbed... Name: D77022.254043.patch Type: text/x-patch Size: 696 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 17:12:30 2020 From: cfe-commits at lists.llvm.org (Fangrui Song via cfe-commits) Date: Tue, 31 Mar 2020 17:12:30 -0700 (PDT) Subject: [clang] 4805901 - [Driver] Don't pass -fmessage-length=0 to CC1 Message-ID: <5e83dc6e.1c69fb81.af8bc.1155@mx.google.com> Author: Fangrui Song Date: 2020-03-31T17:12:08-07:00 New Revision: 4805901930f27f80d3b97ccd88e4f5240b784abd URL: https://github.com/llvm/llvm-project/commit/4805901930f27f80d3b97ccd88e4f5240b784abd DIFF: https://github.com/llvm/llvm-project/commit/4805901930f27f80d3b97ccd88e4f5240b784abd.diff LOG: [Driver] Don't pass -fmessage-length=0 to CC1 -fmessage-length=0 is common (unless the environment variable COLUMNS is set and exported. This simplifies a common CC1 command line. Added: clang/test/Driver/fmessage-length.c Modified: clang/include/clang/Driver/CC1Options.td clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/Driver/rewrite-legacy-objc.m clang/test/Driver/rewrite-objc.m clang/test/Frontend/source-col-map.c clang/test/Misc/diag-line-wrapping.cpp clang/test/Misc/message-length.c clang/test/Misc/unnecessary-elipses.cpp clang/test/Misc/unprintable.c clang/test/Misc/wrong-encoding2.c Removed: ################################################################################ diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index a40923392c94..a9e2e306632b 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -453,8 +453,6 @@ def fspell_checking_limit : Separate<["-"], "fspell-checking-limit">, MetaVarNam def fcaret_diagnostics_max_lines : Separate<["-"], "fcaret-diagnostics-max-lines">, MetaVarName<"">, HelpText<"Set the maximum number of source lines to show in a caret diagnostic">; -def fmessage_length : Separate<["-"], "fmessage-length">, MetaVarName<"">, - HelpText<"Format message diagnostics so that they fit within N columns or fewer, when possible.">; def verify_EQ : CommaJoined<["-"], "verify=">, MetaVarName<"">, HelpText<"Verify diagnostic output using comment directives that start with" diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 635fe67095ff..e413a8600bf0 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1364,7 +1364,8 @@ def fmacro_backtrace_limit_EQ : Joined<["-"], "fmacro-backtrace-limit=">, Group, Flags<[DriverOption, CoreOption]>; def fmerge_all_constants : Flag<["-"], "fmerge-all-constants">, Group, Flags<[CC1Option, CoreOption]>, HelpText<"Allow merging of constants">; -def fmessage_length_EQ : Joined<["-"], "fmessage-length=">, Group; +def fmessage_length_EQ : Joined<["-"], "fmessage-length=">, Group, Flags<[CC1Option]>, + HelpText<"Format message diagnostics so that they fit within N columns">; def fms_extensions : Flag<["-"], "fms-extensions">, Group, Flags<[CC1Option, CoreOption]>, HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">; def fms_compatibility : Flag<["-"], "fms-compatibility">, Group, Flags<[CC1Option, CoreOption]>, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index f22e1082357d..661a02f858e6 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5130,15 +5130,20 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } // Pass -fmessage-length=. - CmdArgs.push_back("-fmessage-length"); + unsigned MessageLength = 0; if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) { - CmdArgs.push_back(A->getValue()); + StringRef V(A->getValue()); + if (V.getAsInteger(0, MessageLength)) + D.Diag(diag::err_drv_invalid_argument_to_option) + << V << A->getOption().getName(); } else { // If -fmessage-length=N was not specified, determine whether this is a // terminal and, if so, implicitly define -fmessage-length appropriately. - unsigned N = llvm::sys::Process::StandardErrColumns(); - CmdArgs.push_back(Args.MakeArgString(Twine(N))); + MessageLength = llvm::sys::Process::StandardErrColumns(); } + if (MessageLength != 0) + CmdArgs.push_back( + Args.MakeArgString("-fmessage-length=" + Twine(MessageLength))); // -fvisibility= and -fvisibility-ms-compat are of a piece. if (const Arg *A = Args.getLastArg(options::OPT_fvisibility_EQ, diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 46ba46df8999..5bfad6f1de6c 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1675,7 +1675,8 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Diags->Report(diag::warn_ignoring_ftabstop_value) << Opts.TabStop << DiagnosticOptions::DefaultTabStop; } - Opts.MessageLength = getLastArgIntValue(Args, OPT_fmessage_length, 0, Diags); + Opts.MessageLength = + getLastArgIntValue(Args, OPT_fmessage_length_EQ, 0, Diags); addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, Opts.Warnings); addDiagnosticArgs(Args, OPT_R_Group, OPT_R_value_Group, Opts.Remarks); diff --git a/clang/test/Driver/fmessage-length.c b/clang/test/Driver/fmessage-length.c new file mode 100644 index 000000000000..638add05b2e5 --- /dev/null +++ b/clang/test/Driver/fmessage-length.c @@ -0,0 +1,9 @@ +// RUN: %clang -### -c %s -fmessage-length=80 2>&1 | FileCheck %s +// CHECK: "-fmessage-length=80" + +/// Omit -fmessage-length=0 to simplify common CC1 command lines. +// RUN: %clang -### -c %s -fmessage-length=0 2>&1 | FileCheck --check-prefix=ZERO %s +// ZERO-NOT: "-fmessage-length=0" + +// RUN: %clang -### -c %s -fmessage-length=nan 2>&1 | FileCheck --check-prefix=ERR %s +// ERR: error: invalid argument 'nan' to -fmessage-length= diff --git a/clang/test/Driver/rewrite-legacy-objc.m b/clang/test/Driver/rewrite-legacy-objc.m index dc92dd4bf107..3bbdd66c9cc0 100644 --- a/clang/test/Driver/rewrite-legacy-objc.m +++ b/clang/test/Driver/rewrite-legacy-objc.m @@ -3,11 +3,11 @@ // TEST0: clang{{.*}}" "-cc1" // TEST0: "-rewrite-objc" // FIXME: CHECK-NOT is broken somehow, it doesn't work here. Check adjacency instead. -// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx-fragile" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fmax-type-align=16" "-fdiagnostics-show-option" +// TEST0: "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx-fragile" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fmax-type-align=16" "-fdiagnostics-show-option" // TEST0: rewrite-legacy-objc.m" // RUN: %clang -no-canonical-prefixes -target i386-apple-macosx10.9.0 -rewrite-legacy-objc %s -o - -### 2>&1 | \ // RUN: FileCheck -check-prefix=TEST1 %s // RUN: %clang -no-canonical-prefixes -target i386-apple-macosx10.6.0 -rewrite-legacy-objc %s -o - -### 2>&1 | \ // RUN: FileCheck -check-prefix=TEST2 %s -// TEST1: "-fmessage-length" "0" "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx-fragile" "-fobjc-subscripting-legacy-runtime" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fmax-type-align=16" "-fdiagnostics-show-option" -// TEST2: "-fmessage-length" "0" "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx-fragile" "-fobjc-subscripting-legacy-runtime" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fmax-type-align=16" "-fdiagnostics-show-option" +// TEST1: "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx-fragile" "-fobjc-subscripting-legacy-runtime" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fmax-type-align=16" "-fdiagnostics-show-option" +// TEST2: "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx-fragile" "-fobjc-subscripting-legacy-runtime" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fmax-type-align=16" "-fdiagnostics-show-option" diff --git a/clang/test/Driver/rewrite-objc.m b/clang/test/Driver/rewrite-objc.m index b04062992b7f..b1bbad11f265 100644 --- a/clang/test/Driver/rewrite-objc.m +++ b/clang/test/Driver/rewrite-objc.m @@ -3,4 +3,4 @@ // TEST0: clang{{.*}}" "-cc1" // TEST0: "-rewrite-objc" // FIXME: CHECK-NOT is broken somehow, it doesn't work here. Check adjacency instead. -// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fmax-type-align=16" "-fdiagnostics-show-option" +// TEST0: "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fmax-type-align=16" "-fdiagnostics-show-option" diff --git a/clang/test/Frontend/source-col-map.c b/clang/test/Frontend/source-col-map.c index 1c8078998c56..b257261b8b2b 100644 --- a/clang/test/Frontend/source-col-map.c +++ b/clang/test/Frontend/source-col-map.c @@ -1,4 +1,4 @@ -// RUN: not %clang_cc1 -fsyntax-only -fmessage-length 75 -o /dev/null -x c < %s 2>&1 | FileCheck %s -strict-whitespace +// RUN: not %clang_cc1 -fsyntax-only -fmessage-length=75 -o /dev/null -x c < %s 2>&1 | FileCheck %s -strict-whitespace // REQUIRES: utf8-capable-terminal // Test case for the text diagnostics source column conversion crash. diff --git a/clang/test/Misc/diag-line-wrapping.cpp b/clang/test/Misc/diag-line-wrapping.cpp index 2bcb03f9781c..9e8cb9b53da5 100644 --- a/clang/test/Misc/diag-line-wrapping.cpp +++ b/clang/test/Misc/diag-line-wrapping.cpp @@ -1,5 +1,5 @@ -// RUN: not %clang_cc1 -fsyntax-only -fmessage-length 60 %s 2>&1 | FileCheck %s -// RUN: not %clang_cc1 -fsyntax-only -fmessage-length 0 %s 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -fsyntax-only -fmessage-length=60 %s 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -fsyntax-only -fmessage-length=0 %s 2>&1 | FileCheck %s struct B { void f(); }; struct D1 : B {}; diff --git a/clang/test/Misc/message-length.c b/clang/test/Misc/message-length.c index a6f4f44e6b9c..1e0b4edb7c03 100644 --- a/clang/test/Misc/message-length.c +++ b/clang/test/Misc/message-length.c @@ -1,6 +1,6 @@ -// RUN: not %clang_cc1 -fmessage-length 72 %s 2>&1 | FileCheck -strict-whitespace %s -// RUN: not %clang_cc1 -fmessage-length 1 %s -// RUN: not %clang_cc1 -fmessage-length 8 %s 2>&1 | FileCheck -check-prefix=CHECK-DOT %s +// RUN: not %clang_cc1 -fmessage-length=72 %s 2>&1 | FileCheck -strict-whitespace %s +// RUN: not %clang_cc1 -fmessage-length=1 %s +// RUN: not %clang_cc1 -fmessage-length=8 %s 2>&1 | FileCheck -check-prefix=CHECK-DOT %s // Hack so we can check things better, force the file name and line. # 1 "FILE" 1 diff --git a/clang/test/Misc/unnecessary-elipses.cpp b/clang/test/Misc/unnecessary-elipses.cpp index 2ee725869b5c..c8c178c37f6c 100644 --- a/clang/test/Misc/unnecessary-elipses.cpp +++ b/clang/test/Misc/unnecessary-elipses.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -fmessage-length 80 %s 2>&1 | FileCheck -strict-whitespace %s +// RUN: %clang_cc1 -fsyntax-only -fmessage-length=80 %s 2>&1 | FileCheck -strict-whitespace %s int main() { "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; @@ -12,4 +12,4 @@ int main() { "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ; // CHECK: {{^ ..."xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"...}} -} \ No newline at end of file +} diff --git a/clang/test/Misc/unprintable.c b/clang/test/Misc/unprintable.c index eaa4f34d8028..30e449456630 100644 --- a/clang/test/Misc/unprintable.c +++ b/clang/test/Misc/unprintable.c @@ -1,4 +1,4 @@ -// RUN: not %clang_cc1 %s -fmessage-length 40 2>&1 | FileCheck -strict-whitespace %s +// RUN: not %clang_cc1 %s -fmessage-length=40 2>&1 | FileCheck -strict-whitespace %s int main() { int i; diff --git a/clang/test/Misc/wrong-encoding2.c b/clang/test/Misc/wrong-encoding2.c index 43a0f4e900ed..b60ed7f92b86 100644 --- a/clang/test/Misc/wrong-encoding2.c +++ b/clang/test/Misc/wrong-encoding2.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -fmessage-length 100 %s 2>&1 | FileCheck -strict-whitespace %s +// RUN: %clang_cc1 -fsyntax-only -fmessage-length=100 %s 2>&1 | FileCheck -strict-whitespace %s // REQUIRES: asserts int main() { From cfe-commits at lists.llvm.org Tue Mar 31 17:33:46 2020 From: cfe-commits at lists.llvm.org (via cfe-commits) Date: Tue, 31 Mar 2020 17:33:46 -0700 (PDT) Subject: [clang] f93aed6 - Fix diagnostics where _Atomic can't be applied Message-ID: <5e83e16a.1c69fb81.183aa.17ba@mx.google.com> Author: Weverything Date: 2020-03-31T17:23:35-07:00 New Revision: f93aed66f22f230213a99205f8bcec975c45d8ba URL: https://github.com/llvm/llvm-project/commit/f93aed66f22f230213a99205f8bcec975c45d8ba DIFF: https://github.com/llvm/llvm-project/commit/f93aed66f22f230213a99205f8bcec975c45d8ba.diff LOG: Fix diagnostics where _Atomic can't be applied adb290d97482aa9311ee4b4b5917a0f2ece55b30 added a new case to err_atomic_specifier_bad_type. The diagnostic has two %select's controlled by the same argument, but only the first was updated to have the new case. Add the extra case for the second %select and add a test case that exercises the last case. Added: Modified: clang/include/clang/Basic/DiagnosticSemaKinds.td clang/test/SemaCXX/atomic-type.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 61bf2535e127..951a955984f6 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5946,7 +5946,7 @@ def err_func_def_incomplete_result : Error< def err_atomic_specifier_bad_type : Error< "_Atomic cannot be applied to " "%select{incomplete |array |function |reference |atomic |qualified |sizeless |}0type " - "%1 %select{||||||which is not trivially copyable}0">; + "%1 %select{|||||||which is not trivially copyable}0">; // Expressions. def select_unary_expr_or_type_trait_kind : TextSubstitution< diff --git a/clang/test/SemaCXX/atomic-type.cpp b/clang/test/SemaCXX/atomic-type.cpp index 1ed321e47b9a..d7d8bbba50ca 100644 --- a/clang/test/SemaCXX/atomic-type.cpp +++ b/clang/test/SemaCXX/atomic-type.cpp @@ -103,3 +103,11 @@ namespace copy_init { bool PR21836(_Atomic(int) *x) { // expected-warning {{'_Atomic' is a C11 extension}} return *x; } + +namespace non_trivially_copyable { + struct S { + ~S() {} + }; + _Atomic S s; // expected-error {{_Atomic cannot be applied to type 'non_trivially_copyable::S' which is not trivially copyable}} \ + // expected-warning {{'_Atomic' is a C11 extension}} +} From cfe-commits at lists.llvm.org Tue Mar 31 17:39:31 2020 From: cfe-commits at lists.llvm.org (Thomas Lively via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 00:39:31 +0000 (UTC) Subject: [PATCH] D77185: [WebAssembly] Rename SIMD min/max/avgr intrinsics for consistency Message-ID: tlively created this revision. tlively added a reviewer: aheejin. Herald added subscribers: cfe-commits, sunfish, jgravelle-google, sbc100, dschuff. Herald added a project: clang. The convention for the wasm_simd128.h intrinsics is to have the integer sign in the lane interpretation rather than as a suffix. This PR changes the names of the integer min, max, and avgr intrinsics to match this convention. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77185 Files: clang/lib/Headers/wasm_simd128.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D77185.254047.patch Type: text/x-patch Size: 5670 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 17:39:36 2020 From: cfe-commits at lists.llvm.org (JF Bastien via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 00:39:36 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: <839ae944477cda1dd0a117921e96c05c@localhost.localdomain> jfb added a comment. I'd much rather see folks bisect using something like: void use(void*); #pragma clang attribute push ([[clang::uninitialized]], apply_to = variable) void buggy() { int arr[256]; int boom; float bam; struct { int oops; } oops; union { int oof; float aaaaa; } oof; use(&arr); use(&boom); use(&bam); use(&oops); use(&oof); } #pragma clang attribute pop This should be easy to add support for. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 From cfe-commits at lists.llvm.org Tue Mar 31 17:39:37 2020 From: cfe-commits at lists.llvm.org (Csaba Dabis via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 00:39:37 +0000 (UTC) Subject: [PATCH] D69726: [analyzer] DynamicSize: Store the dynamic size In-Reply-To: References: Message-ID: Charusso updated this revision to Diff 254051. Charusso added a comment. - Remove the last gymnastic. - Rebase. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D69726/new/ https://reviews.llvm.org/D69726 Files: clang/docs/analyzer/developer-docs/DebugChecks.rst clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h clang/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp clang/lib/StaticAnalyzer/Core/DynamicSize.cpp clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp clang/lib/StaticAnalyzer/Core/MemRegion.cpp clang/test/Analysis/explain-svals.cpp clang/test/Analysis/expr-inspection.cpp clang/test/Analysis/memory-model.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D69726.254051.patch Type: text/x-patch Size: 32635 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 17:39:38 2020 From: cfe-commits at lists.llvm.org (Paula Toth via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 00:39:38 +0000 (UTC) Subject: [PATCH] D76818: [clang-tidy] Add check llvmlibc-implementation-in-namespace. In-Reply-To: References: Message-ID: PaulkaToast added a comment. Friendly Ping @njames93 (: Any other changes needed? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76818/new/ https://reviews.llvm.org/D76818 From cfe-commits at lists.llvm.org Tue Mar 31 17:50:55 2020 From: cfe-commits at lists.llvm.org (Fangrui Song via cfe-commits) Date: Tue, 31 Mar 2020 17:50:55 -0700 (PDT) Subject: [clang] 3341dc7 - [Driver] Don't pass -fobjc-rumtime= for non-ObjC input Message-ID: <5e83e56f.1c69fb81.82e71.1a05@mx.google.com> Author: Fangrui Song Date: 2020-03-31T17:50:37-07:00 New Revision: 3341dc7339969d3cb1bff30b49d866db041d689b URL: https://github.com/llvm/llvm-project/commit/3341dc7339969d3cb1bff30b49d866db041d689b DIFF: https://github.com/llvm/llvm-project/commit/3341dc7339969d3cb1bff30b49d866db041d689b.diff LOG: [Driver] Don't pass -fobjc-rumtime= for non-ObjC input Added: Modified: clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Driver/ToolChains/Clang.h clang/test/Driver/darwin-objc-options.m Removed: ################################################################################ diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 661a02f858e6..197fe07cb012 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5613,7 +5613,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fexperimental_new_pass_manager, options::OPT_fno_experimental_new_pass_manager); - ObjCRuntime Runtime = AddObjCRuntimeArgs(Args, CmdArgs, rewriteKind); + ObjCRuntime Runtime = AddObjCRuntimeArgs(Args, Inputs, CmdArgs, rewriteKind); RenderObjCOptions(TC, D, RawTriple, Args, Runtime, rewriteKind != RK_None, Input, CmdArgs); @@ -6257,6 +6257,7 @@ Clang::~Clang() {} /// /// Returns true if the runtime is non-fragile. ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args, + const InputInfoList &inputs, ArgStringList &cmdArgs, RewriteKind rewriteKind) const { // Look for the controlling runtime option. @@ -6380,8 +6381,11 @@ ObjCRuntime Clang::AddObjCRuntimeArgs(const ArgList &args, runtime = ObjCRuntime(ObjCRuntime::GCC, VersionTuple()); } - cmdArgs.push_back( - args.MakeArgString("-fobjc-runtime=" + runtime.getAsString())); + if (llvm::any_of(inputs, [](const InputInfo &input) { + return types::isObjC(input.getType()); + })) + cmdArgs.push_back( + args.MakeArgString("-fobjc-runtime=" + runtime.getAsString())); return runtime; } diff --git a/clang/lib/Driver/ToolChains/Clang.h b/clang/lib/Driver/ToolChains/Clang.h index b345c02489d4..48100c2fc6ec 100644 --- a/clang/lib/Driver/ToolChains/Clang.h +++ b/clang/lib/Driver/ToolChains/Clang.h @@ -77,6 +77,7 @@ class LLVM_LIBRARY_VISIBILITY Clang : public Tool { enum RewriteKind { RK_None, RK_Fragile, RK_NonFragile }; ObjCRuntime AddObjCRuntimeArgs(const llvm::opt::ArgList &args, + const InputInfoList &inputs, llvm::opt::ArgStringList &cmdArgs, RewriteKind rewrite) const; diff --git a/clang/test/Driver/darwin-objc-options.m b/clang/test/Driver/darwin-objc-options.m index 3e21fb38c0a9..60827f2937ed 100644 --- a/clang/test/Driver/darwin-objc-options.m +++ b/clang/test/Driver/darwin-objc-options.m @@ -31,5 +31,12 @@ // CHECK-CHECK-I386_IOS-NOT: -fobjc-dispatch-method // CHECK-CHECK-I386_IOS: darwin-objc-options +/// Don't add -fobjc-runtime for non-ObjC input. +// RUN: touch %t.c +// RUN: %clang -target x86_64-apple-darwin -x objective-c -S -### %t.c 2>&1 | FileCheck --check-prefix=F %s +// RUN: %clang -target x86_64-apple-darwin -S -### %t.c 2>&1 | FileCheck --check-prefix=NO_F %s +// F: -fobjc-runtime= +// NO_F-NOT: -fobjc-runtime= + // Don't crash with an unexpected target triple. // RUN: %clang -target i386-apple-ios7 -S -### %s From cfe-commits at lists.llvm.org Tue Mar 31 18:12:50 2020 From: cfe-commits at lists.llvm.org (Csaba Dabis via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 01:12:50 +0000 (UTC) Subject: [PATCH] D70411: [analyzer] CERT: STR31-C In-Reply-To: References: Message-ID: Charusso updated this revision to Diff 254061. Charusso marked 6 inline comments as done. Charusso edited the summary of this revision. Charusso added a comment. - Get rid of the secondary behavior for now. - Fix review comments. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70411/new/ https://reviews.llvm.org/D70411 Files: clang/docs/analyzer/checkers.rst clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/lib/StaticAnalyzer/Checkers/AllocationState.h clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp clang/lib/StaticAnalyzer/Checkers/cert/StrChecker.cpp clang/test/Analysis/Inputs/system-header-simulator.h clang/test/Analysis/cert/str31-c-false-positive-suppression.cpp clang/test/Analysis/cert/str31-c-notes.cpp clang/test/Analysis/cert/str31-c.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D70411.254061.patch Type: text/x-patch Size: 27701 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 18:12:50 2020 From: cfe-commits at lists.llvm.org (Csaba Dabis via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 01:12:50 +0000 (UTC) Subject: [PATCH] D70411: [analyzer] CERT: STR31-C In-Reply-To: References: Message-ID: <91011e1dfb5caf0f74db5bf9a9f8bc63@localhost.localdomain> Charusso added a comment. Given that the secondary behavior confuse people I have removed it for now. May if someone introduce a NullTerminationChecker then we introduce such option to warn on insecure calls instant. Thanks @balazske for influencing that change. @NoQ this project had a deadline like half year ago, could you smash that green button please? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70411/new/ https://reviews.llvm.org/D70411 From cfe-commits at lists.llvm.org Tue Mar 31 18:12:51 2020 From: cfe-commits at lists.llvm.org (Vitaly Buka via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 01:12:51 +0000 (UTC) Subject: [PATCH] D77189: Bisect autoinit Message-ID: vitalybuka created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77189 Files: clang/lib/CodeGen/CGDecl.cpp Index: clang/lib/CodeGen/CGDecl.cpp =================================================================== --- clang/lib/CodeGen/CGDecl.cpp +++ clang/lib/CodeGen/CGDecl.cpp @@ -37,6 +37,7 @@ #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Type.h" +#include using namespace clang; using namespace CodeGen; @@ -44,6 +45,11 @@ static_assert(clang::Sema::MaximumAlignment <= llvm::Value::MaximumAlignment, "Clang max alignment greater than what LLVM supports?"); +#include "llvm/Support/CommandLine.h" +static llvm::cl::opt ClUninitBegin("uninit-begin", llvm::cl::init(1)); +static llvm::cl::opt ClUninitEnd("uninit-end", llvm::cl::init(0)); +static llvm::cl::opt ClUninitPrint("uninit-print", llvm::cl::init(false)); + void CodeGenFunction::EmitDecl(const Decl &D) { switch (D.getKind()) { case Decl::BuiltinTemplate: @@ -1793,13 +1799,26 @@ const Address Loc = locIsByrefHeader ? emission.getObjectAddress(*this) : emission.Addr; + static const uint64_t HB = ClUninitBegin; + static const uint64_t HE = ClUninitEnd; + size_t v = llvm::hash_value( + D.getLocation().printToString(getContext().getSourceManager())); + bool attr = D.getAttr(); + if (v >= HB && v <= HE) { + if (ClUninitPrint) { + std::cerr << v << " " + << D.getLocation().printToString( + getContext().getSourceManager()) + << "\n"; + } + attr = true; + } // Note: constexpr already initializes everything correctly. LangOptions::TrivialAutoVarInitKind trivialAutoVarInit = (D.isConstexpr() ? LangOptions::TrivialAutoVarInitKind::Uninitialized - : (D.getAttr() - ? LangOptions::TrivialAutoVarInitKind::Uninitialized - : getContext().getLangOpts().getTrivialAutoVarInit())); + : (attr ? LangOptions::TrivialAutoVarInitKind::Uninitialized + : getContext().getLangOpts().getTrivialAutoVarInit())); auto initializeWhatIsTechnicallyUninitialized = [&](Address Loc) { if (trivialAutoVarInit == -------------- next part -------------- A non-text attachment was scrubbed... Name: D77189.254064.patch Type: text/x-patch Size: 2189 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 18:12:52 2020 From: cfe-commits at lists.llvm.org (Stephen Hines via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 01:12:52 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: srhines added a comment. In D77168#1953635 , @jfb wrote: > I'm not sure this is a good idea at all. We want to keep the codepath as simple as possible to avoid introducing bugs. If a codebase sees a crash then it's easier to bisect one function at a time than doing something like this. I'd much rather see bisection using pragma to apply the `uninitialized` attribute to multiple declarations. Certainly one function at a time is preferable, but that's not always possible. I do think that this would be a useful feature for making bisection easier, since automating the injection of `pragma`s into code seems a lot more challenging. Of course, the `pragma` approach is nice for other reasons (letting people carve out entire functions for initialized/uninitialized, but I think that is orthogonal to the debugging aspect. ================ Comment at: clang/lib/CodeGen/CGDecl.cpp:1814 + if (StopAfter) { + static unsigned Counter = 0; + if (Counter >= StopAfter) ---------------- MaskRay wrote: > I am a bit worried about the static variable. This makes CodeGen not reusable. The counter could exist in ASTContext instead. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 From cfe-commits at lists.llvm.org Tue Mar 31 18:45:02 2020 From: cfe-commits at lists.llvm.org (Xingwei Lin via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 01:45:02 +0000 (UTC) Subject: [PATCH] D63616: Implement `-fsanitize-coverage-whitelist` and `-fsanitize-coverage-blacklist` for clang In-Reply-To: References: Message-ID: xwlin222 added a comment. Think so, and when can this feature be merge to the mainline? look forward it. In D63616#1809697 , @dende wrote: > This is a really useful feature for fuzzing bigger software projects and the review was accepted. Any plans to merge this? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63616/new/ https://reviews.llvm.org/D63616 From cfe-commits at lists.llvm.org Tue Mar 31 18:46:06 2020 From: cfe-commits at lists.llvm.org (sakura via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 01:46:06 +0000 (UTC) Subject: [PATCH] D63616: Implement `-fsanitize-coverage-whitelist` and `-fsanitize-coverage-blacklist` for clang In-Reply-To: References: Message-ID: <42ee65f0fbb0f5585d1f1b4ecf731719@localhost.localdomain> eternalsakura added a comment. In D63616#1562824 , @tuktuk wrote: > Thanks for the reviews. Hi, @tuktuk. I want to use this function on the latest llvm, but now the code has been modified, this patch is no longer valid, can you take a look, thank you very much. : ) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63616/new/ https://reviews.llvm.org/D63616 From cfe-commits at lists.llvm.org Tue Mar 31 19:18:48 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 02:18:48 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift In-Reply-To: References: Message-ID: <01a7237cfb9901c1732382d00aea124b@localhost.localdomain> rjmccall added inline comments. ================ Comment at: clang/lib/CodeGen/CGObjCRuntime.h:217 + /// ProtocolPtrTy. + virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) = 0; + ---------------- aschwaighofer wrote: > aschwaighofer wrote: > > rjmccall wrote: > > > Can this name more closely parallel the "external" name, like `getOrEmitProtocolObject`? > > > > > > Also, I think we're incrementally lowercasing new method names. > > This is an already existing method. I just moved it higher in the class hierarchy to CGObjCRuntime from CGObjCMac so that it is callable from getOrEmitProtocolObject. > s/getOrEmitProtocolObject/emitObjCProtocolObject I see. Well, in that case, I won't ask you to rename it, but please do implement it for the GNU runtime as I mentioned. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77077/new/ https://reviews.llvm.org/D77077 From cfe-commits at lists.llvm.org Tue Mar 31 19:50:43 2020 From: cfe-commits at lists.llvm.org (Puyan Lotfi via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 02:50:43 +0000 (UTC) Subject: [PATCH] D76979: [clang][llvm] Interface Stubs new yaml file format changes. In-Reply-To: References: Message-ID: <8f9174f3586ff8a9fe621d095ae9d562@localhost.localdomain> plotfi updated this revision to Diff 254075. plotfi added a comment. Updating to change im about to land, to see what precommit changes show. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76979/new/ https://reviews.llvm.org/D76979 Files: clang/include/clang/Frontend/FrontendActions.h clang/include/clang/Frontend/FrontendOptions.h clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp clang/test/InterfaceStubs/bad-format.cpp clang/test/InterfaceStubs/blocks.c clang/test/InterfaceStubs/class-template-partial-specialization.cpp clang/test/InterfaceStubs/conflict-type.ifs clang/test/InterfaceStubs/constructor-using-shadow.cpp clang/test/InterfaceStubs/cxx-conversion.cpp clang/test/InterfaceStubs/cxxdeduction-guide.cpp clang/test/InterfaceStubs/driver-test3.c clang/test/InterfaceStubs/empty.c clang/test/InterfaceStubs/func.ifs clang/test/InterfaceStubs/hidden-class-inheritance.cpp clang/test/InterfaceStubs/indirect-field-decl.cpp clang/test/InterfaceStubs/inline.c clang/test/InterfaceStubs/lambda.cpp clang/test/InterfaceStubs/namespace-alias.cpp clang/test/InterfaceStubs/namespace.cpp clang/test/InterfaceStubs/non-type-template-parm-decl.cpp clang/test/InterfaceStubs/object.c clang/test/InterfaceStubs/object.ifs clang/test/InterfaceStubs/ppc.cpp clang/test/InterfaceStubs/template-constexpr.cpp clang/test/InterfaceStubs/template-namespace-function.cpp clang/test/InterfaceStubs/template-template-parm-decl.cpp clang/test/InterfaceStubs/trycatch.cpp clang/test/InterfaceStubs/unresolved-using-typename.cpp clang/test/InterfaceStubs/usings.cpp clang/test/InterfaceStubs/var-template-specialization-decl.cpp clang/test/InterfaceStubs/weak.cpp clang/test/InterfaceStubs/windows.cpp llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-size.ifs llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-type.ifs llvm/test/tools/llvm-ifs/conflict-header-format.ifs llvm/test/tools/llvm-ifs/conflict-header-triple.ifs llvm/test/tools/llvm-ifs/conflict-header-version.ifs llvm/test/tools/llvm-ifs/conflict-size.ifs llvm/test/tools/llvm-ifs/conflict-type.ifs llvm/test/tools/llvm-ifs/conflict-weak.ifs llvm/test/tools/llvm-ifs/default-empty.ifs llvm/test/tools/llvm-ifs/empty1.ifs llvm/test/tools/llvm-ifs/empty2.ifs llvm/test/tools/llvm-ifs/func.ifs llvm/test/tools/llvm-ifs/ios-tbd.ifs llvm/test/tools/llvm-ifs/macos-tbd.ifs llvm/test/tools/llvm-ifs/object-function-size-weak-combo.ifs llvm/test/tools/llvm-ifs/object.ifs llvm/test/tools/llvm-ifs/strong.ifs llvm/test/tools/llvm-ifs/tvos-tbd.ifs llvm/test/tools/llvm-ifs/version-ok.ifs llvm/test/tools/llvm-ifs/watchos-tbd.ifs llvm/test/tools/llvm-ifs/weak-mismatch.ifs llvm/test/tools/llvm-ifs/weak.ifs llvm/tools/llvm-ifs/llvm-ifs.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76979.254075.patch Type: text/x-patch Size: 49490 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 19:50:44 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 02:50:44 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: <36176362f64e3f106b29badff7187745@localhost.localdomain> rjmccall added a comment. I can understand the automation benefits of just counting the number of variables initialized so far in the translation unit without having to modify source, but if you can possibly do this with the pragma, that seems like both a more flexible tool (you can isolate multiple variables) and one that will produce more easily-interpretable results. For example, won't you need some way of figuring out what the 1,134th variable in a file was after you've successfully bisected? ================ Comment at: clang/lib/CodeGen/CGDecl.cpp:1814 + if (StopAfter) { + static unsigned Counter = 0; + if (Counter >= StopAfter) ---------------- srhines wrote: > MaskRay wrote: > > I am a bit worried about the static variable. This makes CodeGen not reusable. > The counter could exist in ASTContext instead. IRGenModule would be the more appropriate place. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 From cfe-commits at lists.llvm.org Tue Mar 31 20:23:02 2020 From: cfe-commits at lists.llvm.org (Ian Levesque via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 03:23:02 +0000 (UTC) Subject: [PATCH] D77191: [clang][xray] Add xray attributes to functions without decls too Message-ID: ianlevesque created this revision. ianlevesque added reviewers: dberris, MaskRay, smeenai. Herald added a project: clang. Herald added a subscriber: cfe-commits. This allows instrumenting things like global initializers Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77191 Files: clang/lib/CodeGen/CodeGenFunction.cpp clang/test/CodeGen/xray-global-init.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77191.254079.patch Type: text/x-patch Size: 5144 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 20:23:02 2020 From: cfe-commits at lists.llvm.org (Manoj Gupta via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 03:23:02 +0000 (UTC) Subject: [PATCH] D71082: Allow system header to provide their own implementation of some builtin In-Reply-To: References: Message-ID: <2443204f5eedf2efbeb1c76350259ed0@localhost.localdomain> manojgupta added subscribers: nickdesaulniers, llozano, srhines. manojgupta added a comment. I was able to reduce to following: typedef unsigned int u32; typedef unsigned long long u64; typedef unsigned long size_t; void fortify_panic(const char *name) __attribute__((noreturn)) ; void __read_overflow(void) ; void __read_overflow2(void) ; void __write_overflow(void) ; extern void *memcpy(void *to, const void *from, size_t len); extern void *__memcpy(void *to, const void *from, size_t len); extern inline __attribute__((unused)) __attribute__((no_instrument_function)) __attribute__((always_inline)) __attribute__((gnu_inline)) void *memcpy(void *p, const void *q, size_t size) { size_t p_size = __builtin_object_size(p, 0); size_t q_size = __builtin_object_size(q, 0); if (__builtin_constant_p(size)) { if (p_size < size) __write_overflow(); if (q_size < size) __read_overflow2(); } if (p_size < size || q_size < size) fortify_panic(__func__); return __builtin_memcpy(p, q, size); } static inline __attribute__((unused)) __attribute__((no_instrument_function)) void memcpy_fromio(void *dst, const volatile void *src, size_t count) { memcpy(dst, (const void *)src, count); } u64 sst_shim32_read64(void *addr, u32 offset) { u64 val; memcpy_fromio(&val, addr + offset, sizeof(val)); return val; } Compiling with clang -Qunused-arguments -D_FORTIFY_SOURCE=2 -fno-omit-frame-pointer -fno-stack-protector -nostdinc -fno-strict-aliasing -fno-common -std=gnu89 -fno-PIE -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m64 -mno-80387 -mstack-alignment=8 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -pipe -mretpoline-external-thunk -fno-delete-null-pointer-checks -Os -fstack-protector-strong -mno-global-merge -no-integrated-as -fno-omit-frame-pointer -fno-optimize-sibling-calls -ftrivial-auto-var-init=pattern -pg -mfentry -fno-strict-overflow -fno-merge-all-constants -fno-stack-check -c -o test.o test.c -target x86_64-cros-linux-gnu and objdump -drW test.o before: No memcpy is emitted as clang is able to optimize it. 0000000000000000 : 0: e8 00 00 00 00 callq 5 1: R_X86_64_PLT32 __fentry__-0x4 5: 55 push %rbp 6: 48 89 e5 mov %rsp,%rbp 9: 89 f0 mov %esi,%eax b: 48 8b 04 07 mov (%rdi,%rax,1),%rax f: 5d pop %rbp 10: c3 retq After: A call to memcpy is emitted. 0000000000000000 : 0: e8 00 00 00 00 callq 5 1: R_X86_64_PLT32 __fentry__-0x4 5: 55 push %rbp 6: 48 89 e5 mov %rsp,%rbp 9: 53 push %rbx a: 48 83 ec 10 sub $0x10,%rsp e: 65 48 8b 04 25 28 00 mov %gs:0x28,%rax 15: 00 00 17: 48 89 45 f0 mov %rax,-0x10(%rbp) 1b: 48 b8 aa aa aa aa aa movabs $0xaaaaaaaaaaaaaaaa,%rax 22: aa aa aa 25: 48 8d 5d e8 lea -0x18(%rbp),%rbx 29: 48 89 03 mov %rax,(%rbx) 2c: 89 f6 mov %esi,%esi 2e: 48 01 fe add %rdi,%rsi 31: ba 08 00 00 00 mov $0x8,%edx 36: 48 89 df mov %rbx,%rdi 39: e8 00 00 00 00 callq 3e 3a: R_X86_64_PLT32 memcpy-0x4 3e: 48 8b 03 mov (%rbx),%rax 41: 65 48 8b 0c 25 28 00 mov %gs:0x28,%rcx 48: 00 00 4a: 48 3b 4d f0 cmp -0x10(%rbp),%rcx 4e: 75 07 jne 57 50: 48 83 c4 10 add $0x10,%rsp 54: 5b pop %rbx 55: 5d pop %rbp 56: c3 retq 57: e8 00 00 00 00 callq 5c 58: R_X86_64_PLT32 __stack_chk_fail-0x4 At this point, it is not clear to me if clang is doing anything wrong here is or this a bug in kernel 4.4 that it is using a regular memcpy for IO which cannot use regular memcpy. And so I suspect we need to backport https://github.com/torvalds/linux/commit/c2327da06b33d8e1093ce2c28f395bc500d1b0d3 to older kernel versions. @nickdesaulniers wdyt? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71082/new/ https://reviews.llvm.org/D71082 From cfe-commits at lists.llvm.org Tue Mar 31 20:23:03 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 03:23:03 +0000 (UTC) Subject: [PATCH] D59321: AMDGPU: Teach toolchain to link rocm device libs In-Reply-To: References: Message-ID: <12a492e0e37f85ced632e00978a21bef@localhost.localdomain> yaxunl added inline comments. ================ Comment at: clang/include/clang/Basic/DiagnosticDriverKinds.td:264 def err_drv_invalid_malign_branch_EQ : Error< "invalid argument '%0' to -malign-branch=; each element must be one of: %1">; ---------------- could you please rebase your patch? The patch seems to contain irrelevant diffs. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D59321/new/ https://reviews.llvm.org/D59321 From cfe-commits at lists.llvm.org Tue Mar 31 20:55:02 2020 From: cfe-commits at lists.llvm.org (Dean Michael Berris via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 03:55:02 +0000 (UTC) Subject: [PATCH] D77191: [clang][xray] Add xray attributes to functions without decls too In-Reply-To: References: Message-ID: dberris accepted this revision. dberris added a comment. This revision is now accepted and ready to land. LGTM Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77191/new/ https://reviews.llvm.org/D77191 From cfe-commits at lists.llvm.org Tue Mar 31 20:55:04 2020 From: cfe-commits at lists.llvm.org (Puyan Lotfi via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 03:55:04 +0000 (UTC) Subject: [PATCH] D76979: [clang][llvm] Interface Stubs new yaml file format changes. In-Reply-To: References: Message-ID: plotfi updated this revision to Diff 254080. plotfi added a comment. Trying to fix precommit / clang tidy checks. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76979/new/ https://reviews.llvm.org/D76979 Files: clang/include/clang/Frontend/FrontendActions.h clang/include/clang/Frontend/FrontendOptions.h clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp clang/test/InterfaceStubs/bad-format.cpp clang/test/InterfaceStubs/blocks.c clang/test/InterfaceStubs/class-template-partial-specialization.cpp clang/test/InterfaceStubs/conflict-type.ifs clang/test/InterfaceStubs/constructor-using-shadow.cpp clang/test/InterfaceStubs/cxx-conversion.cpp clang/test/InterfaceStubs/cxxdeduction-guide.cpp clang/test/InterfaceStubs/driver-test3.c clang/test/InterfaceStubs/empty.c clang/test/InterfaceStubs/func.ifs clang/test/InterfaceStubs/hidden-class-inheritance.cpp clang/test/InterfaceStubs/indirect-field-decl.cpp clang/test/InterfaceStubs/inline.c clang/test/InterfaceStubs/lambda.cpp clang/test/InterfaceStubs/namespace-alias.cpp clang/test/InterfaceStubs/namespace.cpp clang/test/InterfaceStubs/non-type-template-parm-decl.cpp clang/test/InterfaceStubs/object.c clang/test/InterfaceStubs/object.ifs clang/test/InterfaceStubs/ppc.cpp clang/test/InterfaceStubs/template-constexpr.cpp clang/test/InterfaceStubs/template-namespace-function.cpp clang/test/InterfaceStubs/template-template-parm-decl.cpp clang/test/InterfaceStubs/trycatch.cpp clang/test/InterfaceStubs/unresolved-using-typename.cpp clang/test/InterfaceStubs/usings.cpp clang/test/InterfaceStubs/var-template-specialization-decl.cpp clang/test/InterfaceStubs/weak.cpp clang/test/InterfaceStubs/windows.cpp llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-size.ifs llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-type.ifs llvm/test/tools/llvm-ifs/conflict-header-format.ifs llvm/test/tools/llvm-ifs/conflict-header-triple.ifs llvm/test/tools/llvm-ifs/conflict-header-version.ifs llvm/test/tools/llvm-ifs/conflict-size.ifs llvm/test/tools/llvm-ifs/conflict-type.ifs llvm/test/tools/llvm-ifs/conflict-weak.ifs llvm/test/tools/llvm-ifs/default-empty.ifs llvm/test/tools/llvm-ifs/empty1.ifs llvm/test/tools/llvm-ifs/empty2.ifs llvm/test/tools/llvm-ifs/func.ifs llvm/test/tools/llvm-ifs/ios-tbd.ifs llvm/test/tools/llvm-ifs/macos-tbd.ifs llvm/test/tools/llvm-ifs/object-function-size-weak-combo.ifs llvm/test/tools/llvm-ifs/object.ifs llvm/test/tools/llvm-ifs/strong.ifs llvm/test/tools/llvm-ifs/tvos-tbd.ifs llvm/test/tools/llvm-ifs/version-ok.ifs llvm/test/tools/llvm-ifs/watchos-tbd.ifs llvm/test/tools/llvm-ifs/weak-mismatch.ifs llvm/test/tools/llvm-ifs/weak.ifs llvm/tools/llvm-ifs/llvm-ifs.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76979.254080.patch Type: text/x-patch Size: 49490 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 21:14:32 2020 From: cfe-commits at lists.llvm.org (Ian Levesque via cfe-commits) Date: Tue, 31 Mar 2020 21:14:32 -0700 (PDT) Subject: [clang] bb3111c - [clang][xray] Add xray attributes to functions without decls too Message-ID: <5e841528.1c69fb81.28911.324e@mx.google.com> Author: Ian Levesque Date: 2020-04-01T00:02:39-04:00 New Revision: bb3111cbaf7b181bcda94415456a69b2a6b767ad URL: https://github.com/llvm/llvm-project/commit/bb3111cbaf7b181bcda94415456a69b2a6b767ad DIFF: https://github.com/llvm/llvm-project/commit/bb3111cbaf7b181bcda94415456a69b2a6b767ad.diff LOG: [clang][xray] Add xray attributes to functions without decls too Summary: This allows instrumenting things like global initializers Reviewers: dberris, MaskRay, smeenai Subscribers: cfe-commits, johnislarry Tags: #clang Differential Revision: https://reviews.llvm.org/D77191 Added: clang/test/CodeGen/xray-global-init.cpp Modified: clang/lib/CodeGen/CodeGenFunction.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 3393b1b3c5fb..618c9a046321 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -810,55 +810,54 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass) SanOpts.Mask &= ~SanitizerKind::Null; - if (D) { - // Apply xray attributes to the function (as a string, for now) - if (const auto *XRayAttr = D->getAttr()) { - if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has( - XRayInstrKind::FunctionEntry) || - CGM.getCodeGenOpts().XRayInstrumentationBundle.has( - XRayInstrKind::FunctionExit)) { - if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction()) - Fn->addFnAttr("function-instrument", "xray-always"); - if (XRayAttr->neverXRayInstrument()) - Fn->addFnAttr("function-instrument", "xray-never"); - if (const auto *LogArgs = D->getAttr()) - if (ShouldXRayInstrumentFunction()) - Fn->addFnAttr("xray-log-args", - llvm::utostr(LogArgs->getArgumentCount())); - } - } else { - if (ShouldXRayInstrumentFunction() && !CGM.imbueXRayAttrs(Fn, Loc)) - Fn->addFnAttr( - "xray-instruction-threshold", - llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold)); + // Apply xray attributes to the function (as a string, for now) + if (const auto *XRayAttr = D ? D->getAttr() : nullptr) { + if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has( + XRayInstrKind::FunctionEntry) || + CGM.getCodeGenOpts().XRayInstrumentationBundle.has( + XRayInstrKind::FunctionExit)) { + if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction()) + Fn->addFnAttr("function-instrument", "xray-always"); + if (XRayAttr->neverXRayInstrument()) + Fn->addFnAttr("function-instrument", "xray-never"); + if (const auto *LogArgs = D->getAttr()) + if (ShouldXRayInstrumentFunction()) + Fn->addFnAttr("xray-log-args", + llvm::utostr(LogArgs->getArgumentCount())); } + } else { + if (ShouldXRayInstrumentFunction() && !CGM.imbueXRayAttrs(Fn, Loc)) + Fn->addFnAttr( + "xray-instruction-threshold", + llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold)); + } - if (ShouldXRayInstrumentFunction()) { - if (CGM.getCodeGenOpts().XRayIgnoreLoops) - Fn->addFnAttr("xray-ignore-loops"); + if (ShouldXRayInstrumentFunction()) { + if (CGM.getCodeGenOpts().XRayIgnoreLoops) + Fn->addFnAttr("xray-ignore-loops"); - if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has( - XRayInstrKind::FunctionExit)) - Fn->addFnAttr("xray-skip-exit"); + if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has( + XRayInstrKind::FunctionExit)) + Fn->addFnAttr("xray-skip-exit"); - if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has( - XRayInstrKind::FunctionEntry)) - Fn->addFnAttr("xray-skip-entry"); - } + if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has( + XRayInstrKind::FunctionEntry)) + Fn->addFnAttr("xray-skip-entry"); + } - unsigned Count, Offset; - if (const auto *Attr = D->getAttr()) { - Count = Attr->getCount(); - Offset = Attr->getOffset(); - } else { - Count = CGM.getCodeGenOpts().PatchableFunctionEntryCount; - Offset = CGM.getCodeGenOpts().PatchableFunctionEntryOffset; - } - if (Count && Offset <= Count) { - Fn->addFnAttr("patchable-function-entry", std::to_string(Count - Offset)); - if (Offset) - Fn->addFnAttr("patchable-function-prefix", std::to_string(Offset)); - } + unsigned Count, Offset; + if (const auto *Attr = + D ? D->getAttr() : nullptr) { + Count = Attr->getCount(); + Offset = Attr->getOffset(); + } else { + Count = CGM.getCodeGenOpts().PatchableFunctionEntryCount; + Offset = CGM.getCodeGenOpts().PatchableFunctionEntryOffset; + } + if (Count && Offset <= Count) { + Fn->addFnAttr("patchable-function-entry", std::to_string(Count - Offset)); + if (Offset) + Fn->addFnAttr("patchable-function-prefix", std::to_string(Offset)); } // Add no-jump-tables value. diff --git a/clang/test/CodeGen/xray-global-init.cpp b/clang/test/CodeGen/xray-global-init.cpp new file mode 100644 index 000000000000..588be8a45a50 --- /dev/null +++ b/clang/test/CodeGen/xray-global-init.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -fxray-instrument -fxray-instruction-threshold=1 %s -o - \ +// RUN: | FileCheck %s + +struct A { + A(); + ~A(); +}; + +A a; + +// Check that the xray-instruction-threshold was applied +// CHECK: define internal void @_GLOBAL__sub_I_xray_global_init.cpp() [[NUX:#[0-9]+]] section ".text.startup" { +// CHECK: attributes [[NUX]] = { noinline nounwind {{.*}}"xray-instruction-threshold"="1"{{.*}} } From cfe-commits at lists.llvm.org Tue Mar 31 21:27:19 2020 From: cfe-commits at lists.llvm.org (Marcus Johnson via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 04:27:19 +0000 (UTC) Subject: [PATCH] D33029: [clang-format] add option for dangling parenthesis In-Reply-To: References: Message-ID: MarcusJohnson91 added a comment. In D33029#1946761 , @bbassi wrote: > I don't think that's quite right. Then you will also have to have a `AlignWithDanglingParenthesis` for cases when people still want closing parenthesis on new line but want parameters as well as closing parenthesis to be aligned with opening parenthesis. I think we need a separate option, something like `BreakBeforeClosingBracket`. I think that's the biggest problem with making changes to Clang-Format, every name does things that the name doesn't imply. Here it's very similar to the bin packing options, in my case it's BraceWrapping.AfterExternBlock also indenting by default, making adding a IndentExternBlock a real pain. I personally say fuck backwards compatibility when maintaining it requires ever more workarounds to fix an obviously flawed abstraction, but I'm just some dude and AFAIK the guys in charge support the status quo. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D33029/new/ https://reviews.llvm.org/D33029 From cfe-commits at lists.llvm.org Tue Mar 31 21:27:26 2020 From: cfe-commits at lists.llvm.org (Ian Levesque via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 04:27:26 +0000 (UTC) Subject: [PATCH] D77191: [clang][xray] Add xray attributes to functions without decls too In-Reply-To: References: Message-ID: <744239e201631cf856b13ab1e1d28f2f@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGbb3111cbaf7b: [clang][xray] Add xray attributes to functions without decls too (authored by ianlevesque). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77191/new/ https://reviews.llvm.org/D77191 Files: clang/lib/CodeGen/CodeGenFunction.cpp clang/test/CodeGen/xray-global-init.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77191.254085.patch Type: text/x-patch Size: 5144 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 22:00:14 2020 From: cfe-commits at lists.llvm.org (Manoj Gupta via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 05:00:14 +0000 (UTC) Subject: [PATCH] D71082: Allow system header to provide their own implementation of some builtin In-Reply-To: References: Message-ID: <00a58e93f20b3a989e81f7b5b9c12616@localhost.localdomain> manojgupta added a comment. Unfortunately, cherry-picking the kernel patches didn't work including latest memcpy for x86 (https://github.com/torvalds/linux/commit/170d13ca3a2fdaaa0283399247631b76b441cca2 and https://github.com/torvalds/linux/commit/c228d294f2040c3a5f5965ff04d4947d0bf6e7da ). Also tried ToT Linux kernel but still the same problem. So far, it is not clear to me whether clang is at fault or Linux kernel has incorrect assumptions about memcpy. Also note that memcpy_fromio has the argument type as volatile void* which I believe is to inhibit some compiler optimizations. @efriedma do you have any suggestions? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71082/new/ https://reviews.llvm.org/D71082 From cfe-commits at lists.llvm.org Tue Mar 31 22:04:28 2020 From: cfe-commits at lists.llvm.org (Fangrui Song via cfe-commits) Date: Tue, 31 Mar 2020 22:04:28 -0700 (PDT) Subject: [clang] d0d076f - [Driver] Flip the CC1 default of -fdiagnostics-show-option Message-ID: <5e8420dc.1c69fb81.543bf.2e3f@mx.google.com> Author: Fangrui Song Date: 2020-03-31T21:59:27-07:00 New Revision: d0d076fed9681ebf2c2aed22e18cc5b89c5ac940 URL: https://github.com/llvm/llvm-project/commit/d0d076fed9681ebf2c2aed22e18cc5b89c5ac940 DIFF: https://github.com/llvm/llvm-project/commit/d0d076fed9681ebf2c2aed22e18cc5b89c5ac940.diff LOG: [Driver] Flip the CC1 default of -fdiagnostics-show-option The driver enables -fdiagnostics-show-option by default, so flip the CC1 default to reduce the lengths of common CC1 command lines. This change also makes ParseDiagnosticArgs() consistently enable -fdiagnostics-show-option by default. Added: clang/test/Driver/fdiagnostics-show-option.c Modified: clang/include/clang/Driver/Options.td clang/include/clang/Frontend/CompilerInvocation.h clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1-cxx11.cpp clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp clang/test/Driver/rewrite-legacy-objc.m clang/test/Driver/rewrite-objc.m clang/test/Frontend/diagnostics-option-names.c clang/test/Misc/show-diag-options.c clang/test/Sema/parentheses.c Removed: clang/test/Driver/show-option-names.c ################################################################################ diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index e413a8600bf0..26098a8c062a 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -899,7 +899,7 @@ def fdiagnostics_hotness_threshold_EQ : Joined<["-"], "fdiagnostics-hotness-thre Group, Flags<[CC1Option]>, MetaVarName<"">, HelpText<"Prevent optimization remarks from being output if they do not have at least this profile count">; def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group, - Flags<[CC1Option]>, HelpText<"Print option name with mappable diagnostics">; + HelpText<"Print option name with mappable diagnostics">; def fdiagnostics_show_note_include_stack : Flag<["-"], "fdiagnostics-show-note-include-stack">, Group, Flags<[CC1Option]>, HelpText<"Display include stacks for diagnostic notes">; def fdiagnostics_format_EQ : Joined<["-"], "fdiagnostics-format=">, Group; @@ -1515,7 +1515,7 @@ def fno_cxx_modules : Flag <["-"], "fno-cxx-modules">, Group, def fno_diagnostics_fixit_info : Flag<["-"], "fno-diagnostics-fixit-info">, Group, Flags<[CC1Option]>, HelpText<"Do not include fixit information in diagnostics">; def fno_diagnostics_show_hotness : Flag<["-"], "fno-diagnostics-show-hotness">, Group; -def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group; +def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group, Flags<[CC1Option]>; def fno_diagnostics_show_note_include_stack : Flag<["-"], "fno-diagnostics-show-note-include-stack">, Flags<[CC1Option]>, Group; def fdigraphs : Flag<["-"], "fdigraphs">, Group, Flags<[CC1Option]>, diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h index f3253d5b40e3..25476f78a6a0 100644 --- a/clang/include/clang/Frontend/CompilerInvocation.h +++ b/clang/include/clang/Frontend/CompilerInvocation.h @@ -59,8 +59,7 @@ class TargetOptions; /// report the error(s). bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args, DiagnosticsEngine *Diags = nullptr, - bool DefaultDiagColor = true, - bool DefaultShowOpt = true); + bool DefaultDiagColor = true); class CompilerInvocationBase { public: diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 197fe07cb012..8773468ddbe6 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3559,9 +3559,9 @@ static void RenderDiagnosticsOptions(const Driver &D, const ArgList &Args, CmdArgs.push_back("-fno-diagnostics-fixit-info"); // Enable -fdiagnostics-show-option by default. - if (Args.hasFlag(options::OPT_fdiagnostics_show_option, - options::OPT_fno_diagnostics_show_option)) - CmdArgs.push_back("-fdiagnostics-show-option"); + if (!Args.hasFlag(options::OPT_fdiagnostics_show_option, + options::OPT_fno_diagnostics_show_option, true)) + CmdArgs.push_back("-fno-diagnostics-show-option"); if (const Arg *A = Args.getLastArg(options::OPT_fdiagnostics_show_category_EQ)) { diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 5bfad6f1de6c..f8129ea4ac26 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1547,7 +1547,7 @@ static bool checkVerifyPrefixes(const std::vector &VerifyPrefixes, bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, DiagnosticsEngine *Diags, - bool DefaultDiagColor, bool DefaultShowOpt) { + bool DefaultDiagColor) { bool Success = true; Opts.DiagnosticLogFile = @@ -1565,9 +1565,7 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Opts.ShowFixits = !Args.hasArg(OPT_fno_diagnostics_fixit_info); Opts.ShowLocation = !Args.hasArg(OPT_fno_show_source_location); Opts.AbsolutePath = Args.hasArg(OPT_fdiagnostics_absolute_paths); - Opts.ShowOptionNames = - Args.hasFlag(OPT_fdiagnostics_show_option, - OPT_fno_diagnostics_show_option, DefaultShowOpt); + Opts.ShowOptionNames = !Args.hasArg(OPT_fno_diagnostics_show_option); llvm::sys::Process::UseANSIEscapeCodes(Args.hasArg(OPT_fansi_escape_codes)); @@ -3597,9 +3595,8 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Diags.Report(diag::err_fe_dependency_file_requires_MT); Success = false; } - Success &= - ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags, - false /*DefaultDiagColor*/, false /*DefaultShowOpt*/); + Success &= ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags, + /*DefaultDiagColor=*/false); ParseCommentArgs(LangOpts.CommentOpts, Args); ParseFileSystemArgs(Res.getFileSystemOpts(), Args); // FIXME: We shouldn't have to pass the DashX option around here diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1-cxx11.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1-cxx11.cpp index f812ea1bd8be..1afea99e8895 100644 --- a/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1-cxx11.cpp +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1-cxx11.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fdiagnostics-show-option -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s template struct set{}; diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp index bb6bb73ec702..e3599db18350 100644 --- a/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp +++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify %s -// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify -std=c++98 %s -// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s // C++98 [basic.lookup.classref]p1: // In a class member access expression (5.2.5), if the . or -> token is diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp index 7a5caef36e73..e3190245d240 100644 --- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++03 -fdiagnostics-show-option -Wbind-to-temporary-copy -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++03 -Wbind-to-temporary-copy -verify %s // C++03 requires that we check for a copy constructor when binding a // reference to a temporary, since we are allowed to make a copy, Even diff --git a/clang/test/Driver/fdiagnostics-show-option.c b/clang/test/Driver/fdiagnostics-show-option.c new file mode 100644 index 000000000000..a574503cacee --- /dev/null +++ b/clang/test/Driver/fdiagnostics-show-option.c @@ -0,0 +1,7 @@ +/// -fdiagnostics-show-option is the default +// RUN: %clang -### -c %s 2>&1 | FileCheck --check-prefix=ENABLED %s +// ENABLED-NOT: "-fno-diagnostics-show-option" + +// RUN: %clang -### -c %s -fdiagnostics-show-option -fno-diagnostics-show-option 2>&1 | \ +// RUN: FileCheck --check-prefix=DISABLED %s +// DISABLED: "-fno-diagnostics-show-option" diff --git a/clang/test/Driver/rewrite-legacy-objc.m b/clang/test/Driver/rewrite-legacy-objc.m index 3bbdd66c9cc0..fb7df4b97c06 100644 --- a/clang/test/Driver/rewrite-legacy-objc.m +++ b/clang/test/Driver/rewrite-legacy-objc.m @@ -3,11 +3,11 @@ // TEST0: clang{{.*}}" "-cc1" // TEST0: "-rewrite-objc" // FIXME: CHECK-NOT is broken somehow, it doesn't work here. Check adjacency instead. -// TEST0: "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx-fragile" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fmax-type-align=16" "-fdiagnostics-show-option" +// TEST0: "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx-fragile" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fmax-type-align=16" // TEST0: rewrite-legacy-objc.m" // RUN: %clang -no-canonical-prefixes -target i386-apple-macosx10.9.0 -rewrite-legacy-objc %s -o - -### 2>&1 | \ // RUN: FileCheck -check-prefix=TEST1 %s // RUN: %clang -no-canonical-prefixes -target i386-apple-macosx10.6.0 -rewrite-legacy-objc %s -o - -### 2>&1 | \ // RUN: FileCheck -check-prefix=TEST2 %s -// TEST1: "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx-fragile" "-fobjc-subscripting-legacy-runtime" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fmax-type-align=16" "-fdiagnostics-show-option" -// TEST2: "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx-fragile" "-fobjc-subscripting-legacy-runtime" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fmax-type-align=16" "-fdiagnostics-show-option" +// TEST1: "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx-fragile" "-fobjc-subscripting-legacy-runtime" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fmax-type-align=16" +// TEST2: "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx-fragile" "-fobjc-subscripting-legacy-runtime" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fmax-type-align=16" diff --git a/clang/test/Driver/rewrite-objc.m b/clang/test/Driver/rewrite-objc.m index b1bbad11f265..6073dcdfdafe 100644 --- a/clang/test/Driver/rewrite-objc.m +++ b/clang/test/Driver/rewrite-objc.m @@ -3,4 +3,4 @@ // TEST0: clang{{.*}}" "-cc1" // TEST0: "-rewrite-objc" // FIXME: CHECK-NOT is broken somehow, it doesn't work here. Check adjacency instead. -// TEST0: "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fmax-type-align=16" "-fdiagnostics-show-option" +// TEST0: "-stack-protector" "1" "-fblocks" "-fencode-extended-block-signature" "-fregister-global-dtors-with-atexit" "-fgnuc-version=4.2.1" "-fobjc-runtime=macosx" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fmax-type-align=16" diff --git a/clang/test/Driver/show-option-names.c b/clang/test/Driver/show-option-names.c deleted file mode 100644 index 9843a4371f14..000000000000 --- a/clang/test/Driver/show-option-names.c +++ /dev/null @@ -1,7 +0,0 @@ -// REQUIRES: x86-registered-target - -// RUN: %clang -target x86_64-apple-darwin -fsyntax-only -isysroot /FOO %s 2>&1 | FileCheck --check-prefix=CHECK-SHOW-OPTION-NAMES %s -// CHECK-SHOW-OPTION-NAMES: warning: no such sysroot directory: '{{([A-Za-z]:.*)?}}/FOO' [-Wmissing-sysroot] - -// RUN: %clang -target x86_64-apple-darwin -fsyntax-only -fno-diagnostics-show-option -isysroot /FOO %s 2>&1 | FileCheck --check-prefix=CHECK-NO-SHOW-OPTION-NAMES %s -// CHECK-NO-SHOW-OPTION-NAMES: warning: no such sysroot directory: '{{([A-Za-z]:.*)?}}/FOO'{{$}} diff --git a/clang/test/Frontend/diagnostics-option-names.c b/clang/test/Frontend/diagnostics-option-names.c index ed0d2ed8ef9e..71455be0a75b 100644 --- a/clang/test/Frontend/diagnostics-option-names.c +++ b/clang/test/Frontend/diagnostics-option-names.c @@ -1,4 +1,4 @@ -// RUN: not %clang_cc1 -fdiagnostics-show-option -Werror -Weverything %s 2> %t +// RUN: not %clang_cc1 -Werror -Weverything %s 2> %t // RUN: FileCheck < %t %s int f0(int, unsigned); diff --git a/clang/test/Misc/show-diag-options.c b/clang/test/Misc/show-diag-options.c index 8f05fbc76b56..4e98d63195f1 100644 --- a/clang/test/Misc/show-diag-options.c +++ b/clang/test/Misc/show-diag-options.c @@ -1,16 +1,16 @@ -// RUN: %clang_cc1 -fsyntax-only %s 2>&1 \ +// RUN: %clang_cc1 -fsyntax-only -fno-diagnostics-show-option %s 2>&1 \ // RUN: | FileCheck %s -check-prefix=BASE -// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option %s 2>&1 \ +// RUN: %clang_cc1 -fsyntax-only %s 2>&1 \ // RUN: | FileCheck %s -check-prefix=OPTION -// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-show-option -Werror %s 2>&1 \ +// RUN: not %clang_cc1 -fsyntax-only -Werror %s 2>&1 \ // RUN: | FileCheck %s -check-prefix=OPTION_ERROR -// RUN: %clang_cc1 -fsyntax-only -std=c89 -pedantic -fdiagnostics-show-option %s 2>&1 \ +// RUN: %clang_cc1 -fsyntax-only -std=c89 -pedantic %s 2>&1 \ // RUN: | FileCheck %s -check-prefix=OPTION_PEDANTIC -// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-category id %s 2>&1 \ +// RUN: %clang_cc1 -fsyntax-only -fno-diagnostics-show-option -fdiagnostics-show-category id %s 2>&1 \ // RUN: | FileCheck %s -check-prefix=CATEGORY_ID -// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-category name %s 2>&1 \ +// RUN: %clang_cc1 -fsyntax-only -fno-diagnostics-show-option -fdiagnostics-show-category name %s 2>&1 \ // RUN: | FileCheck %s -check-prefix=CATEGORY_NAME -// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-show-option -fdiagnostics-show-category name -Werror %s 2>&1 \ +// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-show-category name -Werror %s 2>&1 \ // RUN: | FileCheck %s -check-prefix=OPTION_ERROR_CATEGORY void test(int x, int y) { diff --git a/clang/test/Sema/parentheses.c b/clang/test/Sema/parentheses.c index 047bcbfe6caf..164fe4c0f12d 100644 --- a/clang/test/Sema/parentheses.c +++ b/clang/test/Sema/parentheses.c @@ -117,5 +117,5 @@ void conditional_op(int x, int y, _Bool b, void* p) { (void)(x && b ? 1 : 2); // no warning, logical operator } -// RUN: not %clang_cc1 -fsyntax-only -Wparentheses -Werror -fdiagnostics-show-option %s 2>&1 | FileCheck %s -check-prefix=CHECK-FLAG +// RUN: not %clang_cc1 -fsyntax-only -Wparentheses -Werror %s 2>&1 | FileCheck %s -check-prefix=CHECK-FLAG // CHECK-FLAG: error: using the result of an assignment as a condition without parentheses [-Werror,-Wparentheses] From cfe-commits at lists.llvm.org Tue Mar 31 22:32:48 2020 From: cfe-commits at lists.llvm.org (Siva Chandra via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 05:32:48 +0000 (UTC) Subject: [PATCH] D76818: [clang-tidy] Add check llvmlibc-implementation-in-namespace. In-Reply-To: References: Message-ID: <1594d518dd26b8803d548f5547739ad9@localhost.localdomain> sivachandra added inline comments. ================ Comment at: clang-tools-extra/test/clang-tidy/checkers/llvmlibc-implementation-in-namespace.cpp:16 + +namespace namespaceG { +// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: '__llvm_libc' needs to be the outermost namespace. ---------------- Can you add `__llvm_libc` as a nested namespace here. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76818/new/ https://reviews.llvm.org/D76818 From cfe-commits at lists.llvm.org Tue Mar 31 22:32:50 2020 From: cfe-commits at lists.llvm.org (Kim Viggedal via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 05:32:50 +0000 (UTC) Subject: [PATCH] D70265: [clang-tidy] Add CppCoreGuidelines I.2 "Avoid non-const global variables" check In-Reply-To: References: Message-ID: <37e80b8a34c36aa2d1e863f7eb9f1172@localhost.localdomain> vingeldal added a comment. In D70265#1953335 , @lebedev.ri wrote: > Hello. > 2 points: > > rG512767eb3fe9c34c655a480d034147c54f1d4f85 doesn't reference this review, > so it's a bit hard to find. Please try to reference it next time. Will do > Is this check really intentionally complaining about function-scope static variables? > How are they global? > https://godbolt.org/z/2QMemL > > void bar(int*); > > void foo() { > static int a; > bar(&a); > } > > > > > :4:14: warning: variable 'a' is non-const and globally accessible, consider making it const [cppcoreguidelines-avoid-non-const-global-variables] > static int a; > ^ I think that's a false positive, I think it's caught because the variable is static, I'll submit a patch where that doesn't happen ASAP. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70265/new/ https://reviews.llvm.org/D70265 From cfe-commits at lists.llvm.org Tue Mar 31 22:32:50 2020 From: cfe-commits at lists.llvm.org (Wang Tianqing via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 05:32:50 +0000 (UTC) Subject: [PATCH] D77193: [X86] Add SERIALIZE instruction. Message-ID: tianqing created this revision. tianqing added reviewers: craig.topper, RKSimon, LuoYuanke. Herald added subscribers: cfe-commits, hiraditya, mgorny. Herald added a project: clang. For more details about this instruction, please refer to the latest ISE document: https://software.intel.com/en-us/download/intel-architecture-instruction-set-extensions-programming-reference Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77193 Files: clang/docs/ClangCommandLineReference.rst clang/include/clang/Basic/BuiltinsX86.def clang/include/clang/Driver/Options.td clang/lib/Basic/Targets/X86.cpp clang/lib/Basic/Targets/X86.h clang/lib/Headers/CMakeLists.txt clang/lib/Headers/cpuid.h clang/lib/Headers/immintrin.h clang/lib/Headers/serializeintrin.h clang/test/CodeGen/x86-serialize-intrin.c clang/test/Driver/x86-target-features.c clang/test/Preprocessor/x86_target_features.c llvm/include/llvm/IR/IntrinsicsX86.td llvm/lib/Support/Host.cpp llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86InstrInfo.td llvm/lib/Target/X86/X86Subtarget.h llvm/test/CodeGen/X86/serialize-intrinsic.ll llvm/test/MC/Disassembler/X86/x86-16.txt llvm/test/MC/Disassembler/X86/x86-32.txt llvm/test/MC/Disassembler/X86/x86-64.txt llvm/test/MC/X86/x86-16.s llvm/test/MC/X86/x86-32-coverage.s llvm/test/MC/X86/x86-64.s -------------- next part -------------- A non-text attachment was scrubbed... Name: D77193.254083.patch Type: text/x-patch Size: 15202 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 22:32:51 2020 From: cfe-commits at lists.llvm.org (Nathan Ridge via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 05:32:51 +0000 (UTC) Subject: [PATCH] D77194: [clang] Persist Attr::IsPackExpansion into the serialized AST Message-ID: nridge created this revision. Herald added subscribers: cfe-commits, usaxena95, kadircet, ilya-biryukov. Herald added a project: clang. Fixes https://github.com/clangd/clangd/issues/309 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77194 Files: clang/utils/TableGen/ClangAttrEmitter.cpp Index: clang/utils/TableGen/ClangAttrEmitter.cpp =================================================================== --- clang/utils/TableGen/ClangAttrEmitter.cpp +++ clang/utils/TableGen/ClangAttrEmitter.cpp @@ -2911,6 +2911,7 @@ if (R.isSubClassOf(InhClass)) OS << " bool isInherited = Record.readInt();\n"; OS << " bool isImplicit = Record.readInt();\n"; + OS << " bool isPackExpansion = Record.readInt();\n"; ArgRecords = R.getValueAsListOfDefs("Args"); Args.clear(); for (const auto *Arg : ArgRecords) { @@ -2926,6 +2927,7 @@ if (R.isSubClassOf(InhClass)) OS << " cast(New)->setInherited(isInherited);\n"; OS << " New->setImplicit(isImplicit);\n"; + OS << " New->setPackExpansion(isPackExpansion);\n"; OS << " break;\n"; OS << " }\n"; } @@ -2952,6 +2954,7 @@ if (R.isSubClassOf(InhClass)) OS << " Record.push_back(SA->isInherited());\n"; OS << " Record.push_back(A->isImplicit());\n"; + OS << " Record.push_back(A->isPackExpansion());\n"; for (const auto *Arg : Args) createArgument(*Arg, R.getName())->writePCHWrite(OS); -------------- next part -------------- A non-text attachment was scrubbed... Name: D77194.254093.patch Type: text/x-patch Size: 1177 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Tue Mar 31 22:34:30 2020 From: cfe-commits at lists.llvm.org (Fangrui Song via cfe-commits) Date: Tue, 31 Mar 2020 22:34:30 -0700 (PDT) Subject: [clang] 531b3af - [Frontend] Replace CC1 option -masm-verbose with -fno-verbose-asm Message-ID: <5e8427e6.1c69fb81.a1862.392b@mx.google.com> Author: Fangrui Song Date: 2020-03-31T22:33:55-07:00 New Revision: 531b3aff3094dcd2e7ffed7f72ebd932ea386baf URL: https://github.com/llvm/llvm-project/commit/531b3aff3094dcd2e7ffed7f72ebd932ea386baf DIFF: https://github.com/llvm/llvm-project/commit/531b3aff3094dcd2e7ffed7f72ebd932ea386baf.diff LOG: [Frontend] Replace CC1 option -masm-verbose with -fno-verbose-asm Most OS✕target enable -fverbose-asm, so it makes sense to flip the CC1 option to reduce common command lines. Added: Modified: clang/include/clang/Driver/CC1Options.td clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGenObjC/debug-info-class-extension.m clang/test/CodeGenObjC/debug-info-class-extension2.m clang/test/CodeGenObjC/debug-info-class-extension3.m clang/test/CodeGenObjC/debug-info-property.m clang/test/CodeGenObjC/debug-info-property2.m clang/test/CodeGenObjC/debug-info-property4.m clang/test/CodeGenObjC/debug-info-property5.m clang/test/CodeGenObjC/property-dbg.m clang/test/Driver/clang-translation.c clang/test/Driver/integrated-as.c Removed: ################################################################################ diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index a9e2e306632b..ebefb20c4639 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -282,8 +282,6 @@ def no_struct_path_tbaa : Flag<["-"], "no-struct-path-tbaa">, HelpText<"Turn off struct-path aware Type Based Alias Analysis">; def new_struct_path_tbaa : Flag<["-"], "new-struct-path-tbaa">, HelpText<"Enable enhanced struct-path aware Type Based Alias Analysis">; -def masm_verbose : Flag<["-"], "masm-verbose">, - HelpText<"Generate verbose assembly output">; def mdebug_pass : Separate<["-"], "mdebug-pass">, HelpText<"Enable additional debug output">; def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">, diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 26098a8c062a..becabcf21878 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1608,7 +1608,7 @@ def fno_register_global_dtors_with_atexit : Flag<["-"], "fno-register-global-dto HelpText<"Don't use atexit or __cxa_atexit to register global destructors">; def fno_unit_at_a_time : Flag<["-"], "fno-unit-at-a-time">, Group; def fno_unwind_tables : Flag<["-"], "fno-unwind-tables">, Group; -def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group; +def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group, Flags<[CC1Option]>; def fno_working_directory : Flag<["-"], "fno-working-directory">, Group; def fno_wrapv : Flag<["-"], "fno-wrapv">, Group; def fno_zero_initialized_in_bss : Flag<["-"], "fno-zero-initialized-in-bss">, Group; @@ -1927,7 +1927,8 @@ def fuse_init_array : Flag<["-"], "fuse-init-array">, Group, def fno_use_init_array : Flag<["-"], "fno-use-init-array">, Group, Flags<[CC1Option]>, HelpText<"Don't use .init_array instead of .ctors">; def fno_var_tracking : Flag<["-"], "fno-var-tracking">, Group; -def fverbose_asm : Flag<["-"], "fverbose-asm">, Group; +def fverbose_asm : Flag<["-"], "fverbose-asm">, Group, + HelpText<"Generate verbose assembly output">; def dA : Flag<["-"], "dA">, Alias; def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group, HelpText<"Set the default symbol visibility for all global declarations">, Values<"hidden,default">; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 8773468ddbe6..161af89a67e1 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4644,9 +4644,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Decide whether to use verbose asm. Verbose assembly is the default on // toolchains which have the integrated assembler on by default. bool IsIntegratedAssemblerDefault = TC.IsIntegratedAssemblerDefault(); - if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm, - IsIntegratedAssemblerDefault)) - CmdArgs.push_back("-masm-verbose"); + if (!Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm, + IsIntegratedAssemblerDefault)) + CmdArgs.push_back("-fno-verbose-asm"); if (!TC.useIntegratedAs()) CmdArgs.push_back("-no-integrated-as"); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index f8129ea4ac26..e0567138b782 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -855,7 +855,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.CoverageMapping = Args.hasFlag(OPT_fcoverage_mapping, OPT_fno_coverage_mapping, false); Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping); - Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose); + Opts.AsmVerbose = !Args.hasArg(OPT_fno_verbose_asm); Opts.PreserveAsmComments = !Args.hasArg(OPT_fno_preserve_as_comments); Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new); Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions); diff --git a/clang/test/CodeGenObjC/debug-info-class-extension.m b/clang/test/CodeGenObjC/debug-info-class-extension.m index a27810cce743..db654e6a60a5 100644 --- a/clang/test/CodeGenObjC/debug-info-class-extension.m +++ b/clang/test/CodeGenObjC/debug-info-class-extension.m @@ -1,5 +1,5 @@ // FIXME: Check IR rather than asm, then triple is not needed. -// RUN: %clang_cc1 -triple %itanium_abi_triple -masm-verbose -S -debug-info-kind=limited %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple %itanium_abi_triple -S -debug-info-kind=limited %s -o - | FileCheck %s // CHECK: AT_APPLE_objc_complete_type diff --git a/clang/test/CodeGenObjC/debug-info-class-extension2.m b/clang/test/CodeGenObjC/debug-info-class-extension2.m index d4750c120f60..ea7865b4ac5b 100644 --- a/clang/test/CodeGenObjC/debug-info-class-extension2.m +++ b/clang/test/CodeGenObjC/debug-info-class-extension2.m @@ -1,5 +1,5 @@ // FIXME: Check IR rather than asm, then triple is not needed. -// RUN: %clang_cc1 -triple %itanium_abi_triple -masm-verbose -S -debug-info-kind=limited %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple %itanium_abi_triple -S -debug-info-kind=limited %s -o - | FileCheck %s // CHECK: AT_APPLE_objc_complete_type @interface Foo {} @end diff --git a/clang/test/CodeGenObjC/debug-info-class-extension3.m b/clang/test/CodeGenObjC/debug-info-class-extension3.m index a9cf6f6a5c59..f81445b47a21 100644 --- a/clang/test/CodeGenObjC/debug-info-class-extension3.m +++ b/clang/test/CodeGenObjC/debug-info-class-extension3.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -masm-verbose -S -debug-info-kind=limited %s -o - | FileCheck %s +// RUN: %clang_cc1 -S -debug-info-kind=limited %s -o - | FileCheck %s // CHECK-NOT: AT_APPLE_objc_complete_type diff --git a/clang/test/CodeGenObjC/debug-info-property.m b/clang/test/CodeGenObjC/debug-info-property.m index 9b471be23dbd..ca013b24be42 100644 --- a/clang/test/CodeGenObjC/debug-info-property.m +++ b/clang/test/CodeGenObjC/debug-info-property.m @@ -1,5 +1,5 @@ // FIXME: Check IR rather than asm, then triple is not needed. -// RUN: %clang_cc1 -triple %itanium_abi_triple -masm-verbose -S -debug-info-kind=limited %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple %itanium_abi_triple -S -debug-info-kind=limited %s -o - | FileCheck %s // CHECK: AT_APPLE_property_name // CHECK: AT_APPLE_property_attribute diff --git a/clang/test/CodeGenObjC/debug-info-property2.m b/clang/test/CodeGenObjC/debug-info-property2.m index 6a15922c932c..7e0a5e9f954b 100644 --- a/clang/test/CodeGenObjC/debug-info-property2.m +++ b/clang/test/CodeGenObjC/debug-info-property2.m @@ -1,5 +1,5 @@ // FIXME: Check IR rather than asm, then triple is not needed. -// RUN: %clang_cc1 -triple %itanium_abi_triple -masm-verbose -S -debug-info-kind=limited %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple %itanium_abi_triple -S -debug-info-kind=limited %s -o - | FileCheck %s // CHECK: AT_APPLE_property_name @interface C { diff --git a/clang/test/CodeGenObjC/debug-info-property4.m b/clang/test/CodeGenObjC/debug-info-property4.m index f862c85b344d..1f489f2f6b63 100644 --- a/clang/test/CodeGenObjC/debug-info-property4.m +++ b/clang/test/CodeGenObjC/debug-info-property4.m @@ -1,5 +1,5 @@ // FIXME: Check IR rather than asm, then triple is not needed. -// RUN: %clang_cc1 -triple %itanium_abi_triple -masm-verbose -S -debug-info-kind=limited %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple %itanium_abi_triple -S -debug-info-kind=limited %s -o - | FileCheck %s // CHECK: AT_APPLE_property_name // CHECK-NOT: AT_APPLE_property_getter diff --git a/clang/test/CodeGenObjC/debug-info-property5.m b/clang/test/CodeGenObjC/debug-info-property5.m index 191da9c16fcc..8b70f1ff2082 100644 --- a/clang/test/CodeGenObjC/debug-info-property5.m +++ b/clang/test/CodeGenObjC/debug-info-property5.m @@ -1,5 +1,5 @@ // FIXME: Check IR rather than asm, then triple is not needed. -// RUN: %clang_cc1 -triple %itanium_abi_triple -masm-verbose -S -debug-info-kind=limited %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple %itanium_abi_triple -S -debug-info-kind=limited %s -o - | FileCheck %s // CHECK: AT_APPLE_property_name // CHECK: AT_APPLE_property_getter diff --git a/clang/test/CodeGenObjC/property-dbg.m b/clang/test/CodeGenObjC/property-dbg.m index fb70747f5db8..f15213131ccc 100644 --- a/clang/test/CodeGenObjC/property-dbg.m +++ b/clang/test/CodeGenObjC/property-dbg.m @@ -1,5 +1,5 @@ // FIXME: Check IR rather than asm, then triple is not needed. -// RUN: %clang_cc1 -triple %itanium_abi_triple -S -debug-info-kind=limited -masm-verbose -x objective-c < %s | grep DW_AT_name +// RUN: %clang_cc1 -triple %itanium_abi_triple -S -debug-info-kind=limited -x objective-c < %s | grep DW_AT_name @interface Foo { int i; } diff --git a/clang/test/Driver/clang-translation.c b/clang/test/Driver/clang-translation.c index 79d8f6f18ab0..2f02970a2a8e 100644 --- a/clang/test/Driver/clang-translation.c +++ b/clang/test/Driver/clang-translation.c @@ -4,7 +4,6 @@ // I386: "-disable-free" // I386: "-mrelocation-model" "static" // I386: "-mframe-pointer=all" -// I386: "-masm-verbose" // I386: "-munwind-tables" // I386: "-Os" // I386: "-fvisibility" diff --git a/clang/test/Driver/integrated-as.c b/clang/test/Driver/integrated-as.c index df5cf1a17ecc..170515579b1a 100644 --- a/clang/test/Driver/integrated-as.c +++ b/clang/test/Driver/integrated-as.c @@ -12,6 +12,7 @@ // NOFIAS-NOT: cc1as // NOFIAS: -cc1 +// NOFIAS: "-fno-verbose-asm" // NOFIAS: -no-integrated-as // RUN: %clang -target arm-linux-androideabi -### \ From cfe-commits at lists.llvm.org Tue Mar 31 23:25:39 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 06:25:39 +0000 (UTC) Subject: [PATCH] D77193: [X86] Add SERIALIZE instruction. In-Reply-To: References: Message-ID: <12b4f88dfe68eb6cc0f72046c9f78067@localhost.localdomain> craig.topper accepted this revision. craig.topper added a comment. This revision is now accepted and ready to land. LGTM Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77193/new/ https://reviews.llvm.org/D77193 From cfe-commits at lists.llvm.org Tue Mar 31 23:25:40 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 06:25:40 +0000 (UTC) Subject: [PATCH] D77193: [X86] Add SERIALIZE instruction. In-Reply-To: References: Message-ID: <8b91f72ae112c46b99d121d1f6657b01@localhost.localdomain> craig.topper requested changes to this revision. craig.topper added inline comments. This revision now requires changes to proceed. ================ Comment at: clang/lib/Headers/serializeintrin.h:17 + +static __inline__ void +__attribute__((__always_inline__, __nodebug__, __target__("serialize"))) ---------------- Can you add a doxygen comment to this? We've been trying to add them to new intrinsics. There are some in some of the other intrinsic headers but not all. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77193/new/ https://reviews.llvm.org/D77193 From cfe-commits at lists.llvm.org Tue Mar 31 23:58:03 2020 From: cfe-commits at lists.llvm.org (serge via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 06:58:03 +0000 (UTC) Subject: [PATCH] D71082: Allow system header to provide their own implementation of some builtin In-Reply-To: References: Message-ID: serge-sans-paille added a comment. @manojgupta prior to this patch, clang was using its version of `memcpy` and not the one provided inline. I slightly modified your reproducer to showcase that aspect: https://godbolt.org/z/NmxC0v Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71082/new/ https://reviews.llvm.org/D71082 From cfe-commits at lists.llvm.org Wed Apr 1 00:18:32 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via cfe-commits) Date: Wed, 01 Apr 2020 00:18:32 -0700 (PDT) Subject: [clang-tools-extra] 72439b6 - [clangd] Add a flag to turn on recovery-expr. Message-ID: <5e844048.1c69fb81.5353d.4b27@mx.google.com> Author: Haojian Wu Date: 2020-04-01T09:03:56+02:00 New Revision: 72439b6b9557d5c58ec7f95a14722ef581906a17 URL: https://github.com/llvm/llvm-project/commit/72439b6b9557d5c58ec7f95a14722ef581906a17 DIFF: https://github.com/llvm/llvm-project/commit/72439b6b9557d5c58ec7f95a14722ef581906a17.diff LOG: [clangd] Add a flag to turn on recovery-expr. Reviewers: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77142 Added: Modified: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/ClangdServer.h clang-tools-extra/clangd/Compiler.h clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/tool/ClangdMain.cpp clang-tools-extra/clangd/unittests/FindTargetTests.cpp clang-tools-extra/clangd/unittests/TestTU.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index 36af6c98d18b..0882784f7031 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -134,7 +134,8 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, : nullptr), GetClangTidyOptions(Opts.GetClangTidyOptions), SuggestMissingIncludes(Opts.SuggestMissingIncludes), - TweakFilter(Opts.TweakFilter), WorkspaceRoot(Opts.WorkspaceRoot), + BuildRecoveryAST(Opts.BuildRecoveryAST), TweakFilter(Opts.TweakFilter), + WorkspaceRoot(Opts.WorkspaceRoot), // Pass a callback into `WorkScheduler` to extract symbols from a newly // parsed file and rebuild the file index synchronously each time an AST // is parsed. @@ -191,6 +192,7 @@ void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents, Inputs.ForceRebuild = ForceRebuild; Inputs.Opts = std::move(Opts); Inputs.Index = Index; + Inputs.Opts.BuildRecoveryAST = BuildRecoveryAST; bool NewFile = WorkScheduler.update(File, Inputs, WantDiags); // If we loaded Foo.h, we want to make sure Foo.cpp is indexed. if (NewFile && BackgroundIdx) diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index a0659c7c3d22..f1e981e6c14f 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -118,6 +118,9 @@ class ClangdServer { /// enabled. ClangTidyOptionsBuilder GetClangTidyOptions; + /// If true, turn on the `-frecovery-ast` clang flag. + bool BuildRecoveryAST = false; + /// Clangd's workspace root. Relevant for "workspace" operations not bound /// to a particular file. /// FIXME: If not set, should use the current working directory. @@ -345,6 +348,9 @@ class ClangdServer { // can be caused by missing includes (e.g. member access in incomplete type). bool SuggestMissingIncludes = false; + // If true, preserve expressions in AST for broken code. + bool BuildRecoveryAST = false; + std::function TweakFilter; // GUARDED_BY(CachedCompletionFuzzyFindRequestMutex) diff --git a/clang-tools-extra/clangd/Compiler.h b/clang-tools-extra/clangd/Compiler.h index ef5386bb0d17..b7cc174455f3 100644 --- a/clang-tools-extra/clangd/Compiler.h +++ b/clang-tools-extra/clangd/Compiler.h @@ -38,6 +38,7 @@ class IgnoreDiagnostics : public DiagnosticConsumer { struct ParseOptions { tidy::ClangTidyOptions ClangTidyOpts; bool SuggestMissingIncludes = false; + bool BuildRecoveryAST = false; }; /// Information required to run clang, e.g. to parse AST or do code completion. diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp index 1d6997f0b4d4..2c7cb5d2b85d 100644 --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -253,6 +253,10 @@ ParsedAST::build(llvm::StringRef Version, const PrecompiledPreamble *PreamblePCH = Preamble ? &Preamble->Preamble : nullptr; + // Recovery expression currently only works for C++. + if (CI->getLangOpts()->CPlusPlus) + CI->getLangOpts()->RecoveryAST = Opts.BuildRecoveryAST; + StoreDiags ASTDiags; std::string Content = std::string(Buffer->getBuffer()); std::string Filename = diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index fdee71fd2244..48f15420032f 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -132,6 +132,10 @@ buildPreamble(PathRef FileName, CompilerInvocation &CI, // to read back. We rely on dynamic index for the comments instead. CI.getPreprocessorOpts().WriteCommentListToPCH = false; + // Recovery expression currently only works for C++. + if (CI.getLangOpts()->CPlusPlus) + CI.getLangOpts()->RecoveryAST = Inputs.Opts.BuildRecoveryAST; + CppFilePreambleCallbacks SerializedDeclsCollector(FileName, PreambleCallback); if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) { log("Couldn't set working directory when building the preamble."); diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index 7a7bb9b0718e..9bfc58b55f71 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -281,6 +281,15 @@ opt CrossFileRename{ Hidden, }; +opt RecoveryAST{ + "recovery-ast", + cat(Features), + desc("Preserve expressions in AST for broken code (C++ only). Note that " + "this feature is experimental and may lead to crashes"), + init(false), + Hidden, +}; + opt WorkerThreadsCount{ "j", cat(Misc), @@ -629,6 +638,7 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var } Opts.StaticIndex = StaticIdx.get(); Opts.AsyncThreadsCount = WorkerThreadsCount; + Opts.BuildRecoveryAST = RecoveryAST; clangd::CodeCompleteOptions CCOpts; CCOpts.IncludeIneligibleResults = IncludeIneligibleResults; diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp index 53d29a236a07..7b6fff292e66 100644 --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -132,6 +132,16 @@ TEST_F(TargetDeclTest, Exprs) { EXPECT_DECLS("CXXOperatorCallExpr", "void operator()(int n)"); } +TEST_F(TargetDeclTest, Recovery) { + Code = R"cpp( + // error-ok: testing behavior on broken code + int f(); + int f(int, int); + int x = [[f]](42); + )cpp"; + EXPECT_DECLS("UnresolvedLookupExpr", "int f()", "int f(int, int)"); +} + TEST_F(TargetDeclTest, UsingDecl) { Code = R"cpp( namespace foo { @@ -685,6 +695,15 @@ TEST_F(FindExplicitReferencesTest, All) { )cpp", "0: targets = {x}\n" "1: targets = {X::a}\n"}, + {R"cpp( + // error-ok: testing with broken code + int bar(); + int foo() { + return $0^bar() + $1^bar(42); + } + )cpp", + "0: targets = {bar}\n" + "1: targets = {bar}\n"}, // Namespaces and aliases. {R"cpp( namespace ns {} diff --git a/clang-tools-extra/clangd/unittests/TestTU.cpp b/clang-tools-extra/clangd/unittests/TestTU.cpp index dfcdb0884e27..2adcfc338cc2 100644 --- a/clang-tools-extra/clangd/unittests/TestTU.cpp +++ b/clang-tools-extra/clangd/unittests/TestTU.cpp @@ -56,6 +56,7 @@ ParseInputs TestTU::inputs() const { Inputs.Contents = Code; Inputs.FS = buildTestFS(Files); Inputs.Opts = ParseOptions(); + Inputs.Opts.BuildRecoveryAST = true; Inputs.Opts.ClangTidyOpts.Checks = ClangTidyChecks; Inputs.Opts.ClangTidyOpts.WarningsAsErrors = ClangTidyWarningsAsErrors; Inputs.Index = ExternalIndex; From cfe-commits at lists.llvm.org Wed Apr 1 00:30:56 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 07:30:56 +0000 (UTC) Subject: [PATCH] D77142: [clangd] Add a flag to turn on recovery-expr. In-Reply-To: References: Message-ID: hokein updated this revision to Diff 254097. hokein added a comment. mention C++ only. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77142/new/ https://reviews.llvm.org/D77142 Files: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/ClangdServer.h clang-tools-extra/clangd/Compiler.h clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/tool/ClangdMain.cpp clang-tools-extra/clangd/unittests/FindTargetTests.cpp clang-tools-extra/clangd/unittests/TestTU.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77142.254097.patch Type: text/x-patch Size: 6208 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 00:30:56 2020 From: cfe-commits at lists.llvm.org (Csaba Dabis via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 07:30:56 +0000 (UTC) Subject: [PATCH] D77066: [analyzer] ApiModeling: Add buffer size arg constraint In-Reply-To: References: Message-ID: <2339b0cf3b8ad32d43a411d164790a5d@localhost.localdomain> Charusso added a comment. In D77066#1953280 , @Charusso wrote: > getDynamicSizeWithOffset(State, MR, SVB) { > Offset = State->getStoreManager().getStaticOffset(MR, SVB); > ... > } > Hm, the MemRegion's offset should be great. I was thinking about if we would store SVal offsets in the Store. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77066/new/ https://reviews.llvm.org/D77066 From cfe-commits at lists.llvm.org Wed Apr 1 00:30:59 2020 From: cfe-commits at lists.llvm.org (Momchil Velikov via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 07:30:59 +0000 (UTC) Subject: [PATCH] D75181: [AArch64] Handle BTI/PAC in case of generated functions. In-Reply-To: References: Message-ID: <567c109023217c6cf040a08715d9d1e1@localhost.localdomain> chill added inline comments. ================ Comment at: clang/lib/CodeGen/CGCall.cpp:1828 + if (CodeGenOpts.BranchTargetEnforcement) { + FuncAttrs.addAttribute("branch-target-enforcement", "true"); + } ---------------- danielkiss wrote: > chill wrote: > > I would really prefer to not set values "true" or "false" for the attribute: we don't really have tri-state logic there (absent/present-true/present-false), and those values just add some not-very useful string processing. > > > the attribute will be "absent" for the runtime emitted function. How about setting the attribute for LLVM created functions at the time of creation, just like Clang created functions get their attribute at the time of creation? ================ Comment at: clang/lib/CodeGen/CGCall.cpp:1831 + + auto RASignKind = CodeGenOpts.getSignReturnAddress(); + if (RASignKind != CodeGenOptions::SignReturnAddressScope::None) { ---------------- danielkiss wrote: > chill wrote: > > What do we get from setting the PACBTI state in the default function attributes? We still have > > to do a per function processing, we can just as well avoid repeating the logic, and spare us some > > adding and potentially removing attributes churn. > > > in the new patch the per function processing will change the attribute only if really need. Sure, but that's duplication of code/logic, it's a source of countless issues "oh, here's the place I should fix that thing ... oh noes, turns out I have to fix ten more ... hope I've found all ..." ;) ================ Comment at: llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp:200 + if (!F.hasFnAttribute("branch-target-enforcement")) + return false; + Attribute A = F.getFnAttribute("branch-target-enforcement"); ---------------- chill wrote: > chill wrote: > > This should be "true", although the comment might turn out moot. > > > > If we somehow end up with a function, that does not have that attribute, we should clear the > > ELF flag. > > > Oh, I see, those are the cases of sanitizer functions, created at LLVM level, that don't have the attribute. > Please, leave a comment in that sense. Or, as mentioned in the other comment, check if it's possible to set the attribute at the time of creation (from module attributes?). Tri-state logic is added complexity, if it's necessary, it's necessary, but if it's not, better make it simpler. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75181/new/ https://reviews.llvm.org/D75181 From cfe-commits at lists.llvm.org Wed Apr 1 00:31:09 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 07:31:09 +0000 (UTC) Subject: [PATCH] D77142: [clangd] Add a flag to turn on recovery-expr. In-Reply-To: References: Message-ID: <5d5aabda320adbfdb601dc45cc4cea79@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG72439b6b9557: [clangd] Add a flag to turn on recovery-expr. (authored by hokein). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77142/new/ https://reviews.llvm.org/D77142 Files: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/ClangdServer.h clang-tools-extra/clangd/Compiler.h clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/tool/ClangdMain.cpp clang-tools-extra/clangd/unittests/FindTargetTests.cpp clang-tools-extra/clangd/unittests/TestTU.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77142.254099.patch Type: text/x-patch Size: 6208 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 01:09:37 2020 From: cfe-commits at lists.llvm.org (Dylan McKay via cfe-commits) Date: Wed, 01 Apr 2020 01:09:37 -0700 (PDT) Subject: [clang] 57fd86d - [AVR] Fix function pointer address space Message-ID: <5e844c41.1c69fb81.b3d59.51b5@mx.google.com> Author: Vlastimil Labsky Date: 2020-04-01T21:08:37+13:00 New Revision: 57fd86de879cf2b4c7001b6d0a09df60877ce24d URL: https://github.com/llvm/llvm-project/commit/57fd86de879cf2b4c7001b6d0a09df60877ce24d DIFF: https://github.com/llvm/llvm-project/commit/57fd86de879cf2b4c7001b6d0a09df60877ce24d.diff LOG: [AVR] Fix function pointer address space Summary: Function pointers should be created with program address space. This fixes function pointers on AVR. Reviewers: dylanmckay Reviewed By: dylanmckay Subscribers: Jim, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77119 Added: Modified: clang/lib/CodeGen/CodeGenTypes.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index befd80de96f0..29adc2c7adb3 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -595,7 +595,11 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { llvm::Type *PointeeType = ConvertTypeForMem(ETy); if (PointeeType->isVoidTy()) PointeeType = llvm::Type::getInt8Ty(getLLVMContext()); - unsigned AS = Context.getTargetAddressSpace(ETy); + + unsigned AS = PointeeType->isFunctionTy() + ? getDataLayout().getProgramAddressSpace() + : Context.getTargetAddressSpace(ETy); + ResultType = llvm::PointerType::get(PointeeType, AS); break; } From cfe-commits at lists.llvm.org Wed Apr 1 01:36:53 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 08:36:53 +0000 (UTC) Subject: [PATCH] D77194: [clang] Persist Attr::IsPackExpansion into the serialized AST In-Reply-To: References: Message-ID: <0c0308470e2c1e5070227dc32f4a45db@localhost.localdomain> kadircet added a comment. oh wow! thanks for looking into this. Looking at the history, it seems like an oversight. The patch that introduced packexpansion bit: https://github.com/llvm/llvm-project/commit/44c247f0f009eec70a193335c8a353d6f8602bfd. it didn't add that field to pchattr serialization code unfortunately. (another example on isimplicit, which adds attr to record https://github.com/llvm/llvm-project/commit/36a5350e51a6dcfae424332aaa266a1e5bfb8c4f) Could you add tests though ? Something similar to clang/test/PCH/attrs-PR8406.c should be enough. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77194/new/ https://reviews.llvm.org/D77194 From cfe-commits at lists.llvm.org Wed Apr 1 01:36:53 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 08:36:53 +0000 (UTC) Subject: [PATCH] D77194: [clang] Persist Attr::IsPackExpansion into the serialized AST In-Reply-To: References: Message-ID: <1b1f0b0e5578fe00760521c9c65d7c1f@localhost.localdomain> kadircet added a comment. also please update the commit message to mention "PCH" rather than "serialized ast". Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77194/new/ https://reviews.llvm.org/D77194 From cfe-commits at lists.llvm.org Wed Apr 1 01:36:57 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Bal=C3=A1zs_K=C3=A9ri_via_Phabricator?= via cfe-commits) Date: Wed, 01 Apr 2020 08:36:57 +0000 (UTC) Subject: [PATCH] D70411: [analyzer] CERT: STR31-C In-Reply-To: References: Message-ID: <16e2a5198dbe2dc8bce6e64fca58c38e@localhost.localdomain> balazske added inline comments. ================ Comment at: clang/lib/StaticAnalyzer/Checkers/cert/StrChecker.cpp:55 + // they can cause a not null-terminated string. In this case we store the + // string is being not null-terminated in the 'NullTerminationMap'. + // ---------------- The functions `gets`, `strcpy` return a null-terminated string according to standard, probably `sprintf` too, and the `fscanf` `%s` output is null-terminated too even if no length is specified (maybe it writes outside of the specified buffer but null terminated). ================ Comment at: clang/test/Analysis/cert/str31-c.cpp:117 + if (editor != NULL) { + size_t len = strlen(editor) + 1; + buff2 = (char *)malloc(len); ---------------- Do we get a warning if the `+1` above is missing? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70411/new/ https://reviews.llvm.org/D70411 From cfe-commits at lists.llvm.org Wed Apr 1 01:36:58 2020 From: cfe-commits at lists.llvm.org (Tamas Petz via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 08:36:58 +0000 (UTC) Subject: [PATCH] D77131: [clang] Move branch-protection from CodeGenOptions to LangOptions In-Reply-To: References: Message-ID: tamas.petz added a comment. Tests pass, however, I am not sure ParseLangArgs is called in all the necessary cases (see the occurrences in the code). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77131/new/ https://reviews.llvm.org/D77131 From cfe-commits at lists.llvm.org Wed Apr 1 01:36:58 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 08:36:58 +0000 (UTC) Subject: [PATCH] D77199: [clang-tidy] Address false positive in modernize-use-default-member-init Message-ID: njames93 created this revision. njames93 added reviewers: aaron.ballman, alexfh, gribozavr2. Herald added subscribers: cfe-commits, xazax.hun. Herald added a project: clang. Fixes incorrect warning emitted by "modernize-use-default-member-init" (new to 10.0.0) . Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77199 Files: clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp Index: clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp +++ clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp @@ -432,3 +432,9 @@ // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: use default member initializer for 'k' [modernize-use-default-member-init] // CHECK-FIXES: int i{5}, k{8}; }; + +struct PR45363 { + // Ensure no warning is emitted here + PR45363(int i = 0) : m_i{i} {} + int m_i; +}; Index: clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp +++ clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp @@ -17,6 +17,12 @@ namespace tidy { namespace modernize { +namespace { +AST_MATCHER_P(InitListExpr, initCountIs, unsigned, N) { + return Node.getNumInits() == N; +} +} // namespace + static StringRef getValueOfValueInit(const QualType InitType) { switch (InitType->getScalarTypeKind()) { case Type::STK_CPointer: @@ -190,7 +196,7 @@ } void UseDefaultMemberInitCheck::registerMatchers(MatchFinder *Finder) { - auto Init = + auto InitBase = anyOf(stringLiteral(), characterLiteral(), integerLiteral(), unaryOperator(hasAnyOperatorName("+", "-"), hasUnaryOperand(integerLiteral())), @@ -198,7 +204,13 @@ unaryOperator(hasAnyOperatorName("+", "-"), hasUnaryOperand(floatLiteral())), cxxBoolLiteral(), cxxNullPtrLiteralExpr(), implicitValueInitExpr(), - initListExpr(), declRefExpr(to(enumConstantDecl()))); + declRefExpr(to(enumConstantDecl()))); + + auto Init = + anyOf(initListExpr(anyOf( + allOf(initCountIs(1), hasInit(0, ignoringImplicit(InitBase))), + initCountIs(0))), + InitBase); Finder->addMatcher( cxxConstructorDecl( -------------- next part -------------- A non-text attachment was scrubbed... Name: D77199.254109.patch Type: text/x-patch Size: 2132 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 01:37:34 2020 From: cfe-commits at lists.llvm.org (Dylan McKay via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 08:37:34 +0000 (UTC) Subject: [PATCH] D77119: [AVR] Fix function pointer address space In-Reply-To: References: Message-ID: <394d8482baae0146fc5a892994db1edf@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG57fd86de879c: [AVR] Fix function pointer address space (authored by vlastik, committed by dylanmckay). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77119/new/ https://reviews.llvm.org/D77119 Files: clang/lib/CodeGen/CodeGenTypes.cpp Index: clang/lib/CodeGen/CodeGenTypes.cpp =================================================================== --- clang/lib/CodeGen/CodeGenTypes.cpp +++ clang/lib/CodeGen/CodeGenTypes.cpp @@ -595,7 +595,11 @@ llvm::Type *PointeeType = ConvertTypeForMem(ETy); if (PointeeType->isVoidTy()) PointeeType = llvm::Type::getInt8Ty(getLLVMContext()); - unsigned AS = Context.getTargetAddressSpace(ETy); + + unsigned AS = PointeeType->isFunctionTy() + ? getDataLayout().getProgramAddressSpace() + : Context.getTargetAddressSpace(ETy); + ResultType = llvm::PointerType::get(PointeeType, AS); break; } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77119.254112.patch Type: text/x-patch Size: 669 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 01:40:46 2020 From: cfe-commits at lists.llvm.org (Sylvestre Ledru via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 08:40:46 +0000 (UTC) Subject: [PATCH] D75171: [Analyzer] Fix for incorrect use of container and iterator checkers In-Reply-To: References: Message-ID: sylvestre.ledru added a comment. @baloghadamsoftware @Szelethus it would be great to have the name of the checkers in the error message The error is "error: checker cannot be enabled with analyzer option 'aggressive-binary-operation-simplification' == false" and I had to look at this patch to understand that it is about iterator Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75171/new/ https://reviews.llvm.org/D75171 From cfe-commits at lists.llvm.org Wed Apr 1 01:40:50 2020 From: cfe-commits at lists.llvm.org (Wang Tianqing via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 08:40:50 +0000 (UTC) Subject: [PATCH] D77193: [X86] Add SERIALIZE instruction. In-Reply-To: References: Message-ID: <148898e4223b3c10220eea8497456a9c@localhost.localdomain> tianqing updated this revision to Diff 254114. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77193/new/ https://reviews.llvm.org/D77193 Files: clang/docs/ClangCommandLineReference.rst clang/include/clang/Basic/BuiltinsX86.def clang/include/clang/Driver/Options.td clang/lib/Basic/Targets/X86.cpp clang/lib/Basic/Targets/X86.h clang/lib/Headers/CMakeLists.txt clang/lib/Headers/cpuid.h clang/lib/Headers/immintrin.h clang/lib/Headers/serializeintrin.h clang/test/CodeGen/x86-serialize-intrin.c clang/test/Driver/x86-target-features.c clang/test/Preprocessor/x86_target_features.c llvm/include/llvm/IR/IntrinsicsX86.td llvm/lib/Support/Host.cpp llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86InstrInfo.td llvm/lib/Target/X86/X86Subtarget.h llvm/test/CodeGen/X86/serialize-intrinsic.ll llvm/test/MC/Disassembler/X86/x86-16.txt llvm/test/MC/Disassembler/X86/x86-32.txt llvm/test/MC/Disassembler/X86/x86-64.txt llvm/test/MC/X86/x86-16.s llvm/test/MC/X86/x86-32-coverage.s llvm/test/MC/X86/x86-64.s -------------- next part -------------- A non-text attachment was scrubbed... Name: D77193.254114.patch Type: text/x-patch Size: 15367 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 01:50:04 2020 From: cfe-commits at lists.llvm.org (Raphael Isemann via cfe-commits) Date: Wed, 01 Apr 2020 01:50:04 -0700 (PDT) Subject: [clang] 08a53db - [clang] Minor cleanup in CloneDetectionTest Message-ID: <5e8455bc.1c69fb81.8bad.5078@mx.google.com> Author: Raphael Isemann Date: 2020-04-01T10:48:50+02:00 New Revision: 08a53dba93389a9859c12e948d8281a839cffbdb URL: https://github.com/llvm/llvm-project/commit/08a53dba93389a9859c12e948d8281a839cffbdb DIFF: https://github.com/llvm/llvm-project/commit/08a53dba93389a9859c12e948d8281a839cffbdb.diff LOG: [clang] Minor cleanup in CloneDetectionTest Follow up to e8f13f4f62f. Added: Modified: clang/unittests/Analysis/CloneDetectionTest.cpp Removed: ################################################################################ diff --git a/clang/unittests/Analysis/CloneDetectionTest.cpp b/clang/unittests/Analysis/CloneDetectionTest.cpp index e09d0733f044..f8f3602f5a2a 100644 --- a/clang/unittests/Analysis/CloneDetectionTest.cpp +++ b/clang/unittests/Analysis/CloneDetectionTest.cpp @@ -42,7 +42,7 @@ class NoBarFunctionConstraint { for (const StmtSequence &Arg : {A, B}) { if (const auto *D = dyn_cast(Arg.getContainingDecl())) { - if (StringRef(D->getNameAsString()).startswith("bar")) + if (D->getName().startswith("bar")) return false; } } From cfe-commits at lists.llvm.org Wed Apr 1 02:09:21 2020 From: cfe-commits at lists.llvm.org (Momchil Velikov via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 09:09:21 +0000 (UTC) Subject: [PATCH] D77131: [clang] Move branch-protection from CodeGenOptions to LangOptions In-Reply-To: References: Message-ID: <053597d7756eaa905c48d355b255874f@localhost.localdomain> chill added a reviewer: efriedma. chill added a subscriber: efriedma. chill added a comment. Following @efriedma comment here http://lists.llvm.org/pipermail/cfe-dev/2020-March/065017.html LGTM. ================ Comment at: clang/include/clang/Basic/TargetInfo.h:18 #include "clang/Basic/AddressSpaces.h" -#include "clang/Basic/LLVM.h" #include "clang/Basic/CodeGenOptions.h" +#include "clang/Basic/LLVM.h" ---------------- This include is probably not needed anymore. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77131/new/ https://reviews.llvm.org/D77131 From cfe-commits at lists.llvm.org Wed Apr 1 02:09:22 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 09:09:22 +0000 (UTC) Subject: [PATCH] D77176: [clangd] Force delayed-template-parsing off in code completion. In-Reply-To: References: Message-ID: <0be127a97bb9e07e753f5f2e29a4691e@localhost.localdomain> kadircet accepted this revision. kadircet added a comment. This revision is now accepted and ready to land. thanks, LGTM! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77176/new/ https://reviews.llvm.org/D77176 From cfe-commits at lists.llvm.org Wed Apr 1 02:09:24 2020 From: cfe-commits at lists.llvm.org (Sam McCall via cfe-commits) Date: Wed, 01 Apr 2020 02:09:24 -0700 (PDT) Subject: [clang-tools-extra] 038f03c - [clangd] Force delayed-template-parsing off in code completion. Message-ID: <5e845a44.1c69fb81.7ac17.5532@mx.google.com> Author: Sam McCall Date: 2020-04-01T11:09:15+02:00 New Revision: 038f03cb5ef5d44676cbde06560ed2668f4a7acc URL: https://github.com/llvm/llvm-project/commit/038f03cb5ef5d44676cbde06560ed2668f4a7acc DIFF: https://github.com/llvm/llvm-project/commit/038f03cb5ef5d44676cbde06560ed2668f4a7acc.diff LOG: [clangd] Force delayed-template-parsing off in code completion. Summary: It prevents code completion entirely in affected method bodies. The main reason it's turned on is for compatibility with headers, so we turn it off for the main file only. This is allowed because it's a compatible langopt. Fixes https://github.com/clangd/clangd/issues/302 Reviewers: kadircet Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77176 Added: Modified: clang-tools-extra/clangd/CodeComplete.cpp clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp index 344b90ecaa32..86ea5f26d397 100644 --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -1072,6 +1072,10 @@ bool semaCodeComplete(std::unique_ptr Consumer, FrontendOpts.SkipFunctionBodies = true; // Disable typo correction in Sema. CI->getLangOpts()->SpellChecking = false; + // Code completion won't trigger in delayed template bodies. + // This is on-by-default in windows to allow parsing SDK headers; we're only + // disabling it for the main-file (not preamble). + CI->getLangOpts()->DelayedTemplateParsing = false; // Setup code completion. FrontendOpts.CodeCompleteOpts = Options; FrontendOpts.CodeCompletionAt.FileName = std::string(Input.FileName); diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp index 06dccfa93956..3cb18f6893e9 100644 --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -127,7 +127,6 @@ CodeCompleteResult completions(llvm::StringRef Text, Annotations Test(Text); auto TU = TestTU::withCode(Test.code()); // To make sure our tests for completiopns inside templates work on Windows. - TU.ExtraArgs = {"-fno-delayed-template-parsing"}; TU.Filename = FilePath.str(); return completions(TU, Test.point(), std::move(IndexSymbols), std::move(Opts)); @@ -2660,6 +2659,20 @@ TEST(CompletionTest, NoCrashWithIncompleteLambda) { EXPECT_THAT(Signatures, Contains(Sig("x() -> auto"))); } +TEST(CompletionTest, DelayedTemplateParsing) { + Annotations Test(R"cpp( + int xxx; + template int foo() { return xx^; } + )cpp"); + auto TU = TestTU::withCode(Test.code()); + // Even though delayed-template-parsing is on, we will disable it to provide + // completion in templates. + TU.ExtraArgs.push_back("-fdelayed-template-parsing"); + + EXPECT_THAT(completions(TU, Test.point()).Completions, + Contains(Named("xxx"))); +} + TEST(CompletionTest, CompletionRange) { const char *WithRange = "auto x = [[abc]]^"; auto Completions = completions(WithRange); From cfe-commits at lists.llvm.org Wed Apr 1 02:11:00 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 09:11:00 +0000 (UTC) Subject: [PATCH] D77176: [clangd] Force delayed-template-parsing off in code completion. In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rG038f03cb5ef5: [clangd] Force delayed-template-parsing off in code completion. (authored by sammccall). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77176/new/ https://reviews.llvm.org/D77176 Files: clang-tools-extra/clangd/CodeComplete.cpp clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp Index: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -127,7 +127,6 @@ Annotations Test(Text); auto TU = TestTU::withCode(Test.code()); // To make sure our tests for completiopns inside templates work on Windows. - TU.ExtraArgs = {"-fno-delayed-template-parsing"}; TU.Filename = FilePath.str(); return completions(TU, Test.point(), std::move(IndexSymbols), std::move(Opts)); @@ -2660,6 +2659,20 @@ EXPECT_THAT(Signatures, Contains(Sig("x() -> auto"))); } +TEST(CompletionTest, DelayedTemplateParsing) { + Annotations Test(R"cpp( + int xxx; + template int foo() { return xx^; } + )cpp"); + auto TU = TestTU::withCode(Test.code()); + // Even though delayed-template-parsing is on, we will disable it to provide + // completion in templates. + TU.ExtraArgs.push_back("-fdelayed-template-parsing"); + + EXPECT_THAT(completions(TU, Test.point()).Completions, + Contains(Named("xxx"))); +} + TEST(CompletionTest, CompletionRange) { const char *WithRange = "auto x = [[abc]]^"; auto Completions = completions(WithRange); Index: clang-tools-extra/clangd/CodeComplete.cpp =================================================================== --- clang-tools-extra/clangd/CodeComplete.cpp +++ clang-tools-extra/clangd/CodeComplete.cpp @@ -1072,6 +1072,10 @@ FrontendOpts.SkipFunctionBodies = true; // Disable typo correction in Sema. CI->getLangOpts()->SpellChecking = false; + // Code completion won't trigger in delayed template bodies. + // This is on-by-default in windows to allow parsing SDK headers; we're only + // disabling it for the main-file (not preamble). + CI->getLangOpts()->DelayedTemplateParsing = false; // Setup code completion. FrontendOpts.CodeCompleteOpts = Options; FrontendOpts.CodeCompletionAt.FileName = std::string(Input.FileName); -------------- next part -------------- A non-text attachment was scrubbed... Name: D77176.254123.patch Type: text/x-patch Size: 2063 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 02:16:43 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 09:16:43 +0000 (UTC) Subject: [PATCH] D77041: [AST] Fix a crash on invalid constexpr Ctorinitializer when building RecoveryExpr. In-Reply-To: References: Message-ID: hokein marked 2 inline comments as done. hokein added inline comments. ================ Comment at: clang/lib/Sema/SemaDeclCXX.cpp:1688 CheckConstexprKind Kind) { + assert(!NewFD->isInvalidDecl()); const CXXMethodDecl *MD = dyn_cast(NewFD); ---------------- rsmith wrote: > Instead of asserting this, please just return false on an invalid declaration. There's nothing fundamentally wrong with calling this function on an invalid declaration, but as usual, if we encounter something invalid, we should suppress follow-on diagnostics. oh, thanks. This function is only called in two places, and both of them check the NewFD->isValid before calling it, so my understanding is that this function is required a valid NewFD. ================ Comment at: clang/lib/Sema/SemaDeclCXX.cpp:5005 + if (Member->getInit() && Member->getInit()->containsErrors()) + Constructor->setInvalidDecl(); if (Member->isBaseInitializer()) ---------------- rsmith wrote: > rsmith wrote: > > This is inappropriate. The "invalid" bit on a declaration indicates whether the declaration is invalid, not whether the definition is invalid. > > > > What we should do is add a "contains errors" bit to `Stmt`, and mark the function body as containing errors if it has an initializer that contains an error. > As an example of why this distinction matters: the "contains errors" bit indicates whether external users of the declaration should ignore it / suppress errors on it, or whether they can still treat it as a regular declaration. It's not ideal for an error in the body of a function to affect the diagnostic behavior of a caller to that function, since the body is (typically) irrelevant to the validity of that caller. Thanks for the suggestions and clarifications! The "invalid" bit of decl is subtle, I didn't infer it from the code before, thanks for the explanation. Setting the decl invalid seemed much safer to us, and would avoid running a lot of unexpected code paths in clang which might violate the assumptions. > What we should do is add a "contains errors" bit to Stmt, and mark the function body as containing errors if it has an initializer that contains an error. This sounds promising, but there are no free bit in Stmt at the moment :( (to add the ErrorBit to expr, we have sacrificed the `IsOMPStructuredBlock` bit, it would be easier after the ongoing FPOptions stuff finished, which will free certain bits). since this crash is blocking recovery-expr stuff, it is prioritized for us to fix it. Maybe a compromising plan for now is to fix it in `CheckConstexprFunctionDefinition` (just moving the inspecting `InitExpr` code there) -- the crash is from `isPotentialConstantExpr` which is only called in `CheckConstexprFunctionDefinition`, should cover all cases. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77041/new/ https://reviews.llvm.org/D77041 From cfe-commits at lists.llvm.org Wed Apr 1 02:43:48 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Wed, 01 Apr 2020 09:43:48 +0000 (UTC) Subject: [PATCH] D75171: [Analyzer] Fix for incorrect use of container and iterator checkers In-Reply-To: References: Message-ID: Szelethus added a comment. In D75171#1954279 , @sylvestre.ledru wrote: > @baloghadamsoftware @Szelethus it would be great to have the name of the checkers in the error message > The error is "error: checker cannot be enabled with analyzer option 'aggressive-binary-operation-simplification' == false" > and I had to look at this patch to understand that it is about iterator Huh, that is a fair point -- Adam, can you patch it in please? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75171/new/ https://reviews.llvm.org/D75171 From cfe-commits at lists.llvm.org Wed Apr 1 02:43:49 2020 From: cfe-commits at lists.llvm.org (Raphael Isemann via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 09:43:49 +0000 (UTC) Subject: [PATCH] D75561: Remove const qualifier from Modules returned by ExternalASTSource. (NFC) In-Reply-To: References: Message-ID: <25f9a7042a4d109fbe7422591d9bd501@localhost.localdomain> teemperor accepted this revision. teemperor added a comment. This revision is now accepted and ready to land. I seems quite a lot of APIs in Clang are already requiring non-const Modules so I think this is fine to make D75488 possible. Let's ship it CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75561/new/ https://reviews.llvm.org/D75561 From cfe-commits at lists.llvm.org Wed Apr 1 02:43:50 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 09:43:50 +0000 (UTC) Subject: [PATCH] D77041: [AST] Fix a crash on invalid constexpr Ctorinitializer when building RecoveryExpr. In-Reply-To: References: Message-ID: <98486004ef8a1e84ffe6950b18b2cbba@localhost.localdomain> sammccall added inline comments. ================ Comment at: clang/lib/Sema/SemaDeclCXX.cpp:5005 + if (Member->getInit() && Member->getInit()->containsErrors()) + Constructor->setInvalidDecl(); if (Member->isBaseInitializer()) ---------------- hokein wrote: > rsmith wrote: > > rsmith wrote: > > > This is inappropriate. The "invalid" bit on a declaration indicates whether the declaration is invalid, not whether the definition is invalid. > > > > > > What we should do is add a "contains errors" bit to `Stmt`, and mark the function body as containing errors if it has an initializer that contains an error. > > As an example of why this distinction matters: the "contains errors" bit indicates whether external users of the declaration should ignore it / suppress errors on it, or whether they can still treat it as a regular declaration. It's not ideal for an error in the body of a function to affect the diagnostic behavior of a caller to that function, since the body is (typically) irrelevant to the validity of that caller. > Thanks for the suggestions and clarifications! The "invalid" bit of decl is subtle, I didn't infer it from the code before, thanks for the explanation. > > Setting the decl invalid seemed much safer to us, and would avoid running a lot of unexpected code paths in clang which might violate the assumptions. > > > What we should do is add a "contains errors" bit to Stmt, and mark the function body as containing errors if it has an initializer that contains an error. > > This sounds promising, but there are no free bit in Stmt at the moment :( (to add the ErrorBit to expr, we have sacrificed the `IsOMPStructuredBlock` bit, it would be easier after the ongoing FPOptions stuff finished, which will free certain bits). > > since this crash is blocking recovery-expr stuff, it is prioritized for us to fix it. Maybe a compromising plan for now is to fix it in `CheckConstexprFunctionDefinition` (just moving the inspecting `InitExpr` code there) -- the crash is from `isPotentialConstantExpr` which is only called in `CheckConstexprFunctionDefinition`, should cover all cases. I don't think the availability or otherwise of a bit in stmt is the critical factor here. Adding a bit to stmt will be a huge amount of work because (unlike expr/type) stmts don't have dependence, so there's no existing dependence propagation/handling to reuse. When a ctor has an init expr with an error, I think we ultimately need to choose between: 1. ctor is constant-evaluable. (This seems obviously wrong) 2. ctor is not-constant-evaluable. (This creates spurious "must be a constant expression" diags) 3. ctor is invalid and therefore we never ask. (This creates other spurious diags due to not finding the ctor) 4. ctor-with-errors is handled specially (we find it but don't check it for constant-evaluability). Adding a stmt bit is 4, and is certainly the best long-term direction. 2 seems like a reasonable short-term solution though. Can we modify the is-constexpr check to return false if errors are present, before asserting there's no dependent code? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77041/new/ https://reviews.llvm.org/D77041 From cfe-commits at lists.llvm.org Wed Apr 1 02:43:51 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 09:43:51 +0000 (UTC) Subject: [PATCH] D77204: [clangd] Run semaCodeComplete only with a preamble Message-ID: kadircet created this revision. kadircet added a reviewer: sammccall. Herald added subscribers: cfe-commits, usaxena95, arphaman, jkorous, MaskRay, ilya-biryukov. Herald added a project: clang. It is used by code completion and signature help. Code completion already uses a special no-compile mode for missing preambles, so this change is a no-op for that. As for signature help, it already blocks for a preamble and missing it implies clang has failed to parse the preamble and retrying it in signature help likely will fail again. And even if it doesn't, request latency will be too high to be useful as parsing preambles is expensive. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77204 Files: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/CodeComplete.cpp clang-tools-extra/clangd/CodeComplete.h clang-tools-extra/clangd/unittests/ClangdTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77204.254133.patch Type: text/x-patch Size: 5669 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 02:43:52 2020 From: cfe-commits at lists.llvm.org (Momchil Velikov via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 09:43:52 +0000 (UTC) Subject: [PATCH] D77134: [clang][AARCH64] Add __ARM_FEATURE_{PAC, BTI}_DEFAULT defines In-Reply-To: References: Message-ID: <42cde07c4e5e28a24976d7f03ef5006c@localhost.localdomain> chill accepted this revision. chill added a comment. This revision is now accepted and ready to land. LGTM, conditional on the dependent patch. Thanks! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77134/new/ https://reviews.llvm.org/D77134 From cfe-commits at lists.llvm.org Wed Apr 1 02:43:53 2020 From: cfe-commits at lists.llvm.org (Daniel Kiss via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 09:43:53 +0000 (UTC) Subject: [PATCH] D75181: [AArch64] Handle BTI/PAC in case of generated functions. In-Reply-To: References: Message-ID: danielkiss added inline comments. ================ Comment at: clang/lib/CodeGen/CGCall.cpp:1828 + if (CodeGenOpts.BranchTargetEnforcement) { + FuncAttrs.addAttribute("branch-target-enforcement", "true"); + } ---------------- chill wrote: > danielkiss wrote: > > chill wrote: > > > I would really prefer to not set values "true" or "false" for the attribute: we don't really have tri-state logic there (absent/present-true/present-false), and those values just add some not-very useful string processing. > > > > > the attribute will be "absent" for the runtime emitted function. > How about setting the attribute for LLVM created functions at the time of creation, just like Clang created functions > get their attribute at the time of creation? > Attributes are not always set in clang as I see: CodeGenModule::CreateRuntimeFunction() -> CodeGenModule::GetOrCreateLLVMFunction CreateRuntimeFunction could be fixed but, the common location for LLVM created function is the llvm::Function::Create() where the CodeGenOpts and LangOpts are no available. Adding target specific code there seems not right for me. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75181/new/ https://reviews.llvm.org/D75181 From cfe-commits at lists.llvm.org Wed Apr 1 02:43:54 2020 From: cfe-commits at lists.llvm.org (Wang Tianqing via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 09:43:54 +0000 (UTC) Subject: [PATCH] D77205: [X86] Add TSXLDTRK instructions. Message-ID: tianqing created this revision. tianqing added reviewers: craig.topper, RKSimon, LuoYuanke. Herald added subscribers: cfe-commits, hiraditya, mgorny. Herald added a project: clang. For more details about these instructions, please refer to the latest ISE document: https://software.intel.com/en-us/download/intel-architecture-instruction-set-extensions-programming-reference Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77205 Files: clang/docs/ClangCommandLineReference.rst clang/include/clang/Basic/BuiltinsX86.def clang/include/clang/Driver/Options.td clang/lib/Basic/Targets/X86.cpp clang/lib/Basic/Targets/X86.h clang/lib/Headers/CMakeLists.txt clang/lib/Headers/cpuid.h clang/lib/Headers/immintrin.h clang/lib/Headers/tsxldtrkintrin.h clang/test/CodeGen/x86-tsxldtrk-builtins.c clang/test/Driver/x86-target-features.c clang/test/Preprocessor/x86_target_features.c llvm/include/llvm/IR/IntrinsicsX86.td llvm/lib/Support/Host.cpp llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86InstrInfo.td llvm/lib/Target/X86/X86Subtarget.h llvm/test/CodeGen/X86/tsxldtrk-intrinsic.ll llvm/test/MC/Disassembler/X86/x86-16.txt llvm/test/MC/Disassembler/X86/x86-32.txt llvm/test/MC/Disassembler/X86/x86-64.txt llvm/test/MC/X86/x86-16.s llvm/test/MC/X86/x86-32-coverage.s llvm/test/MC/X86/x86-64.s -------------- next part -------------- A non-text attachment was scrubbed... Name: D77205.254134.patch Type: text/x-patch Size: 17345 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 03:18:33 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 10:18:33 +0000 (UTC) Subject: [PATCH] D77206: [clangd] Don't send semanticHighlights to clients that support semanticTokens. Message-ID: sammccall created this revision. sammccall added a reviewer: hokein. Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay, ilya-biryukov. Herald added a project: clang. This allows the standard mechanism to gracefully displace the old one. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77206 Files: clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/ClangdServer.h clang-tools-extra/clangd/Protocol.cpp clang-tools-extra/clangd/Protocol.h clang-tools-extra/clangd/test/semantic-tokens.test Index: clang-tools-extra/clangd/test/semantic-tokens.test =================================================================== --- clang-tools-extra/clangd/test/semantic-tokens.test +++ clang-tools-extra/clangd/test/semantic-tokens.test @@ -1,5 +1,10 @@ -# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s -{"jsonrpc":"2.0","id":0,"method":"initialize","params":{}} +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s -implicit-check-not=semanticHighlight +# Send capabilities for both Theia semanticHighlight & standard semanticTokens. +# clangd should not use/acknowledge the Theia protocol in this case. +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"capabilities":{"textDocument":{ + "semanticHighlightingCapabilities":{"semanticHighlighting":true}, + "semanticTokens":{"dynamicRegistration":true} +}}}} --- {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.cpp","languageId":"cpp","text":"int x = 2;"}}} --- Index: clang-tools-extra/clangd/Protocol.h =================================================================== --- clang-tools-extra/clangd/Protocol.h +++ clang-tools-extra/clangd/Protocol.h @@ -433,8 +433,13 @@ /// textDocument.codeAction.codeActionLiteralSupport. bool CodeActionStructure = false; + /// Client advertises support for the semanticTokens feature. + /// We support the textDocument/semanticTokens request in any case. + /// textDocument.semanticTokens + bool SemanticTokens = false; /// Client supports Theia semantic highlighting extension. /// https://github.com/microsoft/vscode-languageserver-node/pull/367 + /// This will be ignored if the client also supports semanticTokens. /// textDocument.semanticHighlightingCapabilities.semanticHighlighting /// FIXME: drop this support once clients support LSP 3.16 Semantic Tokens. bool TheiaSemanticHighlighting = false; Index: clang-tools-extra/clangd/Protocol.cpp =================================================================== --- clang-tools-extra/clangd/Protocol.cpp +++ clang-tools-extra/clangd/Protocol.cpp @@ -297,6 +297,8 @@ SemanticHighlighting->getBoolean("semanticHighlighting")) R.TheiaSemanticHighlighting = *SemanticHighlightingSupport; } + if (auto *SemanticHighlighting = TextDocument->getObject("semanticTokens")) + R.SemanticTokens = true; if (auto *Diagnostics = TextDocument->getObject("publishDiagnostics")) { if (auto CategorySupport = Diagnostics->getBoolean("categorySupport")) R.DiagnosticCategory = *CategorySupport; Index: clang-tools-extra/clangd/ClangdServer.h =================================================================== --- clang-tools-extra/clangd/ClangdServer.h +++ clang-tools-extra/clangd/ClangdServer.h @@ -145,7 +145,7 @@ /// fetch system include path. std::vector QueryDriverGlobs; - /// Enable semantic highlighting features. + /// Enable notification-based semantic highlighting. bool TheiaSemanticHighlighting = false; /// Returns true if the tweak should be enabled. Index: clang-tools-extra/clangd/ClangdLSPServer.cpp =================================================================== --- clang-tools-extra/clangd/ClangdLSPServer.cpp +++ clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -480,6 +480,13 @@ ClangdServerOpts.TheiaSemanticHighlighting = Params.capabilities.TheiaSemanticHighlighting; + if (Params.capabilities.TheiaSemanticHighlighting && + Params.capabilities.SemanticTokens) { + log("Client supports legacy semanticHighlights notification and standard " + "semanticTokens request, choosing the latter (no notifications)."); + ClangdServerOpts.TheiaSemanticHighlighting = false; + } + if (Params.rootUri && *Params.rootUri) ClangdServerOpts.WorkspaceRoot = std::string(Params.rootUri->file()); else if (Params.rootPath && !Params.rootPath->empty()) @@ -612,7 +619,7 @@ }}}}; if (NegotiatedOffsetEncoding) Result["offsetEncoding"] = *NegotiatedOffsetEncoding; - if (Params.capabilities.TheiaSemanticHighlighting) + if (ClangdServerOpts.TheiaSemanticHighlighting) Result.getObject("capabilities") ->insert( {"semanticHighlighting", -------------- next part -------------- A non-text attachment was scrubbed... Name: D77206.254141.patch Type: text/x-patch Size: 4277 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 03:18:37 2020 From: cfe-commits at lists.llvm.org (Sander de Smalen via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 10:18:37 +0000 (UTC) Subject: [PATCH] D76238: [SveEmitter] Implement builtins for contiguous loads/stores In-Reply-To: References: Message-ID: sdesmalen updated this revision to Diff 254144. sdesmalen added a comment. Removed the _shortform.c files, in favour of describing the overloaded forms with a macro. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76238/new/ https://reviews.llvm.org/D76238 Files: clang/include/clang/Basic/TargetBuiltins.h clang/include/clang/Basic/arm_sve.td clang/lib/CodeGen/CGBuiltin.cpp clang/lib/CodeGen/CodeGenFunction.h clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1_shortform.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sh.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1sw.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1ub.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1uh.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ld1uw.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1sh.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1sw.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1ub.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1uh.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldff1uw.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1sh.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1sw.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1ub.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1uh.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnf1uw.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_ldnt1.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1b.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1h.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_st1w.c clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_stnt1.c clang/utils/TableGen/SveEmitter.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76238.254144.patch Type: text/x-patch Size: 187638 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 03:18:38 2020 From: cfe-commits at lists.llvm.org (Sander de Smalen via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 10:18:38 +0000 (UTC) Subject: [PATCH] D76238: [SveEmitter] Implement builtins for contiguous loads/stores In-Reply-To: References: Message-ID: sdesmalen added a comment. @SjoerdMeijer are you happy with the changes I've made to the tests? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76238/new/ https://reviews.llvm.org/D76238 From cfe-commits at lists.llvm.org Wed Apr 1 03:51:03 2020 From: cfe-commits at lists.llvm.org (Sander de Smalen via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 10:51:03 +0000 (UTC) Subject: [PATCH] D76617: [SveEmitter] Fix encoding/decoding of SVETypeFlags In-Reply-To: References: Message-ID: <1d8a2bd0ac8bbc3fdb84bcb204f3180e@localhost.localdomain> sdesmalen updated this revision to Diff 254148. sdesmalen marked an inline comment as done. sdesmalen added a comment. - Made Flags `uint64_t` instead of `unsigned`. - Simplified encoding of flags in SveEmitter and moved encoding of properties into the `Flags` variable to the constructor of Intrinsic. - Added (encoding of) MergeType as well. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76617/new/ https://reviews.llvm.org/D76617 Files: clang/include/clang/Basic/TargetBuiltins.h clang/include/clang/Basic/arm_sve.td clang/utils/TableGen/SveEmitter.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76617.254148.patch Type: text/x-patch Size: 16418 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 03:51:09 2020 From: cfe-commits at lists.llvm.org (Sjoerd Meijer via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 10:51:09 +0000 (UTC) Subject: [PATCH] D76238: [SveEmitter] Implement builtins for contiguous loads/stores In-Reply-To: References: Message-ID: <32fa81f8bbeb01f1b3516825417df32a@localhost.localdomain> SjoerdMeijer added a comment. Thanks for the ping, hadn't noticed the updates. I may have also missed why you need the SVE_ACLE_FUNC macro. Can you quickly comment why you need that? Just asking because in my opinion it doesn't really make it more pleasant to read (so it's there for another reason). On one of the other tickets (may have missed a notification there too) I asked why you need option `-fallow-half-arguments-and-returns`. Do you really need that, and why? And last question is if you really need to pass these defines `-D__ARM_FEATURE_SVE`? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76238/new/ https://reviews.llvm.org/D76238 From cfe-commits at lists.llvm.org Wed Apr 1 04:03:45 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via cfe-commits) Date: Wed, 01 Apr 2020 04:03:45 -0700 (PDT) Subject: [clang-tools-extra] 43aa04e - [clangd] Run semaCodeComplete only with a preamble Message-ID: <5e847511.1c69fb81.12b73.51ee@mx.google.com> Author: Kadir Cetinkaya Date: 2020-04-01T13:02:47+02:00 New Revision: 43aa04eb7a617ee75dfcbbe2d395b8208e66c0e0 URL: https://github.com/llvm/llvm-project/commit/43aa04eb7a617ee75dfcbbe2d395b8208e66c0e0 DIFF: https://github.com/llvm/llvm-project/commit/43aa04eb7a617ee75dfcbbe2d395b8208e66c0e0.diff LOG: [clangd] Run semaCodeComplete only with a preamble Summary: It is used by code completion and signature help. Code completion already uses a special no-compile mode for missing preambles, so this change is a no-op for that. As for signature help, it already blocks for a preamble and missing it implies clang has failed to parse the preamble and retrying it in signature help likely will fail again. And even if it doesn't, request latency will be too high to be useful as parsing preambles is expensive. Reviewers: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77204 Added: Modified: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/CodeComplete.cpp clang-tools-extra/clangd/CodeComplete.h clang-tools-extra/clangd/unittests/ClangdTests.cpp clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index 0882784f7031..c1773258554c 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -271,9 +271,13 @@ void ClangdServer::signatureHelp(PathRef File, Position Pos, if (!IP) return CB(IP.takeError()); - auto PreambleData = IP->Preamble; - CB(clangd::signatureHelp(File, IP->Command, PreambleData, IP->Contents, Pos, - FS, Index)); + const auto *PreambleData = IP->Preamble; + if (!PreambleData) + return CB(llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to parse includes")); + + CB(clangd::signatureHelp(File, IP->Command, *PreambleData, IP->Contents, + Pos, FS, Index)); }; // Unlike code completion, we wait for an up-to-date preamble here. diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp index 86ea5f26d397..b544510ecea1 100644 --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -1022,7 +1022,7 @@ class SignatureHelpCollector final : public CodeCompleteConsumer { struct SemaCompleteInput { PathRef FileName; const tooling::CompileCommand &Command; - const PreambleData *Preamble; + const PreambleData &Preamble; llvm::StringRef Contents; size_t Offset; llvm::IntrusiveRefCntPtr VFS; @@ -1054,8 +1054,8 @@ bool semaCodeComplete(std::unique_ptr Consumer, IncludeStructure *Includes = nullptr) { trace::Span Tracer("Sema completion"); llvm::IntrusiveRefCntPtr VFS = Input.VFS; - if (Input.Preamble && Input.Preamble->StatCache) - VFS = Input.Preamble->StatCache->getConsumingFS(std::move(VFS)); + if (Input.Preamble.StatCache) + VFS = Input.Preamble.StatCache->getConsumingFS(std::move(VFS)); ParseInputs ParseInput; ParseInput.CompileCommand = Input.Command; ParseInput.FS = VFS; @@ -1099,9 +1099,7 @@ bool semaCodeComplete(std::unique_ptr Consumer, // NOTE: we must call BeginSourceFile after prepareCompilerInstance. Otherwise // the remapped buffers do not get freed. auto Clang = prepareCompilerInstance( - std::move(CI), - (Input.Preamble && !CompletingInPreamble) ? &Input.Preamble->Preamble - : nullptr, + std::move(CI), !CompletingInPreamble ? &Input.Preamble.Preamble : nullptr, std::move(ContentsBuffer), std::move(VFS), IgnoreDiags); Clang->getPreprocessorOpts().SingleFileParseMode = CompletingInPreamble; Clang->setCodeCompletionConsumer(Consumer.release()); @@ -1118,8 +1116,7 @@ bool semaCodeComplete(std::unique_ptr Consumer, // - but Sema code complete won't see them: as part of the preamble, they're // deserialized only when mentioned. // Force them to be deserialized so SemaCodeComplete sees them. - if (Input.Preamble) - loadMainFilePreambleMacros(Clang->getPreprocessor(), *Input.Preamble); + loadMainFilePreambleMacros(Clang->getPreprocessor(), Input.Preamble); if (Includes) Clang->getPreprocessor().addPPCallbacks( collectIncludeStructureCallback(Clang->getSourceManager(), Includes)); @@ -1758,12 +1755,12 @@ codeComplete(PathRef FileName, const tooling::CompileCommand &Command, return (!Preamble || Opts.RunParser == CodeCompleteOptions::NeverParse) ? std::move(Flow).runWithoutSema(Contents, *Offset, VFS) : std::move(Flow).run( - {FileName, Command, Preamble, Contents, *Offset, VFS}); + {FileName, Command, *Preamble, Contents, *Offset, VFS}); } SignatureHelp signatureHelp(PathRef FileName, const tooling::CompileCommand &Command, - const PreambleData *Preamble, + const PreambleData &Preamble, llvm::StringRef Contents, Position Pos, llvm::IntrusiveRefCntPtr VFS, const SymbolIndex *Index) { diff --git a/clang-tools-extra/clangd/CodeComplete.h b/clang-tools-extra/clangd/CodeComplete.h index df06c156049f..3adea47c89a1 100644 --- a/clang-tools-extra/clangd/CodeComplete.h +++ b/clang-tools-extra/clangd/CodeComplete.h @@ -276,7 +276,7 @@ CodeCompleteResult codeComplete(PathRef FileName, /// Get signature help at a specified \p Pos in \p FileName. SignatureHelp signatureHelp(PathRef FileName, const tooling::CompileCommand &Command, - const PreambleData *Preamble, StringRef Contents, + const PreambleData &Preamble, StringRef Contents, Position Pos, IntrusiveRefCntPtr VFS, const SymbolIndex *Index); diff --git a/clang-tools-extra/clangd/unittests/ClangdTests.cpp b/clang-tools-extra/clangd/unittests/ClangdTests.cpp index 1e5fcf3d97e1..d15eba80ae29 100644 --- a/clang-tools-extra/clangd/unittests/ClangdTests.cpp +++ b/clang-tools-extra/clangd/unittests/ClangdTests.cpp @@ -552,15 +552,13 @@ TEST_F(ClangdVFSTest, InvalidCompileCommand) { EXPECT_ERROR(runFindDocumentHighlights(Server, FooCpp, Position())); EXPECT_ERROR(runRename(Server, FooCpp, Position(), "new_name", clangd::RenameOptions())); + EXPECT_ERROR(runSignatureHelp(Server, FooCpp, Position())); // Identifier-based fallback completion. EXPECT_THAT(cantFail(runCodeComplete(Server, FooCpp, Position(), clangd::CodeCompleteOptions())) .Completions, ElementsAre(Field(&CodeCompletion::Name, "int"), Field(&CodeCompletion::Name, "main"))); - auto SigHelp = runSignatureHelp(Server, FooCpp, Position()); - ASSERT_TRUE(bool(SigHelp)) << "signatureHelp returned an error"; - EXPECT_THAT(SigHelp->signatures, IsEmpty()); } class ClangdThreadingTest : public ClangdVFSTest {}; diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp index 3cb18f6893e9..1084b1550579 100644 --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -1049,8 +1049,12 @@ SignatureHelp signatures(llvm::StringRef Text, Position Point, auto Preamble = buildPreamble(testPath(TU.Filename), *CI, /*OldPreamble=*/nullptr, Inputs, /*InMemory=*/true, /*Callback=*/nullptr); - return signatureHelp(testPath(TU.Filename), Inputs.CompileCommand, - Preamble.get(), Text, Point, Inputs.FS, Index.get()); + if (!Preamble) { + ADD_FAILURE() << "Couldn't build Preamble"; + return {}; + } + return signatureHelp(testPath(TU.Filename), Inputs.CompileCommand, *Preamble, + Text, Point, Inputs.FS, Index.get()); } SignatureHelp signatures(llvm::StringRef Text, From cfe-commits at lists.llvm.org Wed Apr 1 04:24:47 2020 From: cfe-commits at lists.llvm.org (Sander de Smalen via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 11:24:47 +0000 (UTC) Subject: [PATCH] D76679: [SveEmitter] Add more immediate operand checks. In-Reply-To: References: Message-ID: sdesmalen marked an inline comment as done. sdesmalen added a comment. (sorry, I wrote the comments earlier but forgot to click 'submit' :) ) ================ Comment at: clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_ext.c:1 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -D__ARM_FEATURE_SVE %s + ---------------- SjoerdMeijer wrote: > Just curious about the `-fallow-half-arguments-and-returns`, do you need that here? > > And if not here, why do you need it elsewhere (looks enabled on all tests)? It's not needed for this test, but we've generated most of our tests from the ACLE spec and the tests that use a scalar float16_t (== __fp16) will need this, such as the ACLE intrinsic: svfloat16_t svadd_m(svbool_t, svfloat16_t, float16_t); If you feel strongly about it, I could remove it from the other RUN lines. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76679/new/ https://reviews.llvm.org/D76679 From cfe-commits at lists.llvm.org Wed Apr 1 04:24:50 2020 From: cfe-commits at lists.llvm.org (Sander de Smalen via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 11:24:50 +0000 (UTC) Subject: [PATCH] D76678: [SveEmitter] Add range checks for immediates and predicate patterns. In-Reply-To: References: Message-ID: sdesmalen marked 3 inline comments as done. sdesmalen added inline comments. ================ Comment at: clang/include/clang/Basic/arm_sve.td:153 +} +def ImmCheckPredicatePattern : ImmCheckType<0>; // 0..31 +def ImmCheck1_16 : ImmCheckType<1>; // 1..16 ---------------- SjoerdMeijer wrote: > would it make sense to call this `ImmCheck0_31`? Sure, I can change that. ================ Comment at: clang/lib/CodeGen/CGBuiltin.cpp:7571 + else if (Builtin->LLVMIntrinsic != 0) { + llvm::Type* OverloadedTy = getSVEType(TypeFlags); + ---------------- efriedma wrote: > I'm not sure why you need a second way to convert SVE types separate from ConvertType For the intrinsics added here, that's indeed correct, but for others, the OverloadedTy is not necessarily the return type. This is determined by the type string in the arm_sve.td file. For example: ```def SVQDECH_S : SInst<"svqdech_pat[_{d}]", "ddIi", "s", MergeNone, "aarch64_sve_sqdech", ^ ``` The `default` type `d` (in this case both return value, and first parameter) is the overloaded type. For other intrinsics, such as ```def SVSHRNB : SInst<"svshrnb[_n_{d}]", "hdi", "silUsUiUl", MergeNone, "aarch64_sve_shrnb", ^ ``` The overloaded type is the first parameter, not the result type. ================ Comment at: clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_qdech.c:10 +{ + return svqdech_pat_s16(op, SV_VL8, 0); // expected-error-re {{argument value {{[0-9]+}} is outside the valid range [1, 16]}} +} ---------------- SjoerdMeijer wrote: > nit: why use a regexp for the argument value and not just its value? Mostly because for most tests, there is no ambiguity and it would be a hassle to update all the generated tests. The regular expression is also used for many similar tests in Clang for e.g. Neon or other builtins. I guess for these tests it makes sense to be more explicit which operand is out of range (given that there are two immediates). Are you happy for me to change it for these tests, but not others where there is only a single immediate (i.e. where the message cannot be ambiguous)? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76678/new/ https://reviews.llvm.org/D76678 From cfe-commits at lists.llvm.org Wed Apr 1 04:24:50 2020 From: cfe-commits at lists.llvm.org (Lucas Prates via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 11:24:50 +0000 (UTC) Subject: [PATCH] D77048: [Clang][CodeGen] Fixing mismatch between memory layout and const expressions for oversized bitfields In-Reply-To: References: Message-ID: <5ad94462c3790f23e019dd664bc8e6b5@localhost.localdomain> pratlucas updated this revision to Diff 254156. pratlucas added a comment. Removing unecessary handling of padding bits. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77048/new/ https://reviews.llvm.org/D77048 Files: clang/lib/CodeGen/CGExprConstant.cpp clang/test/CodeGenCXX/bitfield-layout.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77048.254156.patch Type: text/x-patch Size: 3511 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 04:24:50 2020 From: cfe-commits at lists.llvm.org (Lucas Prates via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 11:24:50 +0000 (UTC) Subject: [PATCH] D77048: [Clang][CodeGen] Fixing mismatch between memory layout and const expressions for oversized bitfields In-Reply-To: References: Message-ID: pratlucas marked 2 inline comments as done. pratlucas added inline comments. ================ Comment at: clang/lib/CodeGen/CGExprConstant.cpp:613 + + // Add padding bits in case of over-sized bit-field. + // "The first sizeof(T)*8 bits are used to hold the value of the bit-field, ---------------- efriedma wrote: > The existing code in ConstantAggregateBuilder::add should skip over padding. I'm not sure what you're trying to accomplish by adding more code dealing with padding here. You're right, I missed the fact that `FieldOffset`s take care of this. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77048/new/ https://reviews.llvm.org/D77048 From cfe-commits at lists.llvm.org Wed Apr 1 04:24:51 2020 From: cfe-commits at lists.llvm.org (Marcel Hlopko via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 11:24:51 +0000 (UTC) Subject: [PATCH] D77209: [Syntax] Add mapping from spelled to expanded tokens for TokenBuffer Message-ID: hlopko created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Same restrictions apply as in the other direction: macro arguments are not supported yet, only full macro expansions can be mapped. Taking over from https://reviews.llvm.org/D72581. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77209 Files: clang/include/clang/Tooling/Syntax/Tokens.h clang/lib/Tooling/Syntax/Tokens.cpp clang/unittests/Tooling/Syntax/TokensTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77209.254157.patch Type: text/x-patch Size: 11664 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 04:24:52 2020 From: cfe-commits at lists.llvm.org (Sander de Smalen via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 11:24:52 +0000 (UTC) Subject: [PATCH] D76238: [SveEmitter] Implement builtins for contiguous loads/stores In-Reply-To: References: Message-ID: <0a108692bb60806ab9b508653e71deb5@localhost.localdomain> sdesmalen added a comment. In D76238#1954585 , @SjoerdMeijer wrote: > Thanks for the ping, hadn't noticed the updates. > > I may have also missed why you need the SVE_ACLE_FUNC macro. Can you quickly comment why you need that? Just asking because in my opinion it doesn't really make it more pleasant to read (so it's there for another reason). Thanks, these are all good questions! In the previous revision of the patch there were separate test files for the short-forms (overloaded forms) of the tests. For example: svint8_t svadd[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) has the fully specific intrinsic `svadd_s8_z`, but also the overloaded form `svadd_z`. With the SVE_ACLE_FUNC(..) macro we can test both variants with a different RUN line, one where the [_s] suffix is ignored, the other where all suffixes are concatenated, depending on whether SVE_OVERLOADED_FORMS is defined. > On one of the other tickets (may have missed a notification there too) I asked why you need option `-fallow-half-arguments-and-returns`. Do you really need that, and why? I answered that on the other patch now. Sorry about that, forgot to click 'submit' earlier. > And last question is if you really need to pass these defines `-D__ARM_FEATURE_SVE`? `__ARM_FEATURE_SVE` is automatically enabled by the compiler when the compiler implements the ACLE spec and +sve is specified. Given that the compiler doesn't yet implement the spec, these tests add the feature macro explicitly. Once all builtins are upstreamed, we'll update these tests by removing the explicit `-D__ARM_FEATURE_SVE` flag. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76238/new/ https://reviews.llvm.org/D76238 From cfe-commits at lists.llvm.org Wed Apr 1 04:25:07 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 11:25:07 +0000 (UTC) Subject: [PATCH] D77204: [clangd] Run semaCodeComplete only with a preamble In-Reply-To: References: Message-ID: <1bf17080f01f3662959a78bf391ccf2e@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG43aa04eb7a61: [clangd] Run semaCodeComplete only with a preamble (authored by kadircet). Changed prior to commit: https://reviews.llvm.org/D77204?vs=254133&id=254165#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77204/new/ https://reviews.llvm.org/D77204 Files: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/CodeComplete.cpp clang-tools-extra/clangd/CodeComplete.h clang-tools-extra/clangd/unittests/ClangdTests.cpp clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77204.254165.patch Type: text/x-patch Size: 6544 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 04:58:20 2020 From: cfe-commits at lists.llvm.org (Adam Czachorowski via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 11:58:20 +0000 (UTC) Subject: [PATCH] D76432: [clangd] Add a tweak for adding "using" statement. In-Reply-To: References: Message-ID: <00edadd83e003f72f8a2341b3e3e9f2a@localhost.localdomain> adamcz added a comment. In D76432#1952798 , @sammccall wrote: > Still LG, should I land this? Yes please :) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76432/new/ https://reviews.llvm.org/D76432 From cfe-commits at lists.llvm.org Wed Apr 1 05:17:21 2020 From: cfe-commits at lists.llvm.org (Kirill Bobyrev via cfe-commits) Date: Wed, 01 Apr 2020 05:17:21 -0700 (PDT) Subject: [clang-tools-extra] db3d64e - [clangd-vscode] NFC; Improve wording in documentation and update VSCode tasks Message-ID: <5e848651.1c69fb81.54633.6cb8@mx.google.com> Author: Kirill Bobyrev Date: 2020-04-01T14:16:55+02:00 New Revision: db3d64eebbe0aad87631c6fada01b06753377a44 URL: https://github.com/llvm/llvm-project/commit/db3d64eebbe0aad87631c6fada01b06753377a44 DIFF: https://github.com/llvm/llvm-project/commit/db3d64eebbe0aad87631c6fada01b06753377a44.diff LOG: [clangd-vscode] NFC; Improve wording in documentation and update VSCode tasks Summary: VSCode tasks are updated to the latest supported versions: deprecated values are removed and replaced by their new counterparts. Reviewers: hokein Reviewed By: hokein Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D76595 Added: Modified: clang-tools-extra/clangd/clients/clangd-vscode/.vscode/launch.json clang-tools-extra/clangd/clients/clangd-vscode/.vscode/tasks.json clang-tools-extra/clangd/clients/clangd-vscode/DEVELOPING.md clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts clang-tools-extra/clangd/clients/clangd-vscode/tsconfig.json Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/clients/clangd-vscode/.vscode/launch.json b/clang-tools-extra/clangd/clients/clangd-vscode/.vscode/launch.json index cd6b87bd05c0..7d414bc00f32 100644 --- a/clang-tools-extra/clangd/clients/clangd-vscode/.vscode/launch.json +++ b/clang-tools-extra/clangd/clients/clangd-vscode/.vscode/launch.json @@ -1,4 +1,4 @@ -// A launch configuration that compiles the extension and then opens it inside a new window +// A launch configuration that compiles extension and opens it inside a new window. { "version": "0.1.0", "configurations": [ diff --git a/clang-tools-extra/clangd/clients/clangd-vscode/.vscode/tasks.json b/clang-tools-extra/clangd/clients/clangd-vscode/.vscode/tasks.json index fb7f662e14d1..65b1c9598c0e 100644 --- a/clang-tools-extra/clangd/clients/clangd-vscode/.vscode/tasks.json +++ b/clang-tools-extra/clangd/clients/clangd-vscode/.vscode/tasks.json @@ -6,25 +6,27 @@ // ${fileExtname}: the current opened file's extension // ${cwd}: the current working directory of the spawned process -// A task runner that calls a custom npm script that compiles the extension. +// Task runner calls custom npm script to compile the extension. { - "version": "0.1.0", + "version": "2.0.0", - // we want to run npm + // Run NPM. "command": "npm", - // the command is a shell script - "isShellCommand": true, + // This command is a shell script. + "type": "shell", // show the output window only if unrecognized errors occur. - "showOutput": "silent", + "presentation": { + "reveal": "silent", + }, - // we run the custom script "compile" as defined in package.json + // Run custom "compile" script as defined in package.json "args": ["run", "compile", "--loglevel", "silent"], - // The tsc compiler is started in watching mode - "isWatching": true, + // tsc compiler is kept alive and runs in the background. + "isBackground": true, - // use the standard tsc in watch mode problem matcher to find compile problems in the output. + // Find compilation problems in the output through tsc in watch mode. "problemMatcher": "$tsc-watch" -} \ No newline at end of file +} diff --git a/clang-tools-extra/clangd/clients/clangd-vscode/DEVELOPING.md b/clang-tools-extra/clangd/clients/clangd-vscode/DEVELOPING.md index e888aba3ea20..15f2b930329e 100644 --- a/clang-tools-extra/clangd/clients/clangd-vscode/DEVELOPING.md +++ b/clang-tools-extra/clangd/clients/clangd-vscode/DEVELOPING.md @@ -10,20 +10,20 @@ A guide of developing `vscode-clangd` extension. ## Steps 1. Make sure you disable the installed `vscode-clangd` extension in VS Code. -2. Make sure you have clangd in /usr/bin/clangd or edit src/extension.ts to +2. Make sure you have clangd in `/usr/bin/clangd` or edit `src/extension.ts` to point to the binary. -3. In order to start a development instance of VS code extended with this, run: +3. To start a development instance of VS code extended with this, run: ```bash $ cd /path/to/clang-tools-extra/clangd/clients/clangd-vscode/ $ npm install $ code . - # When VS Code starts, press . + # When VSCode starts, press . ``` # Contributing -Please follow the exsiting code style when contributing to the extension, we +Please follow the existing code style when contributing to the extension, we recommend to run `npm run format` before sending a patch. # Publish to VS Code Marketplace @@ -38,15 +38,15 @@ to the marketplace. * Bump the version in `package.json`, and commit the change to upstream The extension is published under `llvm-vs-code-extensions` account, which is -currently maintained by clangd developers. If you want to make a new release, -please contact clangd-dev at lists.llvm.org. +maintained by clangd developers. If you want to make a new release, please +contact clangd-dev at lists.llvm.org. ## Steps ```bash $ cd /path/to/clang-tools-extra/clangd/clients/clangd-vscode/ - # For the first time, you need to login in the account. vsce will ask you for - the Personal Access Token, and remember it for future commands. + # For the first time, you need to login into the account. vsce will ask you + for the Personal Access Token and will remember it for future commands. $ vsce login llvm-vs-code-extensions # Publish the extension to the VSCode marketplace. $ npm run publish diff --git a/clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts b/clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts index 4749cd1bb582..a7570b63e552 100644 --- a/clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts +++ b/clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts @@ -3,7 +3,7 @@ import * as vscodelc from 'vscode-languageclient'; import * as semanticHighlighting from './semantic-highlighting'; /** - * Method to get workspace configuration option + * Get an option from workspace configuration. * @param option name of the option (e.g. for clangd.path should be path) * @param defaultValue default value to return if option is not set */ @@ -75,8 +75,8 @@ class EnableEditsNearCursorFeature implements vscodelc.StaticFeature { } /** - * this method is called when your extension is activate - * your extension is activated the very first time the command is executed + * This method is called when the extension is activated. The extension is + * activated the very first time a command is executed. */ export function activate(context: vscode.ExtensionContext) { const syncFileEvents = getConfig('syncFileEvents', true); @@ -97,7 +97,7 @@ export function activate(context: vscode.ExtensionContext) { documentSelector: [ { scheme: 'file', language: 'c' }, { scheme: 'file', language: 'cpp' }, - // cuda is not supported by vscode, but our extension does. + // CUDA is not supported by vscode, but our extension does supports it. { scheme: 'file', language: 'cuda' }, { scheme: 'file', language: 'objective-c'}, { scheme: 'file', language: 'objective-cpp'} @@ -106,7 +106,7 @@ export function activate(context: vscode.ExtensionContext) { // FIXME: send sync file events when clangd provides implementations. }, initializationOptions: { clangdFileStatus: true }, - // Do not switch to output window when clangd returns output + // Do not switch to output window when clangd returns output. revealOutputChannelOn: vscodelc.RevealOutputChannelOn.Never, // We hack up the completion items a bit to prevent VSCode from re-ranking them @@ -126,7 +126,7 @@ export function activate(context: vscode.ExtensionContext) { provideCompletionItem: async (document, position, context, token, next) => { let list = await next(document, position, context, token); let items = (Array.isArray(list) ? list : list.items).map(item => { - // Gets the prefix used by vscode when doing fuzzymatch. + // Gets the prefix used by VSCode when doing fuzzymatch. let prefix = document.getText(new vscode.Range(item.range.start, position)) if (prefix) item.filterText = prefix + "_" + item.filterText; diff --git a/clang-tools-extra/clangd/clients/clangd-vscode/tsconfig.json b/clang-tools-extra/clangd/clients/clangd-vscode/tsconfig.json index 0b05f3090920..71a62c71da02 100644 --- a/clang-tools-extra/clangd/clients/clangd-vscode/tsconfig.json +++ b/clang-tools-extra/clangd/clients/clangd-vscode/tsconfig.json @@ -26,4 +26,4 @@ "node_modules", ".vscode-test" ] -} \ No newline at end of file +} From cfe-commits at lists.llvm.org Wed Apr 1 05:30:58 2020 From: cfe-commits at lists.llvm.org (Sjoerd Meijer via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 12:30:58 +0000 (UTC) Subject: [PATCH] D76679: [SveEmitter] Add more immediate operand checks. In-Reply-To: References: Message-ID: SjoerdMeijer added a comment. ================ Comment at: clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_ext.c:1 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -D__ARM_FEATURE_SVE %s + ---------------- sdesmalen wrote: > SjoerdMeijer wrote: > > Just curious about the `-fallow-half-arguments-and-returns`, do you need that here? > > > > And if not here, why do you need it elsewhere (looks enabled on all tests)? > It's not needed for this test, but we've generated most of our tests from the ACLE spec and the tests that use a scalar float16_t (== __fp16) will need this, such as the ACLE intrinsic: > > svfloat16_t svadd_m(svbool_t, svfloat16_t, float16_t); > > If you feel strongly about it, I could remove it from the other RUN lines. Well, I think this is my surprise then. Thinking out loud: we're talking SVE here, which always implies FP16. That's why I am surprised that we bother with a storage-type only type. Looking at the SVE ACLE I indeed see: float16_t equivalent to __fp16 where I was probably expecting: float16_t equivalent to _Float16 and with that everything would be sorted I guess, then we also don't need the hack^W workaround that is `-fallow-half-arguments-and-returns`. But maybe there is a good reason to use/choose `__fp16` that I don't see here. Probably worth a quick question for the ARM SVE ACLE, would you mind quickly checking? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76679/new/ https://reviews.llvm.org/D76679 From cfe-commits at lists.llvm.org Wed Apr 1 05:30:58 2020 From: cfe-commits at lists.llvm.org (Arnold Schwaighofer via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 12:30:58 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift In-Reply-To: References: Message-ID: <50b7af64c51112b7c48eb995edc86e2e@localhost.localdomain> aschwaighofer updated this revision to Diff 254171. aschwaighofer added a comment. - Implement for the GNU runtimes Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77077/new/ https://reviews.llvm.org/D77077 Files: clang/include/clang/CodeGen/CodeGenABITypes.h clang/lib/CodeGen/CGObjCGNU.cpp clang/lib/CodeGen/CGObjCMac.cpp clang/lib/CodeGen/CGObjCRuntime.cpp clang/lib/CodeGen/CGObjCRuntime.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D77077.254171.patch Type: text/x-patch Size: 5815 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 05:30:58 2020 From: cfe-commits at lists.llvm.org (Arnold Schwaighofer via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 12:30:58 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift In-Reply-To: References: Message-ID: <7cab9a7d33f4e2f8eefc25f0e5460ce3@localhost.localdomain> aschwaighofer marked an inline comment as done. aschwaighofer added inline comments. ================ Comment at: clang/lib/CodeGen/CGObjCRuntime.h:217 + /// ProtocolPtrTy. + virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) = 0; + ---------------- rjmccall wrote: > aschwaighofer wrote: > > aschwaighofer wrote: > > > rjmccall wrote: > > > > Can this name more closely parallel the "external" name, like `getOrEmitProtocolObject`? > > > > > > > > Also, I think we're incrementally lowercasing new method names. > > > This is an already existing method. I just moved it higher in the class hierarchy to CGObjCRuntime from CGObjCMac so that it is callable from getOrEmitProtocolObject. > > s/getOrEmitProtocolObject/emitObjCProtocolObject > I see. Well, in that case, I won't ask you to rename it, but please do implement it for the GNU runtime as I mentioned. Done. I introduced `CGObjCGNU::GenerateProtocolRef(const ObjCProtocolDecl *PD)` because it only existed in the `CGObjCGNUstep2` subclass. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77077/new/ https://reviews.llvm.org/D77077 From cfe-commits at lists.llvm.org Wed Apr 1 05:31:04 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 12:31:04 +0000 (UTC) Subject: [PATCH] D77041: [AST] Fix a crash on invalid constexpr Ctorinitializer when building RecoveryExpr. In-Reply-To: References: Message-ID: <9613e4325eff74982467e658a8b3b897@localhost.localdomain> hokein updated this revision to Diff 254170. hokein added a comment. refine the fix based on the comment: now constexpr ctor with error initializers is still a valid decl but not constant-evaluate. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77041/new/ https://reviews.llvm.org/D77041 Files: clang/lib/AST/ExprConstant.cpp clang/lib/Sema/SemaDecl.cpp clang/test/SemaCXX/invalid-constructor-init.cpp Index: clang/test/SemaCXX/invalid-constructor-init.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/invalid-constructor-init.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -frecovery-ast -verify %s + +struct X { + int Y; + constexpr X() // expected-error {{constexpr constructor never produces}} + : Y(foo()) {} // expected-error {{use of undeclared identifier 'foo'}} +}; +// no crash on evaluating the constexpr ctor. +constexpr int Z = X().Y; // expected-error {{constexpr variable 'Z' must be initialized by a constant expression}} + +struct X2 { + int Y = foo(); // expected-error {{use of undeclared identifier 'foo'}} \ + // expected-note {{subexpression not valid in a constant expression}} + constexpr X2() {} // expected-error {{constexpr constructor never produces a constant expression}} +}; + +struct CycleDelegate { + int Y; + CycleDelegate(int) + : Y(foo()) {} // expected-error {{use of undeclared identifier 'foo'}} + // no bogus "delegation cycle" diagnostic + CycleDelegate(float) : CycleDelegate(1) {} +}; Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -45,6 +45,7 @@ #include "clang/Sema/Template.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Triple.h" +#include "llvm/Support/Casting.h" #include #include #include Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -4975,6 +4975,13 @@ return false; } + if (const auto *CtorDecl = dyn_cast_or_null(Definition)) { + for (const auto *InitExpr : CtorDecl->inits()) { + if (InitExpr->getInit() && InitExpr->getInit()->containsErrors()) + return false; + } + } + // Can we evaluate this function call? if (Definition && Definition->isConstexpr() && Body) return true; @@ -14736,6 +14743,15 @@ if (FD->isDependentContext()) return true; + // Bail out if a constexpr constructor has an initializer that contains an + // error. We deliberately don't produce a diagnostic, as we have produced a + // relevant diagnostic when parsing the error initializer. + if (const auto *Ctor = dyn_cast(FD)) { + for (const auto *InitExpr : Ctor->inits()) { + if (InitExpr->getInit() && InitExpr->getInit()->containsErrors()) + return false; + } + } Expr::EvalStatus Status; Status.Diag = &Diags; -------------- next part -------------- A non-text attachment was scrubbed... Name: D77041.254170.patch Type: text/x-patch Size: 2660 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 05:31:07 2020 From: cfe-commits at lists.llvm.org (Kirill Bobyrev via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 12:31:07 +0000 (UTC) Subject: [PATCH] D76595: [clangd-vscode] NFC; Improve wording in documentation and update VSCode tasks In-Reply-To: References: Message-ID: <4ef94155e649844824ebea0a75507e11@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGdb3d64eebbe0: [clangd-vscode] NFC; Improve wording in documentation and update VSCode tasks (authored by kbobyrev). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76595/new/ https://reviews.llvm.org/D76595 Files: clang-tools-extra/clangd/clients/clangd-vscode/.vscode/launch.json clang-tools-extra/clangd/clients/clangd-vscode/.vscode/tasks.json clang-tools-extra/clangd/clients/clangd-vscode/DEVELOPING.md clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts clang-tools-extra/clangd/clients/clangd-vscode/tsconfig.json -------------- next part -------------- A non-text attachment was scrubbed... Name: D76595.254173.patch Type: text/x-patch Size: 7153 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 06:03:02 2020 From: cfe-commits at lists.llvm.org (Tamas Petz via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 13:03:02 +0000 (UTC) Subject: [PATCH] D77131: [clang] Move branch-protection from CodeGenOptions to LangOptions In-Reply-To: References: Message-ID: <165895b8d6eb80a16169094a124af9d1@localhost.localdomain> tamas.petz updated this revision to Diff 254174. tamas.petz added a comment. Address review comments. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77131/new/ https://reviews.llvm.org/D77131 Files: clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Basic/CodeGenOptions.h clang/include/clang/Basic/LangOptions.def clang/include/clang/Basic/LangOptions.h clang/include/clang/Basic/TargetInfo.h clang/lib/AST/PrintfFormatString.cpp clang/lib/Basic/Targets/AArch64.cpp clang/lib/CodeGen/CGDeclCXX.cpp clang/lib/CodeGen/TargetInfo.cpp clang/lib/Frontend/CompilerInvocation.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77131.254174.patch Type: text/x-patch Size: 12830 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 06:03:05 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Bal=C3=A1zs_K=C3=A9ri_via_Phabricator?= via cfe-commits) Date: Wed, 01 Apr 2020 13:03:05 +0000 (UTC) Subject: [PATCH] D77148: [analyzer] ApiModeling: Add buffer size arg constraint with multiplier involved In-Reply-To: References: Message-ID: <2c5fbee4247562181538daaca90c7ae1@localhost.localdomain> balazske added inline comments. ================ Comment at: clang/test/Analysis/std-c-library-functions-arg-constraints.c:155 + __buf_size_arg_constraint_mul(buf, s, sizeof(short)); + clang_analyzer_eval(s * sizeof(short) <= 6); // \ + // report-warning{{TRUE}} \ ---------------- `s <= 3` is better here? We know that the buffer has space for 3 short's. But it is better to assume nothing about `sizeof(short)`. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77148/new/ https://reviews.llvm.org/D77148 From cfe-commits at lists.llvm.org Wed Apr 1 06:10:07 2020 From: cfe-commits at lists.llvm.org (Simon Pilgrim via cfe-commits) Date: Wed, 01 Apr 2020 06:10:07 -0700 (PDT) Subject: [clang-tools-extra] 43eca88 - Fix "control reaches end of non-void function" warning. NFCI. Message-ID: <5e8492af.1c69fb81.32c17.78ff@mx.google.com> Author: Simon Pilgrim Date: 2020-04-01T14:08:48+01:00 New Revision: 43eca880c6eda10fd191c4e9e04bf04830c9c6f2 URL: https://github.com/llvm/llvm-project/commit/43eca880c6eda10fd191c4e9e04bf04830c9c6f2 DIFF: https://github.com/llvm/llvm-project/commit/43eca880c6eda10fd191c4e9e04bf04830c9c6f2.diff LOG: Fix "control reaches end of non-void function" warning. NFCI. Added: Modified: clang-tools-extra/clangd/SemanticHighlighting.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp index 77b2cbce40d9..59af922d4005 100644 --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -520,6 +520,7 @@ llvm::StringRef toSemanticTokenType(HighlightingKind Kind) { case HighlightingKind::InactiveCode: return "comment"; } + llvm_unreachable("unhandled HighlightingKind"); } std::vector From cfe-commits at lists.llvm.org Wed Apr 1 07:41:02 2020 From: cfe-commits at lists.llvm.org (Sander de Smalen via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 14:41:02 +0000 (UTC) Subject: [PATCH] D76679: [SveEmitter] Add more immediate operand checks. In-Reply-To: References: Message-ID: <66827b2c2ac9b8012651886dcb9d2967@localhost.localdomain> sdesmalen marked an inline comment as done. sdesmalen added a subscriber: rsandifo-arm. sdesmalen added inline comments. ================ Comment at: clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_ext.c:1 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -D__ARM_FEATURE_SVE %s + ---------------- SjoerdMeijer wrote: > sdesmalen wrote: > > SjoerdMeijer wrote: > > > Just curious about the `-fallow-half-arguments-and-returns`, do you need that here? > > > > > > And if not here, why do you need it elsewhere (looks enabled on all tests)? > > It's not needed for this test, but we've generated most of our tests from the ACLE spec and the tests that use a scalar float16_t (== __fp16) will need this, such as the ACLE intrinsic: > > > > svfloat16_t svadd_m(svbool_t, svfloat16_t, float16_t); > > > > If you feel strongly about it, I could remove it from the other RUN lines. > Well, I think this is my surprise then. Thinking out loud: we're talking SVE here, which always implies FP16. That's why I am surprised that we bother with a storage-type only type. Looking at the SVE ACLE I indeed see: > > float16_t equivalent to __fp16 > > where I was probably expecting: > > float16_t equivalent to _Float16 > > and with that everything would be sorted I guess, then we also don't need the hack^W workaround that is `-fallow-half-arguments-and-returns`. But maybe there is a good reason to use/choose `__fp16` that I don't see here. Probably worth a quick question for the ARM SVE ACLE, would you mind quickly checking? > > As just checked with @rsandifo-arm, the reason is that the definition of `float16_t` has to be compatible with `arm_neon.h`, which uses `__fp16` for both Clang and GCC. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76679/new/ https://reviews.llvm.org/D76679 From cfe-commits at lists.llvm.org Wed Apr 1 07:41:05 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 14:41:05 +0000 (UTC) Subject: [PATCH] D77148: [analyzer] ApiModeling: Add buffer size arg constraint with multiplier involved In-Reply-To: References: Message-ID: <81f4a8eaa6630803351444a387169d99@localhost.localdomain> martong marked 2 inline comments as done. martong added inline comments. ================ Comment at: clang/test/Analysis/std-c-library-functions-arg-constraints.c:155 + __buf_size_arg_constraint_mul(buf, s, sizeof(short)); + clang_analyzer_eval(s * sizeof(short) <= 6); // \ + // report-warning{{TRUE}} \ ---------------- balazske wrote: > `s <= 3` is better here? We know that the buffer has space for 3 short's. But it is better to assume nothing about `sizeof(short)`. That would have been better if the range based constraint solver was able to solve the in-equation to `s`. So, even though the analyzer knows that `s * 2 <= 6` it cannot reason about `s` itself. This is the limitation of the solver. I believe @baloghadamsoftware has a few patches that directs this deficiency: D49074 and D50256 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77148/new/ https://reviews.llvm.org/D77148 From cfe-commits at lists.llvm.org Wed Apr 1 07:41:06 2020 From: cfe-commits at lists.llvm.org (Marcel Hlopko via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 14:41:06 +0000 (UTC) Subject: [PATCH] D77209: [Syntax] Add mapping from spelled to expanded tokens for TokenBuffer In-Reply-To: References: Message-ID: <6b91e94fcfce4fd1203e3c7fb7786428@localhost.localdomain> hlopko updated this revision to Diff 254188. hlopko added a comment. Adding comments. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77209/new/ https://reviews.llvm.org/D77209 Files: clang/include/clang/Tooling/Syntax/Tokens.h clang/lib/Tooling/Syntax/Tokens.cpp clang/unittests/Tooling/Syntax/TokensTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77209.254188.patch Type: text/x-patch Size: 13164 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 07:41:07 2020 From: cfe-commits at lists.llvm.org (Marcel Hlopko via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 14:41:07 +0000 (UTC) Subject: [PATCH] D72581: [Syntax] Add mapping from spelled to expanded tokens for TokenBuffer In-Reply-To: References: Message-ID: <8f7813f8a11677134ab182ca4ac2b962@localhost.localdomain> hlopko marked 5 inline comments as done. hlopko added a comment. I'm submitting this patch at https://reviews.llvm.org/D77209 (with Ilya's permission). Let's continue the review there. ================ Comment at: clang/include/clang/Tooling/Syntax/Tokens.h:228 + /// multiple times and this function will return multiple results in those + /// cases. This happens when \p Spelled is inside a macro argument. + /// ---------------- sammccall wrote: > Nit: move the FIXME up here? Documenting this justifies the signature, but currently it *never* happens. Done. ================ Comment at: clang/include/clang/Tooling/Syntax/Tokens.h:248 + llvm::SmallVector, 1> + expandedForSpelled(llvm::ArrayRef Spelled) const; + ---------------- sammccall wrote: > out of curiosity, do you have a motivating use for this function? > > I think it's clear enough that it will be useful, completeness dictates it should be here, and use cases aren't always the best way to think about designing these libraries. But it'd help me understand some of the details better. Will ask Ilya offline. ================ Comment at: clang/lib/Tooling/Syntax/Tokens.cpp:198 +TokenBuffer::expandedForSpelled(llvm::ArrayRef Spelled) const { + assert(!Spelled.empty()); + assert(Spelled.front().location().isFileID()); ---------------- sammccall wrote: > This is a little surprising (vs returning `{}`). > > It seems plausible that you'll map file offsets -> spelled tokens -> expanded tokens, and that the middle step might "accidentally" be empty. Caller can always check, but why require them to here? Done. ================ Comment at: clang/lib/Tooling/Syntax/Tokens.cpp:205 + + auto &File = It->second; + assert(File.SpelledTokens.data() <= Spelled.data()); ---------------- sammccall wrote: > nit: mind spelling this type out? it's important, not particularly verbose, and long-lived Done. ================ Comment at: clang/lib/Tooling/Syntax/Tokens.cpp:209 + + auto *FrontMapping = mappingStartingBeforeSpelled(File, &Spelled.front()); + unsigned SpelledFrontI = &Spelled.front() - File.SpelledTokens.data(); ---------------- sammccall wrote: > This section could use some comments about how the index calculations relate to high-level concepts. > > AIUI the branches are: spelled token precedes all PP usage, spelled token is transformed by PP (subcases: macro args and other PP usage), spelled token follows PP usage. > > The next section probably only needs to comment about the purpose of the divergence (+1/End to refer to one-past the region of interest). Done. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72581/new/ https://reviews.llvm.org/D72581 From cfe-commits at lists.llvm.org Wed Apr 1 07:41:08 2020 From: cfe-commits at lists.llvm.org (Zarko Todorovski via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 14:41:08 +0000 (UTC) Subject: [PATCH] D76130: [PPC][AIX] Implement variadic function handling in LowerFormalArguments_AIX In-Reply-To: References: Message-ID: <21264148146fb935de1028e6835c92a6@localhost.localdomain> ZarkoCA updated this revision to Diff 254193. ZarkoCA added a comment. Fixed test cases that were breaking. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76130/new/ https://reviews.llvm.org/D76130 Files: llvm/lib/Target/PowerPC/PPCISelLowering.cpp llvm/test/CodeGen/PowerPC/aix32-cc-abi-vaarg.ll llvm/test/CodeGen/PowerPC/aix64-cc-abi-vaarg.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D76130.254193.patch Type: text/x-patch Size: 41721 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 07:49:16 2020 From: cfe-commits at lists.llvm.org (Puyan Lotfi via cfe-commits) Date: Wed, 01 Apr 2020 07:49:16 -0700 (PDT) Subject: [clang] e3033c0 - [llvm][clang][IFS] Enhancing the llvm-ifs yaml format for symbol lists. Message-ID: <5e84a9ec.1c69fb81.bc20d.6905@mx.google.com> Author: Puyan Lotfi Date: 2020-04-01T10:49:06-04:00 New Revision: e3033c0ce5517efddbf92a079ad1e0ca4868591f URL: https://github.com/llvm/llvm-project/commit/e3033c0ce5517efddbf92a079ad1e0ca4868591f DIFF: https://github.com/llvm/llvm-project/commit/e3033c0ce5517efddbf92a079ad1e0ca4868591f.diff LOG: [llvm][clang][IFS] Enhancing the llvm-ifs yaml format for symbol lists. Prior to this change the clang interface stubs format resembled something ending with a symbol list like this: Symbols: a: { Type: Func } This was problematic because we didn't actually want a map format and also because we didn't like that an empty symbol list required "Symbols: {}". That is to say without the empty {} llvm-ifs would crash on an empty list. With this new format it is much more clear which field is the symbol name, and instead the [] that is used to express an empty symbol vector is optional, ie: Symbols: - { Name: a, Type: Func } or Symbols: [] or Symbols: This further diverges the format from existing llvm-elftapi. This is a good thing because although the format originally came from the same place, they are not the same in any way. Differential Revision: https://reviews.llvm.org/D76979 Added: clang/test/InterfaceStubs/empty.c llvm/test/tools/llvm-ifs/empty1.ifs llvm/test/tools/llvm-ifs/empty2.ifs Modified: clang/include/clang/Frontend/FrontendActions.h clang/include/clang/Frontend/FrontendOptions.h clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp clang/test/InterfaceStubs/bad-format.cpp clang/test/InterfaceStubs/blocks.c clang/test/InterfaceStubs/class-template-partial-specialization.cpp clang/test/InterfaceStubs/conflict-type.ifs clang/test/InterfaceStubs/constructor-using-shadow.cpp clang/test/InterfaceStubs/cxx-conversion.cpp clang/test/InterfaceStubs/cxxdeduction-guide.cpp clang/test/InterfaceStubs/driver-test3.c clang/test/InterfaceStubs/func.ifs clang/test/InterfaceStubs/hidden-class-inheritance.cpp clang/test/InterfaceStubs/indirect-field-decl.cpp clang/test/InterfaceStubs/inline.c clang/test/InterfaceStubs/lambda.cpp clang/test/InterfaceStubs/namespace-alias.cpp clang/test/InterfaceStubs/namespace.cpp clang/test/InterfaceStubs/non-type-template-parm-decl.cpp clang/test/InterfaceStubs/object.c clang/test/InterfaceStubs/object.ifs clang/test/InterfaceStubs/ppc.cpp clang/test/InterfaceStubs/template-constexpr.cpp clang/test/InterfaceStubs/template-namespace-function.cpp clang/test/InterfaceStubs/template-template-parm-decl.cpp clang/test/InterfaceStubs/trycatch.cpp clang/test/InterfaceStubs/unresolved-using-typename.cpp clang/test/InterfaceStubs/usings.cpp clang/test/InterfaceStubs/var-template-specialization-decl.cpp clang/test/InterfaceStubs/weak.cpp clang/test/InterfaceStubs/windows.cpp llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-size.ifs llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-type.ifs llvm/test/tools/llvm-ifs/conflict-header-format.ifs llvm/test/tools/llvm-ifs/conflict-header-triple.ifs llvm/test/tools/llvm-ifs/conflict-header-version.ifs llvm/test/tools/llvm-ifs/conflict-size.ifs llvm/test/tools/llvm-ifs/conflict-type.ifs llvm/test/tools/llvm-ifs/conflict-weak.ifs llvm/test/tools/llvm-ifs/default-empty.ifs llvm/test/tools/llvm-ifs/func.ifs llvm/test/tools/llvm-ifs/ios-tbd.ifs llvm/test/tools/llvm-ifs/macos-tbd.ifs llvm/test/tools/llvm-ifs/object-function-size-weak-combo.ifs llvm/test/tools/llvm-ifs/object.ifs llvm/test/tools/llvm-ifs/strong.ifs llvm/test/tools/llvm-ifs/tvos-tbd.ifs llvm/test/tools/llvm-ifs/version-ok.ifs llvm/test/tools/llvm-ifs/watchos-tbd.ifs llvm/test/tools/llvm-ifs/weak-mismatch.ifs llvm/test/tools/llvm-ifs/weak.ifs llvm/tools/llvm-ifs/llvm-ifs.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Frontend/FrontendActions.h b/clang/include/clang/Frontend/FrontendActions.h index 89ac20075fa4..9ca2bfda2138 100644 --- a/clang/include/clang/Frontend/FrontendActions.h +++ b/clang/include/clang/Frontend/FrontendActions.h @@ -119,17 +119,13 @@ class GenerateModuleAction : public ASTFrontendAction { bool hasASTFileSupport() const override { return false; } }; -class GenerateInterfaceStubAction : public ASTFrontendAction { -protected: - TranslationUnitKind getTranslationUnitKind() override { return TU_Module; } - - bool hasASTFileSupport() const override { return false; } -}; - -class GenerateInterfaceIfsExpV1Action : public GenerateInterfaceStubAction { +class GenerateInterfaceStubsAction : public ASTFrontendAction { protected: std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override; + + TranslationUnitKind getTranslationUnitKind() override { return TU_Module; } + bool hasASTFileSupport() const override { return false; } }; class GenerateModuleFromModuleMapAction : public GenerateModuleAction { diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index 66fec6436a40..6069b5eea265 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -90,7 +90,7 @@ enum ActionKind { GeneratePCH, /// Generate Interface Stub Files. - GenerateInterfaceIfsExpV1, + GenerateInterfaceStubs, /// Only execute frontend initialization. InitOnly, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 161af89a67e1..4d825301be41 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4184,7 +4184,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, StringRef ArgStr = Args.hasArg(options::OPT_interface_stub_version_EQ) ? Args.getLastArgValue(options::OPT_interface_stub_version_EQ) - : "experimental-ifs-v1"; + : "experimental-ifs-v2"; CmdArgs.push_back("-emit-interface-stubs"); CmdArgs.push_back( Args.MakeArgString(Twine("-interface-stub-version=") + ArgStr.str())); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index e0567138b782..5d0be3c1f1b0 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1780,25 +1780,26 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, StringRef ArgStr = Args.hasArg(OPT_interface_stub_version_EQ) ? Args.getLastArgValue(OPT_interface_stub_version_EQ) - : "experimental-ifs-v1"; + : "experimental-ifs-v2"; if (ArgStr == "experimental-yaml-elf-v1" || + ArgStr == "experimental-ifs-v1" || ArgStr == "experimental-tapi-elf-v1") { std::string ErrorMessage = "Invalid interface stub format: " + ArgStr.str() + " is deprecated."; Diags.Report(diag::err_drv_invalid_value) << "Must specify a valid interface stub format type, ie: " - "-interface-stub-version=experimental-ifs-v1" + "-interface-stub-version=experimental-ifs-v2" << ErrorMessage; - } else if (ArgStr != "experimental-ifs-v1") { + } else if (!ArgStr.startswith("experimental-ifs-")) { std::string ErrorMessage = "Invalid interface stub format: " + ArgStr.str() + "."; Diags.Report(diag::err_drv_invalid_value) << "Must specify a valid interface stub format type, ie: " - "-interface-stub-version=experimental-ifs-v1" + "-interface-stub-version=experimental-ifs-v2" << ErrorMessage; } else { - Opts.ProgramAction = frontend::GenerateInterfaceIfsExpV1; + Opts.ProgramAction = frontend::GenerateInterfaceStubs; } break; } @@ -3367,7 +3368,7 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { case frontend::GenerateModuleInterface: case frontend::GenerateHeaderModule: case frontend::GeneratePCH: - case frontend::GenerateInterfaceIfsExpV1: + case frontend::GenerateInterfaceStubs: case frontend::ParseSyntaxOnly: case frontend::ModuleFileInfo: case frontend::VerifyPCH: diff --git a/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp b/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp index 2b7f0f8f9b66..b7c1e693413b 100644 --- a/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp +++ b/clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp @@ -290,7 +290,7 @@ class InterfaceStubFunctionsConsumer : public ASTConsumer { const ASTContext &context, StringRef Format, raw_ostream &OS) -> void { OS << "--- !" << Format << "\n"; - OS << "IfsVersion: 1.0\n"; + OS << "IfsVersion: 2.0\n"; OS << "Triple: " << T.str() << "\n"; OS << "ObjectFileFormat: " << "ELF" @@ -299,11 +299,11 @@ class InterfaceStubFunctionsConsumer : public ASTConsumer { for (const auto &E : Symbols) { const MangledSymbol &Symbol = E.second; for (auto Name : Symbol.Names) { - OS << " \"" + OS << " - { Name: \"" << (Symbol.ParentName.empty() || Instance.getLangOpts().CPlusPlus ? "" : (Symbol.ParentName + ".")) - << Name << "\" : { Type: "; + << Name << "\", Type: "; switch (Symbol.Type) { default: llvm_unreachable( @@ -330,15 +330,15 @@ class InterfaceStubFunctionsConsumer : public ASTConsumer { OS.flush(); }; - assert(Format == "experimental-ifs-v1" && "Unexpected IFS Format."); + assert(Format == "experimental-ifs-v2" && "Unexpected IFS Format."); writeIfsV1(Instance.getTarget().getTriple(), Symbols, context, Format, *OS); } }; } // namespace std::unique_ptr -GenerateInterfaceIfsExpV1Action::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +GenerateInterfaceStubsAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { return std::make_unique( - CI, InFile, "experimental-ifs-v1"); + CI, InFile, "experimental-ifs-v2"); } diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index ab7a1e32e301..7c59ae42d2a2 100644 --- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -65,8 +65,8 @@ CreateFrontendBaseAction(CompilerInstance &CI) { case GenerateHeaderModule: return std::make_unique(); case GeneratePCH: return std::make_unique(); - case GenerateInterfaceIfsExpV1: - return std::make_unique(); + case GenerateInterfaceStubs: + return std::make_unique(); case InitOnly: return std::make_unique(); case ParseSyntaxOnly: return std::make_unique(); case ModuleFileInfo: return std::make_unique(); diff --git a/clang/test/InterfaceStubs/bad-format.cpp b/clang/test/InterfaceStubs/bad-format.cpp index 4d51ac867eb2..1289067a365a 100644 --- a/clang/test/InterfaceStubs/bad-format.cpp +++ b/clang/test/InterfaceStubs/bad-format.cpp @@ -7,6 +7,9 @@ // RUN: not %clang -emit-interface-stubs -interface-stub-version=experimental-yaml-elf-v1 %s 2>&1 | \ // RUN: FileCheck -check-prefix=CHECK-YAML-DEPRECATED %s +// RUN: not %clang -emit-interface-stubs -interface-stub-version=experimental-ifs-v1 %s 2>&1 | \ +// RUN: FileCheck -check-prefix=CHECK-V1-DEPRECATED %s + // RUN: not %clang -emit-interface-stubs -interface-stub-version=bad-format %s 2>&1 | \ // RUN: FileCheck %s @@ -21,16 +24,22 @@ // CHECK: error: invalid value // CHECK: 'Invalid interface stub format: bad-format.' in 'Must specify a // CHECK: valid interface stub format type, ie: -// CHECK: -interface-stub-version=experimental-ifs-v1' +// CHECK: -interface-stub-version=experimental-ifs-v2' // CHECK-TAPI-DEPRECATED: error: invalid value // CHECK-TAPI-DEPRECATED: 'Invalid interface stub format: // CHECK-TAPI-DEPRECATED: experimental-tapi-elf-v1 is deprecated.' in 'Must // CHECK-TAPI-DEPRECATED: specify a valid interface stub format type, ie: -// CHECK-TAPI-DEPRECATED: -interface-stub-version=experimental-ifs-v1' +// CHECK-TAPI-DEPRECATED: -interface-stub-version=experimental-ifs-v2' // CHECK-YAML-DEPRECATED: error: invalid value // CHECK-YAML-DEPRECATED: 'Invalid interface stub format: // CHECK-YAML-DEPRECATED: experimental-yaml-elf-v1 is deprecated.' in 'Must // CHECK-YAML-DEPRECATED: specify a valid interface stub format type, ie: -// CHECK-YAML-DEPRECATED: -interface-stub-version=experimental-ifs-v1' +// CHECK-YAML-DEPRECATED: -interface-stub-version=experimental-ifs-v2' + +// CHECK-V1-DEPRECATED: error: invalid value +// CHECK-V1-DEPRECATED: 'Invalid interface stub format: +// CHECK-V1-DEPRECATED: experimental-ifs-v1 is deprecated.' in 'Must +// CHECK-V1-DEPRECATED: specify a valid interface stub format type, ie: +// CHECK-V1-DEPRECATED: -interface-stub-version=experimental-ifs-v2' diff --git a/clang/test/InterfaceStubs/blocks.c b/clang/test/InterfaceStubs/blocks.c index 927f2bf28869..8e2a01159aab 100644 --- a/clang/test/InterfaceStubs/blocks.c +++ b/clang/test/InterfaceStubs/blocks.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -emit-interface-stubs -fblocks -o - %s | FileCheck %s -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: diff --git a/clang/test/InterfaceStubs/class-template-partial-specialization.cpp b/clang/test/InterfaceStubs/class-template-partial-specialization.cpp index 4c0edaa2dd8f..b6580861de8b 100644 --- a/clang/test/InterfaceStubs/class-template-partial-specialization.cpp +++ b/clang/test/InterfaceStubs/class-template-partial-specialization.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: diff --git a/clang/test/InterfaceStubs/conflict-type.ifs b/clang/test/InterfaceStubs/conflict-type.ifs index aaa04775e317..cc6191900a30 100644 --- a/clang/test/InterfaceStubs/conflict-type.ifs +++ b/clang/test/InterfaceStubs/conflict-type.ifs @@ -7,10 +7,10 @@ # CHECK-IFS-NEXT: Filename: # CHECK-IFS-NEXT: Type Values: Object Func ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-linux-gnu ObjectFileFormat: ELF Symbols: - a: { Type: Object, Size: 1 } + - { Name: a, Type: Object, Size: 1 } ... diff --git a/clang/test/InterfaceStubs/constructor-using-shadow.cpp b/clang/test/InterfaceStubs/constructor-using-shadow.cpp index d4b85ac73e56..e806cc323ee7 100644 --- a/clang/test/InterfaceStubs/constructor-using-shadow.cpp +++ b/clang/test/InterfaceStubs/constructor-using-shadow.cpp @@ -1,12 +1,12 @@ // RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: // CHECK-NEXT: ... - // ConstructorUsingShadowDecl +// ConstructorUsingShadowDecl struct Base { Base(int); }; struct Derived : public Base { using Base::Base; }; diff --git a/clang/test/InterfaceStubs/cxx-conversion.cpp b/clang/test/InterfaceStubs/cxx-conversion.cpp index 96425a42b6fc..f9de07d17850 100644 --- a/clang/test/InterfaceStubs/cxx-conversion.cpp +++ b/clang/test/InterfaceStubs/cxx-conversion.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: diff --git a/clang/test/InterfaceStubs/cxxdeduction-guide.cpp b/clang/test/InterfaceStubs/cxxdeduction-guide.cpp index f09b9d929ca3..4d9f24bae5b3 100644 --- a/clang/test/InterfaceStubs/cxxdeduction-guide.cpp +++ b/clang/test/InterfaceStubs/cxxdeduction-guide.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -o - -emit-interface-stubs -std=c++17 %s | FileCheck %s -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: diff --git a/clang/test/InterfaceStubs/driver-test3.c b/clang/test/InterfaceStubs/driver-test3.c index bccd1c9bccd4..a3f3966dbe8f 100644 --- a/clang/test/InterfaceStubs/driver-test3.c +++ b/clang/test/InterfaceStubs/driver-test3.c @@ -8,12 +8,12 @@ // CHECK-OBJ: bar -// CHECK-IFS: --- !experimental-ifs-v1 +// CHECK-IFS: --- !experimental-ifs-v2 // CHECK-IFS-NEXT: IfsVersion: // CHECK-IFS-NEXT: Triple: // CHECK-IFS-NEXT: ObjectFileFormat: // CHECK-IFS-NEXT: Symbols: -// CHECK-IFS-NEXT: "bar" : { Type: Func } +// CHECK-IFS-NEXT: - { Name: "bar", Type: Func } // CHECK-IFS-NEXT: ... int bar(int a) { return a; } diff --git a/clang/test/InterfaceStubs/empty.c b/clang/test/InterfaceStubs/empty.c new file mode 100644 index 000000000000..c68c124e513e --- /dev/null +++ b/clang/test/InterfaceStubs/empty.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s + +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 +// CHECK-NEXT: Triple: +// CHECK-NEXT: ObjectFileFormat: +// CHECK-NEXT: Symbols: +// CHECK-NEXT: ... diff --git a/clang/test/InterfaceStubs/func.ifs b/clang/test/InterfaceStubs/func.ifs index d115523bfda4..9de5213de9d6 100644 --- a/clang/test/InterfaceStubs/func.ifs +++ b/clang/test/InterfaceStubs/func.ifs @@ -7,13 +7,13 @@ # RUN: %clang -emit-interface-stubs -o - %s %s -emit-merged-ifs | \ # RUN: FileCheck %s --check-prefixes=CHECK-MERGE-IFS -# CHECK-IFS: --- !experimental-ifs-v1 -# CHECK-IFS-NEXT: IfsVersion: 1.0 +# CHECK-IFS: --- !experimental-ifs-v2 +# CHECK-IFS-NEXT: IfsVersion: 2.0 # CHECK-IFS-NEXT: Triple: x86_64-linux-gnu # CHECK-IFS-NEXT: ObjectFileFormat: ELF # CHECK-IFS-NEXT: Symbols: -# CHECK-IFS-DAG: a: { Type: Func } -# CHECK-IFS-DAG: b: { Type: Object, Size: 4 } +# CHECK-IFS-DAG: - { Name: a, Type: Func } +# CHECK-IFS-DAG: - { Name: b, Type: Object, Size: 4 } # CHECK-IFS: ... # CHECK-ELF: ELF Header: @@ -23,18 +23,18 @@ # CHECK-ELF: OBJECT GLOBAL DEFAULT 1 b # Here we are testing to see if two identical symbols will merge. -# CHECK-MERGE-IFS: --- !experimental-ifs-v1 -# CHECK-MERGE-IFS-NEXT: IfsVersion: 1.0 +# CHECK-MERGE-IFS: --- !experimental-ifs-v2 +# CHECK-MERGE-IFS-NEXT: IfsVersion: 2.0 # CHECK-MERGE-IFS-NEXT: Triple: x86_64-linux-gnu # CHECK-MERGE-IFS-NEXT: ObjectFileFormat: ELF # CHECK-MERGE-IFS-NEXT: Symbols: -# CHECK-MERGE-IFS-NEXT: a: { Type: Func } +# CHECK-MERGE-IFS-NEXT: - { Name: a, Type: Func } # CHECK-MERGE-IFS-NEXT: ... ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-linux-gnu ObjectFileFormat: ELF Symbols: - a: { Type: Func } + - { Name: a, Type: Func } ... diff --git a/clang/test/InterfaceStubs/hidden-class-inheritance.cpp b/clang/test/InterfaceStubs/hidden-class-inheritance.cpp index 19ba579608ec..2219fd5b2e8a 100644 --- a/clang/test/InterfaceStubs/hidden-class-inheritance.cpp +++ b/clang/test/InterfaceStubs/hidden-class-inheritance.cpp @@ -14,7 +14,7 @@ // RUN: -DPARENT_METHOD_VISIBILITY="" -DCHILD_METHOD_VISIBILITY="" %s | \ // RUN: FileCheck -check-prefix=CHECK-HP %s // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -o - -emit-interface-stubs \ -// RUN: -interface-stub-version=experimental-ifs-v1 \ +// RUN: -interface-stub-version=experimental-ifs-v2 \ // RUN: -DPARENT_CLASS_VISIBILITY=HIDDEN -DCHILD_CLASS_VISIBILITY="" \ // RUN: -DPARENT_METHOD_VISIBILITY="" -DCHILD_METHOD_VISIBILITY="" %s | \ // RUN: FileCheck -check-prefix=CHECK-HP2 %s diff --git a/clang/test/InterfaceStubs/indirect-field-decl.cpp b/clang/test/InterfaceStubs/indirect-field-decl.cpp index d0e5fd26e4b7..2c30b0ee4005 100644 --- a/clang/test/InterfaceStubs/indirect-field-decl.cpp +++ b/clang/test/InterfaceStubs/indirect-field-decl.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: diff --git a/clang/test/InterfaceStubs/inline.c b/clang/test/InterfaceStubs/inline.c index 0b0ac83726ad..1dec4ae677d7 100644 --- a/clang/test/InterfaceStubs/inline.c +++ b/clang/test/InterfaceStubs/inline.c @@ -55,8 +55,8 @@ INLINE int foo() { // RUN: -c -std=gnu89 -xc %s | llvm-nm - 2>&1 | \ // RUN: FileCheck -check-prefix=CHECK-SYMBOLS %s -// CHECK-TAPI-DAG: foo" : { Type: Func } -// CHECK-TAPI-DAG: foo.var" : { Type: Object, Size: 4 } +// CHECK-TAPI-DAG: foo", Type: Func } +// CHECK-TAPI-DAG: foo.var", Type: Object, Size: 4 } // CHECK-SYMBOLS-DAG: foo // CHECK-SYMBOLS-DAG: foo.var #include "inline.h" diff --git a/clang/test/InterfaceStubs/lambda.cpp b/clang/test/InterfaceStubs/lambda.cpp index e892f1eee11c..a167f6556b94 100644 --- a/clang/test/InterfaceStubs/lambda.cpp +++ b/clang/test/InterfaceStubs/lambda.cpp @@ -1,11 +1,11 @@ // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-interface-stubs -o - %s \ // RUN: | FileCheck %s -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: -// CHECK-NEXT: f" : { Type: Object, Size: 1 } +// CHECK-NEXT: f", Type: Object, Size: 1 } // CHECK-NEXT: ... auto f = [](void* data) { int i; }; diff --git a/clang/test/InterfaceStubs/namespace-alias.cpp b/clang/test/InterfaceStubs/namespace-alias.cpp index 6a7f27c9b7b0..a4e05f904701 100644 --- a/clang/test/InterfaceStubs/namespace-alias.cpp +++ b/clang/test/InterfaceStubs/namespace-alias.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: diff --git a/clang/test/InterfaceStubs/namespace.cpp b/clang/test/InterfaceStubs/namespace.cpp index 1c62346d22fc..ad4db24ff7de 100644 --- a/clang/test/InterfaceStubs/namespace.cpp +++ b/clang/test/InterfaceStubs/namespace.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: diff --git a/clang/test/InterfaceStubs/non-type-template-parm-decl.cpp b/clang/test/InterfaceStubs/non-type-template-parm-decl.cpp index 51176ac0ba0b..6390099dee5f 100644 --- a/clang/test/InterfaceStubs/non-type-template-parm-decl.cpp +++ b/clang/test/InterfaceStubs/non-type-template-parm-decl.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: diff --git a/clang/test/InterfaceStubs/object.c b/clang/test/InterfaceStubs/object.c index d6e28c5f884a..45e2d38ba3e9 100644 --- a/clang/test/InterfaceStubs/object.c +++ b/clang/test/InterfaceStubs/object.c @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fvisibility default -o - -emit-interface-stubs %s | FileCheck -check-prefix=CHECK-TAPI %s // RUN: %clang -fvisibility=default -c -o - %s | llvm-nm - 2>&1 | FileCheck -check-prefix=CHECK-SYMBOLS %s -// CHECK-TAPI: data" : { Type: Object, Size: 4 } +// CHECK-TAPI: data", Type: Object, Size: 4 } // CHECK-SYMBOLS: data int data = 42; diff --git a/clang/test/InterfaceStubs/object.ifs b/clang/test/InterfaceStubs/object.ifs index 7dc1134bac93..3afdf4e65eef 100644 --- a/clang/test/InterfaceStubs/object.ifs +++ b/clang/test/InterfaceStubs/object.ifs @@ -4,12 +4,12 @@ # RUN: %clang -emit-interface-stubs -o - %s | llvm-readelf --all | \ # RUN: FileCheck %s --check-prefixes=CHECK-ELF -# CHECK-IFS: --- !experimental-ifs-v1 -# CHECK-IFS-NEXT: IfsVersion: 1.0 +# CHECK-IFS: --- !experimental-ifs-v2 +# CHECK-IFS-NEXT: IfsVersion: 2.0 # CHECK-IFS-NEXT: Triple: x86_64-linux-gnu # CHECK-IFS-NEXT: ObjectFileFormat: ELF # CHECK-IFS-NEXT: Symbols: -# CHECK-IFS-NEXT: b: { Type: Object, Size: 4 } +# CHECK-IFS-NEXT: - { Name: b, Type: Object, Size: 4 } # CHECK-IFS-NEXT: ... # CHECK-ELF: ELF Header: @@ -19,10 +19,10 @@ # CHECK-ELF-NOT: FUNC GLOBAL DEFAULT 1 a # CHECK-ELF: OBJECT GLOBAL DEFAULT 1 b ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-linux-gnu ObjectFileFormat: ELF Symbols: - b: { Type: Object, Size: 4 } + - { Name: b, Type: Object, Size: 4 } ... diff --git a/clang/test/InterfaceStubs/ppc.cpp b/clang/test/InterfaceStubs/ppc.cpp index 9a91697d9506..8b7a276bb054 100644 --- a/clang/test/InterfaceStubs/ppc.cpp +++ b/clang/test/InterfaceStubs/ppc.cpp @@ -4,11 +4,11 @@ // RUN: -emit-interface-stubs -emit-merged-ifs -S | \ // RUN: FileCheck -check-prefix=CHECK-IFS %s - // CHECK-IFS: --- !experimental-ifs-v1 - // CHECK-IFS: IfsVersion: 1.0 - // CHECK-IFS: Triple: powerpc64le - // CHECK-IFS: Symbols: - // CHECK-IFS: _Z8helloPPCv: { Type: Func } - // CHECK-IFS: ... +// CHECK-IFS: --- !experimental-ifs-v2 +// CHECK-IFS: IfsVersion: 2.0 +// CHECK-IFS: Triple: powerpc64le +// CHECK-IFS: Symbols: +// CHECK-IFS: - { Name: _Z8helloPPCv, Type: Func } +// CHECK-IFS: ... int helloPPC(); diff --git a/clang/test/InterfaceStubs/template-constexpr.cpp b/clang/test/InterfaceStubs/template-constexpr.cpp index c4c7afa42f1e..f59a55b2bb45 100644 --- a/clang/test/InterfaceStubs/template-constexpr.cpp +++ b/clang/test/InterfaceStubs/template-constexpr.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: diff --git a/clang/test/InterfaceStubs/template-namespace-function.cpp b/clang/test/InterfaceStubs/template-namespace-function.cpp index 47788d4a3e0a..68f017c4d5ec 100644 --- a/clang/test/InterfaceStubs/template-namespace-function.cpp +++ b/clang/test/InterfaceStubs/template-namespace-function.cpp @@ -6,10 +6,10 @@ // RUN: FileCheck -check-prefix=CHECK-SYMBOLS %s // CHECK: Symbols: -// CHECK-DAG: "_ZN3qux3barEii" : { Type: Func } -// CHECK-DAG: "_ZN3baz3addIiEET_S1_S1_" : { Type: Func } -// CHECK-DAG: "_Z4fbarff" : { Type: Func } -// CHECK-DAG: "_ZN3baz3addIfEET_S1_S1_" : { Type: Func } +// CHECK-DAG: - { Name: "_ZN3qux3barEii", Type: Func } +// CHECK-DAG: - { Name: "_ZN3baz3addIiEET_S1_S1_", Type: Func } +// CHECK-DAG: - { Name: "_Z4fbarff", Type: Func } +// CHECK-DAG: - { Name: "_ZN3baz3addIfEET_S1_S1_", Type: Func } // Same symbols just diff erent order. // CHECK-SYMBOLS-DAG: _Z4fbarff diff --git a/clang/test/InterfaceStubs/template-template-parm-decl.cpp b/clang/test/InterfaceStubs/template-template-parm-decl.cpp index 63883536a816..5451ec6178e2 100644 --- a/clang/test/InterfaceStubs/template-template-parm-decl.cpp +++ b/clang/test/InterfaceStubs/template-template-parm-decl.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: diff --git a/clang/test/InterfaceStubs/trycatch.cpp b/clang/test/InterfaceStubs/trycatch.cpp index 57076a097cb5..dac7806926a5 100644 --- a/clang/test/InterfaceStubs/trycatch.cpp +++ b/clang/test/InterfaceStubs/trycatch.cpp @@ -2,13 +2,12 @@ // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcxx-exceptions -o - -emit-interface-stubs %s | FileCheck %s - -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: x86_64-unknown-linux-gnu // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: -// CHECK-NEXT: "_Z1fv" : { Type: Func } +// CHECK-NEXT: - { Name: "_Z1fv", Type: Func } // CHECK-NEXT: ... class C5 {}; diff --git a/clang/test/InterfaceStubs/unresolved-using-typename.cpp b/clang/test/InterfaceStubs/unresolved-using-typename.cpp index e6afc781412a..d4aad84d7211 100644 --- a/clang/test/InterfaceStubs/unresolved-using-typename.cpp +++ b/clang/test/InterfaceStubs/unresolved-using-typename.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: diff --git a/clang/test/InterfaceStubs/usings.cpp b/clang/test/InterfaceStubs/usings.cpp index 735a040c91dc..2ef83207fcb3 100644 --- a/clang/test/InterfaceStubs/usings.cpp +++ b/clang/test/InterfaceStubs/usings.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -o - -emit-interface-stubs %s | FileCheck %s -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: diff --git a/clang/test/InterfaceStubs/var-template-specialization-decl.cpp b/clang/test/InterfaceStubs/var-template-specialization-decl.cpp index bbb5ae888977..9b67dac9865c 100644 --- a/clang/test/InterfaceStubs/var-template-specialization-decl.cpp +++ b/clang/test/InterfaceStubs/var-template-specialization-decl.cpp @@ -1,12 +1,12 @@ // REQUIRES: x86-registered-target // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -o - -emit-interface-stubs %s | FileCheck %s -// CHECK: --- !experimental-ifs-v1 -// CHECK-NEXT: IfsVersion: 1.0 +// CHECK: --- !experimental-ifs-v2 +// CHECK-NEXT: IfsVersion: 2.0 // CHECK-NEXT: Triple: x86_64-unknown-linux-gnu // CHECK-NEXT: ObjectFileFormat: ELF // CHECK-NEXT: Symbols: -// CHECK-NEXT: "a" : { Type: Object, Size: 4 } +// CHECK-NEXT: - { Name: "a", Type: Object, Size: 4 } // CHECK-NEXT: ... template struct S9 { diff --git a/clang/test/InterfaceStubs/weak.cpp b/clang/test/InterfaceStubs/weak.cpp index 1581ffa9d5d7..e3c0413b6511 100644 --- a/clang/test/InterfaceStubs/weak.cpp +++ b/clang/test/InterfaceStubs/weak.cpp @@ -1,14 +1,14 @@ // REQUIRES: x86-registered-target // RUN: %clang_cc1 -triple x86_64-linux-gnu -o - -emit-interface-stubs \ -// RUN: -interface-stub-version=experimental-ifs-v1 %s | \ +// RUN: -interface-stub-version=experimental-ifs-v2 %s | \ // RUN: FileCheck %s // RUN: %clang -target x86_64-unknown-linux-gnu -o - -c %s | llvm-nm - 2>&1 | \ // RUN: FileCheck -check-prefix=CHECK-SYMBOLS %s // CHECK: Symbols: -// CHECK-DAG: "_Z8weakFuncv" : { Type: Func, Weak: true } -// CHECK-DAG: "_Z10strongFuncv" : { Type: Func } +// CHECK-DAG: - { Name: "_Z8weakFuncv", Type: Func, Weak: true } +// CHECK-DAG: - { Name: "_Z10strongFuncv", Type: Func } // CHECK-SYMBOLS-DAG: _Z10strongFuncv // CHECK-SYMBOLS-DAG: _Z8weakFuncv diff --git a/clang/test/InterfaceStubs/windows.cpp b/clang/test/InterfaceStubs/windows.cpp index c81c702861e4..73f3ed5d39ac 100644 --- a/clang/test/InterfaceStubs/windows.cpp +++ b/clang/test/InterfaceStubs/windows.cpp @@ -6,11 +6,11 @@ // CHECK-CC1: Symbols: // CHECK-CC1-NEXT: ?helloWindowsMsvc@@YAHXZ - // CHECK-IFS: --- !experimental-ifs-v1 - // CHECK-IFS: IfsVersion: 1.0 - // CHECK-IFS: Triple: - // CHECK-IFS: Symbols: - // CHECK-IFS: ?helloWindowsMsvc@@YAHXZ: { Type: Func } - // CHECK-IFS: ... +// CHECK-IFS: --- !experimental-ifs-v2 +// CHECK-IFS: IfsVersion: 2.0 +// CHECK-IFS: Triple: +// CHECK-IFS: Symbols: +// CHECK-IFS: - { Name: '?helloWindowsMsvc@@YAHXZ', Type: Func } +// CHECK-IFS: ... int helloWindowsMsvc(); diff --git a/llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-size.ifs b/llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-size.ifs index 9afb08802726..30b7cda9b548 100644 --- a/llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-size.ifs +++ b/llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-size.ifs @@ -1,8 +1,8 @@ # NOTE: Used by weak-mismatch.ifs ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-unknown-linux-gnu ObjectFileFormat: ELF Symbols: - foobar: { Type: Object, Size: 2 } + - { Name: foobar, Type: Object, Size: 2 } ... diff --git a/llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-type.ifs b/llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-type.ifs index 8fc550a644cb..3f8d54c7e536 100644 --- a/llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-type.ifs +++ b/llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-type.ifs @@ -1,8 +1,8 @@ # NOTE: Used by weak-mismatch.ifs ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-unknown-linux-gnu ObjectFileFormat: ELF Symbols: - foobar: { Type: Func } + - { Name: foobar, Type: Func } ... diff --git a/llvm/test/tools/llvm-ifs/conflict-header-format.ifs b/llvm/test/tools/llvm-ifs/conflict-header-format.ifs index 40ae9c0526f2..4e26fb8080e8 100644 --- a/llvm/test/tools/llvm-ifs/conflict-header-format.ifs +++ b/llvm/test/tools/llvm-ifs/conflict-header-format.ifs @@ -5,10 +5,10 @@ # CHECK-IFS-NEXT: Filenames: # CHECK-IFS-NEXT: ObjectFileFormat Values: TBD ELF ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-apple-unknown ObjectFileFormat: TBD Symbols: - a: { Type: Func } + - { Name: a, Type: Func } ... diff --git a/llvm/test/tools/llvm-ifs/conflict-header-triple.ifs b/llvm/test/tools/llvm-ifs/conflict-header-triple.ifs index 15bddc6a15f7..9ce04b8b3f31 100644 --- a/llvm/test/tools/llvm-ifs/conflict-header-triple.ifs +++ b/llvm/test/tools/llvm-ifs/conflict-header-triple.ifs @@ -5,10 +5,10 @@ # CHECK-IFS-NEXT: Filenames: # CHECK-IFS-NEXT: Triple Values: mips-unknown-linux x86_64-unknown-linux-gnu ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: mips-unknown-linux ObjectFileFormat: ELF Symbols: - a: { Type: Func } + - { Name: a, Type: Func } ... diff --git a/llvm/test/tools/llvm-ifs/conflict-header-version.ifs b/llvm/test/tools/llvm-ifs/conflict-header-version.ifs index addf9943441b..ecdeb311f860 100644 --- a/llvm/test/tools/llvm-ifs/conflict-header-version.ifs +++ b/llvm/test/tools/llvm-ifs/conflict-header-version.ifs @@ -5,12 +5,12 @@ # RUN: FileCheck %s --check-prefixes=CHECK-IFS2 # CHECK-IFS: error: Interface Stub: IfsVersion Mismatch. -# CHECK-IFS2: error: Interface Stub: Bad IfsVersion: 0.0, llvm-ifs supported version: 1.2. +# CHECK-IFS2: error: Interface Stub: Bad IfsVersion: 0.0, llvm-ifs supported version: 2.0. ---- !experimental-ifs-v1 +--- !experimental-ifs-v2 IfsVersion: 0.0 Triple: x86_64-unknown-linux-gnu ObjectFileFormat: ELF Symbols: - a: { Type: Func } + - { Name: a, Type: Func } ... diff --git a/llvm/test/tools/llvm-ifs/conflict-size.ifs b/llvm/test/tools/llvm-ifs/conflict-size.ifs index 173ce268c741..5e0fcafd55db 100644 --- a/llvm/test/tools/llvm-ifs/conflict-size.ifs +++ b/llvm/test/tools/llvm-ifs/conflict-size.ifs @@ -7,10 +7,10 @@ # CHECK-IFS-NEXT: Filename: # CHECK-IFS-NEXT: Size Values: 1 4 ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-unknown-linux-gnu ObjectFileFormat: ELF Symbols: - b: { Type: Object, Size: 1 } + - { Name: b, Type: Object, Size: 1 } ... diff --git a/llvm/test/tools/llvm-ifs/conflict-type.ifs b/llvm/test/tools/llvm-ifs/conflict-type.ifs index c518be4e1411..1a10ea79a41c 100644 --- a/llvm/test/tools/llvm-ifs/conflict-type.ifs +++ b/llvm/test/tools/llvm-ifs/conflict-type.ifs @@ -7,10 +7,10 @@ # CHECK-IFS-NEXT: Filename: # CHECK-IFS-NEXT: Type Values: Object Func ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-unknown-linux-gnu ObjectFileFormat: ELF Symbols: - a: { Type: Object, Size: 1 } + - { Name: a, Type: Object, Size: 1 } ... diff --git a/llvm/test/tools/llvm-ifs/conflict-weak.ifs b/llvm/test/tools/llvm-ifs/conflict-weak.ifs index 823b8f1866c3..23eb73d7535f 100644 --- a/llvm/test/tools/llvm-ifs/conflict-weak.ifs +++ b/llvm/test/tools/llvm-ifs/conflict-weak.ifs @@ -2,12 +2,12 @@ # RUN: FileCheck %s --check-prefixes=CHECK-IFS # CHECK-IFS: Symbols: -# CHECK-IFS-NEXT: a: { Type: Func, Weak: true } +# CHECK-IFS-NEXT: - { Name: a, Type: Func, Weak: true } ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-unknown-linux-gnu ObjectFileFormat: ELF Symbols: - a: { Type: Func, Weak: true } + - { Name: a, Type: Func, Weak: true } ... diff --git a/llvm/test/tools/llvm-ifs/default-empty.ifs b/llvm/test/tools/llvm-ifs/default-empty.ifs index 9848f418f58c..c61f29a37976 100644 --- a/llvm/test/tools/llvm-ifs/default-empty.ifs +++ b/llvm/test/tools/llvm-ifs/default-empty.ifs @@ -1,25 +1,25 @@ # RUN: llvm-ifs -action write-ifs -o - %s | FileCheck --check-prefixes=CHECK-DEFAULT %s # RUN: llvm-ifs -action write-ifs -o - %s %S/weak.ifs | FileCheck --check-prefixes=CHECK-MERGE %s -# CHECK-DEFAULT: --- !experimental-ifs-v1 -# CHECK-DEFAULT-NEXT: IfsVersion: 1.2 +# CHECK-DEFAULT: --- !experimental-ifs-v2 +# CHECK-DEFAULT-NEXT: IfsVersion: 2.0 # CHECK-DEFAULT-NEXT: Triple: '' # CHECK-DEFAULT-NEXT: ObjectFileFormat: ELF -# CHECK-DEFAULT-NEXT: Symbols: {} +# CHECK-DEFAULT-NEXT: Symbols: [] # CHECK-DEFAULT-NEXT: ... -# CHECK-MERGE: --- !experimental-ifs-v1 -# CHECK-MERGE-NEXT: IfsVersion: 1.0 +# CHECK-MERGE: --- !experimental-ifs-v2 +# CHECK-MERGE-NEXT: IfsVersion: 2.0 # CHECK-MERGE-NEXT: Triple: x86_64-unknown-linux-gnu # CHECK-MERGE-NEXT: ObjectFileFormat: ELF # CHECK-MERGE-NEXT: Symbols: -# CHECK-MERGE-DAG: _Z8weakFuncv: { Type: Func, Weak: true } -# CHECK-MERGE-DAG: _Z10strongFuncv: { Type: Func } +# CHECK-MERGE-DAG: - { Name: _Z8weakFuncv, Type: Func, Weak: true } +# CHECK-MERGE-DAG: - { Name: _Z10strongFuncv, Type: Func } # CHECK-MERGE: ... ---- !experimental-ifs-v1 -IfsVersion: 1.2 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: '' ObjectFileFormat: ELF -Symbols: {} +Symbols: [] ... diff --git a/llvm/test/tools/llvm-ifs/empty1.ifs b/llvm/test/tools/llvm-ifs/empty1.ifs new file mode 100644 index 000000000000..d237dd7ea10a --- /dev/null +++ b/llvm/test/tools/llvm-ifs/empty1.ifs @@ -0,0 +1,15 @@ +# RUN: llvm-ifs -action write-ifs -o - %s | FileCheck %s + +# CHECK: --- !experimental-ifs-v2 +# CHECK-NEXT: IfsVersion: 2.0 +# CHECK-NEXT: Triple: x86_64-unknown-linux-gnu +# CHECK-NEXT: ObjectFileFormat: ELF +# CHECK-NEXT: Symbols: [] +# CHECK: ... + +--- !experimental-ifs-v2 +IfsVersion: 2.0 +Triple: x86_64-unknown-linux-gnu +ObjectFileFormat: ELF +Symbols: [] +... diff --git a/llvm/test/tools/llvm-ifs/empty2.ifs b/llvm/test/tools/llvm-ifs/empty2.ifs new file mode 100644 index 000000000000..a294c777bbf9 --- /dev/null +++ b/llvm/test/tools/llvm-ifs/empty2.ifs @@ -0,0 +1,15 @@ +# RUN: llvm-ifs -action write-ifs -o - %s | FileCheck %s + +# CHECK: --- !experimental-ifs-v2 +# CHECK-NEXT: IfsVersion: 2.0 +# CHECK-NEXT: Triple: x86_64-unknown-linux-gnu +# CHECK-NEXT: ObjectFileFormat: ELF +# CHECK-NEXT: Symbols: [] +# CHECK: ... + +--- !experimental-ifs-v2 +IfsVersion: 2.0 +Triple: x86_64-unknown-linux-gnu +ObjectFileFormat: ELF +Symbols: +... diff --git a/llvm/test/tools/llvm-ifs/func.ifs b/llvm/test/tools/llvm-ifs/func.ifs index 496e26241922..d6d85782b2e3 100644 --- a/llvm/test/tools/llvm-ifs/func.ifs +++ b/llvm/test/tools/llvm-ifs/func.ifs @@ -10,13 +10,13 @@ # RUN: llvm-ifs -action write-ifs -o - %s %s | \ # RUN: FileCheck %s --check-prefixes=CHECK-MERGE-IFS -# CHECK-IFS: --- !experimental-ifs-v1 -# CHECK-IFS-NEXT: IfsVersion: 1.0 +# CHECK-IFS: --- !experimental-ifs-v2 +# CHECK-IFS-NEXT: IfsVersion: 2.0 # CHECK-IFS-NEXT: Triple: x86_64-unknown-linux-gnu # CHECK-IFS-NEXT: ObjectFileFormat: ELF # CHECK-IFS-NEXT: Symbols: -# CHECK-IFS-DAG: a: { Type: Func } -# CHECK-IFS-DAG: b: { Type: Object, Size: 4 } +# CHECK-IFS-DAG: - { Name: a, Type: Func } +# CHECK-IFS-DAG: - { Name: b, Type: Object, Size: 4 } # CHECK-IFS: ... # CHECK-ELF: ELF Header: @@ -39,18 +39,18 @@ # CHECK-DARWIN-TBD3-NEXT: ... # Here we are testing to see if two identical symbols will merge. -# CHECK-MERGE-IFS: --- !experimental-ifs-v1 -# CHECK-MERGE-IFS-NEXT: IfsVersion: 1.0 +# CHECK-MERGE-IFS: --- !experimental-ifs-v2 +# CHECK-MERGE-IFS-NEXT: IfsVersion: 2.0 # CHECK-MERGE-IFS-NEXT: Triple: x86_64-unknown-linux-gnu # CHECK-MERGE-IFS-NEXT: ObjectFileFormat: ELF # CHECK-MERGE-IFS-NEXT: Symbols: -# CHECK-MERGE-IFS-NEXT: a: { Type: Func } +# CHECK-MERGE-IFS-NEXT: - { Name: a, Type: Func } # CHECK-MERGE-IFS-NEXT: ... ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-unknown-linux-gnu ObjectFileFormat: ELF Symbols: - a: { Type: Func } + - { Name: a, Type: Func } ... diff --git a/llvm/test/tools/llvm-ifs/ios-tbd.ifs b/llvm/test/tools/llvm-ifs/ios-tbd.ifs index 13671b02c5cb..5b21aedf6500 100644 --- a/llvm/test/tools/llvm-ifs/ios-tbd.ifs +++ b/llvm/test/tools/llvm-ifs/ios-tbd.ifs @@ -13,10 +13,10 @@ # CHECK-NEXT: symbols: [ __Z3fooi ] # CHECK-NEXT: ... ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: arm64-apple-ios ObjectFileFormat: TBD Symbols: - __Z3fooi: { Type: Func } + - { Name: __Z3fooi, Type: Func } ... diff --git a/llvm/test/tools/llvm-ifs/macos-tbd.ifs b/llvm/test/tools/llvm-ifs/macos-tbd.ifs index bd84806fb219..b04828b2a39d 100644 --- a/llvm/test/tools/llvm-ifs/macos-tbd.ifs +++ b/llvm/test/tools/llvm-ifs/macos-tbd.ifs @@ -13,10 +13,10 @@ # CHECK-NEXT: symbols: [ __Z3fooi ] # CHECK-NEXT: ... ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: arm64-apple-macosx ObjectFileFormat: TBD Symbols: - __Z3fooi: { Type: Func } + - { Name: __Z3fooi, Type: Func } ... diff --git a/llvm/test/tools/llvm-ifs/object-function-size-weak-combo.ifs b/llvm/test/tools/llvm-ifs/object-function-size-weak-combo.ifs index b6328fbc58d9..769f423f328a 100644 --- a/llvm/test/tools/llvm-ifs/object-function-size-weak-combo.ifs +++ b/llvm/test/tools/llvm-ifs/object-function-size-weak-combo.ifs @@ -4,17 +4,17 @@ # RUN: llvm-ifs -action write-bin -o - %s %S/func.ifs %S/object.ifs %S/weak.ifs | \ # RUN: llvm-readelf --all | FileCheck %s --check-prefixes=CHECK-ELF -# CHECK-IFS: --- !experimental-ifs-v1 -# CHECK-IFS-NEXT: IfsVersion: 1.0 +# CHECK-IFS: --- !experimental-ifs-v2 +# CHECK-IFS-NEXT: IfsVersion: 2.0 # CHECK-IFS-NEXT: Triple: x86_64-unknown-linux-gnu # CHECK-IFS-NEXT: ObjectFileFormat: ELF # CHECK-IFS-NEXT: Symbols: -# CHECK-IFS-DAG: e: { Type: Object, Size: 8 } -# CHECK-IFS-DAG: a: { Type: Func } -# CHECK-IFS-DAG: f: { Type: Object, Size: 2 } -# CHECK-IFS-DAG: _Z10strongFuncv: { Type: Func } -# CHECK-IFS-DAG: _Z8weakFuncv: { Type: Func, Weak: true } -# CHECK-IFS-DAG: b: { Type: Object, Size: 4 } +# CHECK-IFS-DAG: - { Name: e, Type: Object, Size: 8 } +# CHECK-IFS-DAG: - { Name: a, Type: Func } +# CHECK-IFS-DAG: - { Name: f, Type: Object, Size: 2 } +# CHECK-IFS-DAG: - { Name: _Z10strongFuncv, Type: Func } +# CHECK-IFS-DAG: - { Name: _Z8weakFuncv, Type: Func, Weak: true } +# CHECK-IFS-DAG: - { Name: b, Type: Object, Size: 4 } # CHECK-IFS: ... # CHECK-ELF: FUNC GLOBAL DEFAULT 1 _Z10strongFuncv @@ -24,11 +24,11 @@ # CHECK-ELF: OBJECT GLOBAL DEFAULT 1 e # CHECK-ELF: OBJECT GLOBAL DEFAULT 1 f ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-unknown-linux-gnu ObjectFileFormat: ELF Symbols: - e: { Type: Object, Size: 8 } - f: { Type: Object, Size: 2 } + - { Name: e, Type: Object, Size: 8 } + - { Name: f, Type: Object, Size: 2 } ... diff --git a/llvm/test/tools/llvm-ifs/object.ifs b/llvm/test/tools/llvm-ifs/object.ifs index 733cc38001d3..c4823c20fce2 100644 --- a/llvm/test/tools/llvm-ifs/object.ifs +++ b/llvm/test/tools/llvm-ifs/object.ifs @@ -4,12 +4,12 @@ # RUN: llvm-ifs -action write-bin -o - %s | \ # RUN: llvm-readelf --all | FileCheck %s --check-prefixes=CHECK-ELF -# CHECK-IFS: --- !experimental-ifs-v1 -# CHECK-IFS-NEXT: IfsVersion: 1.0 +# CHECK-IFS: --- !experimental-ifs-v2 +# CHECK-IFS-NEXT: IfsVersion: 2.0 # CHECK-IFS-NEXT: Triple: x86_64-unknown-linux-gnu # CHECK-IFS-NEXT: ObjectFileFormat: ELF # CHECK-IFS-NEXT: Symbols: -# CHECK-IFS-NEXT: b: { Type: Object, Size: 4 } +# CHECK-IFS-NEXT: - { Name: b, Type: Object, Size: 4 } # CHECK-IFS-NEXT: ... # CHECK-ELF: ELF Header: @@ -19,10 +19,10 @@ # CHECK-ELF-NOT: FUNC GLOBAL DEFAULT 1 a # CHECK-ELF: OBJECT GLOBAL DEFAULT 1 b ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-unknown-linux-gnu ObjectFileFormat: ELF Symbols: - b: { Type: Object, Size: 4 } + - { Name: b, Type: Object, Size: 4 } ... diff --git a/llvm/test/tools/llvm-ifs/strong.ifs b/llvm/test/tools/llvm-ifs/strong.ifs index bdc930fbaaa3..ccc1f9e5d8b6 100644 --- a/llvm/test/tools/llvm-ifs/strong.ifs +++ b/llvm/test/tools/llvm-ifs/strong.ifs @@ -1,17 +1,17 @@ # RUN: llvm-ifs -action write-ifs -o - %s %S/strong.ifs | FileCheck %s --check-prefixes=CHECK-IFS -# CHECK-IFS: --- !experimental-ifs-v1 -# CHECK-IFS-NEXT: IfsVersion: 1.0 +# CHECK-IFS: --- !experimental-ifs-v2 +# CHECK-IFS-NEXT: IfsVersion: 2.0 # CHECK-IFS-NEXT: Triple: x86_64-unknown-linux-gnu # CHECK-IFS-NEXT: ObjectFileFormat: ELF # CHECK-IFS-NEXT: Symbols: -# CHECK-IFS-DAG: _Z8weakFuncv: { Type: Func } +# CHECK-IFS-DAG: - { Name: _Z8weakFuncv, Type: Func } # CHECK-IFS: ... ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-unknown-linux-gnu ObjectFileFormat: ELF Symbols: - _Z8weakFuncv: { Type: Func } + - { Name: _Z8weakFuncv, Type: Func } ... diff --git a/llvm/test/tools/llvm-ifs/tvos-tbd.ifs b/llvm/test/tools/llvm-ifs/tvos-tbd.ifs index 08c8478c1daf..6db01bf6162f 100644 --- a/llvm/test/tools/llvm-ifs/tvos-tbd.ifs +++ b/llvm/test/tools/llvm-ifs/tvos-tbd.ifs @@ -13,10 +13,10 @@ # CHECK-NEXT: symbols: [ __Z3fooi ] # CHECK-NEXT: ... ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: arm64-apple-tvos ObjectFileFormat: TBD Symbols: - __Z3fooi: { Type: Func } + - { Name: __Z3fooi, Type: Func } ... diff --git a/llvm/test/tools/llvm-ifs/version-ok.ifs b/llvm/test/tools/llvm-ifs/version-ok.ifs index fd150ee77d55..646b8624feb1 100644 --- a/llvm/test/tools/llvm-ifs/version-ok.ifs +++ b/llvm/test/tools/llvm-ifs/version-ok.ifs @@ -1,9 +1,9 @@ # RUN: llvm-ifs -action write-ifs -o - %s %S/object.ifs ---- !experimental-ifs-v1 -IfsVersion: 1.1 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-unknown-linux-gnu ObjectFileFormat: ELF Symbols: - a: { Type: Func } + - { Name: a, Type: Func } ... diff --git a/llvm/test/tools/llvm-ifs/watchos-tbd.ifs b/llvm/test/tools/llvm-ifs/watchos-tbd.ifs index 74a9d962a3e0..fcb914265202 100644 --- a/llvm/test/tools/llvm-ifs/watchos-tbd.ifs +++ b/llvm/test/tools/llvm-ifs/watchos-tbd.ifs @@ -13,10 +13,10 @@ # CHECK-NEXT: symbols: [ __Z3fooi ] # CHECK-NEXT: ... ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: arm64-apple-watchos ObjectFileFormat: TBD Symbols: - __Z3fooi: { Type: Func } + - { Name: __Z3fooi, Type: Func } ... diff --git a/llvm/test/tools/llvm-ifs/weak-mismatch.ifs b/llvm/test/tools/llvm-ifs/weak-mismatch.ifs index 15abc2064cc2..cf45dff8c062 100644 --- a/llvm/test/tools/llvm-ifs/weak-mismatch.ifs +++ b/llvm/test/tools/llvm-ifs/weak-mismatch.ifs @@ -10,10 +10,10 @@ # CHECK-TYPE-NEXT: Filename: # CHECK-TYPE-NEXT: Type Values: Object Func ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-unknown-linux-gnu ObjectFileFormat: ELF Symbols: - foobar: { Type: Object, Size: 1, Weak: true } + - { Name: foobar, Type: Object, Size: 1, Weak: true } ... diff --git a/llvm/test/tools/llvm-ifs/weak.ifs b/llvm/test/tools/llvm-ifs/weak.ifs index a7441be1c1f2..bf8091050530 100644 --- a/llvm/test/tools/llvm-ifs/weak.ifs +++ b/llvm/test/tools/llvm-ifs/weak.ifs @@ -1,19 +1,19 @@ # RUN: llvm-ifs -action write-ifs -o - %s | FileCheck %s --check-prefixes=CHECK-IFS -# CHECK-IFS: --- !experimental-ifs-v1 -# CHECK-IFS-NEXT: IfsVersion: 1.0 +# CHECK-IFS: --- !experimental-ifs-v2 +# CHECK-IFS-NEXT: IfsVersion: 2.0 # CHECK-IFS-NEXT: Triple: x86_64-unknown-linux-gnu # CHECK-IFS-NEXT: ObjectFileFormat: ELF # CHECK-IFS-NEXT: Symbols: -# CHECK-IFS-DAG: _Z8weakFuncv: { Type: Func, Weak: true } -# CHECK-IFS-DAG: _Z10strongFuncv: { Type: Func } +# CHECK-IFS-DAG: - { Name: _Z8weakFuncv, Type: Func, Weak: true } +# CHECK-IFS-DAG: - { Name: _Z10strongFuncv, Type: Func } # CHECK-IFS: ... ---- !experimental-ifs-v1 -IfsVersion: 1.0 +--- !experimental-ifs-v2 +IfsVersion: 2.0 Triple: x86_64-unknown-linux-gnu ObjectFileFormat: ELF Symbols: - _Z8weakFuncv: { Type: Func, Weak: true } - _Z10strongFuncv: { Type: Func } + - { Name: _Z8weakFuncv, Type: Func, Weak: true } + - { Name: _Z10strongFuncv, Type: Func } ... diff --git a/llvm/tools/llvm-ifs/llvm-ifs.cpp b/llvm/tools/llvm-ifs/llvm-ifs.cpp index 3b0d2ee725ff..0d1a7518dad3 100644 --- a/llvm/tools/llvm-ifs/llvm-ifs.cpp +++ b/llvm/tools/llvm-ifs/llvm-ifs.cpp @@ -26,6 +26,7 @@ #include "llvm/TextAPI/MachO/TextAPIWriter.h" #include #include +#include using namespace llvm; using namespace llvm::yaml; @@ -34,8 +35,8 @@ using namespace llvm::MachO; #define DEBUG_TYPE "llvm-ifs" namespace { -const VersionTuple IFSVersionCurrent(1, 2); -} +const VersionTuple IFSVersionCurrent(2, 0); +} // end anonymous namespace static cl::opt Action("action", cl::desc(""), cl::value_desc("write-ifs | write-bin"), @@ -76,6 +77,7 @@ std::string getTypeName(IFSSymbolType Type) { } struct IFSSymbol { + IFSSymbol() = default; IFSSymbol(std::string SymbolName) : Name(SymbolName) {} std::string Name; uint64_t Size; @@ -85,6 +87,8 @@ struct IFSSymbol { bool operator<(const IFSSymbol &RHS) const { return Name < RHS.Name; } }; +LLVM_YAML_IS_SEQUENCE_VECTOR(IFSSymbol) + namespace llvm { namespace yaml { /// YAML traits for IFSSymbolType. @@ -124,6 +128,7 @@ template <> struct ScalarTraits { /// YAML traits for IFSSymbol. template <> struct MappingTraits { static void mapping(IO &IO, IFSSymbol &Symbol) { + IO.mapRequired("Name", Symbol.Name); IO.mapRequired("Type", Symbol.Type); // The need for symbol size depends on the symbol type. if (Symbol.Type == IFSSymbolType::NoType) @@ -140,20 +145,6 @@ template <> struct MappingTraits { static const bool flow = true; }; -/// YAML traits for set of IFSSymbols. -template <> struct CustomMappingTraits> { - static void inputOne(IO &IO, StringRef Key, std::set &Set) { - std::string Name = Key.str(); - IFSSymbol Sym(Name); - IO.mapRequired(Name.c_str(), Sym); - Set.insert(Sym); - } - - static void output(IO &IO, std::set &Set) { - for (auto &Sym : Set) - IO.mapRequired(Sym.Name.c_str(), const_cast(Sym)); - } -}; } // namespace yaml } // namespace llvm @@ -167,7 +158,7 @@ class IFSStub { std::string ObjectFileFormat; Optional SOName; std::vector NeededLibs; - std::set Symbols; + std::vector Symbols; IFSStub() = default; IFSStub(const IFSStub &Stub) @@ -186,14 +177,18 @@ namespace yaml { /// YAML traits for IFSStub objects. template <> struct MappingTraits { static void mapping(IO &IO, IFSStub &Stub) { - if (!IO.mapTag("!experimental-ifs-v1", true)) + if (!IO.mapTag("!experimental-ifs-v2", true)) IO.setError("Not a .ifs YAML file."); + + auto OldContext = IO.getContext(); + IO.setContext(&Stub); IO.mapRequired("IfsVersion", Stub.IfsVersion); IO.mapOptional("Triple", Stub.Triple); IO.mapOptional("ObjectFileFormat", Stub.ObjectFileFormat); IO.mapOptional("SOName", Stub.SOName); IO.mapOptional("NeededLibs", Stub.NeededLibs); IO.mapRequired("Symbols", Stub.Symbols); + IO.setContext(&OldContext); } }; } // namespace yaml @@ -218,7 +213,7 @@ static Expected> readInputFile(StringRef FilePath) { return std::move(Stub); } -int writeTbdStub(const llvm::Triple &T, const std::set &Symbols, +int writeTbdStub(const llvm::Triple &T, const std::vector &Symbols, const StringRef Format, raw_ostream &Out) { auto PlatformKindOrError = @@ -280,7 +275,7 @@ int writeTbdStub(const llvm::Triple &T, const std::set &Symbols, return 0; } -int writeElfStub(const llvm::Triple &T, const std::set &Symbols, +int writeElfStub(const llvm::Triple &T, const std::vector &Symbols, const StringRef Format, raw_ostream &Out) { SmallString<0> Storage; Storage.clear(); @@ -387,8 +382,8 @@ int writeIfso(const IFSStub &Stub, bool IsWriteIfs, raw_ostream &Out) { // TODO: Drop ObjectFileFormat, it can be subsumed from the triple. // New Interface Stubs Yaml Format: -// --- !experimental-ifs-v1 -// IfsVersion: 1.0 +// --- !experimental-ifs-v2 +// IfsVersion: 2.0 // Triple: // ObjectFileFormat: // Symbols: @@ -517,7 +512,7 @@ int main(int argc, char *argv[]) { } for (auto &Entry : SymbolMap) - Stub.Symbols.insert(Entry.second); + Stub.Symbols.push_back(Entry.second); std::error_code SysErr; From cfe-commits at lists.llvm.org Wed Apr 1 07:52:48 2020 From: cfe-commits at lists.llvm.org (Jason Liu via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 14:52:48 +0000 (UTC) Subject: [PATCH] D76360: [PPC][AIX] Emit correct Vaarg for 32BIT-AIX in clang In-Reply-To: References: Message-ID: jasonliu added inline comments. ================ Comment at: clang/lib/CodeGen/TargetInfo.cpp:10019 + return SetCGInfo( + new PPCAIX32TargetCodeGenInfo(Types, CodeGenOpts.FloatABI == "soft")); return SetCGInfo( ---------------- ZarkoCA wrote: > jasonliu wrote: > > Does AIX have soft Float? If not, do we want to always pass in 'false'? > Thanks, missed changing this. I set it to hard. I don't think `CodeGenOpts.FloatABI == "hard"` is what we want though. Currently it means if CodeGenOpts.FloatABI is really "hard", then it will pass in `true` for `SoftFloatABI` to indicate we are soft float ABI. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76360/new/ https://reviews.llvm.org/D76360 From cfe-commits at lists.llvm.org Wed Apr 1 07:52:52 2020 From: cfe-commits at lists.llvm.org (JF Bastien via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 14:52:52 +0000 (UTC) Subject: [PATCH] D77219: UBSan =?UTF-8?B?4pCH?= runtime Message-ID: jfb created this revision. Herald added subscribers: Sanitizers, cfe-commits, ributzka, dexonsmith, jkorous, cryptoad, mgorny. Herald added projects: clang, Sanitizers. jfb edited the summary of this revision. Yes, this is April 1st and the patch isn't particularly serious. There is a ␇ UBSan runtime available. It is named in honor of Bell Labs (who gave us the C programming language and Undefined Behavior), the ASCII "bell" character (value `07`), and famed violinist Joshua Bell. It is not related to the city of Bell in California. This runtime will emit sound, most traditionally the terminal's bell sound, when undefined behavior occurs. To use the minimal runtime, add `-fsanitize-bel-runtime` to the clang command line options. For example, if you're used to compiling with `-fsanitize=undefined`, you could enable the minimal runtime with `-fsanitize=undefined -fsanitize-bel-runtime`. When combined with `-fsanitize-recover=undefined`, the ␇ runtime will simply chime on Undefined Behavior without killing the program for each chime. To avoid Pavlovian effects, the ␇ runtime uses Advanced Compiler Techniques called "heuristics" to avoid chiming too often at the same location. On macOS, the ␇ runtime will helpfully announce what specific undefined behavior you've encountered, and then taunt you. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77219 Files: clang/docs/UndefinedBehaviorSanitizer.rst clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/CodeGen/CGExpr.cpp clang/lib/Driver/SanitizerArgs.cpp clang/lib/Driver/ToolChains/CommonArgs.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGen/unsigned-overflow-bel.c clang/test/Driver/fsanitize.c clang/test/Driver/sanitizer-ld.c compiler-rt/cmake/config-ix.cmake compiler-rt/lib/ubsan_bel/CMakeLists.txt compiler-rt/lib/ubsan_bel/ubsan.syms.extra compiler-rt/lib/ubsan_bel/ubsan_bel_handlers.cpp compiler-rt/test/ubsan_bel/CMakeLists.txt compiler-rt/test/ubsan_bel/TestCases/alignment-assumption.c compiler-rt/test/ubsan_bel/TestCases/implicit-integer-sign-change.c compiler-rt/test/ubsan_bel/TestCases/implicit-signed-integer-truncation-or-sign-change.c compiler-rt/test/ubsan_bel/TestCases/implicit-signed-integer-truncation.c compiler-rt/test/ubsan_bel/TestCases/implicit-unsigned-integer-truncation.c compiler-rt/test/ubsan_bel/TestCases/nullptr-and-nonzero-offset.c compiler-rt/test/ubsan_bel/TestCases/recover-dedup-limit.cpp compiler-rt/test/ubsan_bel/TestCases/recover-dedup.cpp compiler-rt/test/ubsan_bel/TestCases/test-darwin-interface.c compiler-rt/test/ubsan_bel/TestCases/uadd-overflow.cpp compiler-rt/test/ubsan_bel/lit.common.cfg.py compiler-rt/test/ubsan_bel/lit.site.cfg.py.in -------------- next part -------------- A non-text attachment was scrubbed... Name: D77219.254199.patch Type: text/x-patch Size: 42001 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 07:52:55 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 14:52:55 +0000 (UTC) Subject: [PATCH] D76790: [analyzer] StdLibraryFunctionsChecker: fix bug with arg constraints In-Reply-To: References: Message-ID: <298f267a87cde9fb2a6428325e6ef760@localhost.localdomain> martong added a comment. Ping :) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76790/new/ https://reviews.llvm.org/D76790 From cfe-commits at lists.llvm.org Wed Apr 1 07:53:32 2020 From: cfe-commits at lists.llvm.org (Puyan Lotfi via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 14:53:32 +0000 (UTC) Subject: [PATCH] D76979: [clang][llvm] Interface Stubs new yaml file format changes. In-Reply-To: References: Message-ID: This revision was not accepted when it landed; it landed in state "Needs Review". This revision was automatically updated to reflect the committed changes. Closed by commit rGe3033c0ce551: [llvm][clang][IFS] Enhancing the llvm-ifs yaml format for symbol lists. (authored by plotfi). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76979/new/ https://reviews.llvm.org/D76979 Files: clang/include/clang/Frontend/FrontendActions.h clang/include/clang/Frontend/FrontendOptions.h clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp clang/test/InterfaceStubs/bad-format.cpp clang/test/InterfaceStubs/blocks.c clang/test/InterfaceStubs/class-template-partial-specialization.cpp clang/test/InterfaceStubs/conflict-type.ifs clang/test/InterfaceStubs/constructor-using-shadow.cpp clang/test/InterfaceStubs/cxx-conversion.cpp clang/test/InterfaceStubs/cxxdeduction-guide.cpp clang/test/InterfaceStubs/driver-test3.c clang/test/InterfaceStubs/empty.c clang/test/InterfaceStubs/func.ifs clang/test/InterfaceStubs/hidden-class-inheritance.cpp clang/test/InterfaceStubs/indirect-field-decl.cpp clang/test/InterfaceStubs/inline.c clang/test/InterfaceStubs/lambda.cpp clang/test/InterfaceStubs/namespace-alias.cpp clang/test/InterfaceStubs/namespace.cpp clang/test/InterfaceStubs/non-type-template-parm-decl.cpp clang/test/InterfaceStubs/object.c clang/test/InterfaceStubs/object.ifs clang/test/InterfaceStubs/ppc.cpp clang/test/InterfaceStubs/template-constexpr.cpp clang/test/InterfaceStubs/template-namespace-function.cpp clang/test/InterfaceStubs/template-template-parm-decl.cpp clang/test/InterfaceStubs/trycatch.cpp clang/test/InterfaceStubs/unresolved-using-typename.cpp clang/test/InterfaceStubs/usings.cpp clang/test/InterfaceStubs/var-template-specialization-decl.cpp clang/test/InterfaceStubs/weak.cpp clang/test/InterfaceStubs/windows.cpp llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-size.ifs llvm/test/tools/llvm-ifs/Inputs/strong-mismatch-type.ifs llvm/test/tools/llvm-ifs/conflict-header-format.ifs llvm/test/tools/llvm-ifs/conflict-header-triple.ifs llvm/test/tools/llvm-ifs/conflict-header-version.ifs llvm/test/tools/llvm-ifs/conflict-size.ifs llvm/test/tools/llvm-ifs/conflict-type.ifs llvm/test/tools/llvm-ifs/conflict-weak.ifs llvm/test/tools/llvm-ifs/default-empty.ifs llvm/test/tools/llvm-ifs/empty1.ifs llvm/test/tools/llvm-ifs/empty2.ifs llvm/test/tools/llvm-ifs/func.ifs llvm/test/tools/llvm-ifs/ios-tbd.ifs llvm/test/tools/llvm-ifs/macos-tbd.ifs llvm/test/tools/llvm-ifs/object-function-size-weak-combo.ifs llvm/test/tools/llvm-ifs/object.ifs llvm/test/tools/llvm-ifs/strong.ifs llvm/test/tools/llvm-ifs/tvos-tbd.ifs llvm/test/tools/llvm-ifs/version-ok.ifs llvm/test/tools/llvm-ifs/watchos-tbd.ifs llvm/test/tools/llvm-ifs/weak-mismatch.ifs llvm/test/tools/llvm-ifs/weak.ifs llvm/tools/llvm-ifs/llvm-ifs.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76979.254202.patch Type: text/x-patch Size: 49490 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 08:02:11 2020 From: cfe-commits at lists.llvm.org (Sylvestre Ledru via cfe-commits) Date: Wed, 01 Apr 2020 08:02:11 -0700 (PDT) Subject: [clang-tools-extra] c6a65bb - clagn-tidy/doc: Add a link to readability-static-accessed-through-instance from readability-convert-member-functions-to-static Message-ID: <5e84acf3.1c69fb81.a2353.7b3c@mx.google.com> Author: Sylvestre Ledru Date: 2020-04-01T17:01:48+02:00 New Revision: c6a65bb93f218dbdec98f51952a309afda5608ea URL: https://github.com/llvm/llvm-project/commit/c6a65bb93f218dbdec98f51952a309afda5608ea DIFF: https://github.com/llvm/llvm-project/commit/c6a65bb93f218dbdec98f51952a309afda5608ea.diff LOG: clagn-tidy/doc: Add a link to readability-static-accessed-through-instance from readability-convert-member-functions-to-static Added: Modified: clang-tools-extra/docs/clang-tidy/checks/readability-convert-member-functions-to-static.rst Removed: ################################################################################ diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability-convert-member-functions-to-static.rst b/clang-tools-extra/docs/clang-tidy/checks/readability-convert-member-functions-to-static.rst index 891f6be63714..c2f05cf589ea 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability-convert-member-functions-to-static.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability-convert-member-functions-to-static.rst @@ -10,5 +10,5 @@ After applying modifications as suggested by the check, runnnig the check again might find more opportunities to mark member functions ``static``. After making a member function ``static``, you might want to run the check -`readability-static-accessed-through-instance` to replace calls like +`readability-static-accessed-through-instance `_ to replace calls like ``Instance.method()`` by ``Class::method()``. From cfe-commits at lists.llvm.org Wed Apr 1 08:14:51 2020 From: cfe-commits at lists.llvm.org (Sjoerd Meijer via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 15:14:51 +0000 (UTC) Subject: [PATCH] D76679: [SveEmitter] Add more immediate operand checks. In-Reply-To: References: Message-ID: <107dd303f812f22eac4df51aa3e3873b@localhost.localdomain> SjoerdMeijer added inline comments. ================ Comment at: clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_ext.c:1 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -D__ARM_FEATURE_SVE %s + ---------------- sdesmalen wrote: > SjoerdMeijer wrote: > > sdesmalen wrote: > > > SjoerdMeijer wrote: > > > > Just curious about the `-fallow-half-arguments-and-returns`, do you need that here? > > > > > > > > And if not here, why do you need it elsewhere (looks enabled on all tests)? > > > It's not needed for this test, but we've generated most of our tests from the ACLE spec and the tests that use a scalar float16_t (== __fp16) will need this, such as the ACLE intrinsic: > > > > > > svfloat16_t svadd_m(svbool_t, svfloat16_t, float16_t); > > > > > > If you feel strongly about it, I could remove it from the other RUN lines. > > Well, I think this is my surprise then. Thinking out loud: we're talking SVE here, which always implies FP16. That's why I am surprised that we bother with a storage-type only type. Looking at the SVE ACLE I indeed see: > > > > float16_t equivalent to __fp16 > > > > where I was probably expecting: > > > > float16_t equivalent to _Float16 > > > > and with that everything would be sorted I guess, then we also don't need the hack^W workaround that is `-fallow-half-arguments-and-returns`. But maybe there is a good reason to use/choose `__fp16` that I don't see here. Probably worth a quick question for the ARM SVE ACLE, would you mind quickly checking? > > > > > As just checked with @rsandifo-arm, the reason is that the definition of `float16_t` has to be compatible with `arm_neon.h`, which uses `__fp16` for both Clang and GCC. I was suspecting it was compatability reasons, but perhaps not with `arm_neon.h`. So what exactly does it mean to be compatible with arm_neon.h? I mean, put simply and naively, if you target SVE, you include arm_sve.h, and go from there. How does that interact with arm_neon.h and why can float16_t not be a proper half type? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76679/new/ https://reviews.llvm.org/D76679 From cfe-commits at lists.llvm.org Wed Apr 1 08:14:54 2020 From: cfe-commits at lists.llvm.org (Kim Viggedal via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 15:14:54 +0000 (UTC) Subject: [PATCH] D70265: [clang-tidy] Add CppCoreGuidelines I.2 "Avoid non-const global variables" check In-Reply-To: References: Message-ID: <001969ab91fec16483638e4abc0425ef@localhost.localdomain> vingeldal added a comment. After looking more closely at the code I think the issue is within hasLocalStorage() which is called in hasGlobalStorage(). My expectation would be that anything inside of function scope would be considered local but I'm not very certain. Any thoughts on whether hasLocalStorage() should be modified or if I should change the check and use some more ad-hoc implementation, instead of hasGlobalStorage(), to determine if the variable is local or global? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70265/new/ https://reviews.llvm.org/D70265 From cfe-commits at lists.llvm.org Wed Apr 1 08:14:55 2020 From: cfe-commits at lists.llvm.org (Jason Liu via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 15:14:55 +0000 (UTC) Subject: [PATCH] D76130: [PPC][AIX] Implement variadic function handling in LowerFormalArguments_AIX In-Reply-To: References: Message-ID: <077aa0162a0c4c165c5f3e70ef5acce7@localhost.localdomain> jasonliu added inline comments. ================ Comment at: llvm/test/CodeGen/PowerPC/aix32-cc-abi-vaarg.ll:8 + + target datalayout = "E-m:e-p:32:32-i64:64-n32" + target triple = "powerpc-ibm-aix-xcoff" ---------------- minor nit: I don't think these target datalayout and triple are necessary. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76130/new/ https://reviews.llvm.org/D76130 From cfe-commits at lists.llvm.org Wed Apr 1 08:14:58 2020 From: cfe-commits at lists.llvm.org (Vlastimil Labsky via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 15:14:58 +0000 (UTC) Subject: [PATCH] D77221: [AVR] Rework MCU family detection to support more AVR MCUs Message-ID: vlastik created this revision. vlastik added a reviewer: dylanmckay. Herald added subscribers: cfe-commits, Jim, hiraditya, mgorny. Herald added a project: clang. AVR port now supports only ATmega328. This patch makes more MCUs work with clang Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77221 Files: clang/lib/Basic/Targets/AVR.cpp clang/lib/Basic/Targets/AVR.h clang/lib/Driver/ToolChains/AVR.cpp llvm/include/llvm/Support/AVRTargetParser.h llvm/lib/Support/AVRTargetParser.cpp llvm/lib/Support/CMakeLists.txt -------------- next part -------------- A non-text attachment was scrubbed... Name: D77221.254206.patch Type: text/x-patch Size: 32012 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 08:17:01 2020 From: cfe-commits at lists.llvm.org (Artem Dergachev via cfe-commits) Date: Wed, 01 Apr 2020 08:17:01 -0700 (PDT) Subject: [clang] 3500cc8 - [analyzer] RetainCountChecker: Add a suppression for OSSymbols. Message-ID: <5e84b06d.1c69fb81.74c72.7c33@mx.google.com> Author: Artem Dergachev Date: 2020-04-01T18:16:44+03:00 New Revision: 3500cc8d891bb3825bb3275affe6db8b12f2f695 URL: https://github.com/llvm/llvm-project/commit/3500cc8d891bb3825bb3275affe6db8b12f2f695 DIFF: https://github.com/llvm/llvm-project/commit/3500cc8d891bb3825bb3275affe6db8b12f2f695.diff LOG: [analyzer] RetainCountChecker: Add a suppression for OSSymbols. OSSymbol objects are particular XNU OSObjects that aren't really reference-counted. Therefore you cannot do any harm by over- or under-releasing them. Added: Modified: clang/lib/Analysis/RetainSummaryManager.cpp clang/test/Analysis/osobject-retain-release.cpp Removed: ################################################################################ diff --git a/clang/lib/Analysis/RetainSummaryManager.cpp b/clang/lib/Analysis/RetainSummaryManager.cpp index 00bc854a8804..9f45a8efe546 100644 --- a/clang/lib/Analysis/RetainSummaryManager.cpp +++ b/clang/lib/Analysis/RetainSummaryManager.cpp @@ -146,7 +146,9 @@ static bool isSubclass(const Decl *D, } static bool isOSObjectSubclass(const Decl *D) { - return D && isSubclass(D, "OSMetaClassBase"); + // OSSymbols are particular OSObjects that are allocated globally + // and therefore aren't really refcounted, so we ignore them. + return D && isSubclass(D, "OSMetaClassBase") && !isSubclass(D, "OSSymbol"); } static bool isOSObjectDynamicCast(StringRef S) { diff --git a/clang/test/Analysis/osobject-retain-release.cpp b/clang/test/Analysis/osobject-retain-release.cpp index 41606a30c39f..d88349dcd807 100644 --- a/clang/test/Analysis/osobject-retain-release.cpp +++ b/clang/test/Analysis/osobject-retain-release.cpp @@ -53,6 +53,9 @@ struct MyArray : public OSArray { OSObject *generateObject(OSObject *input) override; }; +// These are never refcounted. +struct OSSymbol : OSObject {}; + struct OtherStruct { static void doNothingToArray(OSArray *array); OtherStruct(OSArray *arr); @@ -754,3 +757,10 @@ void test() { b(0); } } // namespace inherited_constructor_crash + +namespace ossymbol_suppression { +OSSymbol *createSymbol(); +void test() { + OSSymbol *sym = createSymbol(); // no-warning +} +} // namespace ossymbol_suppression From cfe-commits at lists.llvm.org Wed Apr 1 08:27:55 2020 From: cfe-commits at lists.llvm.org (Anna Thomas via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 15:27:55 +0000 (UTC) Subject: [PATCH] D76140: [InlineFunction] update attributes during inlining In-Reply-To: References: Message-ID: anna updated this revision to Diff 254213. anna added a comment. This revision is now accepted and ready to land. whitelist valid return attributes and only add those. Added testcase for signext. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76140/new/ https://reviews.llvm.org/D76140 Files: llvm/lib/Transforms/Utils/InlineFunction.cpp llvm/test/Transforms/Inline/ret_attr_update.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D76140.254213.patch Type: text/x-patch Size: 12360 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 08:27:55 2020 From: cfe-commits at lists.llvm.org (Zarko Todorovski via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 15:27:55 +0000 (UTC) Subject: [PATCH] D76360: [PPC][AIX] Emit correct Vaarg for 32BIT-AIX in clang In-Reply-To: References: Message-ID: <475c3596aa2567d47ee2413358c82931@localhost.localdomain> ZarkoCA marked 4 inline comments as done. ZarkoCA added inline comments. ================ Comment at: clang/lib/CodeGen/TargetInfo.cpp:10019 + return SetCGInfo( + new PPCAIX32TargetCodeGenInfo(Types, CodeGenOpts.FloatABI == "soft")); return SetCGInfo( ---------------- jasonliu wrote: > ZarkoCA wrote: > > jasonliu wrote: > > > Does AIX have soft Float? If not, do we want to always pass in 'false'? > > Thanks, missed changing this. I set it to hard. > I don't think `CodeGenOpts.FloatABI == "hard"` is what we want though. Currently it means if CodeGenOpts.FloatABI is really "hard", then it will pass in `true` for `SoftFloatABI` to indicate we are soft float ABI. You're right. I wanted to keep the symmetry but that's not the correct thing to do. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76360/new/ https://reviews.llvm.org/D76360 From cfe-commits at lists.llvm.org Wed Apr 1 08:27:56 2020 From: cfe-commits at lists.llvm.org (Anna Thomas via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 15:27:56 +0000 (UTC) Subject: [PATCH] D76140: [InlineFunction] update attributes during inlining In-Reply-To: References: Message-ID: <38eee0e30fca55062f388e94a643c694@localhost.localdomain> anna requested review of this revision. anna added a comment. fixed buildbot failure. see above comments and added testcase `test8`. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76140/new/ https://reviews.llvm.org/D76140 From cfe-commits at lists.llvm.org Wed Apr 1 08:28:01 2020 From: cfe-commits at lists.llvm.org (Zarko Todorovski via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 15:28:01 +0000 (UTC) Subject: [PATCH] D76360: [PPC][AIX] Emit correct Vaarg for 32BIT-AIX in clang In-Reply-To: References: Message-ID: <072b95c442f3adf1a159d795ed96b834@localhost.localdomain> ZarkoCA updated this revision to Diff 254214. ZarkoCA marked an inline comment as done. ZarkoCA added a comment. Set isSoftFloat to return false for AIX. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76360/new/ https://reviews.llvm.org/D76360 Files: clang/lib/Basic/Targets/PPC.h clang/lib/CodeGen/TargetInfo.cpp clang/test/CodeGen/aix-vararg.c clang/test/CodeGen/aix32-dwarf-error.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D76360.254214.patch Type: text/x-patch Size: 6849 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 08:28:12 2020 From: cfe-commits at lists.llvm.org (John Regehr via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 15:28:12 +0000 (UTC) Subject: [PATCH] D77219: UBSan =?UTF-8?B?4pCH?= runtime In-Reply-To: References: Message-ID: regehr added a comment. Sorry but I don't think this can land until it has options for sending sanitizer output to Slack channels and SMS numbers. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77219/new/ https://reviews.llvm.org/D77219 From cfe-commits at lists.llvm.org Wed Apr 1 08:47:21 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 15:47:21 +0000 (UTC) Subject: [PATCH] D77222: [clangd] Fix an assertion crash in ReferenceFinder. Message-ID: hokein created this revision. hokein added a reviewer: sammccall. Herald added subscribers: usaxena95, kadircet, arphaman, jkorous, MaskRay, ilya-biryukov. Herald added a project: clang. The assertion is almost correct, but it fails on refs from non-preamble Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77222 Files: clang-tools-extra/clangd/XRefs.cpp clang-tools-extra/clangd/unittests/XRefsTests.cpp Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -1121,6 +1121,30 @@ } } +TEST(FindReferences, MainFileReferencesOnly) { + llvm::StringRef Test = + R"cpp( + void test() { + int [[fo^o]] = 1; + // refs not from main file should not be included. + #include "foo.inc" + })cpp"; + + Annotations Code(Test); + auto TU = TestTU::withCode(Code.code()); + TU.AdditionalFiles["foo.inc"] = R"cpp( + foo = 3; + )cpp"; + auto AST = TU.build(); + + std::vector> ExpectedLocations; + for (const auto &R : Code.ranges()) + ExpectedLocations.push_back(RangeIs(R)); + EXPECT_THAT(findReferences(AST, Code.point(), 0).References, + ElementsAreArray(ExpectedLocations)) + << Test; +} + TEST(FindReferences, ExplicitSymbols) { const char *Tests[] = { R"cpp( Index: clang-tools-extra/clangd/XRefs.cpp =================================================================== --- clang-tools-extra/clangd/XRefs.cpp +++ clang-tools-extra/clangd/XRefs.cpp @@ -583,13 +583,11 @@ SourceLocation Loc, index::IndexDataConsumer::ASTNodeInfo ASTNode) override { assert(D->isCanonicalDecl() && "expect D to be a canonical declaration"); - if (!CanonicalTargets.count(D)) + const SourceManager &SM = AST.getSourceManager(); + if (!CanonicalTargets.count(D) || !isInsideMainFile(Loc, SM)) return true; const auto &TB = AST.getTokens(); - const SourceManager &SM = AST.getSourceManager(); Loc = SM.getFileLoc(Loc); - // We are only traversing decls *inside* the main file, so this should hold. - assert(isInsideMainFile(Loc, SM)); if (const auto *Tok = TB.spelledTokenAt(Loc)) References.push_back({*Tok, Roles}); return true; -------------- next part -------------- A non-text attachment was scrubbed... Name: D77222.254216.patch Type: text/x-patch Size: 1997 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 08:47:21 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 15:47:21 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift In-Reply-To: References: Message-ID: rjmccall accepted this revision. rjmccall added a comment. This revision is now accepted and ready to land. Thanks, LGTM. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77077/new/ https://reviews.llvm.org/D77077 From cfe-commits at lists.llvm.org Wed Apr 1 08:47:25 2020 From: cfe-commits at lists.llvm.org (LevitatingLion via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 15:47:25 +0000 (UTC) Subject: [PATCH] D70366: Add new 'flatten' LLVM attribute to fix clang's 'flatten' function attribute In-Reply-To: References: Message-ID: LevitatingLion updated this revision to Diff 254217. LevitatingLion added a comment. Herald added a reviewer: sstefan1. I rebased my changes onto 49d00824bbb , renamed the attribute to 'alwaysinline_recursively', and added some more tests. The testcase 'highLevelStructure.3.2.ll' does not fail anymore, all regression tests pass. Are there any more places where changes are required? I looked at the changes when other attributes were introduced and grep'd for 'Attribute::AlwaysInline' to find places which need handling of the new attribute. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70366/new/ https://reviews.llvm.org/D70366 Files: clang/lib/CodeGen/CGCall.cpp llvm/docs/BitCodeFormat.rst llvm/docs/LangRef.rst llvm/include/llvm/Bitcode/LLVMBitCodes.h llvm/include/llvm/IR/Attributes.td llvm/lib/Analysis/InlineCost.cpp llvm/lib/AsmParser/LLLexer.cpp llvm/lib/AsmParser/LLParser.cpp llvm/lib/AsmParser/LLToken.h llvm/lib/Bitcode/Reader/BitcodeReader.cpp llvm/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/lib/CodeGen/SafeStack.cpp llvm/lib/IR/Attributes.cpp llvm/lib/IR/Verifier.cpp llvm/lib/Target/AMDGPU/AMDGPUInline.cpp llvm/lib/Target/Hexagon/HexagonLoopIdiomRecognition.cpp llvm/lib/Transforms/IPO/AlwaysInliner.cpp llvm/lib/Transforms/IPO/Attributor.cpp llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp llvm/lib/Transforms/IPO/HotColdSplitting.cpp llvm/lib/Transforms/IPO/Inliner.cpp llvm/lib/Transforms/IPO/PartialInlining.cpp llvm/lib/Transforms/IPO/SyntheticCountsPropagation.cpp llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp llvm/lib/Transforms/Utils/CodeExtractor.cpp llvm/test/Transforms/Inline/always-inline-recursively.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D70366.254217.patch Type: text/x-patch Size: 26315 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 08:59:08 2020 From: cfe-commits at lists.llvm.org (Arnold Schwaighofer via cfe-commits) Date: Wed, 01 Apr 2020 08:59:08 -0700 (PDT) Subject: [clang] 153dadf - [clang] CodeGen: Make getOrEmitProtocol public for Swift Message-ID: <5e84ba4c.1c69fb81.fa882.845b@mx.google.com> Author: Arnold Schwaighofer Date: 2020-04-01T08:55:56-07:00 New Revision: 153dadf3a3ca3c47f8c0fb718ec96616a05e42fd URL: https://github.com/llvm/llvm-project/commit/153dadf3a3ca3c47f8c0fb718ec96616a05e42fd DIFF: https://github.com/llvm/llvm-project/commit/153dadf3a3ca3c47f8c0fb718ec96616a05e42fd.diff LOG: [clang] CodeGen: Make getOrEmitProtocol public for Swift Summary: Swift would like to use clang's apis to emit protocol declarations. This commits adds the public API: ``` emitObjCProtocolObject(CodeGenModule &CGM, const ObjCProtocolDecl *p); ``` rdar://60888524 Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77077 Added: Modified: clang/include/clang/CodeGen/CodeGenABITypes.h clang/lib/CodeGen/CGObjCGNU.cpp clang/lib/CodeGen/CGObjCMac.cpp clang/lib/CodeGen/CGObjCRuntime.cpp clang/lib/CodeGen/CGObjCRuntime.h Removed: ################################################################################ diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h b/clang/include/clang/CodeGen/CodeGenABITypes.h index 31f0cea57232..5f4af7fd2a36 100644 --- a/clang/include/clang/CodeGen/CodeGenABITypes.h +++ b/clang/include/clang/CodeGen/CodeGenABITypes.h @@ -28,11 +28,12 @@ #include "clang/CodeGen/CGFunctionInfo.h" namespace llvm { - class DataLayout; - class Module; - class Function; - class FunctionType; - class Type; +class Constant; +class DataLayout; +class Module; +class Function; +class FunctionType; +class Type; } namespace clang { @@ -44,6 +45,7 @@ class CoverageSourceInfo; class DiagnosticsEngine; class HeaderSearchOptions; class ObjCMethodDecl; +class ObjCProtocolDecl; class PreprocessorOptions; namespace CodeGen { @@ -137,6 +139,13 @@ llvm::Function *getNonTrivialCStructDestructor(CodeGenModule &CGM, CharUnits DstAlignment, bool IsVolatile, QualType QT); +/// Get a pointer to a protocol object for the given declaration, emitting it if +/// it hasn't already been emitted in this translation unit. Note that the ABI +/// for emitting a protocol reference in code (e.g. for a protocol expression) +/// in most runtimes is not as simple as just materializing a pointer to this +/// object. +llvm::Constant *emitObjCProtocolObject(CodeGenModule &CGM, + const ObjCProtocolDecl *p); } // end namespace CodeGen } // end namespace clang diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index db78309e9fd9..35b926808492 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -617,6 +617,13 @@ class CGObjCGNU : public CGObjCRuntime { llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF, const ObjCProtocolDecl *PD) override; void GenerateProtocol(const ObjCProtocolDecl *PD) override; + + virtual llvm::Constant *GenerateProtocolRef(const ObjCProtocolDecl *PD); + + llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override { + return GenerateProtocolRef(PD); + } + llvm::Function *ModuleInitFunction() override; llvm::FunctionCallee GetPropertyGetFunction() override; llvm::FunctionCallee GetPropertySetFunction() override; @@ -1348,7 +1355,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep { void GenerateProtocol(const ObjCProtocolDecl *PD) override { // Do nothing - we only emit referenced protocols. } - llvm::Constant *GenerateProtocolRef(const ObjCProtocolDecl *PD) { + llvm::Constant *GenerateProtocolRef(const ObjCProtocolDecl *PD) override { std::string ProtocolName = PD->getNameAsString(); auto *&Protocol = ExistingProtocols[ProtocolName]; if (Protocol) @@ -3039,13 +3046,18 @@ CGObjCGNU::GenerateProtocolList(ArrayRef Protocols) { llvm::Value *CGObjCGNU::GenerateProtocolRef(CodeGenFunction &CGF, const ObjCProtocolDecl *PD) { + auto protocol = GenerateProtocolRef(PD); + llvm::Type *T = + CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType()); + return CGF.Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T)); +} + +llvm::Constant *CGObjCGNU::GenerateProtocolRef(const ObjCProtocolDecl *PD) { llvm::Constant *&protocol = ExistingProtocols[PD->getNameAsString()]; if (!protocol) GenerateProtocol(PD); assert(protocol && "Unknown protocol"); - llvm::Type *T = - CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType()); - return CGF.Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T)); + return protocol; } llvm::Constant * diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 87fd51b5d8b1..3986310eaa70 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -1107,11 +1107,6 @@ class CGObjCCommonMac : public CodeGen::CGObjCRuntime { void GenerateProtocol(const ObjCProtocolDecl *PD) override; - /// GetOrEmitProtocol - Get the protocol object for the given - /// declaration, emitting it if necessary. The return value has type - /// ProtocolPtrTy. - virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0; - /// GetOrEmitProtocolRef - Get a forward reference to the protocol /// object for the given declaration, emitting it if needed. These /// forward references will be filled in with empty bodies if no diff --git a/clang/lib/CodeGen/CGObjCRuntime.cpp b/clang/lib/CodeGen/CGObjCRuntime.cpp index c34758c7e3b3..39efe040302d 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.cpp +++ b/clang/lib/CodeGen/CGObjCRuntime.cpp @@ -13,14 +13,15 @@ //===----------------------------------------------------------------------===// #include "CGObjCRuntime.h" -#include "CGCleanup.h" #include "CGCXXABI.h" +#include "CGCleanup.h" #include "CGRecordLayout.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/StmtObjC.h" #include "clang/CodeGen/CGFunctionInfo.h" +#include "clang/CodeGen/CodeGenABITypes.h" #include "llvm/Support/SaveAndRestore.h" using namespace clang; @@ -383,3 +384,9 @@ CGObjCRuntime::getMessageSendInfo(const ObjCMethodDecl *method, CGM.getTypes().GetFunctionType(argsInfo)->getPointerTo(); return MessageSendInfo(argsInfo, signatureType); } + +llvm::Constant * +clang::CodeGen::emitObjCProtocolObject(CodeGenModule &CGM, + const ObjCProtocolDecl *protocol) { + return CGM.getObjCRuntime().GetOrEmitProtocol(protocol); +} diff --git a/clang/lib/CodeGen/CGObjCRuntime.h b/clang/lib/CodeGen/CGObjCRuntime.h index f0b3525cfde2..a2c189585f7b 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.h +++ b/clang/lib/CodeGen/CGObjCRuntime.h @@ -211,6 +211,11 @@ class CGObjCRuntime { /// implementations. virtual void GenerateProtocol(const ObjCProtocolDecl *OPD) = 0; + /// GetOrEmitProtocol - Get the protocol object for the given + /// declaration, emitting it if necessary. The return value has type + /// ProtocolPtrTy. + virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) = 0; + /// Generate a function preamble for a method with the specified /// types. From cfe-commits at lists.llvm.org Wed Apr 1 09:01:07 2020 From: cfe-commits at lists.llvm.org (Roman Lebedev via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 16:01:07 +0000 (UTC) Subject: [PATCH] D77219: UBSan =?UTF-8?B?4pCH?= runtime In-Reply-To: References: Message-ID: lebedev.ri added inline comments. ================ Comment at: compiler-rt/lib/ubsan_bel/ubsan_bel_handlers.cpp:40-42 + static std::random_device r; + static std::default_random_engine e(r()); + static std::uniform_int_distribution d(0, sizeof(quips) / sizeof(quips[0]) - 1); ---------------- I'm not sure we should be introducing randomness into UB handler. I think what this instead should do, is attach gdb to the process and fix the UB-invoking instructions. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77219/new/ https://reviews.llvm.org/D77219 From cfe-commits at lists.llvm.org Wed Apr 1 09:01:08 2020 From: cfe-commits at lists.llvm.org (Sander de Smalen via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 16:01:08 +0000 (UTC) Subject: [PATCH] D76679: [SveEmitter] Add more immediate operand checks. In-Reply-To: References: Message-ID: sdesmalen marked an inline comment as done. sdesmalen added inline comments. ================ Comment at: clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_ext.c:1 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -D__ARM_FEATURE_SVE %s + ---------------- SjoerdMeijer wrote: > sdesmalen wrote: > > SjoerdMeijer wrote: > > > sdesmalen wrote: > > > > SjoerdMeijer wrote: > > > > > Just curious about the `-fallow-half-arguments-and-returns`, do you need that here? > > > > > > > > > > And if not here, why do you need it elsewhere (looks enabled on all tests)? > > > > It's not needed for this test, but we've generated most of our tests from the ACLE spec and the tests that use a scalar float16_t (== __fp16) will need this, such as the ACLE intrinsic: > > > > > > > > svfloat16_t svadd_m(svbool_t, svfloat16_t, float16_t); > > > > > > > > If you feel strongly about it, I could remove it from the other RUN lines. > > > Well, I think this is my surprise then. Thinking out loud: we're talking SVE here, which always implies FP16. That's why I am surprised that we bother with a storage-type only type. Looking at the SVE ACLE I indeed see: > > > > > > float16_t equivalent to __fp16 > > > > > > where I was probably expecting: > > > > > > float16_t equivalent to _Float16 > > > > > > and with that everything would be sorted I guess, then we also don't need the hack^W workaround that is `-fallow-half-arguments-and-returns`. But maybe there is a good reason to use/choose `__fp16` that I don't see here. Probably worth a quick question for the ARM SVE ACLE, would you mind quickly checking? > > > > > > > > As just checked with @rsandifo-arm, the reason is that the definition of `float16_t` has to be compatible with `arm_neon.h`, which uses `__fp16` for both Clang and GCC. > I was suspecting it was compatability reasons, but perhaps not with `arm_neon.h`. So what exactly does it mean to be compatible with arm_neon.h? I mean, put simply and naively, if you target SVE, you include arm_sve.h, and go from there. How does that interact with arm_neon.h and why can float16_t not be a proper half type? If you target SVE, you can still use Neon instructions, so it's still possible to include arm_neon.h as well. If those have differing definitions of float16_t, that may give trouble when using builtins from both the Neon and SVE header files. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76679/new/ https://reviews.llvm.org/D76679 From cfe-commits at lists.llvm.org Wed Apr 1 09:01:10 2020 From: cfe-commits at lists.llvm.org (Anna Thomas via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 16:01:10 +0000 (UTC) Subject: [PATCH] D76140: [InlineFunction] update attributes during inlining In-Reply-To: References: Message-ID: <98b655a350ece5506c392eb3d8da1999@localhost.localdomain> anna updated this revision to Diff 254222. anna added a comment. fixed missing code left out during rebase. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76140/new/ https://reviews.llvm.org/D76140 Files: llvm/lib/Transforms/Utils/InlineFunction.cpp llvm/test/Transforms/Inline/ret_attr_update.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D76140.254222.patch Type: text/x-patch Size: 13560 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 09:01:17 2020 From: cfe-commits at lists.llvm.org (Arnold Schwaighofer via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 16:01:17 +0000 (UTC) Subject: [PATCH] D77077: [clang] CodeGen: Make getOrEmitProtocol public for Swift In-Reply-To: References: Message-ID: <9115875870077b2f0c5a176f2e769fef@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG153dadf3a3ca: [clang] CodeGen: Make getOrEmitProtocol public for Swift (authored by aschwaighofer). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77077/new/ https://reviews.llvm.org/D77077 Files: clang/include/clang/CodeGen/CodeGenABITypes.h clang/lib/CodeGen/CGObjCGNU.cpp clang/lib/CodeGen/CGObjCMac.cpp clang/lib/CodeGen/CGObjCRuntime.cpp clang/lib/CodeGen/CGObjCRuntime.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D77077.254224.patch Type: text/x-patch Size: 5815 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 09:20:45 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 16:20:45 +0000 (UTC) Subject: [PATCH] D77225: [clangd] Support textDocument/semanticTokens/edits Message-ID: sammccall created this revision. sammccall added a reviewer: hokein. Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, mgrang, jkorous, MaskRay, ilya-biryukov. Herald added a project: clang. This returns incremental highlights as a set of edits against the previous highlights. Server-side, we compute the full set of highlights, this just saves wire-format size. For now, the diff used is trivial: everything from the first change to the last change is sent as a single edit. The wire format is grungy - the replacement offset/length refer to positions in the encoded array instead of the logical list of tokens. We use token-oriented structs and translating to LSP forms when serializing. This departs from LSP (but is consistent with semanticTokens today). Tested in VSCode insiders (with a patched client to enable experimental features). Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77225 Files: clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/ClangdLSPServer.h clang-tools-extra/clangd/Protocol.cpp clang-tools-extra/clangd/Protocol.h clang-tools-extra/clangd/SemanticHighlighting.cpp clang-tools-extra/clangd/SemanticHighlighting.h clang-tools-extra/clangd/test/initialize-params.test clang-tools-extra/clangd/test/semantic-tokens.test clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77225.254226.patch Type: text/x-patch Size: 19653 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 09:20:51 2020 From: cfe-commits at lists.llvm.org (Denys Petrov via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 16:20:51 +0000 (UTC) Subject: [PATCH] D77062: [analyzer] Added check for unaccaptable equality operation between Loc and NonLoc types In-Reply-To: References: Message-ID: <2a593c2ce35ef9bc4cb305e14e818adc@localhost.localdomain> ASDenysPetrov updated this revision to Diff 254225. ASDenysPetrov edited the summary of this revision. ASDenysPetrov added a comment. Herald added a project: clang. Herald added a subscriber: cfe-commits. Reworked solution. Simplified CStringChecker::assumeZero. Added test (taken from the bug). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77062/new/ https://reviews.llvm.org/D77062 Files: clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp clang/test/Analysis/string.c Index: clang/test/Analysis/string.c =================================================================== --- clang/test/Analysis/string.c +++ clang/test/Analysis/string.c @@ -363,6 +363,14 @@ strcpy(x, y); // no-warning } +void* func_strcpy_no_assertion(); +char*** ptr_strcpy_no_assertion; +void strcpy_no_assertion() { + *(unsigned char **)ptr_strcpy_no_assertion = (unsigned char*)(func_strcpy_no_assertion()); + char c; + strcpy(**ptr_strcpy_no_assertion, &c); // no-assertion +} + //===----------------------------------------------------------------------=== // stpcpy() //===----------------------------------------------------------------------=== Index: clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -266,13 +266,16 @@ std::pair CStringChecker::assumeZero(CheckerContext &C, ProgramStateRef state, SVal V, QualType Ty) { + auto states = std::make_pair(state, state); + + // LazyCompoundVal cannot be handled by assume Optional val = V.getAs(); - if (!val) - return std::pair(state, state); + if (val && !V.getAs()) { + // return pair shall be {null, non-null} so reorder states + std::tie(states.second, states.first) = state->assume(*val); + } - SValBuilder &svalBuilder = C.getSValBuilder(); - DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty); - return state->assume(svalBuilder.evalEQ(state, *val, zero)); + return states; } ProgramStateRef CStringChecker::checkNonNull(CheckerContext &C, -------------- next part -------------- A non-text attachment was scrubbed... Name: D77062.254225.patch Type: text/x-patch Size: 1793 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 09:20:52 2020 From: cfe-commits at lists.llvm.org (JF Bastien via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 16:20:52 +0000 (UTC) Subject: [PATCH] D77219: UBSan =?UTF-8?B?4pCH?= runtime In-Reply-To: References: Message-ID: jfb marked an inline comment as done. jfb added inline comments. ================ Comment at: compiler-rt/lib/ubsan_bel/ubsan_bel_handlers.cpp:40-42 + static std::random_device r; + static std::default_random_engine e(r()); + static std::uniform_int_distribution d(0, sizeof(quips) / sizeof(quips[0]) - 1); ---------------- lebedev.ri wrote: > I'm not sure we should be introducing randomness into UB handler. > I think what this instead should do, is attach gdb to the process and fix the UB-invoking instructions. Hmm, should it be sudo-random to ensure that `rm -rf /` works? What is gdb? Is it like lldb but not as low-level? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77219/new/ https://reviews.llvm.org/D77219 From cfe-commits at lists.llvm.org Wed Apr 1 09:34:13 2020 From: cfe-commits at lists.llvm.org (Erich Keane via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 16:34:13 +0000 (UTC) Subject: [PATCH] D76384: Move FPFeatures from BinaryOperator bitfields to Trailing storage In-Reply-To: References: Message-ID: <0e74457605e96e3b953e5ffbaccf1a4e@localhost.localdomain> erichkeane added a comment. Trying to help Melanie respond to the comments, so I ran through the patch and came up with the following comments/responses. Sorry for the 'surprise hit' :) ================ Comment at: clang/include/clang/AST/Expr.h:3474 + static unsigned sizeOfTrailingObjects(bool hasFP, bool isCompound) { + return (hasFP ? 1 : 0) * sizeof(unsigned) + + (isCompound ? 2 : 0) * sizeof(QualType); ---------------- rjmccall wrote: > Sorry, I wasn't trying to say you need this here! Since you can use TrailingObjects for BinaryOperator, you absolutely should take advantage of what it does. I was just pointing you at the CallExpr stuff so that you can see the places you'll need to update when you add this storage to CallExpr. Yep, this shouldn't be necessary. Uses of this should be able to use totalSizeToAlloc and additionalSizeToAlloc. ================ Comment at: clang/include/clang/AST/Expr.h:3674 + + void setHasFPFeatures(bool B) { BinaryOperatorBits.HasFPFeatures = B; } + bool hasFPFeatures() const { return BinaryOperatorBits.HasFPFeatures; } ---------------- Since changing this value can result in a change of allocation size, I don't think this should be settable after creation. ================ Comment at: clang/include/clang/AST/Expr.h:3680 + } + FPOptions getFPFeatures(const ASTContext &C) const { + if (hasFPFeatures()) ---------------- Whats the purpose of having both of these? It seems that you can either: 1- Have only the first and require consumers to check if they aren't sure, or 2- Only do the second, and those who have checked just get the default anyway. ================ Comment at: clang/include/clang/AST/Expr.h:3739 - BinaryOperator(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) { - BinaryOperatorBits.Opc = BO_MulAssign; - } -}; - -/// CompoundAssignOperator - For compound assignments (e.g. +=), we keep -/// track of the type the operation is performed in. Due to the semantics of -/// these operators, the operands are promoted, the arithmetic performed, an -/// implicit conversion back to the result type done, then the assignment takes -/// place. This captures the intermediate type which the computation is done -/// in. -class CompoundAssignOperator : public BinaryOperator { - QualType ComputationLHSType; - QualType ComputationResultType; -public: - CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType, - ExprValueKind VK, ExprObjectKind OK, - QualType CompLHSType, QualType CompResultType, - SourceLocation OpLoc, FPOptions FPFeatures) - : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures, - true), - ComputationLHSType(CompLHSType), - ComputationResultType(CompResultType) { - assert(isCompoundAssignmentOp() && - "Only should be used for compound assignments"); - } - - /// Build an empty compound assignment operator expression. - explicit CompoundAssignOperator(EmptyShell Empty) - : BinaryOperator(CompoundAssignOperatorClass, Empty) { } - - // The two computation types are the type the LHS is converted - // to for the computation and the type of the result; the two are - // distinct in a few cases (specifically, int+=ptr and ptr-=ptr). - QualType getComputationLHSType() const { return ComputationLHSType; } - void setComputationLHSType(QualType T) { ComputationLHSType = T; } - - QualType getComputationResultType() const { return ComputationResultType; } - void setComputationResultType(QualType T) { ComputationResultType = T; } - - static bool classof(const Stmt *S) { - return S->getStmtClass() == CompoundAssignOperatorClass; + BinaryOperator(EmptyShell Empty, unsigned hasFPFeatures, unsigned isCompound) + : Expr(BinaryOperatorClass, Empty) { ---------------- Nit, I'd prefer this be named 'isCompoundAssignment'. Also, the patch seems a little inconsistent with FPFeatures vs FPOptions. ================ Comment at: clang/include/clang/AST/StmtVisitor.h:146 + RetTy VisitBin##NAME(PTR(BinaryOperator) S, ParamTys... P) { \ + DISPATCH(BinAssign, BinaryOperator); \ } ---------------- rjmccall wrote: > Comment needs updating, but more importantly, you're making all of these fall back on `VisitBinAssign`, which is definitely not correct. @rjmccall : What would you think fits better? If we don't have something like this, VisitBinaryOperator is going to have to redirect to VisitBinAssign anyway. We could presumably keep VisitCompoundAssignOperator, but that seems like a naming difference. ================ Comment at: clang/include/clang/Basic/LangOptions.h:385 + static FPOptions defaultWithoutTrailingStorage() { + FPOptions result; + return result; ---------------- Nit: return {}; ? Also, why are there two versions of this? It seems that the ASTContext one should be the only required one. ================ Comment at: clang/include/clang/Basic/LangOptions.h:394 + return true; + } + ---------------- rjmccall wrote: > The problem with having both functions that take `ASTContext`s and functions that don't is that it's easy to mix them, so they either need to have the same behavior (in which case it's pointless to have an overload that takes the `ASTContext`) or you're making something really error-prone. > > I would feel a lot more confident that you were designing and using these APIs correctly if you actually took advantage of the ability to not store trailing FPOptions in some case, like when they match the global settings in the ASTContext. That way you'll actually be verifying that everything behaves correctly if nodes don't store FPOptions. If you do that, I think you'll see my point about not having all these easily-confusable functions that do or do not take `ASTContext`s.. I think I disagree with @rjmccall that these requiresTrailingStorage should be here at all. I think we should store in the AST ANY programmer opinion, even if they match the global setting. It seems to me that this would be more tolerant of any global-setting rewrites that modules/et-al introduce, as well as make the AST Print consistent. Always storing FPOptions when the user has explicitly overriding it also better captures the programmer's intent. ================ Comment at: clang/lib/AST/Expr.cpp:4347 + unsigned SizeOfTrailingObjects = + BinaryOperator::sizeOfTrailingObjects(hasFPFeatures, isCompound); + void *Mem = C.Allocate(sizeof(BinaryOperator) + SizeOfTrailingObjects, ---------------- Again, should just use the TrailingObjects::totalSizeToAlloc I think. Alternatively, implement a new 'totalSizeToAlloc' based on the hasFPFeatures and isCompound). ================ Comment at: clang/lib/AST/ExprConstant.cpp:7788 -bool LValueExprEvaluator::VisitCompoundAssignOperator( - const CompoundAssignOperator *CAO) { +bool LValueExprEvaluator::VisitBinAssign(const BinaryOperator *E) { if (!Info.getLangOpts().CPlusPlus14 && !Info.keepEvaluatingAfterFailure()) ---------------- Perhaps not changing this name is a good idea, and just leaving this as VisitCompoundOperator, then having the 'default' behavior to be to just call VisitBinaryOperator. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76384/new/ https://reviews.llvm.org/D76384 From cfe-commits at lists.llvm.org Wed Apr 1 09:36:40 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via cfe-commits) Date: Wed, 01 Apr 2020 09:36:40 -0700 (PDT) Subject: [clang] 6593360 - AMDGPU: Fix consistently backwards logic for default denormal mode Message-ID: <5e84c318.1c69fb81.c17d2.83cf@mx.google.com> Author: Matt Arsenault Date: 2020-04-01T12:36:22-04:00 New Revision: 6593360ee760c0c98cf7fb05be70aa4ea455a42a URL: https://github.com/llvm/llvm-project/commit/6593360ee760c0c98cf7fb05be70aa4ea455a42a DIFF: https://github.com/llvm/llvm-project/commit/6593360ee760c0c98cf7fb05be70aa4ea455a42a.diff LOG: AMDGPU: Fix consistently backwards logic for default denormal mode I forgot to squash this into c9d65a48af1d7bbfed7e785613cc9d9acf71821b Added: Modified: clang/lib/Driver/ToolChains/AMDGPU.cpp Removed: ################################################################################ diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index e6a5af99b203..2cec0dc9de22 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -109,11 +109,10 @@ bool AMDGPUToolChain::getDefaultDenormsAreZeroForTarget( // Default to enabling f32 denormals by default on subtargets where fma is // fast with denormals - const bool DefaultDenormsAreZeroForTarget = + const bool BothDenormAndFMAFast = (ArchAttr & llvm::AMDGPU::FEATURE_FAST_FMA_F32) && (ArchAttr & llvm::AMDGPU::FEATURE_FAST_DENORMAL_F32); - - return DefaultDenormsAreZeroForTarget; + return !BothDenormAndFMAFast; } llvm::DenormalMode AMDGPUToolChain::getDefaultDenormalModeForType( @@ -137,7 +136,7 @@ llvm::DenormalMode AMDGPUToolChain::getDefaultDenormalModeForType( // TODO: There are way too many flags that change this. Do we need to check // them all? bool DAZ = DriverArgs.hasArg(options::OPT_cl_denorms_are_zero) || - !getDefaultDenormsAreZeroForTarget(Kind); + getDefaultDenormsAreZeroForTarget(Kind); // Outputs are flushed to zero, preserving sign return DAZ ? llvm::DenormalMode::getPreserveSign() : llvm::DenormalMode::getIEEE(); From cfe-commits at lists.llvm.org Wed Apr 1 09:36:42 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via cfe-commits) Date: Wed, 01 Apr 2020 09:36:42 -0700 (PDT) Subject: [clang] 4ea3650 - HIP: Link correct denormal mode library Message-ID: <5e84c31a.1c69fb81.49c0d.832a@mx.google.com> Author: Matt Arsenault Date: 2020-04-01T12:36:22-04:00 New Revision: 4ea3650c212ae471657d3a253cd424ce9d1316ac URL: https://github.com/llvm/llvm-project/commit/4ea3650c212ae471657d3a253cd424ce9d1316ac DIFF: https://github.com/llvm/llvm-project/commit/4ea3650c212ae471657d3a253cd424ce9d1316ac.diff LOG: HIP: Link correct denormal mode library This wasn't respecting the flush mode based on the default, and also wasn't correctly handling the explicit -fno-cuda-flush-denormals-to-zero overriding the mode. Added: Modified: clang/lib/Driver/ToolChains/HIP.cpp clang/test/Driver/hip-device-libs.hip Removed: ################################################################################ diff --git a/clang/lib/Driver/ToolChains/HIP.cpp b/clang/lib/Driver/ToolChains/HIP.cpp index d21b3f5f0b19..e4ace81dbac7 100644 --- a/clang/lib/Driver/ToolChains/HIP.cpp +++ b/clang/lib/Driver/ToolChains/HIP.cpp @@ -285,6 +285,7 @@ void HIPToolChain::addClangTargetOptions( (void) GpuArch; assert(DeviceOffloadingKind == Action::OFK_HIP && "Only HIP offloading kinds are supported for GPUs."); + auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch); CC1Args.push_back("-target-cpu"); CC1Args.push_back(DriverArgs.MakeArgStringRef(GpuArch)); @@ -345,11 +346,14 @@ void HIPToolChain::addClangTargetOptions( std::string GFXVersion = GpuArch.drop_front(3).str(); std::string ISAVerBC = "oclc_isa_version_" + GFXVersion + ".amdgcn.bc"; - llvm::StringRef FlushDenormalControlBC; - if (DriverArgs.hasArg(options::OPT_fcuda_flush_denormals_to_zero)) - FlushDenormalControlBC = "oclc_daz_opt_on.amdgcn.bc"; - else - FlushDenormalControlBC = "oclc_daz_opt_off.amdgcn.bc"; + bool FTZDAZ = DriverArgs.hasFlag( + options::OPT_fcuda_flush_denormals_to_zero, + options::OPT_fno_cuda_flush_denormals_to_zero, + getDefaultDenormsAreZeroForTarget(Kind)); + + std::string FlushDenormalControlBC = FTZDAZ ? + "oclc_daz_opt_on.amdgcn.bc" : + "oclc_daz_opt_off.amdgcn.bc"; llvm::StringRef WaveFrontSizeBC; if (stoi(GFXVersion) < 1000) @@ -359,7 +363,7 @@ void HIPToolChain::addClangTargetOptions( BCLibs.append({"hip.amdgcn.bc", "ocml.amdgcn.bc", "ockl.amdgcn.bc", "oclc_finite_only_off.amdgcn.bc", - std::string(FlushDenormalControlBC), + FlushDenormalControlBC, "oclc_correctly_rounded_sqrt_on.amdgcn.bc", "oclc_unsafe_math_off.amdgcn.bc", ISAVerBC, std::string(WaveFrontSizeBC)}); diff --git a/clang/test/Driver/hip-device-libs.hip b/clang/test/Driver/hip-device-libs.hip index b79cb70cbe68..cb1747c2d798 100644 --- a/clang/test/Driver/hip-device-libs.hip +++ b/clang/test/Driver/hip-device-libs.hip @@ -2,23 +2,94 @@ // REQUIRES: x86-registered-target // REQUIRES: amdgpu-registered-target -// Test flush-denormals-to-zero enabled uses oclc_daz_opt_on +// Test if oclc_daz_opt_on or if oclc_daz_opt_off is linked depending on +// expected denormal mode. +// Test subtarget with flushing on by default. +// RUN: %clang -### -target x86_64-linux-gnu \ +// RUN: --cuda-gpu-arch=gfx803 \ +// RUN: --hip-device-lib-path=%S/Inputs/hip_dev_lib \ +// RUN: %S/Inputs/hip_multiple_inputs/b.hip \ +// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,FLUSHD + + +// Test subtarget with flushing off by ddefault. // RUN: %clang -### -target x86_64-linux-gnu \ // RUN: --cuda-gpu-arch=gfx900 \ // RUN: --hip-device-lib-path=%S/Inputs/hip_dev_lib \ +// RUN: %S/Inputs/hip_multiple_inputs/b.hip \ +// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,NOFLUSHD + + +// Test explicit flag, opposite of target default. +// RUN: %clang -### -target x86_64-linux-gnu \ +// RUN: --cuda-gpu-arch=gfx900 \ // RUN: -fcuda-flush-denormals-to-zero \ +// RUN: --hip-device-lib-path=%S/Inputs/hip_dev_lib \ // RUN: %S/Inputs/hip_multiple_inputs/b.hip \ // RUN: 2>&1 | FileCheck %s --check-prefixes=COM,FLUSHD -// Test flush-denormals-to-zero disabled uses oclc_daz_opt_off +// Test explicit flag, opposite of target default. +// RUN: %clang -### -target x86_64-linux-gnu \ +// RUN: --cuda-gpu-arch=gfx803 \ +// RUN: -fno-cuda-flush-denormals-to-zero \ +// RUN: --hip-device-lib-path=%S/Inputs/hip_dev_lib \ +// RUN: %S/Inputs/hip_multiple_inputs/b.hip \ +// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,NOFLUSHD + + +// Test explicit flag, same as target default. // RUN: %clang -### -target x86_64-linux-gnu \ // RUN: --cuda-gpu-arch=gfx900 \ +// RUN: -fno-cuda-flush-denormals-to-zero \ // RUN: --hip-device-lib-path=%S/Inputs/hip_dev_lib \ // RUN: %S/Inputs/hip_multiple_inputs/b.hip \ // RUN: 2>&1 | FileCheck %s --check-prefixes=COM,NOFLUSHD + +// Test explicit flag, same as target default. +// RUN: %clang -### -target x86_64-linux-gnu \ +// RUN: --cuda-gpu-arch=gfx803 \ +// RUN: -fcuda-flush-denormals-to-zero \ +// RUN: --hip-device-lib-path=%S/Inputs/hip_dev_lib \ +// RUN: %S/Inputs/hip_multiple_inputs/b.hip \ +// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,FLUSHD + + +// Test last flag wins, not flushing +// RUN: %clang -### -target x86_64-linux-gnu \ +// RUN: --cuda-gpu-arch=gfx803 \ +// RUN: -fcuda-flush-denormals-to-zero -fno-cuda-flush-denormals-to-zero \ +// RUN: --hip-device-lib-path=%S/Inputs/hip_dev_lib \ +// RUN: %S/Inputs/hip_multiple_inputs/b.hip \ +// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,NOFLUSHD + + +// RUN: %clang -### -target x86_64-linux-gnu \ +// RUN: --cuda-gpu-arch=gfx900 \ +// RUN: -fcuda-flush-denormals-to-zero -fno-cuda-flush-denormals-to-zero \ +// RUN: --hip-device-lib-path=%S/Inputs/hip_dev_lib \ +// RUN: %S/Inputs/hip_multiple_inputs/b.hip \ +// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,NOFLUSHD + + +// RUN: %clang -### -target x86_64-linux-gnu \ +// RUN: --cuda-gpu-arch=gfx900 \ +// RUN: -fno-cuda-flush-denormals-to-zero -fcuda-flush-denormals-to-zero \ +// RUN: --hip-device-lib-path=%S/Inputs/hip_dev_lib \ +// RUN: %S/Inputs/hip_multiple_inputs/b.hip \ +// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,FLUSHD + + +// RUN: %clang -### -target x86_64-linux-gnu \ +// RUN: --cuda-gpu-arch=gfx803 \ +// RUN: -fno-cuda-flush-denormals-to-zero -fcuda-flush-denormals-to-zero \ +// RUN: --hip-device-lib-path=%S/Inputs/hip_dev_lib \ +// RUN: %S/Inputs/hip_multiple_inputs/b.hip \ +// RUN: 2>&1 | FileCheck %s --check-prefixes=COM,FLUSHD + + // Test environment variable HIP_DEVICE_LIB_PATH // RUN: env HIP_DEVICE_LIB_PATH=%S/Inputs/hip_dev_lib \ @@ -33,4 +104,3 @@ // COM-SAME: "-mlink-builtin-bitcode" "{{.*}}ockl.amdgcn.bc" // FLUSHD-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_daz_opt_on.amdgcn.bc" // NOFLUSHD-SAME: "-mlink-builtin-bitcode" "{{.*}}oclc_daz_opt_off.amdgcn.bc" - From cfe-commits at lists.llvm.org Wed Apr 1 09:46:28 2020 From: cfe-commits at lists.llvm.org (Thomas Lively via cfe-commits) Date: Wed, 01 Apr 2020 09:46:28 -0700 (PDT) Subject: [clang] 95fac2e - [WebAssembly] Rename SIMD min/max/avgr intrinsics for consistency Message-ID: <5e84c564.1c69fb81.13c99.734d@mx.google.com> Author: Thomas Lively Date: 2020-04-01T09:38:41-07:00 New Revision: 95fac2e46b73c67495dbdb43ef178d33281c05ec URL: https://github.com/llvm/llvm-project/commit/95fac2e46b73c67495dbdb43ef178d33281c05ec DIFF: https://github.com/llvm/llvm-project/commit/95fac2e46b73c67495dbdb43ef178d33281c05ec.diff LOG: [WebAssembly] Rename SIMD min/max/avgr intrinsics for consistency Summary: The convention for the wasm_simd128.h intrinsics is to have the integer sign in the lane interpretation rather than as a suffix. This PR changes the names of the integer min, max, and avgr intrinsics to match this convention. Reviewers: aheejin Subscribers: dschuff, sbc100, jgravelle-google, sunfish, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77185 Added: Modified: clang/lib/Headers/wasm_simd128.h Removed: ################################################################################ diff --git a/clang/lib/Headers/wasm_simd128.h b/clang/lib/Headers/wasm_simd128.h index 3b30ddbd527b..c2c57cadfdf2 100644 --- a/clang/lib/Headers/wasm_simd128.h +++ b/clang/lib/Headers/wasm_simd128.h @@ -650,28 +650,28 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_mul(v128_t __a, return (v128_t)((__u8x16)__a * (__u8x16)__b); } -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_min_s(v128_t __a, - v128_t __b) { +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_min(v128_t __a, + v128_t __b) { return (v128_t)__builtin_wasm_min_s_i8x16((__i8x16)__a, (__i8x16)__b); } -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_min_u(v128_t __a, - v128_t __b) { +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u8x16_min(v128_t __a, + v128_t __b) { return (v128_t)__builtin_wasm_min_u_i8x16((__i8x16)__a, (__i8x16)__b); } -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_max_s(v128_t __a, - v128_t __b) { +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_max(v128_t __a, + v128_t __b) { return (v128_t)__builtin_wasm_max_s_i8x16((__i8x16)__a, (__i8x16)__b); } -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_max_u(v128_t __a, - v128_t __b) { +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u8x16_max(v128_t __a, + v128_t __b) { return (v128_t)__builtin_wasm_max_u_i8x16((__i8x16)__a, (__i8x16)__b); } -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_avgr_u(v128_t __a, - v128_t __b) { +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u8x16_avgr(v128_t __a, + v128_t __b) { return (v128_t)__builtin_wasm_avgr_u_i8x16((__i8x16)__a, (__i8x16)__b); } @@ -745,28 +745,28 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_mul(v128_t __a, return (v128_t)((__u16x8)__a * (__u16x8)__b); } -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_min_s(v128_t __a, - v128_t __b) { +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_min(v128_t __a, + v128_t __b) { return (v128_t)__builtin_wasm_min_s_i16x8((__i16x8)__a, (__i16x8)__b); } -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_min_u(v128_t __a, - v128_t __b) { +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u16x8_min(v128_t __a, + v128_t __b) { return (v128_t)__builtin_wasm_min_u_i16x8((__i16x8)__a, (__i16x8)__b); } -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_max_s(v128_t __a, - v128_t __b) { +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_max(v128_t __a, + v128_t __b) { return (v128_t)__builtin_wasm_max_s_i16x8((__i16x8)__a, (__i16x8)__b); } -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_max_u(v128_t __a, - v128_t __b) { +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u16x8_max(v128_t __a, + v128_t __b) { return (v128_t)__builtin_wasm_max_u_i16x8((__i16x8)__a, (__i16x8)__b); } -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_avgr_u(v128_t __a, - v128_t __b) { +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u16x8_avgr(v128_t __a, + v128_t __b) { return (v128_t)__builtin_wasm_avgr_u_i16x8((__i16x8)__a, (__i16x8)__b); } @@ -816,23 +816,23 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_mul(v128_t __a, return (v128_t)((__u32x4)__a * (__u32x4)__b); } -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_min_s(v128_t __a, - v128_t __b) { +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_min(v128_t __a, + v128_t __b) { return (v128_t)__builtin_wasm_min_s_i32x4((__i32x4)__a, (__i32x4)__b); } -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_min_u(v128_t __a, - v128_t __b) { +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u32x4_min(v128_t __a, + v128_t __b) { return (v128_t)__builtin_wasm_min_u_i32x4((__i32x4)__a, (__i32x4)__b); } -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_max_s(v128_t __a, - v128_t __b) { +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_max(v128_t __a, + v128_t __b) { return (v128_t)__builtin_wasm_max_s_i32x4((__i32x4)__a, (__i32x4)__b); } -static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_max_u(v128_t __a, - v128_t __b) { +static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_u32x4_max(v128_t __a, + v128_t __b) { return (v128_t)__builtin_wasm_max_u_i32x4((__i32x4)__a, (__i32x4)__b); } From cfe-commits at lists.llvm.org Wed Apr 1 09:53:26 2020 From: cfe-commits at lists.llvm.org (Florian Hahn via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 16:53:26 +0000 (UTC) Subject: [PATCH] D76791: [Matrix] Implement matrix index expressions ([][]). In-Reply-To: References: Message-ID: fhahn updated this revision to Diff 254228. fhahn added a comment. Use placeholder type for incomplete matrix index expressions, as suggested by @rjmccall Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76791/new/ https://reviews.llvm.org/D76791 Files: clang/include/clang/AST/ASTContext.h clang/include/clang/AST/BuiltinTypes.def clang/include/clang/AST/Expr.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Serialization/ASTBitCodes.h clang/lib/AST/ASTContext.cpp clang/lib/AST/Expr.cpp clang/lib/AST/ExprConstant.cpp clang/lib/AST/NSAPI.cpp clang/lib/AST/Type.cpp clang/lib/AST/TypeLoc.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGValue.h clang/lib/Sema/SemaExpr.cpp clang/lib/Serialization/ASTCommon.cpp clang/lib/Serialization/ASTReader.cpp clang/test/CodeGen/matrix-type-operators.c clang/test/CodeGenCXX/matrix-type-operators.cpp clang/test/Sema/matrix-type-operators.c clang/test/SemaCXX/matrix-type-operators.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76791.254228.patch Type: text/x-patch Size: 43928 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 09:53:27 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 16:53:27 +0000 (UTC) Subject: [PATCH] D76950: HIP: Link correct denormal mode library In-Reply-To: References: Message-ID: <4a58ab0b65d2590354b51ac48925afb3@localhost.localdomain> arsenm closed this revision. arsenm marked an inline comment as done. arsenm added a comment. 4ea3650c212ae471657d3a253cd424ce9d1316ac CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76950/new/ https://reviews.llvm.org/D76950 From cfe-commits at lists.llvm.org Wed Apr 1 09:53:28 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 16:53:28 +0000 (UTC) Subject: [PATCH] D59321: AMDGPU: Teach toolchain to link rocm device libs In-Reply-To: References: Message-ID: arsenm updated this revision to Diff 254229. arsenm marked an inline comment as done. arsenm added a comment. Rebase again CHANGES SINCE LAST ACTION https://reviews.llvm.org/D59321/new/ https://reviews.llvm.org/D59321 Files: clang/include/clang/Basic/DiagnosticDriverKinds.td clang/include/clang/Driver/Options.td clang/lib/Driver/Driver.cpp clang/lib/Driver/ToolChains/AMDGPU.cpp clang/lib/Driver/ToolChains/AMDGPU.h clang/lib/Driver/ToolChains/HIP.h clang/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl clang/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl clang/test/Driver/Inputs/rocm-device-libs/lib/hip.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/ockl.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_correctly_rounded_sqrt_off.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_correctly_rounded_sqrt_on.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_daz_opt_off.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_daz_opt_on.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_finite_only_off.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_finite_only_on.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_isa_version_1010.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_isa_version_1011.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_isa_version_1012.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_isa_version_803.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_isa_version_900.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_unsafe_math_off.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_unsafe_math_on.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_wavefrontsize64_off.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_wavefrontsize64_on.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/ocml.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/opencl.amdgcn.bc clang/test/Driver/amdgpu-visibility.cl clang/test/Driver/rocm-detect.cl clang/test/Driver/rocm-device-libs.cl clang/test/Driver/rocm-not-found.cl llvm/include/llvm/Support/TargetParser.h llvm/lib/Support/TargetParser.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D59321.254229.patch Type: text/x-patch Size: 33080 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 09:53:28 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 16:53:28 +0000 (UTC) Subject: [PATCH] D59321: AMDGPU: Teach toolchain to link rocm device libs In-Reply-To: References: Message-ID: <9c8ed1048d622fc18c718902dff73e87@localhost.localdomain> arsenm added inline comments. ================ Comment at: clang/include/clang/Basic/DiagnosticDriverKinds.td:264 def err_drv_invalid_malign_branch_EQ : Error< "invalid argument '%0' to -malign-branch=; each element must be one of: %1">; ---------------- yaxunl wrote: > could you please rebase your patch? > > The patch seems to contain irrelevant diffs. You're probably looking at the wrong history diff CHANGES SINCE LAST ACTION https://reviews.llvm.org/D59321/new/ https://reviews.llvm.org/D59321 From cfe-commits at lists.llvm.org Wed Apr 1 09:53:31 2020 From: cfe-commits at lists.llvm.org (Sjoerd Meijer via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 16:53:31 +0000 (UTC) Subject: [PATCH] D76679: [SveEmitter] Add more immediate operand checks. In-Reply-To: References: Message-ID: <81dcb578804d4128087cea8737da1a68@localhost.localdomain> SjoerdMeijer added inline comments. ================ Comment at: clang/test/CodeGen/aarch64-sve-intrinsics/negative/acle_sve_ext.c:1 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -fsyntax-only -verify -D__ARM_FEATURE_SVE %s + ---------------- sdesmalen wrote: > SjoerdMeijer wrote: > > sdesmalen wrote: > > > SjoerdMeijer wrote: > > > > sdesmalen wrote: > > > > > SjoerdMeijer wrote: > > > > > > Just curious about the `-fallow-half-arguments-and-returns`, do you need that here? > > > > > > > > > > > > And if not here, why do you need it elsewhere (looks enabled on all tests)? > > > > > It's not needed for this test, but we've generated most of our tests from the ACLE spec and the tests that use a scalar float16_t (== __fp16) will need this, such as the ACLE intrinsic: > > > > > > > > > > svfloat16_t svadd_m(svbool_t, svfloat16_t, float16_t); > > > > > > > > > > If you feel strongly about it, I could remove it from the other RUN lines. > > > > Well, I think this is my surprise then. Thinking out loud: we're talking SVE here, which always implies FP16. That's why I am surprised that we bother with a storage-type only type. Looking at the SVE ACLE I indeed see: > > > > > > > > float16_t equivalent to __fp16 > > > > > > > > where I was probably expecting: > > > > > > > > float16_t equivalent to _Float16 > > > > > > > > and with that everything would be sorted I guess, then we also don't need the hack^W workaround that is `-fallow-half-arguments-and-returns`. But maybe there is a good reason to use/choose `__fp16` that I don't see here. Probably worth a quick question for the ARM SVE ACLE, would you mind quickly checking? > > > > > > > > > > > As just checked with @rsandifo-arm, the reason is that the definition of `float16_t` has to be compatible with `arm_neon.h`, which uses `__fp16` for both Clang and GCC. > > I was suspecting it was compatability reasons, but perhaps not with `arm_neon.h`. So what exactly does it mean to be compatible with arm_neon.h? I mean, put simply and naively, if you target SVE, you include arm_sve.h, and go from there. How does that interact with arm_neon.h and why can float16_t not be a proper half type? > If you target SVE, you can still use Neon instructions, so it's still possible to include arm_neon.h as well. If those have differing definitions of float16_t, that may give trouble when using builtins from both the Neon and SVE header files. ok, thank, got it. So we are supporting this case: #include #include void foo () { neon_intrinsic(); sve_intrinsic(); } Well, I find this very unfortunate, because it could have been so beautiful, and now we're still have this storage-only type while even the ACLE discourages its use. The use of `-fallow-half-arguments-and-returns` is just a minor annoyance, but point is it shouldn't have been necessary. Now I am wondering why the ARM SVE ACLE is using float16_t, and not just _Float16. Do you have any insights in that too perhaps? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76679/new/ https://reviews.llvm.org/D76679 From cfe-commits at lists.llvm.org Wed Apr 1 09:53:31 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 16:53:31 +0000 (UTC) Subject: [PATCH] D77048: [Clang][CodeGen] Fixing mismatch between memory layout and const expressions for oversized bitfields In-Reply-To: References: Message-ID: efriedma accepted this revision. efriedma added a comment. This revision is now accepted and ready to land. LGTM Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77048/new/ https://reviews.llvm.org/D77048 From cfe-commits at lists.llvm.org Wed Apr 1 09:54:03 2020 From: cfe-commits at lists.llvm.org (Thomas Lively via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 16:54:03 +0000 (UTC) Subject: [PATCH] D77185: [WebAssembly] Rename SIMD min/max/avgr intrinsics for consistency In-Reply-To: References: Message-ID: <296beeb96ce8a3bd942ee874d418fbc2@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG95fac2e46b73: [WebAssembly] Rename SIMD min/max/avgr intrinsics for consistency (authored by tlively). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77185/new/ https://reviews.llvm.org/D77185 Files: clang/lib/Headers/wasm_simd128.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D77185.254233.patch Type: text/x-patch Size: 5670 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 10:01:50 2020 From: cfe-commits at lists.llvm.org (Alexey Bataev via cfe-commits) Date: Wed, 01 Apr 2020 10:01:50 -0700 (PDT) Subject: [clang] f08df46 - [OPENMP50]Add initial support for OpenMP 5.0 iterator. Message-ID: <5e84c8fe.1c69fb81.451a7.8a65@mx.google.com> Author: Alexey Bataev Date: 2020-04-01T12:53:55-04:00 New Revision: f08df464ae89972a777c0a7e299a2c153a9829d8 URL: https://github.com/llvm/llvm-project/commit/f08df464ae89972a777c0a7e299a2c153a9829d8 DIFF: https://github.com/llvm/llvm-project/commit/f08df464ae89972a777c0a7e299a2c153a9829d8.diff LOG: [OPENMP50]Add initial support for OpenMP 5.0 iterator. Added basic parsing/semantic analysis/(de)serialization support for iterator expression introduced in OpenMP 5.0. Added: Modified: clang/include/clang-c/Index.h clang/include/clang/AST/ASTContext.h clang/include/clang/AST/BuiltinTypes.def clang/include/clang/AST/ComputeDependence.h clang/include/clang/AST/ExprOpenMP.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/AST/TextNodeDumper.h clang/include/clang/Basic/DiagnosticParseKinds.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Basic/StmtNodes.td clang/include/clang/Parse/Parser.h clang/include/clang/Sema/Sema.h clang/include/clang/Serialization/ASTBitCodes.h clang/lib/AST/ASTContext.cpp clang/lib/AST/ComputeDependence.cpp clang/lib/AST/Expr.cpp clang/lib/AST/ExprClassification.cpp clang/lib/AST/ExprConstant.cpp clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/NSAPI.cpp clang/lib/AST/OpenMPClause.cpp clang/lib/AST/StmtPrinter.cpp clang/lib/AST/StmtProfile.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/AST/Type.cpp clang/lib/AST/TypeLoc.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaExceptionSpec.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTCommon.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/Serialization/ASTWriterStmt.cpp clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp clang/lib/StaticAnalyzer/Core/ExprEngine.cpp clang/test/OpenMP/depobj_messages.cpp clang/test/OpenMP/task_ast_print.cpp clang/test/OpenMP/task_depend_messages.cpp clang/tools/libclang/CIndex.cpp clang/tools/libclang/CXCursor.cpp Removed: ################################################################################ diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 641f058dafaa..0acd50021ed8 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2180,7 +2180,12 @@ enum CXCursorKind { */ CXCursor_OMPArrayShapingExpr = 150, - CXCursor_LastExpr = CXCursor_OMPArrayShapingExpr, + /** + * OpenMP 5.0 [2.1.6 Iterators] + */ + CXCursor_OMPIteratorExpr = 151, + + CXCursor_LastExpr = CXCursor_OMPIteratorExpr, /* Statements */ CXCursor_FirstStmt = 200, diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index ebb5ca593843..6813ab58874e 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -970,7 +970,7 @@ class ASTContext : public RefCountedBase { #include "clang/Basic/OpenCLImageTypes.def" CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; CanQualType OCLQueueTy, OCLReserveIDTy; - CanQualType OMPArraySectionTy, OMPArrayShapingTy; + CanQualType OMPArraySectionTy, OMPArrayShapingTy, OMPIteratorTy; #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ CanQualType Id##Ty; #include "clang/Basic/OpenCLExtensionTypes.def" diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index f42503773945..f8eb4ec19c8f 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -316,8 +316,11 @@ PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy) // A placeholder type for OpenMP array shaping operation. PLACEHOLDER_TYPE(OMPArrayShaping, OMPArrayShapingTy) +// A placeholder type for OpenMP iterators. +PLACEHOLDER_TYPE(OMPIterator, OMPIteratorTy) + #ifdef LAST_BUILTIN_TYPE -LAST_BUILTIN_TYPE(OMPArrayShaping) +LAST_BUILTIN_TYPE(OMPIterator) #undef LAST_BUILTIN_TYPE #endif diff --git a/clang/include/clang/AST/ComputeDependence.h b/clang/include/clang/AST/ComputeDependence.h index 63947eaff73b..ab742c9b70dd 100644 --- a/clang/include/clang/AST/ComputeDependence.h +++ b/clang/include/clang/AST/ComputeDependence.h @@ -88,6 +88,7 @@ class PseudoObjectExpr; class AtomicExpr; class OMPArraySectionExpr; class OMPArrayShapingExpr; +class OMPIteratorExpr; class ObjCArrayLiteral; class ObjCDictionaryLiteral; class ObjCBoxedExpr; @@ -174,6 +175,7 @@ ExprDependence computeDependence(AtomicExpr *E); ExprDependence computeDependence(OMPArraySectionExpr *E); ExprDependence computeDependence(OMPArrayShapingExpr *E); +ExprDependence computeDependence(OMPIteratorExpr *E); ExprDependence computeDependence(ObjCArrayLiteral *E); ExprDependence computeDependence(ObjCDictionaryLiteral *E); diff --git a/clang/include/clang/AST/ExprOpenMP.h b/clang/include/clang/AST/ExprOpenMP.h index 4a0cd07f1dab..6059df8b33e7 100644 --- a/clang/include/clang/AST/ExprOpenMP.h +++ b/clang/include/clang/AST/ExprOpenMP.h @@ -205,6 +205,173 @@ class OMPArrayShapingExpr final return const_child_range(Begin, Begin + NumDims + 1); } }; + +/// OpenMP 5.0 [2.1.6 Iterators] +/// Iterators are identifiers that expand to multiple values in the clause on +/// which they appear. +/// The syntax of the iterator modifier is as follows: +/// \code +/// iterator(iterators-definition) +/// \endcode +/// where iterators-definition is one of the following: +/// \code +/// iterator-specifier [, iterators-definition ] +/// \endcode +/// where iterator-specifier is one of the following: +/// \code +/// [ iterator-type ] identifier = range-specification +/// \endcode +/// where identifier is a base language identifier. +/// iterator-type is a type name. +/// range-specification is of the form begin:end[:step], where begin and end are +/// expressions for which their types can be converted to iterator-type and step +/// is an integral expression. +/// In an iterator-specifier, if the iterator-type is not specified then the +/// type of that iterator is of int type. +/// The iterator-type must be an integral or pointer type. +/// The iterator-type must not be const qualified. +class OMPIteratorExpr final + : public Expr, + private llvm::TrailingObjects { +public: + /// Iterator range representation begin:end[:step]. + struct IteratorRange { + Expr *Begin = nullptr; + Expr *End = nullptr; + Expr *Step = nullptr; + }; + /// Iterator definition representation. + struct IteratorDefinition { + Decl *IteratorDecl = nullptr; + IteratorRange Range; + SourceLocation AssignmentLoc; + SourceLocation ColonLoc, SecondColonLoc; + }; + +private: + friend TrailingObjects; + friend class ASTStmtReader; + friend class ASTStmtWriter; + + /// Offset in the list of expressions for subelements of the ranges. + enum class RangeExprOffset { + Begin = 0, + End = 1, + Step = 2, + Total = 3, + }; + /// Offset in the list of locations for subelements of colon symbols + /// locations. + enum class RangeLocOffset { + AssignLoc = 0, + FirstColonLoc = 1, + SecondColonLoc = 2, + Total = 3, + }; + /// Location of 'iterator' keyword. + SourceLocation IteratorKwLoc; + /// Location of '('. + SourceLocation LPLoc; + /// Location of ')'. + SourceLocation RPLoc; + /// Number of iterator definitions. + unsigned NumIterators = 0; + + OMPIteratorExpr(QualType ExprTy, SourceLocation IteratorKwLoc, + SourceLocation L, SourceLocation R, + ArrayRef Data); + + /// Construct an empty expression. + explicit OMPIteratorExpr(EmptyShell Shell, unsigned NumIterators) + : Expr(OMPIteratorExprClass, Shell), NumIterators(NumIterators) {} + + /// Sets basic declaration for the specified iterator definition. + void setIteratorDeclaration(unsigned I, Decl *D); + + /// Sets the location of the assignment symbol for the specified iterator + /// definition. + void setAssignmentLoc(unsigned I, SourceLocation Loc); + + /// Sets begin, end and optional step expressions for specified iterator + /// definition. + void setIteratorRange(unsigned I, Expr *Begin, SourceLocation ColonLoc, + Expr *End, SourceLocation SecondColonLoc, Expr *Step); + + unsigned numTrailingObjects(OverloadToken) const { + return NumIterators; + } + + unsigned numTrailingObjects(OverloadToken) const { + return NumIterators * static_cast(RangeExprOffset::Total); + } + + unsigned numTrailingObjects(OverloadToken) const { + return NumIterators * static_cast(RangeLocOffset::Total); + } + +public: + static OMPIteratorExpr *Create(const ASTContext &Context, QualType T, + SourceLocation IteratorKwLoc, SourceLocation L, + SourceLocation R, + ArrayRef Data); + + static OMPIteratorExpr *CreateEmpty(const ASTContext &Context, + unsigned NumIterators); + + SourceLocation getLParenLoc() const { return LPLoc; } + void setLParenLoc(SourceLocation L) { LPLoc = L; } + + SourceLocation getRParenLoc() const { return RPLoc; } + void setRParenLoc(SourceLocation L) { RPLoc = L; } + + SourceLocation getIteratorKwLoc() const { return IteratorKwLoc; } + void setIteratorKwLoc(SourceLocation L) { IteratorKwLoc = L; } + SourceLocation getBeginLoc() const LLVM_READONLY { return IteratorKwLoc; } + SourceLocation getEndLoc() const LLVM_READONLY { return RPLoc; } + + /// Gets the iterator declaration for the given iterator. + Decl *getIteratorDecl(unsigned I); + const Decl *getIteratorDecl(unsigned I) const { + return const_cast(this)->getIteratorDecl(I); + } + + /// Gets the iterator range for the given iterator. + IteratorRange getIteratorRange(unsigned I); + const IteratorRange getIteratorRange(unsigned I) const { + return const_cast(this)->getIteratorRange(I); + } + + /// Gets the location of '=' for the given iterator definition. + SourceLocation getAssignLoc(unsigned I) const; + /// Gets the location of the first ':' in the range for the given iterator + /// definition. + SourceLocation getColonLoc(unsigned I) const; + /// Gets the location of the second ':' (if any) in the range for the given + /// iteratori definition. + SourceLocation getSecondColonLoc(unsigned I) const; + + /// Returns number of iterator definitions. + unsigned numOfIterators() const { return NumIterators; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPIteratorExprClass; + } + + // Iterators + child_range children() { + Stmt **Begin = reinterpret_cast(getTrailingObjects()); + return child_range( + Begin, Begin + NumIterators * static_cast(RangeExprOffset::Total)); + } + const_child_range children() const { + Stmt *const *Begin = + reinterpret_cast(getTrailingObjects()); + return const_child_range( + Begin, Begin + NumIterators * static_cast(RangeExprOffset::Total)); + } +}; + } // end namespace clang #endif diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 0d4b69911f19..028af6ac9a72 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -4372,6 +4372,9 @@ class OMPDependClause final /// Set colon location. void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } + /// Sets optional dependency modifier. + void setModifier(Expr *DepModifier); + public: /// Creates clause with a list of variables \a VL. /// @@ -4387,7 +4390,7 @@ class OMPDependClause final /// clause. static OMPDependClause *Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, + SourceLocation EndLoc, Expr *DepModifier, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef VL, unsigned NumLoops); @@ -4404,6 +4407,12 @@ class OMPDependClause final /// Get dependency type. OpenMPDependClauseKind getDependencyKind() const { return DepKind; } + /// Return optional depend modifier. + Expr *getModifier(); + const Expr *getModifier() const { + return const_cast(this)->getModifier(); + } + /// Get dependency type location. SourceLocation getDependencyLoc() const { return DepLoc; } diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 46661e59f181..345333849659 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2552,6 +2552,7 @@ DEF_TRAVERSE_STMT(AddrLabelExpr, {}) DEF_TRAVERSE_STMT(ArraySubscriptExpr, {}) DEF_TRAVERSE_STMT(OMPArraySectionExpr, {}) DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {}) +DEF_TRAVERSE_STMT(OMPIteratorExpr, {}) DEF_TRAVERSE_STMT(BlockExpr, { TRY_TO(TraverseDecl(S->getBlockDecl())); diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h index b08d1e482be8..0fb4baf0ca4d 100644 --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -274,6 +274,7 @@ class TextNodeDumper void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node); void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node); void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node); + void VisitOMPIteratorExpr(const OMPIteratorExpr *Node); void VisitRValueReferenceType(const ReferenceType *T); void VisitArrayType(const ArrayType *T); diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 6eb320a85a30..f3741531c8b5 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1220,6 +1220,10 @@ def err_omp_expected_identifier_for_critical : Error< "expected identifier specifying the name of the 'omp critical' directive">; def err_omp_expected_reduction_identifier : Error< "expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'">; +def err_omp_expected_equal_in_iterator : Error< + "expected '=' in iterator specifier">; +def err_omp_expected_punc_after_iterator : Error< + "expected ',' or ')' after iterator specifier">; def err_omp_decl_in_declare_simd_variant : Error< "function declaration is expected after 'declare %select{simd|variant}0' directive">; def err_omp_unknown_map_type : Error< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 951a955984f6..901ac758b383 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9760,6 +9760,14 @@ def note_omp_conversion_here : Note< def err_omp_ambiguous_conversion : Error< "ambiguous conversion from type %0 to an integral or unscoped " "enumeration type">; +def err_omp_iterator_not_integral_or_pointer : Error< + "expected integral or pointer type as the iterator-type, not %0">; +def err_omp_iterator_constant : Error< + "expected non-constant type as the iterator-type, constant %0 is provided">; +def err_omp_iterator_step_not_integral : Error< + "iterator step expression %0 is not the integral expression">; +def err_omp_iterator_step_constant_zero : Error< + "iterator step expression %0 evaluates to 0">; def err_omp_required_access : Error< "%0 variable must be %1">; def err_omp_const_variable : Error< @@ -9953,6 +9961,7 @@ def err_omp_invalid_mapper: Error< "cannot find a valid user-defined mapper for type %0 with name %1">; def err_omp_array_section_use : Error<"OpenMP array section is not allowed here">; def err_omp_array_shaping_use : Error<"OpenMP array shaping operation is not allowed here">; +def err_omp_iterator_use : Error<"OpenMP iterator is not allowed here">; def err_omp_typecheck_section_value : Error< "subscripted value is not an array or pointer">; def err_omp_typecheck_section_not_integer : Error< @@ -10031,6 +10040,10 @@ def err_omp_depend_sink_source_not_allowed : Error< "'depend(%select{source|sink:vec}0)' clause%select{|s}0 cannot be mixed with 'depend(%select{sink:vec|source}0)' clause%select{s|}0">; def err_omp_depend_zero_length_array_section_not_allowed : Error< "zero-length array section is not allowed in 'depend' clause">; +def err_omp_depend_sink_source_with_modifier : Error< + "depend modifier cannot be used with 'sink' or 'source' depend type">; +def err_omp_depend_modifier_not_iterator : Error< + "expected iterator specification as depend modifier">; def err_omp_linear_ordered : Error< "'linear' clause cannot be specified along with 'ordered' clause with a parameter">; def err_omp_unexpected_schedule_modifier : Error< diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index ba1b5ebd6305..aecf24f89033 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -70,6 +70,7 @@ def OffsetOfExpr : StmtNode; def UnaryExprOrTypeTraitExpr : StmtNode; def ArraySubscriptExpr : StmtNode; def OMPArraySectionExpr : StmtNode; +def OMPIteratorExpr : StmtNode; def CallExpr : StmtNode; def MemberExpr : StmtNode; def CastExpr : StmtNode; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 290da0006116..ca0a5fd68994 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3086,6 +3086,11 @@ class Parser : public CodeCompletionHandler { OMPClause *ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, bool ParseOnly); + /// Parses and creates OpenMP 5.0 iterators expression: + /// = 'iterator' '(' { [ ] identifier = + /// }+ ')' + ExprResult ParseOpenMPIteratorsExpr(); + public: /// Parses simple expression in parens for single-expression clauses of OpenMP /// constructs. @@ -3095,7 +3100,7 @@ class Parser : public CodeCompletionHandler { /// Data used for parsing list of variables in OpenMP clauses. struct OpenMPVarListDataTy { - Expr *TailExpr = nullptr; + Expr *DepModOrTailExpr = nullptr; SourceLocation ColonLoc; SourceLocation RLoc; CXXScopeSpec ReductionOrMapperIdScopeSpec; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 9a41356ddb70..e1365e84a0b3 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -25,6 +25,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprObjC.h" +#include "clang/AST/ExprOpenMP.h" #include "clang/AST/ExternalASTSource.h" #include "clang/AST/LocInfoType.h" #include "clang/AST/MangleNumberingContext.h" @@ -4904,6 +4905,21 @@ class Sema final { ArrayRef Dims, ArrayRef Brackets); + /// Data structure for iterator expression. + struct OMPIteratorData { + IdentifierInfo *DeclIdent = nullptr; + SourceLocation DeclIdentLoc; + ParsedType Type; + OMPIteratorExpr::IteratorRange Range; + SourceLocation AssignLoc; + SourceLocation ColonLoc; + SourceLocation SecColonLoc; + }; + + ExprResult ActOnOMPIteratorExpr(Scope *S, SourceLocation IteratorKwLoc, + SourceLocation LLoc, SourceLocation RLoc, + ArrayRef Data); + // This struct is for use by ActOnMemberAccess to allow // BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after // changing the access operator from a '.' to a '->' (to see if that is the @@ -10572,7 +10588,7 @@ class Sema final { SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); OMPClause *ActOnOpenMPVarListClause( - OpenMPClauseKind Kind, ArrayRef Vars, Expr *TailExpr, + OpenMPClauseKind Kind, ArrayRef Vars, Expr *DepModOrTailExpr, const OMPVarListLocTy &Locs, SourceLocation ColonLoc, CXXScopeSpec &ReductionOrMapperIdScopeSpec, DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, @@ -10670,10 +10686,10 @@ class Sema final { SourceLocation EndLoc); /// Called on well-formed 'depend' clause. OMPClause * - ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, - SourceLocation ColonLoc, ArrayRef VarList, - SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc); + ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, + SourceLocation DepLoc, SourceLocation ColonLoc, + ArrayRef VarList, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc); /// Called on well-formed 'device' clause. OMPClause *ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *Device, SourceLocation StartLoc, diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 68bcb26b6df5..e6e9c8570cc8 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1019,6 +1019,9 @@ namespace serialization { /// The placeholder type for OpenMP array shaping operation. PREDEF_TYPE_OMP_ARRAY_SHAPING = 70, + /// The placeholder type for OpenMP iterator expression. + PREDEF_TYPE_OMP_ITERATOR = 71, + /// OpenCL image types with auto numeration #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ PREDEF_TYPE_##Id##_ID, @@ -1872,6 +1875,7 @@ namespace serialization { STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE, EXPR_OMP_ARRAY_SECTION, EXPR_OMP_ARRAY_SHAPING, + EXPR_OMP_ITERATOR, // ARC EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 8bee34e65754..1e81e0a67b4d 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1389,6 +1389,7 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target, if (LangOpts.OpenMP) { InitBuiltinType(OMPArraySectionTy, BuiltinType::OMPArraySection); InitBuiltinType(OMPArrayShapingTy, BuiltinType::OMPArrayShaping); + InitBuiltinType(OMPIteratorTy, BuiltinType::OMPIterator); } // C99 6.2.5p11. diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp index a023ed173184..3a326f62a2ec 100644 --- a/clang/lib/AST/ComputeDependence.cpp +++ b/clang/lib/AST/ComputeDependence.cpp @@ -372,6 +372,22 @@ ExprDependence clang::computeDependence(OMPArrayShapingExpr *E) { return D; } +ExprDependence clang::computeDependence(OMPIteratorExpr *E) { + auto D = toExprDependence(E->getType()->getDependence()); + for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) { + if (auto *VD = cast_or_null(E->getIteratorDecl(I))) + D |= toExprDependence(VD->getType()->getDependence()); + OMPIteratorExpr::IteratorRange IR = E->getIteratorRange(I); + if (Expr *BE = IR.Begin) + D |= BE->getDependence(); + if (Expr *EE = IR.End) + D |= EE->getDependence(); + if (Expr *SE = IR.Step) + D |= SE->getDependence(); + } + return D; +} + /// Compute the type-, value-, and instantiation-dependence of a /// declaration reference /// based on the declaration being referenced. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index fb63897d871f..53ec3b7a93db 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -3399,6 +3399,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, case ArraySubscriptExprClass: case OMPArraySectionExprClass: case OMPArrayShapingExprClass: + case OMPIteratorExprClass: case MemberExprClass: case ConditionalOperatorClass: case BinaryConditionalOperatorClass: @@ -4617,3 +4618,118 @@ OMPArrayShapingExpr *OMPArrayShapingExpr::CreateEmpty(const ASTContext &Context, alignof(OMPArrayShapingExpr)); return new (Mem) OMPArrayShapingExpr(EmptyShell(), NumDims); } + +void OMPIteratorExpr::setIteratorDeclaration(unsigned I, Decl *D) { + assert(I < NumIterators && + "Idx is greater or equal the number of iterators definitions."); + getTrailingObjects()[I] = D; +} + +void OMPIteratorExpr::setAssignmentLoc(unsigned I, SourceLocation Loc) { + assert(I < NumIterators && + "Idx is greater or equal the number of iterators definitions."); + getTrailingObjects< + SourceLocation>()[I * static_cast(RangeLocOffset::Total) + + static_cast(RangeLocOffset::AssignLoc)] = Loc; +} + +void OMPIteratorExpr::setIteratorRange(unsigned I, Expr *Begin, + SourceLocation ColonLoc, Expr *End, + SourceLocation SecondColonLoc, + Expr *Step) { + assert(I < NumIterators && + "Idx is greater or equal the number of iterators definitions."); + getTrailingObjects()[I * static_cast(RangeExprOffset::Total) + + static_cast(RangeExprOffset::Begin)] = + Begin; + getTrailingObjects()[I * static_cast(RangeExprOffset::Total) + + static_cast(RangeExprOffset::End)] = End; + getTrailingObjects()[I * static_cast(RangeExprOffset::Total) + + static_cast(RangeExprOffset::Step)] = Step; + getTrailingObjects< + SourceLocation>()[I * static_cast(RangeLocOffset::Total) + + static_cast(RangeLocOffset::FirstColonLoc)] = + ColonLoc; + getTrailingObjects< + SourceLocation>()[I * static_cast(RangeLocOffset::Total) + + static_cast(RangeLocOffset::SecondColonLoc)] = + SecondColonLoc; +} + +Decl *OMPIteratorExpr::getIteratorDecl(unsigned I) { + return getTrailingObjects()[I]; +} + +OMPIteratorExpr::IteratorRange OMPIteratorExpr::getIteratorRange(unsigned I) { + IteratorRange Res; + Res.Begin = + getTrailingObjects()[I * static_cast( + RangeExprOffset::Total) + + static_cast(RangeExprOffset::Begin)]; + Res.End = + getTrailingObjects()[I * static_cast( + RangeExprOffset::Total) + + static_cast(RangeExprOffset::End)]; + Res.Step = + getTrailingObjects()[I * static_cast( + RangeExprOffset::Total) + + static_cast(RangeExprOffset::Step)]; + return Res; +} + +SourceLocation OMPIteratorExpr::getAssignLoc(unsigned I) const { + return getTrailingObjects< + SourceLocation>()[I * static_cast(RangeLocOffset::Total) + + static_cast(RangeLocOffset::AssignLoc)]; +} + +SourceLocation OMPIteratorExpr::getColonLoc(unsigned I) const { + return getTrailingObjects< + SourceLocation>()[I * static_cast(RangeLocOffset::Total) + + static_cast(RangeLocOffset::FirstColonLoc)]; +} + +SourceLocation OMPIteratorExpr::getSecondColonLoc(unsigned I) const { + return getTrailingObjects< + SourceLocation>()[I * static_cast(RangeLocOffset::Total) + + static_cast(RangeLocOffset::SecondColonLoc)]; +} + +OMPIteratorExpr::OMPIteratorExpr( + QualType ExprTy, SourceLocation IteratorKwLoc, SourceLocation L, + SourceLocation R, ArrayRef Data) + : Expr(OMPIteratorExprClass, ExprTy, VK_LValue, OK_Ordinary), + IteratorKwLoc(IteratorKwLoc), LPLoc(L), RPLoc(R), + NumIterators(Data.size()) { + for (unsigned I = 0, End = Data.size(); I < End; ++I) { + const IteratorDefinition &D = Data[I]; + setIteratorDeclaration(I, D.IteratorDecl); + setIteratorRange(I, D.Range.Begin, D.ColonLoc, D.Range.End, + D.SecondColonLoc, D.Range.Step); + } + setDependence(computeDependence(this)); +} + +OMPIteratorExpr * +OMPIteratorExpr::Create(const ASTContext &Context, QualType T, + SourceLocation IteratorKwLoc, SourceLocation L, + SourceLocation R, + ArrayRef Data) { + void *Mem = Context.Allocate( + totalSizeToAlloc( + Data.size(), Data.size() * static_cast(RangeExprOffset::Total), + Data.size() * static_cast(RangeLocOffset::Total)), + alignof(OMPIteratorExpr)); + auto *E = new (Mem) OMPIteratorExpr(T, IteratorKwLoc, L, R, Data); + return E; +} + +OMPIteratorExpr *OMPIteratorExpr::CreateEmpty(const ASTContext &Context, + unsigned NumIterators) { + void *Mem = Context.Allocate( + totalSizeToAlloc( + NumIterators, NumIterators * static_cast(RangeExprOffset::Total), + NumIterators * static_cast(RangeLocOffset::Total)), + alignof(OMPIteratorExpr)); + return new (Mem) OMPIteratorExpr(EmptyShell(), NumIterators); +} diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 4505626bb61f..8587a476a5d9 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -141,6 +141,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::MSPropertySubscriptExprClass: case Expr::OMPArraySectionExprClass: case Expr::OMPArrayShapingExprClass: + case Expr::OMPIteratorExprClass: return Cl::CL_LValue; // C99 6.5.2.5p5 says that compound literals are lvalues. diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 4a11c846f4ab..c6e1cc7b67df 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -14181,6 +14181,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { case Expr::ArraySubscriptExprClass: case Expr::OMPArraySectionExprClass: case Expr::OMPArrayShapingExprClass: + case Expr::OMPIteratorExprClass: case Expr::MemberExprClass: case Expr::CompoundAssignOperatorClass: case Expr::CompoundLiteralExprClass: diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 4c05990ee410..cb7bd61574ef 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3715,6 +3715,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { case Expr::RecoveryExprClass: case Expr::OMPArraySectionExprClass: case Expr::OMPArrayShapingExprClass: + case Expr::OMPIteratorExprClass: case Expr::CXXInheritedCtorInitExprClass: llvm_unreachable("unexpected statement kind"); diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp index 2bfe977a5ba5..3bb3605ea936 100644 --- a/clang/lib/AST/NSAPI.cpp +++ b/clang/lib/AST/NSAPI.cpp @@ -484,6 +484,7 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const { case BuiltinType::BuiltinFn: case BuiltinType::OMPArraySection: case BuiltinType::OMPArrayShaping: + case BuiltinType::OMPIterator: break; } diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 4b7ebbb3c26d..eeb690750fb7 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -900,16 +900,19 @@ OMPDepobjClause *OMPDepobjClause::CreateEmpty(const ASTContext &C) { OMPDependClause * OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, - OpenMPDependClauseKind DepKind, SourceLocation DepLoc, - SourceLocation ColonLoc, ArrayRef VL, - unsigned NumLoops) { - void *Mem = C.Allocate(totalSizeToAlloc(VL.size() + NumLoops)); + Expr *DepModifier, OpenMPDependClauseKind DepKind, + SourceLocation DepLoc, SourceLocation ColonLoc, + ArrayRef VL, unsigned NumLoops) { + void *Mem = C.Allocate( + totalSizeToAlloc(VL.size() + /*depend-modifier*/ 1 + NumLoops), + alignof(OMPDependClause)); OMPDependClause *Clause = new (Mem) OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops); Clause->setVarRefs(VL); Clause->setDependencyKind(DepKind); Clause->setDependencyLoc(DepLoc); Clause->setColonLoc(ColonLoc); + Clause->setModifier(DepModifier); for (unsigned I = 0 ; I < NumLoops; ++I) Clause->setLoopData(I, nullptr); return Clause; @@ -917,7 +920,9 @@ OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc, OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N, unsigned NumLoops) { - void *Mem = C.Allocate(totalSizeToAlloc(N + NumLoops)); + void *Mem = + C.Allocate(totalSizeToAlloc(N + /*depend-modifier*/ 1 + NumLoops), + alignof(OMPDependClause)); return new (Mem) OMPDependClause(N, NumLoops); } @@ -927,7 +932,7 @@ void OMPDependClause::setLoopData(unsigned NumLoop, Expr *Cnt) { NumLoop < NumLoops && "Expected sink or source depend + loop index must be less number of " "loops."); - auto It = std::next(getVarRefs().end(), NumLoop); + auto *It = std::next(getVarRefs().end(), NumLoop + 1); *It = Cnt; } @@ -937,7 +942,7 @@ Expr *OMPDependClause::getLoopData(unsigned NumLoop) { NumLoop < NumLoops && "Expected sink or source depend + loop index must be less number of " "loops."); - auto It = std::next(getVarRefs().end(), NumLoop); + auto *It = std::next(getVarRefs().end(), NumLoop + 1); return *It; } @@ -947,10 +952,15 @@ const Expr *OMPDependClause::getLoopData(unsigned NumLoop) const { NumLoop < NumLoops && "Expected sink or source depend + loop index must be less number of " "loops."); - auto It = std::next(getVarRefs().end(), NumLoop); + const auto *It = std::next(getVarRefs().end(), NumLoop + 1); return *It; } +void OMPDependClause::setModifier(Expr *DepModifier) { + *getVarRefs().end() = DepModifier; +} +Expr *OMPDependClause::getModifier() { return *getVarRefs().end(); } + unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber( MappableExprComponentListsRef ComponentLists) { unsigned TotalNum = 0u; @@ -1727,6 +1737,10 @@ void OMPClausePrinter::VisitOMPDepobjClause(OMPDepobjClause *Node) { void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) { OS << "depend("; + if (Expr *DepModifier = Node->getModifier()) { + DepModifier->printPretty(OS, nullptr, Policy); + OS << ", "; + } OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Node->getDependencyKind()); if (!Node->varlist_empty()) { diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 3d03f3902d61..26e1a5009565 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1361,6 +1361,24 @@ void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) { PrintExpr(Node->getBase()); } +void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) { + OS << "iterator("; + for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) { + auto *VD = cast(Node->getIteratorDecl(I)); + VD->getType().print(OS, Policy); + const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I); + OS << " " << VD->getName() << " = "; + PrintExpr(Range.Begin); + OS << ":"; + PrintExpr(Range.End); + if (Node->getSecondColonLoc(I).isValid()) + PrintExpr(Range.Step); + if (I < E - 1) + OS << ", "; + } + OS << ")"; +} + void StmtPrinter::PrintCallArgs(CallExpr *Call) { for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { if (isa(Call->getArg(i))) { diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 054276a98424..fec12ac98b4e 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -1198,6 +1198,12 @@ void StmtProfiler::VisitOMPArrayShapingExpr(const OMPArrayShapingExpr *S) { VisitExpr(S); } +void StmtProfiler::VisitOMPIteratorExpr(const OMPIteratorExpr *S) { + VisitExpr(S); + for (unsigned I = 0, E = S->numOfIterators(); I < E; ++I) + VisitDecl(S->getIteratorDecl(I)); +} + void StmtProfiler::VisitCallExpr(const CallExpr *S) { VisitExpr(S); } diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 6a6d8692228a..dc0dd92f09df 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1086,6 +1086,23 @@ void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) { OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); } +void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) { + OS << " "; + for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) { + Visit(Node->getIteratorDecl(I)); + OS << " = "; + const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I); + OS << " begin "; + Visit(Range.Begin); + OS << " end "; + Visit(Range.End); + if (Range.Step) { + OS << " step "; + Visit(Range.Step); + } + } +} + void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) { if (T->isSpelledAsLValue()) OS << " written as lvalue reference"; diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index f90eb5cb9c92..3428437c3146 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2910,6 +2910,8 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { return ""; case OMPArrayShaping: return ""; + case OMPIterator: + return ""; #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ case Id: \ return #ExtType; @@ -3917,6 +3919,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const { case BuiltinType::NullPtr: case BuiltinType::OMPArraySection: case BuiltinType::OMPArrayShaping: + case BuiltinType::OMPIterator: return false; } llvm_unreachable("unknown builtin type"); diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index dd48ae3fc262..50391dba2a05 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -405,6 +405,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const { case BuiltinType::BuiltinFn: case BuiltinType::OMPArraySection: case BuiltinType::OMPArrayShaping: + case BuiltinType::OMPIterator: return TST_unspecified; } diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 147d1b271d0c..42083b8b921e 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -755,7 +755,8 @@ static bool parseDeclareSimdClauses( getOpenMPClauseKind(ClauseName), *Vars, Data)) IsError = true; if (CKind == OMPC_aligned) { - Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr); + Alignments.append(Aligneds.size() - Alignments.size(), + Data.DepModOrTailExpr); } else if (CKind == OMPC_linear) { assert(0 <= Data.ExtraModifier && Data.ExtraModifier <= OMPC_LINEAR_unknown && @@ -766,7 +767,7 @@ static bool parseDeclareSimdClauses( Data.ExtraModifier = OMPC_LINEAR_val; LinModifiers.append(Linears.size() - LinModifiers.size(), Data.ExtraModifier); - Steps.append(Linears.size() - Steps.size(), Data.TailExpr); + Steps.append(Linears.size() - Steps.size(), Data.DepModOrTailExpr); } } else // TODO: add parsing of other clauses. @@ -3054,6 +3055,114 @@ static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) { P.ConsumeToken(); } +/// Parses simple expression in parens for single-expression clauses of OpenMP +/// constructs. +/// \param RLoc Returned location of right paren. +ExprResult Parser::ParseOpenMPIteratorsExpr() { + assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator" && + "Expected 'iterator' token."); + SourceLocation IteratorKwLoc = ConsumeToken(); + + BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); + if (T.expectAndConsume(diag::err_expected_lparen_after, "iterator")) + return ExprError(); + + SourceLocation LLoc = T.getOpenLocation(); + SmallVector Data; + while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) { + // Check if the type parsing is required. + ParsedType IteratorType; + if (Tok.isNot(tok::identifier) || NextToken().isNot(tok::equal)) { + // identifier '=' is not found - parse type. + TypeResult TR = ParseTypeName(); + if (TR.isInvalid()) { + T.skipToEnd(); + return ExprError(); + } + IteratorType = TR.get(); + } + + // Parse identifier. + IdentifierInfo *II = nullptr; + SourceLocation IdLoc; + if (Tok.is(tok::identifier)) { + II = Tok.getIdentifierInfo(); + IdLoc = ConsumeToken(); + } else { + Diag(Tok, diag::err_expected_unqualified_id) << 0; + } + + // Parse '='. + SourceLocation AssignLoc; + if (Tok.is(tok::equal)) + AssignLoc = ConsumeToken(); + else + Diag(Tok, diag::err_omp_expected_equal_in_iterator); + + // Parse range-specification - ':' [ ':' ] + ColonProtectionRAIIObject ColonRAII(*this); + // Parse + SourceLocation Loc = Tok.getLocation(); + ExprResult LHS = ParseCastExpression(AnyCastExpr); + ExprResult Begin = Actions.CorrectDelayedTyposInExpr( + ParseRHSOfBinaryExpression(LHS, prec::Conditional)); + Begin = Actions.ActOnFinishFullExpr(Begin.get(), Loc, + /*DiscardedValue=*/false); + // Parse ':'. + SourceLocation ColonLoc; + if (Tok.is(tok::colon)) + ColonLoc = ConsumeToken(); + + // Parse + Loc = Tok.getLocation(); + LHS = ParseCastExpression(AnyCastExpr); + ExprResult End = Actions.CorrectDelayedTyposInExpr( + ParseRHSOfBinaryExpression(LHS, prec::Conditional)); + End = Actions.ActOnFinishFullExpr(End.get(), Loc, + /*DiscardedValue=*/false); + + SourceLocation SecColonLoc; + ExprResult Step; + // Parse optional step. + if (Tok.is(tok::colon)) { + // Parse ':' + ColonLoc = ConsumeToken(); + // Parse + Loc = Tok.getLocation(); + LHS = ParseCastExpression(AnyCastExpr); + Step = Actions.CorrectDelayedTyposInExpr( + ParseRHSOfBinaryExpression(LHS, prec::Conditional)); + Step = Actions.ActOnFinishFullExpr(Step.get(), Loc, + /*DiscardedValue=*/false); + } + + // Parse ',' or ')' + if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren)) + Diag(Tok, diag::err_omp_expected_punc_after_iterator); + if (Tok.is(tok::comma)) + ConsumeToken(); + + Sema::OMPIteratorData &D = Data.emplace_back(); + D.DeclIdent = II; + D.DeclIdentLoc = IdLoc; + D.Type = IteratorType; + D.AssignLoc = AssignLoc; + D.ColonLoc = ColonLoc; + D.SecColonLoc = SecColonLoc; + D.Range.Begin = Begin.get(); + D.Range.End = End.get(); + D.Range.Step = Step.get(); + } + + // Parse ')'. + SourceLocation RLoc = Tok.getLocation(); + if (!T.consumeClose()) + RLoc = T.getCloseLocation(); + + return Actions.ActOnOMPIteratorExpr(getCurScope(), IteratorKwLoc, LLoc, RLoc, + Data); +} + /// Parses clauses with list. bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, @@ -3069,6 +3178,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, getOpenMPClauseName(Kind))) return true; + bool DependWithIterator = false; bool NeedRParenForLinear = false; BalancedDelimiterTracker LinearT(*this, tok::l_paren, tok::annot_pragma_openmp_end); @@ -3106,6 +3216,22 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Data.ReductionOrMapperId = Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId); } else if (Kind == OMPC_depend) { + if (getLangOpts().OpenMP >= 50) { + if (Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator") { + // Handle optional dependence modifier. + // iterator(iterators-definition) + // where iterators-definition is iterator-specifier [, + // iterators-definition ] + // where iterator-specifier is [ iterator-type ] identifier = + // range-specification + DependWithIterator = true; + EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope); + ExprResult IteratorRes = ParseOpenMPIteratorsExpr(); + Data.DepModOrTailExpr = IteratorRes.get(); + // Parse ',' + ExpectAndConsume(tok::comma); + } + } // Handle dependency type for depend clause. ColonProtectionRAIIObject ColonRAII(*this); Data.ExtraModifier = getOpenMPSimpleClauseType( @@ -3227,7 +3353,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, /*DiscardedValue=*/false); if (Tail.isUsable()) { if (Tok.is(tok::colon)) { - Data.TailExpr = Tail.get(); + Data.DepModOrTailExpr = Tail.get(); Data.ColonLoc = ConsumeToken(); TPA.Commit(); } else { @@ -3253,6 +3379,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned); while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) && Tok.isNot(tok::annot_pragma_openmp_end))) { + ParseScope OMPListScope(this, Scope::OpenMPDirectiveScope); ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail); // Parse variable ExprResult VarExpr = @@ -3289,7 +3416,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false); if (Tail.isUsable()) - Data.TailExpr = Tail.get(); + Data.DepModOrTailExpr = Tail.get(); else SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); @@ -3299,8 +3426,11 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Data.RLoc = Tok.getLocation(); if (!T.consumeClose()) Data.RLoc = T.getCloseLocation(); + // Exit from scope when the iterator is used in depend clause. + if (DependWithIterator) + ExitScope(); return (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) || - (MustHaveTail && !Data.TailExpr) || InvalidReductionId || + (MustHaveTail && !Data.DepModOrTailExpr) || InvalidReductionId || IsInvalidMapperModifier; } @@ -3372,7 +3502,7 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, return nullptr; OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc); return Actions.ActOnOpenMPVarListClause( - Kind, Vars, Data.TailExpr, Locs, Data.ColonLoc, + Kind, Vars, Data.DepModOrTailExpr, Locs, Data.ColonLoc, Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, Data.ExtraModifier, Data.MapTypeModifiers, Data.MapTypeModifiersLoc, Data.IsMapTypeImplicit, Data.ExtraModifierLoc); diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index fad2ae1cc066..0dc0c68205fb 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1300,6 +1300,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Expr::ArraySubscriptExprClass: case Expr::OMPArraySectionExprClass: case Expr::OMPArrayShapingExprClass: + case Expr::OMPIteratorExprClass: case Expr::BinaryOperatorClass: case Expr::DependentCoawaitExprClass: case Expr::CompoundAssignOperatorClass: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c0f8600aa0cc..8d0e97c85771 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4873,6 +4873,131 @@ ExprResult Sema::ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, LParenLoc, RParenLoc, NewDims, Brackets); } +ExprResult Sema::ActOnOMPIteratorExpr(Scope *S, SourceLocation IteratorKwLoc, + SourceLocation LLoc, SourceLocation RLoc, + ArrayRef Data) { + SmallVector ID; + bool IsCorrect = true; + for (const OMPIteratorData &D : Data) { + TypeSourceInfo *TInfo = nullptr; + SourceLocation StartLoc; + QualType DeclTy; + if (!D.Type.getAsOpaquePtr()) { + // OpenMP 5.0, 2.1.6 Iterators + // In an iterator-specifier, if the iterator-type is not specified then + // the type of that iterator is of int type. + DeclTy = Context.IntTy; + StartLoc = D.DeclIdentLoc; + } else { + DeclTy = GetTypeFromParser(D.Type, &TInfo); + StartLoc = TInfo->getTypeLoc().getBeginLoc(); + } + + bool IsDeclTyDependent = DeclTy->isDependentType() || + DeclTy->containsUnexpandedParameterPack() || + DeclTy->isInstantiationDependentType(); + if (!IsDeclTyDependent) { + if (!DeclTy->isIntegralType(Context) && !DeclTy->isAnyPointerType()) { + // OpenMP 5.0, 2.1.6 Iterators, Restrictions, C/C++ + // The iterator-type must be an integral or pointer type. + Diag(StartLoc, diag::err_omp_iterator_not_integral_or_pointer) + << DeclTy; + IsCorrect = false; + continue; + } + if (DeclTy.isConstant(Context)) { + // OpenMP 5.0, 2.1.6 Iterators, Restrictions, C/C++ + // The iterator-type must not be const qualified. + Diag(StartLoc, diag::err_omp_iterator_not_integral_or_pointer) + << DeclTy; + IsCorrect = false; + continue; + } + } + + // Iterator declaration. + assert(D.DeclIdent && "Identifier expected."); + // Always try to create iterator declarator to avoid extra error messages + // about unknown declarations use. + auto *VD = VarDecl::Create(Context, CurContext, StartLoc, D.DeclIdentLoc, + D.DeclIdent, DeclTy, TInfo, SC_None); + VD->setImplicit(); + if (S) { + // Check for conflicting previous declaration. + DeclarationNameInfo NameInfo(VD->getDeclName(), D.DeclIdentLoc); + LookupResult Previous(*this, NameInfo, LookupOrdinaryName, + ForVisibleRedeclaration); + Previous.suppressDiagnostics(); + LookupName(Previous, S); + + FilterLookupForScope(Previous, CurContext, S, /*ConsiderLinkage=*/false, + /*AllowInlineNamespace=*/false); + if (!Previous.empty()) { + NamedDecl *Old = Previous.getRepresentativeDecl(); + Diag(D.DeclIdentLoc, diag::err_redefinition) << VD->getDeclName(); + Diag(Old->getLocation(), diag::note_previous_definition); + } else { + PushOnScopeChains(VD, S); + } + } else { + CurContext->addDecl(VD); + } + Expr *Begin = D.Range.Begin; + if (!IsDeclTyDependent && Begin && !Begin->isTypeDependent()) { + ExprResult BeginRes = + PerformImplicitConversion(Begin, DeclTy, AA_Converting); + Begin = BeginRes.get(); + } + Expr *End = D.Range.End; + if (!IsDeclTyDependent && End && !End->isTypeDependent()) { + ExprResult EndRes = PerformImplicitConversion(End, DeclTy, AA_Converting); + End = EndRes.get(); + } + Expr *Step = D.Range.Step; + if (!IsDeclTyDependent && Step && !Step->isTypeDependent()) { + if (!Step->getType()->isIntegralType(Context)) { + Diag(Step->getExprLoc(), diag::err_omp_iterator_step_not_integral) + << Step << Step->getSourceRange(); + IsCorrect = false; + continue; + } + llvm::APSInt Result; + bool IsConstant = Step->isIntegerConstantExpr(Result, Context); + // OpenMP 5.0, 2.1.6 Iterators, Restrictions + // If the step expression of a range-specification equals zero, the + // behavior is unspecified. + if (IsConstant && Result.isNullValue()) { + Diag(Step->getExprLoc(), diag::err_omp_iterator_step_constant_zero) + << Step << Step->getSourceRange(); + IsCorrect = false; + continue; + } + } + if (!Begin || !End || !IsCorrect) { + IsCorrect = false; + continue; + } + OMPIteratorExpr::IteratorDefinition &IDElem = ID.emplace_back(); + IDElem.IteratorDecl = VD; + IDElem.AssignmentLoc = D.AssignLoc; + IDElem.Range.Begin = Begin; + IDElem.Range.End = End; + IDElem.Range.Step = Step; + IDElem.ColonLoc = D.ColonLoc; + IDElem.SecondColonLoc = D.SecColonLoc; + } + if (!IsCorrect) { + // Invalidate all created iterator declarations if error is found. + for (const OMPIteratorExpr::IteratorDefinition &D : ID) { + if (Decl *ID = D.IteratorDecl) + ID->setInvalidDecl(); + } + return ExprError(); + } + return OMPIteratorExpr::Create(Context, Context.OMPIteratorTy, IteratorKwLoc, + LLoc, RLoc, ID); +} + ExprResult Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc) { @@ -5634,6 +5759,7 @@ static bool isPlaceholderToRemoveAsArg(QualType type) { case BuiltinType::BuiltinFn: case BuiltinType::OMPArraySection: case BuiltinType::OMPArrayShaping: + case BuiltinType::OMPIterator: return true; } @@ -18513,6 +18639,9 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { case BuiltinType::OMPArrayShaping: return ExprError(Diag(E->getBeginLoc(), diag::err_omp_array_shaping_use)); + case BuiltinType::OMPIterator: + return ExprError(Diag(E->getBeginLoc(), diag::err_omp_iterator_use)); + // Everything else should be impossible. #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ case BuiltinType::Id: diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 7d2ae172fe4d..df56c3be43fc 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -13053,7 +13053,7 @@ OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, } OMPClause *Sema::ActOnOpenMPVarListClause( - OpenMPClauseKind Kind, ArrayRef VarList, Expr *TailExpr, + OpenMPClauseKind Kind, ArrayRef VarList, Expr *DepModOrTailExpr, const OMPVarListLocTy &Locs, SourceLocation ColonLoc, CXXScopeSpec &ReductionOrMapperIdScopeSpec, DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, @@ -13103,13 +13103,13 @@ OMPClause *Sema::ActOnOpenMPVarListClause( assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && "Unexpected linear modifier."); Res = ActOnOpenMPLinearClause( - VarList, TailExpr, StartLoc, LParenLoc, + VarList, DepModOrTailExpr, StartLoc, LParenLoc, static_cast(ExtraModifier), ExtraModifierLoc, ColonLoc, EndLoc); break; case OMPC_aligned: - Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, - ColonLoc, EndLoc); + Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, + LParenLoc, ColonLoc, EndLoc); break; case OMPC_copyin: Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); @@ -13124,8 +13124,8 @@ OMPClause *Sema::ActOnOpenMPVarListClause( assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && "Unexpected depend modifier."); Res = ActOnOpenMPDependClause( - static_cast(ExtraModifier), ExtraModifierLoc, - ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); + DepModOrTailExpr, static_cast(ExtraModifier), + ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); break; case OMPC_map: assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && @@ -13150,8 +13150,8 @@ OMPClause *Sema::ActOnOpenMPVarListClause( Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); break; case OMPC_allocate: - Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, - ColonLoc, EndLoc); + Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, + LParenLoc, ColonLoc, EndLoc); break; case OMPC_nontemporal: Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); @@ -15642,7 +15642,7 @@ OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, } OMPClause * -Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, +Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { @@ -15664,12 +15664,26 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, Except.push_back(OMPC_DEPEND_sink); if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) Except.push_back(OMPC_DEPEND_depobj); + std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) + ? "depend modifier(iterator) or " + : ""; Diag(DepLoc, diag::err_omp_unexpected_clause_value) - << getListOfPossibleValues(OMPC_depend, /*First=*/0, - /*Last=*/OMPC_DEPEND_unknown, Except) + << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, + /*Last=*/OMPC_DEPEND_unknown, + Except) << getOpenMPClauseName(OMPC_depend); return nullptr; } + if (DepModifier && + (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { + Diag(DepModifier->getExprLoc(), + diag::err_omp_depend_sink_source_with_modifier); + return nullptr; + } + if (DepModifier && + !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) + Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); + SmallVector Vars; DSAStackTy::OperatorOffsetTy OpsOffs; llvm::APSInt DepCounter(/*BitWidth=*/32); @@ -15878,8 +15892,8 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, return nullptr; auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, - DepKind, DepLoc, ColonLoc, Vars, - TotalDepCount.getZExtValue()); + DepModifier, DepKind, DepLoc, ColonLoc, + Vars, TotalDepCount.getZExtValue()); if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && DSAStack->isParentOrderedRegion()) DSAStack->addDoacrossDependClause(C, OpsOffs); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 82cfa246e3f7..de05d436d3b9 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1842,12 +1842,13 @@ class TreeTransform { /// By default, performs semantic analysis to build the new OpenMP clause. /// Subclasses may override this routine to provide diff erent behavior. OMPClause * - RebuildOMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, - SourceLocation ColonLoc, ArrayRef VarList, - SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPDependClause(DepKind, DepLoc, ColonLoc, VarList, - StartLoc, LParenLoc, EndLoc); + RebuildOMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, + SourceLocation DepLoc, SourceLocation ColonLoc, + ArrayRef VarList, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc) { + return getSema().ActOnOpenMPDependClause(DepModifier, DepKind, DepLoc, + ColonLoc, VarList, StartLoc, + LParenLoc, EndLoc); } /// Build a new OpenMP 'device' clause. @@ -2391,6 +2392,17 @@ class TreeTransform { BracketsRanges); } + /// Build a new iterator expression. + /// + /// By default, performs semantic analysis to build the new expression. + /// Subclasses may override this routine to provide diff erent behavior. + ExprResult RebuildOMPIteratorExpr( + SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc, + ArrayRef Data) { + return getSema().ActOnOMPIteratorExpr(/*Scope=*/nullptr, IteratorKwLoc, + LLoc, RLoc, Data); + } + /// Build a new call expression. /// /// By default, performs semantic analysis to build the new expression. @@ -9291,6 +9303,13 @@ template OMPClause * TreeTransform::TransformOMPDependClause(OMPDependClause *C) { llvm::SmallVector Vars; + Expr *DepModifier = C->getModifier(); + if (DepModifier) { + ExprResult DepModRes = getDerived().TransformExpr(DepModifier); + if (DepModRes.isInvalid()) + return nullptr; + DepModifier = DepModRes.get(); + } Vars.reserve(C->varlist_size()); for (auto *VE : C->varlists()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); @@ -9299,8 +9318,9 @@ TreeTransform::TransformOMPDependClause(OMPDependClause *C) { Vars.push_back(EVar.get()); } return getDerived().RebuildOMPDependClause( - C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(), Vars, - C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); + DepModifier, C->getDependencyKind(), C->getDependencyLoc(), + C->getColonLoc(), Vars, C->getBeginLoc(), C->getLParenLoc(), + C->getEndLoc()); } template @@ -10054,6 +10074,65 @@ TreeTransform::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) { E->getBracketsRanges()); } +template +ExprResult +TreeTransform::TransformOMPIteratorExpr(OMPIteratorExpr *E) { + unsigned NumIterators = E->numOfIterators(); + SmallVector Data(NumIterators); + + bool ErrorFound = false; + bool NeedToRebuild = getDerived().AlwaysRebuild(); + for (unsigned I = 0; I < NumIterators; ++I) { + auto *D = cast(E->getIteratorDecl(I)); + Data[I].DeclIdent = D->getIdentifier(); + Data[I].DeclIdentLoc = D->getLocation(); + if (D->getLocation() == D->getBeginLoc()) { + assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) && + "Implicit type must be int."); + } else { + TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo()); + QualType DeclTy = getDerived().TransformType(D->getType()); + Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI); + } + OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I); + ExprResult Begin = getDerived().TransformExpr(Range.Begin); + ExprResult End = getDerived().TransformExpr(Range.End); + ExprResult Step = getDerived().TransformExpr(Range.Step); + ErrorFound = ErrorFound || + !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() && + !Data[I].Type.get().isNull())) || + Begin.isInvalid() || End.isInvalid() || Step.isInvalid(); + if (ErrorFound) + continue; + Data[I].Range.Begin = Begin.get(); + Data[I].Range.End = End.get(); + Data[I].Range.Step = Step.get(); + Data[I].AssignLoc = E->getAssignLoc(I); + Data[I].ColonLoc = E->getColonLoc(I); + Data[I].SecColonLoc = E->getSecondColonLoc(I); + NeedToRebuild = + NeedToRebuild || + (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() != + D->getType().getTypePtrOrNull()) || + Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End || + Range.Step != Data[I].Range.Step; + } + if (ErrorFound) + return ExprError(); + if (!NeedToRebuild) + return E; + + ExprResult Res = getDerived().RebuildOMPIteratorExpr( + E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data); + if (!Res.isUsable()) + return Res; + auto *IE = cast(Res.get()); + for (unsigned I = 0; I < NumIterators; ++I) + getDerived().transformedLocalDecl(E->getIteratorDecl(I), + IE->getIteratorDecl(I)); + return Res; +} + template ExprResult TreeTransform::TransformCallExpr(CallExpr *E) { diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp index 158a12f0329d..566bda2d71f7 100644 --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -246,6 +246,9 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) { case BuiltinType::OMPArrayShaping: ID = PREDEF_TYPE_OMP_ARRAY_SHAPING; break; + case BuiltinType::OMPIterator: + ID = PREDEF_TYPE_OMP_ITERATOR; + break; } return TypeIdx(ID); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 7437f649a090..d4764229abfc 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -6960,6 +6960,9 @@ QualType ASTReader::GetType(TypeID ID) { case PREDEF_TYPE_OMP_ARRAY_SHAPING: T = Context.OMPArraySectionTy; break; + case PREDEF_TYPE_OMP_ITERATOR: + T = Context.OMPIteratorTy; + break; #define SVE_TYPE(Name, Id, SingletonId) \ case PREDEF_TYPE_##Id##_ID: \ T = Context.SingletonId; \ @@ -12307,6 +12310,7 @@ void OMPClauseReader::VisitOMPDepobjClause(OMPDepobjClause *C) { void OMPClauseReader::VisitOMPDependClause(OMPDependClause *C) { C->setLParenLoc(Record.readSourceLocation()); + C->setModifier(Record.readSubExpr()); C->setDependencyKind( static_cast(Record.readInt())); C->setDependencyLoc(Record.readSourceLocation()); diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index bc8c231731e8..d5f2213aaabe 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -927,6 +927,24 @@ void ASTStmtReader::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { E->setRParenLoc(readSourceLocation()); } +void ASTStmtReader::VisitOMPIteratorExpr(OMPIteratorExpr *E) { + VisitExpr(E); + unsigned NumIterators = Record.readInt(); + E->setIteratorKwLoc(readSourceLocation()); + E->setLParenLoc(readSourceLocation()); + E->setRParenLoc(readSourceLocation()); + for (unsigned I = 0; I < NumIterators; ++I) { + E->setIteratorDeclaration(I, Record.readDeclRef()); + E->setAssignmentLoc(I, readSourceLocation()); + Expr *Begin = Record.readSubExpr(); + Expr *End = Record.readSubExpr(); + Expr *Step = Record.readSubExpr(); + SourceLocation ColonLoc = readSourceLocation(); + SourceLocation SecColonLoc = readSourceLocation(); + E->setIteratorRange(I, Begin, ColonLoc, End, SecColonLoc, Step); + } +} + void ASTStmtReader::VisitCallExpr(CallExpr *E) { VisitExpr(E); unsigned NumArgs = Record.readInt(); @@ -2887,6 +2905,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Context, Record[ASTStmtReader::NumExprFields]); break; + case EXPR_OMP_ITERATOR: + S = OMPIteratorExpr::CreateEmpty(Context, + Record[ASTStmtReader::NumExprFields]); + break; + case EXPR_CALL: S = CallExpr::CreateEmpty( Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index f7c58ed11d9f..27f44a706f9f 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6379,6 +6379,7 @@ void OMPClauseWriter::VisitOMPDependClause(OMPDependClause *C) { Record.push_back(C->varlist_size()); Record.push_back(C->getNumLoops()); Record.AddSourceLocation(C->getLParenLoc()); + Record.AddStmt(C->getModifier()); Record.push_back(C->getDependencyKind()); Record.AddSourceLocation(C->getDependencyLoc()); Record.AddSourceLocation(C->getColonLoc()); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 840823298be7..5a56b265b781 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -787,6 +787,25 @@ void ASTStmtWriter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { Code = serialization::EXPR_OMP_ARRAY_SHAPING; } +void ASTStmtWriter::VisitOMPIteratorExpr(OMPIteratorExpr *E) { + VisitExpr(E); + Record.push_back(E->numOfIterators()); + Record.AddSourceLocation(E->getIteratorKwLoc()); + Record.AddSourceLocation(E->getLParenLoc()); + Record.AddSourceLocation(E->getRParenLoc()); + for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) { + Record.AddDeclRef(E->getIteratorDecl(I)); + Record.AddSourceLocation(E->getAssignLoc(I)); + OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I); + Record.AddStmt(Range.Begin); + Record.AddStmt(Range.End); + Record.AddStmt(Range.Step); + Record.AddSourceLocation(E->getColonLoc(I)); + Record.AddSourceLocation(E->getSecondColonLoc(I)); + } + Code = serialization::EXPR_OMP_ITERATOR; +} + void ASTStmtWriter::VisitCallExpr(CallExpr *E) { VisitExpr(E); Record.push_back(E->getNumArgs()); diff --git a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp index d16410a19b97..1cf81b54e77d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp @@ -352,6 +352,7 @@ static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1, case Stmt::ArraySubscriptExprClass: case Stmt::OMPArraySectionExprClass: case Stmt::OMPArrayShapingExprClass: + case Stmt::OMPIteratorExprClass: case Stmt::ImplicitCastExprClass: case Stmt::ParenExprClass: case Stmt::BreakStmtClass: diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 4c0914628a0d..1f0d89d59120 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1414,6 +1414,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::CXXNullPtrLiteralExprClass: case Stmt::OMPArraySectionExprClass: case Stmt::OMPArrayShapingExprClass: + case Stmt::OMPIteratorExprClass: case Stmt::TypeTraitExprClass: { Bldr.takeNodes(Pred); ExplodedNodeSet preVisit; diff --git a/clang/test/OpenMP/depobj_messages.cpp b/clang/test/OpenMP/depobj_messages.cpp index a33b16f985a0..1b20b1c525e7 100644 --- a/clang/test/OpenMP/depobj_messages.cpp +++ b/clang/test/OpenMP/depobj_messages.cpp @@ -142,7 +142,7 @@ label1 : { #pragma omp parallel depobj(argc) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}} ; #pragma omp depobj(x) seq_cst // expected-error {{unexpected OpenMP clause 'seq_cst' in directive '#pragma omp depobj'}} -#pragma omp depobj(x) depend(source: x) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp depobj(x) depend(source: x) // expected-error {{expected depend modifier(iterator) or 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} #pragma omp depobj(x) update // expected-error {{expected '(' after 'update'}} #pragma omp depobj(x) update( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'update'}} #pragma omp depobj(x) update(sink // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'update'}} diff --git a/clang/test/OpenMP/task_ast_print.cpp b/clang/test/OpenMP/task_ast_print.cpp index 1da6c5045934..c465a1b1b07f 100644 --- a/clang/test/OpenMP/task_ast_print.cpp +++ b/clang/test/OpenMP/task_ast_print.cpp @@ -26,7 +26,7 @@ struct S1 { template class S7 : public T { protected: - T a, b; + T a, b, c[10], d[10]; S7() : a(0) {} public: @@ -34,7 +34,7 @@ class S7 : public T { omp_depend_t x; omp_event_handle_t evt; #pragma omp taskgroup allocate(b) task_reduction(+:b) -#pragma omp task private(a) private(this->a) private(T::a) in_reduction(+:this->b) allocate(b) depend(depobj:x) detach(evt) +#pragma omp task private(a) private(this->a) private(T::a) in_reduction(+:this->b) allocate(b) depend(depobj:x) detach(evt) depend(iterator(i=0:10:1, T *k = &a:&b), in: c[i], d[(int)(k-&a)]) for (int k = 0; k < a.a; ++k) ++this->a.a; } @@ -47,9 +47,9 @@ class S7 : public T { }; // CHECK: #pragma omp taskgroup allocate(this->b) task_reduction(+: this->b) -// CHECK: #pragma omp task private(this->a) private(this->a) private(T::a) in_reduction(+: this->b) allocate(this->b) depend(depobj : x) detach(evt){{$}} +// CHECK: #pragma omp task private(this->a) private(this->a) private(T::a) in_reduction(+: this->b) allocate(this->b) depend(depobj : x) detach(evt) depend(iterator(int i = 0:10, T * k = &this->a:&this->b), in : this->c[i],this->d[(int)(k - &this->a)]){{$}} // CHECK: #pragma omp task private(this->a) private(this->a) -// CHECK: #pragma omp task private(this->a) private(this->a) private(this->S1::a) +// CHECK: #pragma omp task private(this->a) private(this->a) private(this->S1::a) in_reduction(+: this->b) allocate(this->b) depend(depobj : x) detach(evt) depend(iterator(int i = 0:10, S1 * k = &this->a:&this->b), in : this->c[i],this->d[(int)(k - &this->a)]) class S8 : public S7 { S8() {} @@ -176,10 +176,10 @@ int main(int argc, char **argv) { // CHECK-NEXT: foo(); #pragma omp taskgroup task_reduction(min: arr1) #pragma omp parallel reduction(+:arr1) -#pragma omp task in_reduction(min: arr1) +#pragma omp task in_reduction(min: arr1) depend(iterator(i=0:argc, unsigned j=argc:0:a), out: argv[i][j]) // CHECK-NEXT: #pragma omp taskgroup task_reduction(min: arr1) // CHECK-NEXT: #pragma omp parallel reduction(+: arr1) - // CHECK-NEXT: #pragma omp task in_reduction(min: arr1) + // CHECK-NEXT: #pragma omp task in_reduction(min: arr1) depend(iterator(int i = 0:argc, unsigned int j = argc:0), out : argv[i][j]) foo(); // CHECK-NEXT: foo(); // CHECK-NEXT: #pragma omp task in_reduction(+: arr1) diff --git a/clang/test/OpenMP/task_depend_messages.cpp b/clang/test/OpenMP/task_depend_messages.cpp index f04c167cbdcc..bfb0e771b2ca 100644 --- a/clang/test/OpenMP/task_depend_messages.cpp +++ b/clang/test/OpenMP/task_depend_messages.cpp @@ -28,11 +28,11 @@ int main(int argc, char **argv, char *env[]) { #pragma omp task depend(in : arr[0]) #pragma omp task depend // expected-error {{expected '(' after 'depend'}} - #pragma omp task depend ( // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} - #pragma omp task depend () // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} - #pragma omp task depend (argc // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} - #pragma omp task depend (source : argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} - #pragma omp task depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend ( // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend () // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend (argc // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend (source : argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} #pragma omp task depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}} #pragma omp task depend (out: ) // expected-error {{expected expression}} #pragma omp task depend (inout : foobool(argc)), depend (in, argc) // omp50-error {{expected addressable lvalue expression, array element, array section or array shaping expression}} omp45-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} @@ -70,7 +70,19 @@ int main(int argc, char **argv, char *env[]) { #pragma omp task depend(in : ([a])a) // omp45-error {{expected body of lambda expression}} omp50-error {{expected expression with a pointer to a complete type as a base of an array shaping operation}} #pragma omp task depend(in : ([a])argc) // omp45-error {{expected body of lambda expression}} omp50-error {{expected expression with a pointer to a complete type as a base of an array shaping operation}} #pragma omp task depend(in : ([-1][0])argv) // omp45-error {{expected variable name or 'this' in lambda capture list}} omp45-error {{expected ')'}} omp45-note {{to match this '('}} omp50-error {{array shaping dimension is evaluated to a non-positive value -1}} omp50-error {{array shaping dimension is evaluated to a non-positive value 0}} + #pragma omp task depend(iterator // expected-error {{expected ')'}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-note {{to match this '('}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} omp50-error {{expected '(' after 'iterator'}} omp50-error {{expected ','}} + #pragma omp task depend(iterator():argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected ','}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend(iterator(argc // expected-error {{expected ')'}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-note {{to match this '('}} omp50-error {{unknown type name 'argc'}} omp50-error {{expected ')'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} omp50-error {{expected ','}} omp50-note {{to match this '('}} + #pragma omp task depend(iterator(unsigned argc: // expected-error {{expected ')'}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-note {{to match this '('}} omp50-error {{expected '=' in iterator specifier}} omp50-error 2 {{expected expression}} omp50-error {{expected ',' or ')' after iterator specifier}} omp50-error {{expected ')'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} omp50-error {{expected ','}} omp50-note {{to match this '('}} + #pragma omp task depend(iterator(unsigned argc = // expected-error {{expected ')'}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-note {{to match this '('}} omp50-error 2 {{expected expression}} omp50-error {{expected ',' or ')' after iterator specifier}} omp50-error {{expected ')'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} omp50-error {{expected ','}} omp50-note {{to match this '('}} + #pragma omp task depend(iterator(vector argc = 0:2):argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected integral or pointer type as the iterator-type, not 'vector'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} omp50-error {{expected ','}} + #pragma omp task depend(iterator(vector *argc = nullptr:nullptr+2:0), in:argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{invalid operands to binary expression ('nullptr_t' and 'int')}} omp50-error {{iterator step expression 0 evaluates to 0}} + #pragma omp task depend(iterator(vector *argc = 0:vector():argc), in:argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{converting 'vector' to incompatible type 'vector *'}} foo(); +#pragma omp task depend(iterator(unsigned argc = 0:10), in : argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} + argc = 0; +#pragma omp task depend(iterator(i = 0:10, i = 0:10), in : argv[i]) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp45-error {{use of undeclared identifier 'i'}} omp50-error {{redefinition of 'i'}} omp50-note {{previous definition is here}} + i = 0; // expected-error {{use of undeclared identifier 'i'}} return 0; } diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index bb9fed165679..14814f89d97d 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -5185,6 +5185,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return cxstring::createRef("OMPArraySectionExpr"); case CXCursor_OMPArrayShapingExpr: return cxstring::createRef("OMPArrayShapingExpr"); + case CXCursor_OMPIteratorExpr: + return cxstring::createRef("OMPIteratorExpr"); case CXCursor_BinaryOperator: return cxstring::createRef("BinaryOperator"); case CXCursor_CompoundAssignOperator: diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index 4f4e0c4ea1d5..3bcc7cc7af05 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -427,6 +427,10 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent, K = CXCursor_OMPArrayShapingExpr; break; + case Stmt::OMPIteratorExprClass: + K = CXCursor_OMPIteratorExpr; + break; + case Stmt::BinaryOperatorClass: K = CXCursor_BinaryOperator; break; From cfe-commits at lists.llvm.org Wed Apr 1 10:07:16 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 17:07:16 +0000 (UTC) Subject: [PATCH] D76384: Move FPFeatures from BinaryOperator bitfields to Trailing storage In-Reply-To: References: Message-ID: <9d1a79f77cba5edded43498860238cf7@localhost.localdomain> rjmccall added inline comments. ================ Comment at: clang/include/clang/AST/StmtVisitor.h:146 + RetTy VisitBin##NAME(PTR(BinaryOperator) S, ParamTys... P) { \ + DISPATCH(BinAssign, BinaryOperator); \ } ---------------- erichkeane wrote: > rjmccall wrote: > > Comment needs updating, but more importantly, you're making all of these fall back on `VisitBinAssign`, which is definitely not correct. > @rjmccall : What would you think fits better? If we don't have something like this, VisitBinaryOperator is going to have to redirect to VisitBinAssign anyway. We could presumably keep VisitCompoundAssignOperator, but that seems like a naming difference. `VisitBinAssign` is an existing method that is used specifically for the simple assignment operator. The old delegation was that `VisitBinMulAssign` delegated to `VisitCompoundAssignOperator`, which delegated to `VisitBinaryOperator` (because CAO was a subclass of that), which delegated to `VisitExpr`. The natural new delegation here would be for `VisitBinMulAssign` to just delegate directly to `VisitBinaryOperator`. If it's still useful to have an intermediate visitor method in the delegation chain for all the compound assignment operators, that's fine, but it shouldn't be `VisitBinAssign`. ================ Comment at: clang/include/clang/Basic/LangOptions.h:394 + return true; + } + ---------------- erichkeane wrote: > rjmccall wrote: > > The problem with having both functions that take `ASTContext`s and functions that don't is that it's easy to mix them, so they either need to have the same behavior (in which case it's pointless to have an overload that takes the `ASTContext`) or you're making something really error-prone. > > > > I would feel a lot more confident that you were designing and using these APIs correctly if you actually took advantage of the ability to not store trailing FPOptions in some case, like when they match the global settings in the ASTContext. That way you'll actually be verifying that everything behaves correctly if nodes don't store FPOptions. If you do that, I think you'll see my point about not having all these easily-confusable functions that do or do not take `ASTContext`s.. > I think I disagree with @rjmccall that these requiresTrailingStorage should be here at all. I think we should store in the AST ANY programmer opinion, even if they match the global setting. It seems to me that this would be more tolerant of any global-setting rewrites that modules/et-al introduce, as well as make the AST Print consistent. Always storing FPOptions when the user has explicitly overriding it also better captures the programmer's intent. I covered this elsewhere in the review. If you want to have that tolerance — and I think you should — then expressions should store (and Sema should track) the active pragma state, which can be most easily expressed as a pair of an FPOptions and a mask to apply to the global FPOptions. When you enter a pragma, you clear the relevant bits from the global FPOptions mask. But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76384/new/ https://reviews.llvm.org/D76384 From cfe-commits at lists.llvm.org Wed Apr 1 10:07:17 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 17:07:17 +0000 (UTC) Subject: [PATCH] D71082: Allow system header to provide their own implementation of some builtin In-Reply-To: References: Message-ID: <6d34cefe671d514c3459fc4e693529d4@localhost.localdomain> rnk added a comment. It's unsurprising that the Linux kernel's own Fortify implementation is incompatible with Clang. The whole feature should never have been implemented in the library to begin with, but here we are. I think the Linux kernel folks would prefer it if we can fix forward and find a way to make their Fortify implementation work, though. For fixing forward, the question is, why did LLVM emit a standalone call to mempcy? Did LLVM inline the thing marked always_inline? Or did `__builtin_memcpy` compile down to `call i8* @memcpy(...)` instead of `call void @llvm.memcpy.*`? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71082/new/ https://reviews.llvm.org/D71082 From cfe-commits at lists.llvm.org Wed Apr 1 10:08:25 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 17:08:25 +0000 (UTC) Subject: [PATCH] D76384: Move FPFeatures from BinaryOperator bitfields to Trailing storage In-Reply-To: References: Message-ID: rjmccall added inline comments. ================ Comment at: clang/include/clang/Basic/LangOptions.h:394 + return true; + } + ---------------- rjmccall wrote: > erichkeane wrote: > > rjmccall wrote: > > > The problem with having both functions that take `ASTContext`s and functions that don't is that it's easy to mix them, so they either need to have the same behavior (in which case it's pointless to have an overload that takes the `ASTContext`) or you're making something really error-prone. > > > > > > I would feel a lot more confident that you were designing and using these APIs correctly if you actually took advantage of the ability to not store trailing FPOptions in some case, like when they match the global settings in the ASTContext. That way you'll actually be verifying that everything behaves correctly if nodes don't store FPOptions. If you do that, I think you'll see my point about not having all these easily-confusable functions that do or do not take `ASTContext`s.. > > I think I disagree with @rjmccall that these requiresTrailingStorage should be here at all. I think we should store in the AST ANY programmer opinion, even if they match the global setting. It seems to me that this would be more tolerant of any global-setting rewrites that modules/et-al introduce, as well as make the AST Print consistent. Always storing FPOptions when the user has explicitly overriding it also better captures the programmer's intent. > I covered this elsewhere in the review. If you want to have that tolerance — and I think you should — then expressions should store (and Sema should track) the active pragma state, which can be most easily expressed as a pair of an FPOptions and a mask to apply to the global FPOptions. When you enter a pragma, you clear the relevant bits from the global FPOptions mask. > > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. I meant to say: for a million nodes that don't care in the slightest about FPOptions, as well as for a million more nodes that aren't using pragma overrides. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76384/new/ https://reviews.llvm.org/D76384 From cfe-commits at lists.llvm.org Wed Apr 1 10:26:31 2020 From: cfe-commits at lists.llvm.org (Erich Keane via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 17:26:31 +0000 (UTC) Subject: [PATCH] D76384: Move FPFeatures from BinaryOperator bitfields to Trailing storage In-Reply-To: References: Message-ID: <4e760c312714531ad252220402ef274f@localhost.localdomain> erichkeane added inline comments. ================ Comment at: clang/include/clang/Basic/LangOptions.h:394 + return true; + } + ---------------- rjmccall wrote: > rjmccall wrote: > > erichkeane wrote: > > > rjmccall wrote: > > > > The problem with having both functions that take `ASTContext`s and functions that don't is that it's easy to mix them, so they either need to have the same behavior (in which case it's pointless to have an overload that takes the `ASTContext`) or you're making something really error-prone. > > > > > > > > I would feel a lot more confident that you were designing and using these APIs correctly if you actually took advantage of the ability to not store trailing FPOptions in some case, like when they match the global settings in the ASTContext. That way you'll actually be verifying that everything behaves correctly if nodes don't store FPOptions. If you do that, I think you'll see my point about not having all these easily-confusable functions that do or do not take `ASTContext`s.. > > > I think I disagree with @rjmccall that these requiresTrailingStorage should be here at all. I think we should store in the AST ANY programmer opinion, even if they match the global setting. It seems to me that this would be more tolerant of any global-setting rewrites that modules/et-al introduce, as well as make the AST Print consistent. Always storing FPOptions when the user has explicitly overriding it also better captures the programmer's intent. > > I covered this elsewhere in the review. If you want to have that tolerance — and I think you should — then expressions should store (and Sema should track) the active pragma state, which can be most easily expressed as a pair of an FPOptions and a mask to apply to the global FPOptions. When you enter a pragma, you clear the relevant bits from the global FPOptions mask. > > > > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. > > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. > > I meant to say: for a million nodes that don't care in the slightest about FPOptions, as well as for a million more nodes that aren't using pragma overrides. Right, I get the intent, and I completely agree with that. My point was EVERY Expr that is affected by a #pragma should store it. Though, after looking at your Macro concern above, I'm less compelled. I guess was suggesting that the logic for "requiresTrailingStorage" should just be "modified by a pragma" instead of "FPOptions != The global setting". Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76384/new/ https://reviews.llvm.org/D76384 From cfe-commits at lists.llvm.org Wed Apr 1 10:26:32 2020 From: cfe-commits at lists.llvm.org (Dmitry Polukhin via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 17:26:32 +0000 (UTC) Subject: [PATCH] D75184: [clang-tidy] Optional inheritance of file configs from parent =?UTF-8?Q?directories=C2=A0?= In-Reply-To: References: Message-ID: <5b5eb8180a729537ff33750b210adf7f@localhost.localdomain> DmitryPolukhin updated this revision to Diff 254238. DmitryPolukhin added a comment. Use options priority instead of overriding local options by global Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75184/new/ https://reviews.llvm.org/D75184 Files: clang-tools-extra/clang-tidy/ClangTidy.cpp clang-tools-extra/clang-tidy/ClangTidyCheck.cpp clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp clang-tools-extra/clang-tidy/ClangTidyOptions.cpp clang-tools-extra/clang-tidy/ClangTidyOptions.h clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp clang-tools-extra/docs/clang-tidy/index.rst clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/3/.clang-tidy clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/4/.clang-tidy clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/4/44/.clang-tidy clang-tools-extra/test/clang-tidy/infrastructure/config-files.cpp clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D75184.254238.patch Type: text/x-patch Size: 16994 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 10:26:34 2020 From: cfe-commits at lists.llvm.org (Jian Cai via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 17:26:34 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: jcai19 updated this revision to Diff 254240. jcai19 added a comment. Address some of the concerns. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 Files: clang/include/clang/AST/ASTContext.h clang/include/clang/Basic/LangOptions.def clang/include/clang/Driver/Options.td clang/lib/CodeGen/CGDecl.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGenCXX/auto-var-init-stop-after.cpp clang/test/Driver/clang_f_opts.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77168.254240.patch Type: text/x-patch Size: 7826 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 10:26:35 2020 From: cfe-commits at lists.llvm.org (Jian Cai via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 17:26:35 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: jcai19 updated this revision to Diff 254242. jcai19 added a comment. Remove an unnecessary line. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 Files: clang/include/clang/AST/ASTContext.h clang/include/clang/Basic/LangOptions.def clang/include/clang/Driver/Options.td clang/lib/CodeGen/CGDecl.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGenCXX/auto-var-init-stop-after.cpp clang/test/Driver/clang_f_opts.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77168.254242.patch Type: text/x-patch Size: 7773 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 10:26:36 2020 From: cfe-commits at lists.llvm.org (Zarko Todorovski via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 17:26:36 +0000 (UTC) Subject: [PATCH] D76130: [PPC][AIX] Implement variadic function handling in LowerFormalArguments_AIX In-Reply-To: References: Message-ID: ZarkoCA updated this revision to Diff 254243. ZarkoCA added a comment. Removed data layout and target triple info from test output. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76130/new/ https://reviews.llvm.org/D76130 Files: llvm/lib/Target/PowerPC/PPCISelLowering.cpp llvm/test/CodeGen/PowerPC/aix32-cc-abi-vaarg.ll llvm/test/CodeGen/PowerPC/aix64-cc-abi-vaarg.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D76130.254243.patch Type: text/x-patch Size: 41530 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 10:26:37 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Balogh, _=C3=81d=C3=A1m_via_Phabricator?= via cfe-commits) Date: Wed, 01 Apr 2020 17:26:37 +0000 (UTC) Subject: [PATCH] D77229: [Analyzer][WIP] Avoid handling of LazyCompundVals in IteratorModeling Message-ID: baloghadamsoftware created this revision. baloghadamsoftware added a reviewer: NoQ. baloghadamsoftware added a project: clang. Herald added subscribers: ASDenysPetrov, martong, steakhal, Charusso, gamesh411, dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, rnkovacs, szepet, xazax.hun, whisperity. Herald added a reviewer: Szelethus. baloghadamsoftware added a comment. Testing this patch on `test/Analysis/iterator-modeling.cpp` crashes with the following output: Handling operator++() Return Value: lazyCompoundVal{0x55655390c9d8,i1} Bingo! State->get(Key): &i1 Key.getItem().getKind(): 0 clang: /home/edmbalo/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:472: static clang::ento::ProgramStateRef clang::ento::ExprEngine::addObjectUnderConstruction(clang::ento::ProgramStateRef, const clang::ConstructionContextItem&, const clang::LocationContext*, clang::ento::SVal): Assertion `!State->get(Key) || Key.getItem().getKind() == ConstructionContextItem::TemporaryDestructorKind' failed. ... What could be the problem here? Since accessing the region of LazyCompoundVals is an undocumented and unreliable feature, try to find the region of the return value directly, skipping both the LazyCompoundVal and its later materialization. This patch is work in progress. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77229 Files: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp clang/lib/StaticAnalyzer/Core/CallEvent.cpp clang/lib/StaticAnalyzer/Core/ExprEngine.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77229.254239.patch Type: text/x-patch Size: 10403 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 10:26:37 2020 From: cfe-commits at lists.llvm.org (Jian Cai via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 17:26:37 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: jcai19 added a comment. > For example, won't you need some way of figuring out what the 1,134th variable in a file was after you've successfully bisected? Once we know the Xth variable is causing issues, we can compare the IR or assembly of -fvar-auto-init-stop-after=X-1 and -fvar-auto-init-stop-after=X to figure out which variable it is, or I can print out the variable name and the enclosing function if it is preferred. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 From cfe-commits at lists.llvm.org Wed Apr 1 10:26:38 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Balogh, _=C3=81d=C3=A1m_via_Phabricator?= via cfe-commits) Date: Wed, 01 Apr 2020 17:26:38 +0000 (UTC) Subject: [PATCH] D77229: [Analyzer][WIP] Avoid handling of LazyCompundVals in IteratorModeling In-Reply-To: References: Message-ID: baloghadamsoftware added a comment. Testing this patch on `test/Analysis/iterator-modeling.cpp` crashes with the following output: Handling operator++() Return Value: lazyCompoundVal{0x55655390c9d8,i1} Bingo! State->get(Key): &i1 Key.getItem().getKind(): 0 clang: /home/edmbalo/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:472: static clang::ento::ProgramStateRef clang::ento::ExprEngine::addObjectUnderConstruction(clang::ento::ProgramStateRef, const clang::ConstructionContextItem&, const clang::LocationContext*, clang::ento::SVal): Assertion `!State->get(Key) || Key.getItem().getKind() == ConstructionContextItem::TemporaryDestructorKind' failed. ... What could be the problem here? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77229/new/ https://reviews.llvm.org/D77229 From cfe-commits at lists.llvm.org Wed Apr 1 10:26:39 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Balogh, _=C3=81d=C3=A1m_via_Phabricator?= via cfe-commits) Date: Wed, 01 Apr 2020 17:26:39 +0000 (UTC) Subject: [PATCH] D77125: [Analyzer] Model return values of container insert and delete operations In-Reply-To: References: Message-ID: <29797a1bec43c88cffd0bd39e8b70f40@localhost.localdomain> baloghadamsoftware added a comment. In D77125#1952769 , @martong wrote: > It seems like we could model here `emplace` and `emplace_after` exactly the same way we do with `insert` and `insert_after`, couldn't we? Perhaps that could go into this patch too. They are already in this patch (see the tests and the `CallDescriptionMap`), but they share their handing function with `insert` and `insert_after`. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77125/new/ https://reviews.llvm.org/D77125 From cfe-commits at lists.llvm.org Wed Apr 1 10:26:40 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Balogh, _=C3=81d=C3=A1m_via_Phabricator?= via cfe-commits) Date: Wed, 01 Apr 2020 17:26:40 +0000 (UTC) Subject: [PATCH] D77150: [Analyzer] New Option for ContainerModeling: AggressiveEraseModeling In-Reply-To: References: Message-ID: <77ee71214648614f61039a497ff89859@localhost.localdomain> baloghadamsoftware marked an inline comment as done. baloghadamsoftware added inline comments. ================ Comment at: clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp:780 + if (AggressiveEraseModeling) { + if (const auto *CData = getContainerData(State, ContReg)) { ---------------- martong wrote: > This seems to be very similar to the hunk we have in `handleErase`, so this suggests some unnecessary code duplication. I presume we could create a function which is called from both callers. Yes, I was thinking about that as well. Many parameters have to be passed so it will be not so much shorter. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77150/new/ https://reviews.llvm.org/D77150 From cfe-commits at lists.llvm.org Wed Apr 1 10:41:18 2020 From: cfe-commits at lists.llvm.org (Sjoerd Meijer via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 17:41:18 +0000 (UTC) Subject: [PATCH] D76679: [SveEmitter] Add more immediate operand checks. In-Reply-To: References: Message-ID: SjoerdMeijer added a comment. Just to clarify my last sentence: > Now I am wondering why the ARM SVE ACLE is using float16_t, and not just _Float16. Do you have any insights in that too perhaps? What I meant to say is why SVE intrinsics are not using _Float16? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76679/new/ https://reviews.llvm.org/D76679 From cfe-commits at lists.llvm.org Wed Apr 1 10:41:25 2020 From: cfe-commits at lists.llvm.org (Jian Cai via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 17:41:25 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: <0f8af150cf82b4652eac616ea673e6cd@localhost.localdomain> jcai19 marked 4 inline comments as done. jcai19 added inline comments. ================ Comment at: clang/lib/CodeGen/CGDecl.cpp:1814 + if (StopAfter) { + static unsigned Counter = 0; + if (Counter >= StopAfter) ---------------- rjmccall wrote: > srhines wrote: > > MaskRay wrote: > > > I am a bit worried about the static variable. This makes CodeGen not reusable. > > The counter could exist in ASTContext instead. > IRGenModule would be the more appropriate place. I can't seem to find IRGenModule. Do you mean CodeGenModule by any chance? Thanks. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 From cfe-commits at lists.llvm.org Wed Apr 1 10:58:22 2020 From: cfe-commits at lists.llvm.org (Digger via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 17:58:22 +0000 (UTC) Subject: [PATCH] D76932: [AIX] emit .extern and .weak directive linkage In-Reply-To: References: Message-ID: <1149edc3e84ca1f5f3f0a3448d88b323@localhost.localdomain> DiggerLin updated this revision to Diff 254252. DiggerLin marked 3 inline comments as done. DiggerLin added a comment. address comment Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76932/new/ https://reviews.llvm.org/D76932 Files: clang/lib/Driver/ToolChains/AIX.cpp clang/test/Driver/aix-as.c llvm/include/llvm/MC/MCAsmInfo.h llvm/include/llvm/MC/MCDirectives.h llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp llvm/lib/MC/MCAsmInfoXCOFF.cpp llvm/lib/MC/MCAsmStreamer.cpp llvm/lib/MC/MCXCOFFStreamer.cpp llvm/lib/MC/XCOFFObjectWriter.cpp llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp llvm/test/CodeGen/PowerPC/aix-extern-weak.ll llvm/test/CodeGen/PowerPC/aix-reference-func-addr-const.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D76932.254252.patch Type: text/x-patch Size: 35627 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 10:58:23 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 17:58:23 +0000 (UTC) Subject: [PATCH] D77193: [X86] Add SERIALIZE instruction. In-Reply-To: References: Message-ID: <12badcf2904040096ed92bd840409178@localhost.localdomain> craig.topper accepted this revision. craig.topper added a comment. This revision is now accepted and ready to land. LGTM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77193/new/ https://reviews.llvm.org/D77193 From cfe-commits at lists.llvm.org Wed Apr 1 10:58:24 2020 From: cfe-commits at lists.llvm.org (JF Bastien via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 17:58:24 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: jfb added a comment. Do you not think `pragma` is a more general approach? That's what's used in a bunch of other cases, and I'd like to see it attempted here. If not, I agree with John that just counting up isn't a good bisection experience. I'd rather see a begin / end bound. You're also missing the auto-init in `initializeAlloca`. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 From cfe-commits at lists.llvm.org Wed Apr 1 11:15:01 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 18:15:01 +0000 (UTC) Subject: [PATCH] D77205: [X86] Add TSXLDTRK instructions. In-Reply-To: References: Message-ID: <0bac2813696d47169523c82f646eb964@localhost.localdomain> craig.topper accepted this revision. craig.topper added a comment. This revision is now accepted and ready to land. LGTM Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77205/new/ https://reviews.llvm.org/D77205 From cfe-commits at lists.llvm.org Wed Apr 1 11:28:22 2020 From: cfe-commits at lists.llvm.org (Yung, Douglas via cfe-commits) Date: Wed, 1 Apr 2020 18:28:22 +0000 Subject: [clang] 6f428e0 - [AST] Fix crashes on decltype(recovery-expr). In-Reply-To: <5e81ec8d.1c69fb81.c6694.8b3c@mx.google.com> References: <5e81ec8d.1c69fb81.c6694.8b3c@mx.google.com> Message-ID: Hi Haojian, I noticed that after your change, the compiler is now giving an error when trying to create a vector of >= 1024 elements when previously it worked, and gcc has no problem with the same code. Is that intentional? I have put the details in PR45387, can you take a look? Douglas Yung -----Original Message----- From: cfe-commits On Behalf Of Haojian Wu via cfe-commits Sent: Monday, March 30, 2020 5:57 To: cfe-commits at lists.llvm.org Subject: [clang] 6f428e0 - [AST] Fix crashes on decltype(recovery-expr). Author: Haojian Wu Date: 2020-03-30T14:56:33+02:00 New Revision: 6f428e09fbe8ce7e3510ae024031a5fc19653483 URL: https://github.com/llvm/llvm-project/commit/6f428e09fbe8ce7e3510ae024031a5fc19653483 DIFF: https://github.com/llvm/llvm-project/commit/6f428e09fbe8ce7e3510ae024031a5fc19653483.diff LOG: [AST] Fix crashes on decltype(recovery-expr). Summary: We mark these decls as invalid. Reviewers: sammccall Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77037 Added: Modified: clang/include/clang/AST/DependenceFlags.h clang/include/clang/AST/Type.h clang/lib/Parse/ParseExprCXX.cpp clang/lib/Sema/SemaType.cpp clang/test/AST/ast-dump-expr-errors.cpp clang/test/Sema/invalid-member.cpp clang/unittests/Sema/CodeCompleteTest.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/DependenceFlags.h b/clang/include/clang/AST/DependenceFlags.h index 75c9aa1656b8..0b24bae6df9b 100644 --- a/clang/include/clang/AST/DependenceFlags.h +++ b/clang/include/clang/AST/DependenceFlags.h @@ -50,14 +50,16 @@ struct TypeDependenceScope { /// Whether this type is a variably-modified type (C99 6.7.5). VariablyModified = 8, - // FIXME: add Error bit. + /// Whether this type references an error, e.g. decltype(err-expression) + /// yields an error type. + Error = 16, None = 0, - All = 15, + All = 31, DependentInstantiation = Dependent | Instantiation, - LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified) + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) }; }; using TypeDependence = TypeDependenceScope::TypeDependence; @@ -147,6 +149,7 @@ class Dependence { return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) | translate(V, Instantiation, TypeDependence::Instantiation) | translate(V, Dependent, TypeDependence::Dependent) | + translate(V, Error, TypeDependence::Error) | translate(V, VariablyModified, TypeDependence::VariablyModified); } diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 248fbcfba98e..5d2c035ea0fe 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2139,6 +2139,11 @@ class alignas(8) Type : public ExtQualsTypeCommonBase { return static_cast(TypeBits.Dependence); } + /// Whether this type is an error type. + bool containsErrors() const { + return getDependence() & TypeDependence::Error; } + /// Whether this type is a dependent type, meaning that its definition /// somehow depends on a template parameter (C++ [temp.dep.type]). bool isDependentType() const { diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 761fad9456be..4389c8777c6d 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -3105,10 +3105,14 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { auto RunSignatureHelp = [&]() { ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get(); - assert(TypeRep && "invalid types should be handled before"); - QualType PreferredType = Actions.ProduceConstructorSignatureHelp( - getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), - DeclaratorInfo.getEndLoc(), ConstructorArgs, ConstructorLParen); + QualType PreferredType; + // ActOnTypeName might adjust DeclaratorInfo and return a null type even + // the passing DeclaratorInfo is valid, e.g. running SignatureHelp on + // `new decltype(invalid) (^)`. + if (TypeRep) + PreferredType = Actions.ProduceConstructorSignatureHelp( + getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), + DeclaratorInfo.getEndLoc(), ConstructorArgs, + ConstructorLParen); CalledSignatureHelp = true; return PreferredType; }; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 55ce028fb8c2..e128ebf31270 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1678,6 +1678,12 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { break; } + // FIXME: we want resulting declarations to be marked invalid, but + claiming // the type is invalid is too strong - e.g. it causes + ActOnTypeName to return // a null type. + if (Result->containsErrors()) + declarator.setInvalidType(); + if (S.getLangOpts().OpenCL && S.checkOpenCLDisabledTypeDeclSpec(DS, Result)) declarator.setInvalidType(true); diff --git a/clang/test/AST/ast-dump-expr-errors.cpp b/clang/test/AST/ast-dump-expr-errors.cpp index e623fad04f4c..9334b73a4354 100644 --- a/clang/test/AST/ast-dump-expr-errors.cpp +++ b/clang/test/AST/ast-dump-expr-errors.cpp @@ -42,5 +42,9 @@ int d = static_cast(bar() + 1); // FIXME: store initializer even when 'auto' could not be deduced. // Expressions with errors currently do not keep initializers around. -// CHECK: `-VarDecl {{.*}} invalid e 'auto' +// CHECK: -VarDecl {{.*}} invalid e 'auto' auto e = bar(); + +// Error type should result in an invalid decl. +// CHECK: -VarDecl {{.*}} invalid f 'decltype((bar))' +decltype(bar()) f; diff --git a/clang/test/Sema/invalid-member.cpp b/clang/test/Sema/invalid-member.cpp index 5475157e936e..544979980fc9 100644 --- a/clang/test/Sema/invalid-member.cpp +++ b/clang/test/Sema/invalid-member.cpp @@ -1,7 +1,15 @@ -// RUN: %clang_cc1 -verify -fsyntax-only %s -void foo(); // expected-note {{requires 0 arguments}} +// RUN: %clang_cc1 -verify -fsyntax-only -fno-recovery-ast %s // RUN: +%clang_cc1 -verify -fsyntax-only -frecovery-ast %s + +void foo(); // expected-note 2{{requires 0 arguments}} class X { decltype(foo(42)) invalid; // expected-error {{no matching function}} }; // Should be able to evaluate sizeof without crashing. static_assert(sizeof(X) == 1, "No valid members"); + +class Y { + typeof(foo(42)) invalid; // expected-error {{no matching function}} +}; // Should be able to evaluate sizeof without crashing. +static_assert(sizeof(Y) == 1, "No valid members"); diff --git a/clang/unittests/Sema/CodeCompleteTest.cpp b/clang/unittests/Sema/CodeCompleteTest.cpp index a9441a679cac..d8b303d77bb9 100644 --- a/clang/unittests/Sema/CodeCompleteTest.cpp +++ b/clang/unittests/Sema/CodeCompleteTest.cpp @@ -486,7 +486,10 @@ TEST(PreferredTypeTest, NoCrashOnInvalidTypes) { StringRef Code = R"cpp( auto x = decltype(&1)(^); auto y = new decltype(&1)(^); + // GNU decimal type extension is not supported in clang. + auto z = new _Decimal128(^); )cpp"; EXPECT_THAT(collectPreferredTypes(Code), Each("NULL TYPE")); } + } // namespace _______________________________________________ cfe-commits mailing list cfe-commits at lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits From cfe-commits at lists.llvm.org Wed Apr 1 11:31:38 2020 From: cfe-commits at lists.llvm.org (Puyan Lotfi via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 18:31:38 +0000 (UTC) Subject: [PATCH] D77233: [NFC] Refactoring PropertyAttributeKind for ObjCPropertyDecl and ObjCDeclSpec. Message-ID: plotfi created this revision. plotfi added reviewers: compnerd, manmanren. Herald added subscribers: cfe-commits, arphaman. Herald added a project: clang. plotfi edited the summary of this revision. plotfi updated this revision to Diff 254259. plotfi added a comment. Herald added a subscriber: jfb. plotfi added a reviewer: jfb. Herald added a subscriber: dexonsmith.  Clipboard gave me junk the first submit. Sorry I noticed PropertyAttributeKind / ObjCPropertyAttributeKind enums in ObjCPropertyDecl and ObjCDeclSpec are exactly identical. This is a non-functional change to make these two enums less redundant. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77233 Files: clang/include/clang/AST/DeclObjC.h clang/include/clang/AST/DeclObjCCommon.h clang/include/clang/Sema/DeclSpec.h clang/lib/ARCMigrate/TransGCAttrs.cpp clang/lib/ARCMigrate/TransProperties.cpp clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp clang/lib/AST/ASTContext.cpp clang/lib/AST/DeclObjC.cpp clang/lib/AST/DeclPrinter.cpp clang/lib/AST/JSONNodeDumper.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/Analysis/BodyFarm.cpp clang/lib/CodeGen/CGObjC.cpp clang/lib/CodeGen/CGObjCGNU.cpp clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp clang/lib/Frontend/Rewrite/RewriteObjC.cpp clang/lib/Parse/ParseObjc.cpp clang/lib/Sema/SemaChecking.cpp clang/lib/Sema/SemaCodeComplete.cpp clang/lib/Sema/SemaExprObjC.cpp clang/lib/Sema/SemaObjCProperty.cpp clang/lib/Sema/SemaPseudoObject.cpp clang/lib/Serialization/ASTReaderDecl.cpp clang/tools/libclang/CIndex.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77233.254259.patch Type: text/x-patch Size: 95921 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 11:31:41 2020 From: cfe-commits at lists.llvm.org (Puyan Lotfi via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 18:31:41 +0000 (UTC) Subject: [PATCH] D77233: [NFC] Refactoring PropertyAttributeKind for ObjCPropertyDecl and ObjCDeclSpec. In-Reply-To: References: Message-ID: <0860d328d41f019537b58fd7e090705f@localhost.localdomain> plotfi updated this revision to Diff 254259. plotfi added a comment. Herald added a subscriber: jfb.  Clipboard gave me junk the first submit. Sorry Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77233/new/ https://reviews.llvm.org/D77233 Files: clang/include/clang/AST/DeclObjC.h clang/include/clang/AST/DeclObjCCommon.h clang/include/clang/Sema/DeclSpec.h clang/lib/ARCMigrate/TransGCAttrs.cpp clang/lib/ARCMigrate/TransProperties.cpp clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp clang/lib/AST/ASTContext.cpp clang/lib/AST/DeclObjC.cpp clang/lib/AST/DeclPrinter.cpp clang/lib/AST/JSONNodeDumper.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/Analysis/BodyFarm.cpp clang/lib/CodeGen/CGObjC.cpp clang/lib/CodeGen/CGObjCGNU.cpp clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp clang/lib/Frontend/Rewrite/RewriteObjC.cpp clang/lib/Parse/ParseObjc.cpp clang/lib/Sema/SemaChecking.cpp clang/lib/Sema/SemaCodeComplete.cpp clang/lib/Sema/SemaExprObjC.cpp clang/lib/Sema/SemaObjCProperty.cpp clang/lib/Sema/SemaPseudoObject.cpp clang/lib/Serialization/ASTReaderDecl.cpp clang/tools/libclang/CIndex.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77233.254259.patch Type: text/x-patch Size: 95921 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 11:31:43 2020 From: cfe-commits at lists.llvm.org (Jason Liu via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 18:31:43 +0000 (UTC) Subject: [PATCH] D76932: [AIX] emit .extern and .weak directive linkage In-Reply-To: References: Message-ID: <21803843b4ef8e231eb8ef5992c1b8c2@localhost.localdomain> jasonliu added a comment. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76932/new/ https://reviews.llvm.org/D76932 From cfe-commits at lists.llvm.org Wed Apr 1 11:31:44 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 18:31:44 +0000 (UTC) Subject: [PATCH] D76812: [X86] Add Indirect Thunk Support to X86 to mitigate Load Value Injection (LVI) [3/3] In-Reply-To: References: Message-ID: <2c8c282061046e2302f97dc3542afc10@localhost.localdomain> craig.topper added inline comments. ================ Comment at: llvm/lib/Target/X86/X86IndirectThunks.cpp:97 + void populateThunk(MachineFunction &MF) { + // This code mitigates LVI by replacing each indirect call/jump with a direct + // call/jump to a thunk that looks like: ---------------- Why don't you need the code from retpoline that erases extra BBs? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76812/new/ https://reviews.llvm.org/D76812 From cfe-commits at lists.llvm.org Wed Apr 1 11:31:44 2020 From: cfe-commits at lists.llvm.org (Stephen Hines via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 18:31:44 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: <2b692816669d79b7c38d4b8cd9cd3b37@localhost.localdomain> srhines added a comment. In D77168#1955312 , @jfb wrote: > Do you not think `pragma` is a more general approach? That's what's used in a bunch of other cases, and I'd like to see it attempted here. > If not, I agree with John that just counting up isn't a good bisection experience. I'd rather see a begin / end bound. I agree that begin/end is actually better. My experience has been that you really don't want to be modifying source files if you can avoid it, as that is harder to automate in a script. And you do want to script this kind of debugging because it isn't a compiler crash, it's often a runtime issue that might take longer to reproduce/etc., so I think that it is preferable to remove the human (error prone) element of adding/tweaking pragmas. I did say that the pragmas are useful in other ways, but I don't think that it is effective for everything. > You're also missing the auto-init in `initializeAlloca`. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 From cfe-commits at lists.llvm.org Wed Apr 1 11:31:45 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 18:31:45 +0000 (UTC) Subject: [PATCH] D77234: clang/AMDGPU: Stop setting old denormal subtarget features Message-ID: arsenm created this revision. arsenm added a reviewer: yaxunl. Herald added subscribers: kerbowa, t-tye, tpr, dstuttard, nhaehnle, wdng, jvesely, kzhuravl. https://reviews.llvm.org/D77234 Files: clang/lib/Basic/Targets/AMDGPU.cpp clang/lib/Basic/Targets/AMDGPU.h clang/test/CodeGenCUDA/flush-denormals.cu clang/test/CodeGenOpenCL/amdgpu-features.cl -------------- next part -------------- A non-text attachment was scrubbed... Name: D77234.254260.patch Type: text/x-patch Size: 8443 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 11:31:45 2020 From: cfe-commits at lists.llvm.org (Artem Dergachev via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 18:31:45 +0000 (UTC) Subject: [PATCH] D77229: [Analyzer][WIP] Avoid handling of LazyCompundVals in IteratorModeling In-Reply-To: References: Message-ID: <451bb1037db9a6e5b5f10e6eb05210f0@localhost.localdomain> NoQ added a comment. The assert points out that the object under construction is already tracked and you're trying to add it twice. You don't want to add it tho, you just want to find the region. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77229/new/ https://reviews.llvm.org/D77229 From cfe-commits at lists.llvm.org Wed Apr 1 11:32:00 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 18:32:00 +0000 (UTC) Subject: [PATCH] D76384: Move FPFeatures from BinaryOperator bitfields to Trailing storage In-Reply-To: References: Message-ID: rjmccall added inline comments. ================ Comment at: clang/include/clang/Basic/LangOptions.h:394 + return true; + } + ---------------- erichkeane wrote: > rjmccall wrote: > > rjmccall wrote: > > > erichkeane wrote: > > > > rjmccall wrote: > > > > > The problem with having both functions that take `ASTContext`s and functions that don't is that it's easy to mix them, so they either need to have the same behavior (in which case it's pointless to have an overload that takes the `ASTContext`) or you're making something really error-prone. > > > > > > > > > > I would feel a lot more confident that you were designing and using these APIs correctly if you actually took advantage of the ability to not store trailing FPOptions in some case, like when they match the global settings in the ASTContext. That way you'll actually be verifying that everything behaves correctly if nodes don't store FPOptions. If you do that, I think you'll see my point about not having all these easily-confusable functions that do or do not take `ASTContext`s.. > > > > I think I disagree with @rjmccall that these requiresTrailingStorage should be here at all. I think we should store in the AST ANY programmer opinion, even if they match the global setting. It seems to me that this would be more tolerant of any global-setting rewrites that modules/et-al introduce, as well as make the AST Print consistent. Always storing FPOptions when the user has explicitly overriding it also better captures the programmer's intent. > > > I covered this elsewhere in the review. If you want to have that tolerance — and I think you should — then expressions should store (and Sema should track) the active pragma state, which can be most easily expressed as a pair of an FPOptions and a mask to apply to the global FPOptions. When you enter a pragma, you clear the relevant bits from the global FPOptions mask. > > > > > > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. > > > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. > > > > I meant to say: for a million nodes that don't care in the slightest about FPOptions, as well as for a million more nodes that aren't using pragma overrides. > Right, I get the intent, and I completely agree with that. My point was EVERY Expr that is affected by a #pragma should store it. Though, after looking at your Macro concern above, I'm less compelled. > > I guess was suggesting that the logic for "requiresTrailingStorage" should just be "modified by a pragma" instead of "FPOptions != The global setting". Well, "modified by a pragma" still wouldn't make the AST agnostic to global settings, since the pragmas don't override everything in FPOptions at once. But I agree that would achieve the most important goal, which is to stop inflating the AST when pragmas *aren't* in effect, which is approximately 100% of the time. In order to do that, though, we'll need to start tracking pragmas, which we should do but which can wait for a follow-up patch. In the meantime, I don't think you're ever going to get the interfaces right for queries like `BinaryOperator::getFPOptions` unless you actually stop relying on the fact that you're unconditionally storing `FPOptions`. You need to passing around ASTContexts for that. That's why I'm suggesting using an exact match with the global settings as a simple thing you can easily check without modifying what data you collect in `FPOptions`. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76384/new/ https://reviews.llvm.org/D76384 From cfe-commits at lists.llvm.org Wed Apr 1 11:49:07 2020 From: cfe-commits at lists.llvm.org (Diogo N. Sampaio via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 18:49:07 +0000 (UTC) Subject: [PATCH] D77074: [FPEnv][AArch64] Platform-specific builtin constrained FP enablement In-Reply-To: References: Message-ID: <63e5de0e2c72db17e03a3686fc924c98@localhost.localdomain> dnsampaio added inline comments. ================ Comment at: clang/lib/CodeGen/CGBuiltin.cpp:8486-8492 + return Builder.CreateConstrainedFPCall( + F, + {EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2)), Ops[0]}); + } else { + Function *F = CGM.getIntrinsic(Intrinsic::fma, HalfTy); + // NEON intrinsic puts accumulator first, unlike the LLVM fma. + return Builder.CreateCall(F, {EmitScalarExpr(E->getArg(1)), ---------------- It seems that `Builder.CreateCall` and `Builder.CreateConstrainedFPCall` usually have the same arguments, except for the function F being or not part of "experimental_constrained_". Would it make sense to teach the `Builder` to select between creating a constrained or not call, depending if the function passed is constrained? I was thinking in something like this: ``` Function *F = CGM.getIntrinsic( Builder.getIsFPConstrained()? Intrinsic::experimental_constrained_fma : Intrinsic::fma, HalfTy); return Builder.CreateCallConstrainedFPIfRequired(F, .... ``` Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77074/new/ https://reviews.llvm.org/D77074 From cfe-commits at lists.llvm.org Wed Apr 1 11:49:08 2020 From: cfe-commits at lists.llvm.org (Erich Keane via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 18:49:08 +0000 (UTC) Subject: [PATCH] D76384: Move FPFeatures from BinaryOperator bitfields to Trailing storage In-Reply-To: References: Message-ID: <5517b3cbc690413d17165f57c362afa1@localhost.localdomain> erichkeane added inline comments. ================ Comment at: clang/include/clang/Basic/LangOptions.h:394 + return true; + } + ---------------- rjmccall wrote: > erichkeane wrote: > > rjmccall wrote: > > > rjmccall wrote: > > > > erichkeane wrote: > > > > > rjmccall wrote: > > > > > > The problem with having both functions that take `ASTContext`s and functions that don't is that it's easy to mix them, so they either need to have the same behavior (in which case it's pointless to have an overload that takes the `ASTContext`) or you're making something really error-prone. > > > > > > > > > > > > I would feel a lot more confident that you were designing and using these APIs correctly if you actually took advantage of the ability to not store trailing FPOptions in some case, like when they match the global settings in the ASTContext. That way you'll actually be verifying that everything behaves correctly if nodes don't store FPOptions. If you do that, I think you'll see my point about not having all these easily-confusable functions that do or do not take `ASTContext`s.. > > > > > I think I disagree with @rjmccall that these requiresTrailingStorage should be here at all. I think we should store in the AST ANY programmer opinion, even if they match the global setting. It seems to me that this would be more tolerant of any global-setting rewrites that modules/et-al introduce, as well as make the AST Print consistent. Always storing FPOptions when the user has explicitly overriding it also better captures the programmer's intent. > > > > I covered this elsewhere in the review. If you want to have that tolerance — and I think you should — then expressions should store (and Sema should track) the active pragma state, which can be most easily expressed as a pair of an FPOptions and a mask to apply to the global FPOptions. When you enter a pragma, you clear the relevant bits from the global FPOptions mask. > > > > > > > > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. > > > > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. > > > > > > I meant to say: for a million nodes that don't care in the slightest about FPOptions, as well as for a million more nodes that aren't using pragma overrides. > > Right, I get the intent, and I completely agree with that. My point was EVERY Expr that is affected by a #pragma should store it. Though, after looking at your Macro concern above, I'm less compelled. > > > > I guess was suggesting that the logic for "requiresTrailingStorage" should just be "modified by a pragma" instead of "FPOptions != The global setting". > Well, "modified by a pragma" still wouldn't make the AST agnostic to global settings, since the pragmas don't override everything in FPOptions at once. But I agree that would achieve the most important goal, which is to stop inflating the AST when pragmas *aren't* in effect, which is approximately 100% of the time. In order to do that, though, we'll need to start tracking pragmas, which we should do but which can wait for a follow-up patch. In the meantime, I don't think you're ever going to get the interfaces right for queries like `BinaryOperator::getFPOptions` unless you actually stop relying on the fact that you're unconditionally storing `FPOptions`. You need to passing around ASTContexts for that. That's why I'm suggesting using an exact match with the global settings as a simple thing you can easily check without modifying what data you collect in `FPOptions`. That sounds like a good plan to me. Thanks for entertaining my conversation/questions. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76384/new/ https://reviews.llvm.org/D76384 From cfe-commits at lists.llvm.org Wed Apr 1 11:49:09 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 18:49:09 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: <5ef5e7502440906932093a5b1bd4af5f@localhost.localdomain> rjmccall added inline comments. ================ Comment at: clang/lib/CodeGen/CGDecl.cpp:1814 + if (StopAfter) { + static unsigned Counter = 0; + if (Counter >= StopAfter) ---------------- jcai19 wrote: > rjmccall wrote: > > srhines wrote: > > > MaskRay wrote: > > > > I am a bit worried about the static variable. This makes CodeGen not reusable. > > > The counter could exist in ASTContext instead. > > IRGenModule would be the more appropriate place. > I can't seem to find IRGenModule. Do you mean CodeGenModule by any chance? Thanks. Yes, sorry. The Clang and Swift frontends use slightly different names for the same concept. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 From cfe-commits at lists.llvm.org Wed Apr 1 11:49:11 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 18:49:11 +0000 (UTC) Subject: [PATCH] D76937: Fix infinite recursion in deferred diagnostic emitter In-Reply-To: References: Message-ID: <5c57bc42a04a6d444f76abeb97330d07@localhost.localdomain> yaxunl updated this revision to Diff 254261. yaxunl added a comment. Revised by John's comments. Also only check file scope variables. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76937/new/ https://reviews.llvm.org/D76937 Files: clang/lib/Sema/Sema.cpp clang/lib/Sema/SemaDecl.cpp clang/test/OpenMP/nvptx_target_exceptions_messages.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76937.254261.patch Type: text/x-patch Size: 6161 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 11:49:14 2020 From: cfe-commits at lists.llvm.org (Michael Liao via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 18:49:14 +0000 (UTC) Subject: [PATCH] D59321: AMDGPU: Teach toolchain to link rocm device libs In-Reply-To: References: Message-ID: hliao added a comment. Do we have a better way to avoid adding those empty bitcode files? ================ Comment at: clang/lib/Driver/ToolChains/AMDGPU.h:29 + struct ConditionalLibrary { + SmallString<0> On; + SmallString<0> Off; ---------------- may need to add `llvm` namespace prefix just like all other LLVM stuffs used in clang in case the same name is introduced later by accident. ================ Comment at: clang/lib/Driver/ToolChains/AMDGPU.h:44-46 + //RocmVersion Version = RocmVersion::UNKNOWN; + SmallString<0> InstallPath; + //SmallString<0> BinPath; ---------------- sounds to me that both `Version` and `BinPath` should be added. They will be used eventually. ================ Comment at: clang/lib/Driver/ToolChains/HIP.h:76 -class LLVM_LIBRARY_VISIBILITY HIPToolChain final : public AMDGPUToolChain { +class LLVM_LIBRARY_VISIBILITY HIPToolChain final : public ROCMToolChain { public: ---------------- Do you miss the change in HIP.cpp? That constructor needs revising as the base class is changed. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D59321/new/ https://reviews.llvm.org/D59321 From cfe-commits at lists.llvm.org Wed Apr 1 11:49:14 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 18:49:14 +0000 (UTC) Subject: [PATCH] D76937: Fix infinite recursion in deferred diagnostic emitter In-Reply-To: References: Message-ID: yaxunl updated this revision to Diff 254262. yaxunl added a comment. fix assert message CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76937/new/ https://reviews.llvm.org/D76937 Files: clang/lib/Sema/Sema.cpp clang/lib/Sema/SemaDecl.cpp clang/test/OpenMP/nvptx_target_exceptions_messages.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76937.254262.patch Type: text/x-patch Size: 6152 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 12:04:27 2020 From: cfe-commits at lists.llvm.org (Alexey Bataev via cfe-commits) Date: Wed, 01 Apr 2020 12:04:27 -0700 (PDT) Subject: [clang] c028472 - Revert "[OPENMP50]Add initial support for OpenMP 5.0 iterator." Message-ID: <5e84e5bb.1c69fb81.bfe90.abbf@mx.google.com> Author: Alexey Bataev Date: 2020-04-01T14:54:45-04:00 New Revision: c028472fa1f0e20cc87cfa47d87fe0dd65fea830 URL: https://github.com/llvm/llvm-project/commit/c028472fa1f0e20cc87cfa47d87fe0dd65fea830 DIFF: https://github.com/llvm/llvm-project/commit/c028472fa1f0e20cc87cfa47d87fe0dd65fea830.diff LOG: Revert "[OPENMP50]Add initial support for OpenMP 5.0 iterator." This reverts commit f08df464ae89972a777c0a7e299a2c153a9829d8 to fix the bug with serialization support for iterator expression. Added: Modified: clang/include/clang-c/Index.h clang/include/clang/AST/ASTContext.h clang/include/clang/AST/BuiltinTypes.def clang/include/clang/AST/ComputeDependence.h clang/include/clang/AST/ExprOpenMP.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/AST/TextNodeDumper.h clang/include/clang/Basic/DiagnosticParseKinds.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Basic/StmtNodes.td clang/include/clang/Parse/Parser.h clang/include/clang/Sema/Sema.h clang/include/clang/Serialization/ASTBitCodes.h clang/lib/AST/ASTContext.cpp clang/lib/AST/ComputeDependence.cpp clang/lib/AST/Expr.cpp clang/lib/AST/ExprClassification.cpp clang/lib/AST/ExprConstant.cpp clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/NSAPI.cpp clang/lib/AST/OpenMPClause.cpp clang/lib/AST/StmtPrinter.cpp clang/lib/AST/StmtProfile.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/AST/Type.cpp clang/lib/AST/TypeLoc.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaExceptionSpec.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTCommon.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/Serialization/ASTWriterStmt.cpp clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp clang/lib/StaticAnalyzer/Core/ExprEngine.cpp clang/test/OpenMP/depobj_messages.cpp clang/test/OpenMP/task_ast_print.cpp clang/test/OpenMP/task_depend_messages.cpp clang/tools/libclang/CIndex.cpp clang/tools/libclang/CXCursor.cpp Removed: ################################################################################ diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 0acd50021ed8..641f058dafaa 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2180,12 +2180,7 @@ enum CXCursorKind { */ CXCursor_OMPArrayShapingExpr = 150, - /** - * OpenMP 5.0 [2.1.6 Iterators] - */ - CXCursor_OMPIteratorExpr = 151, - - CXCursor_LastExpr = CXCursor_OMPIteratorExpr, + CXCursor_LastExpr = CXCursor_OMPArrayShapingExpr, /* Statements */ CXCursor_FirstStmt = 200, diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 6813ab58874e..ebb5ca593843 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -970,7 +970,7 @@ class ASTContext : public RefCountedBase { #include "clang/Basic/OpenCLImageTypes.def" CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; CanQualType OCLQueueTy, OCLReserveIDTy; - CanQualType OMPArraySectionTy, OMPArrayShapingTy, OMPIteratorTy; + CanQualType OMPArraySectionTy, OMPArrayShapingTy; #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ CanQualType Id##Ty; #include "clang/Basic/OpenCLExtensionTypes.def" diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index f8eb4ec19c8f..f42503773945 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -316,11 +316,8 @@ PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy) // A placeholder type for OpenMP array shaping operation. PLACEHOLDER_TYPE(OMPArrayShaping, OMPArrayShapingTy) -// A placeholder type for OpenMP iterators. -PLACEHOLDER_TYPE(OMPIterator, OMPIteratorTy) - #ifdef LAST_BUILTIN_TYPE -LAST_BUILTIN_TYPE(OMPIterator) +LAST_BUILTIN_TYPE(OMPArrayShaping) #undef LAST_BUILTIN_TYPE #endif diff --git a/clang/include/clang/AST/ComputeDependence.h b/clang/include/clang/AST/ComputeDependence.h index ab742c9b70dd..63947eaff73b 100644 --- a/clang/include/clang/AST/ComputeDependence.h +++ b/clang/include/clang/AST/ComputeDependence.h @@ -88,7 +88,6 @@ class PseudoObjectExpr; class AtomicExpr; class OMPArraySectionExpr; class OMPArrayShapingExpr; -class OMPIteratorExpr; class ObjCArrayLiteral; class ObjCDictionaryLiteral; class ObjCBoxedExpr; @@ -175,7 +174,6 @@ ExprDependence computeDependence(AtomicExpr *E); ExprDependence computeDependence(OMPArraySectionExpr *E); ExprDependence computeDependence(OMPArrayShapingExpr *E); -ExprDependence computeDependence(OMPIteratorExpr *E); ExprDependence computeDependence(ObjCArrayLiteral *E); ExprDependence computeDependence(ObjCDictionaryLiteral *E); diff --git a/clang/include/clang/AST/ExprOpenMP.h b/clang/include/clang/AST/ExprOpenMP.h index 6059df8b33e7..4a0cd07f1dab 100644 --- a/clang/include/clang/AST/ExprOpenMP.h +++ b/clang/include/clang/AST/ExprOpenMP.h @@ -205,173 +205,6 @@ class OMPArrayShapingExpr final return const_child_range(Begin, Begin + NumDims + 1); } }; - -/// OpenMP 5.0 [2.1.6 Iterators] -/// Iterators are identifiers that expand to multiple values in the clause on -/// which they appear. -/// The syntax of the iterator modifier is as follows: -/// \code -/// iterator(iterators-definition) -/// \endcode -/// where iterators-definition is one of the following: -/// \code -/// iterator-specifier [, iterators-definition ] -/// \endcode -/// where iterator-specifier is one of the following: -/// \code -/// [ iterator-type ] identifier = range-specification -/// \endcode -/// where identifier is a base language identifier. -/// iterator-type is a type name. -/// range-specification is of the form begin:end[:step], where begin and end are -/// expressions for which their types can be converted to iterator-type and step -/// is an integral expression. -/// In an iterator-specifier, if the iterator-type is not specified then the -/// type of that iterator is of int type. -/// The iterator-type must be an integral or pointer type. -/// The iterator-type must not be const qualified. -class OMPIteratorExpr final - : public Expr, - private llvm::TrailingObjects { -public: - /// Iterator range representation begin:end[:step]. - struct IteratorRange { - Expr *Begin = nullptr; - Expr *End = nullptr; - Expr *Step = nullptr; - }; - /// Iterator definition representation. - struct IteratorDefinition { - Decl *IteratorDecl = nullptr; - IteratorRange Range; - SourceLocation AssignmentLoc; - SourceLocation ColonLoc, SecondColonLoc; - }; - -private: - friend TrailingObjects; - friend class ASTStmtReader; - friend class ASTStmtWriter; - - /// Offset in the list of expressions for subelements of the ranges. - enum class RangeExprOffset { - Begin = 0, - End = 1, - Step = 2, - Total = 3, - }; - /// Offset in the list of locations for subelements of colon symbols - /// locations. - enum class RangeLocOffset { - AssignLoc = 0, - FirstColonLoc = 1, - SecondColonLoc = 2, - Total = 3, - }; - /// Location of 'iterator' keyword. - SourceLocation IteratorKwLoc; - /// Location of '('. - SourceLocation LPLoc; - /// Location of ')'. - SourceLocation RPLoc; - /// Number of iterator definitions. - unsigned NumIterators = 0; - - OMPIteratorExpr(QualType ExprTy, SourceLocation IteratorKwLoc, - SourceLocation L, SourceLocation R, - ArrayRef Data); - - /// Construct an empty expression. - explicit OMPIteratorExpr(EmptyShell Shell, unsigned NumIterators) - : Expr(OMPIteratorExprClass, Shell), NumIterators(NumIterators) {} - - /// Sets basic declaration for the specified iterator definition. - void setIteratorDeclaration(unsigned I, Decl *D); - - /// Sets the location of the assignment symbol for the specified iterator - /// definition. - void setAssignmentLoc(unsigned I, SourceLocation Loc); - - /// Sets begin, end and optional step expressions for specified iterator - /// definition. - void setIteratorRange(unsigned I, Expr *Begin, SourceLocation ColonLoc, - Expr *End, SourceLocation SecondColonLoc, Expr *Step); - - unsigned numTrailingObjects(OverloadToken) const { - return NumIterators; - } - - unsigned numTrailingObjects(OverloadToken) const { - return NumIterators * static_cast(RangeExprOffset::Total); - } - - unsigned numTrailingObjects(OverloadToken) const { - return NumIterators * static_cast(RangeLocOffset::Total); - } - -public: - static OMPIteratorExpr *Create(const ASTContext &Context, QualType T, - SourceLocation IteratorKwLoc, SourceLocation L, - SourceLocation R, - ArrayRef Data); - - static OMPIteratorExpr *CreateEmpty(const ASTContext &Context, - unsigned NumIterators); - - SourceLocation getLParenLoc() const { return LPLoc; } - void setLParenLoc(SourceLocation L) { LPLoc = L; } - - SourceLocation getRParenLoc() const { return RPLoc; } - void setRParenLoc(SourceLocation L) { RPLoc = L; } - - SourceLocation getIteratorKwLoc() const { return IteratorKwLoc; } - void setIteratorKwLoc(SourceLocation L) { IteratorKwLoc = L; } - SourceLocation getBeginLoc() const LLVM_READONLY { return IteratorKwLoc; } - SourceLocation getEndLoc() const LLVM_READONLY { return RPLoc; } - - /// Gets the iterator declaration for the given iterator. - Decl *getIteratorDecl(unsigned I); - const Decl *getIteratorDecl(unsigned I) const { - return const_cast(this)->getIteratorDecl(I); - } - - /// Gets the iterator range for the given iterator. - IteratorRange getIteratorRange(unsigned I); - const IteratorRange getIteratorRange(unsigned I) const { - return const_cast(this)->getIteratorRange(I); - } - - /// Gets the location of '=' for the given iterator definition. - SourceLocation getAssignLoc(unsigned I) const; - /// Gets the location of the first ':' in the range for the given iterator - /// definition. - SourceLocation getColonLoc(unsigned I) const; - /// Gets the location of the second ':' (if any) in the range for the given - /// iteratori definition. - SourceLocation getSecondColonLoc(unsigned I) const; - - /// Returns number of iterator definitions. - unsigned numOfIterators() const { return NumIterators; } - - static bool classof(const Stmt *T) { - return T->getStmtClass() == OMPIteratorExprClass; - } - - // Iterators - child_range children() { - Stmt **Begin = reinterpret_cast(getTrailingObjects()); - return child_range( - Begin, Begin + NumIterators * static_cast(RangeExprOffset::Total)); - } - const_child_range children() const { - Stmt *const *Begin = - reinterpret_cast(getTrailingObjects()); - return const_child_range( - Begin, Begin + NumIterators * static_cast(RangeExprOffset::Total)); - } -}; - } // end namespace clang #endif diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 028af6ac9a72..0d4b69911f19 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -4372,9 +4372,6 @@ class OMPDependClause final /// Set colon location. void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } - /// Sets optional dependency modifier. - void setModifier(Expr *DepModifier); - public: /// Creates clause with a list of variables \a VL. /// @@ -4390,7 +4387,7 @@ class OMPDependClause final /// clause. static OMPDependClause *Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, Expr *DepModifier, + SourceLocation EndLoc, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef VL, unsigned NumLoops); @@ -4407,12 +4404,6 @@ class OMPDependClause final /// Get dependency type. OpenMPDependClauseKind getDependencyKind() const { return DepKind; } - /// Return optional depend modifier. - Expr *getModifier(); - const Expr *getModifier() const { - return const_cast(this)->getModifier(); - } - /// Get dependency type location. SourceLocation getDependencyLoc() const { return DepLoc; } diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 345333849659..46661e59f181 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2552,7 +2552,6 @@ DEF_TRAVERSE_STMT(AddrLabelExpr, {}) DEF_TRAVERSE_STMT(ArraySubscriptExpr, {}) DEF_TRAVERSE_STMT(OMPArraySectionExpr, {}) DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {}) -DEF_TRAVERSE_STMT(OMPIteratorExpr, {}) DEF_TRAVERSE_STMT(BlockExpr, { TRY_TO(TraverseDecl(S->getBlockDecl())); diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h index 0fb4baf0ca4d..b08d1e482be8 100644 --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -274,7 +274,6 @@ class TextNodeDumper void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node); void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node); void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node); - void VisitOMPIteratorExpr(const OMPIteratorExpr *Node); void VisitRValueReferenceType(const ReferenceType *T); void VisitArrayType(const ArrayType *T); diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index f3741531c8b5..6eb320a85a30 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1220,10 +1220,6 @@ def err_omp_expected_identifier_for_critical : Error< "expected identifier specifying the name of the 'omp critical' directive">; def err_omp_expected_reduction_identifier : Error< "expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'">; -def err_omp_expected_equal_in_iterator : Error< - "expected '=' in iterator specifier">; -def err_omp_expected_punc_after_iterator : Error< - "expected ',' or ')' after iterator specifier">; def err_omp_decl_in_declare_simd_variant : Error< "function declaration is expected after 'declare %select{simd|variant}0' directive">; def err_omp_unknown_map_type : Error< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 901ac758b383..951a955984f6 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9760,14 +9760,6 @@ def note_omp_conversion_here : Note< def err_omp_ambiguous_conversion : Error< "ambiguous conversion from type %0 to an integral or unscoped " "enumeration type">; -def err_omp_iterator_not_integral_or_pointer : Error< - "expected integral or pointer type as the iterator-type, not %0">; -def err_omp_iterator_constant : Error< - "expected non-constant type as the iterator-type, constant %0 is provided">; -def err_omp_iterator_step_not_integral : Error< - "iterator step expression %0 is not the integral expression">; -def err_omp_iterator_step_constant_zero : Error< - "iterator step expression %0 evaluates to 0">; def err_omp_required_access : Error< "%0 variable must be %1">; def err_omp_const_variable : Error< @@ -9961,7 +9953,6 @@ def err_omp_invalid_mapper: Error< "cannot find a valid user-defined mapper for type %0 with name %1">; def err_omp_array_section_use : Error<"OpenMP array section is not allowed here">; def err_omp_array_shaping_use : Error<"OpenMP array shaping operation is not allowed here">; -def err_omp_iterator_use : Error<"OpenMP iterator is not allowed here">; def err_omp_typecheck_section_value : Error< "subscripted value is not an array or pointer">; def err_omp_typecheck_section_not_integer : Error< @@ -10040,10 +10031,6 @@ def err_omp_depend_sink_source_not_allowed : Error< "'depend(%select{source|sink:vec}0)' clause%select{|s}0 cannot be mixed with 'depend(%select{sink:vec|source}0)' clause%select{s|}0">; def err_omp_depend_zero_length_array_section_not_allowed : Error< "zero-length array section is not allowed in 'depend' clause">; -def err_omp_depend_sink_source_with_modifier : Error< - "depend modifier cannot be used with 'sink' or 'source' depend type">; -def err_omp_depend_modifier_not_iterator : Error< - "expected iterator specification as depend modifier">; def err_omp_linear_ordered : Error< "'linear' clause cannot be specified along with 'ordered' clause with a parameter">; def err_omp_unexpected_schedule_modifier : Error< diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index aecf24f89033..ba1b5ebd6305 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -70,7 +70,6 @@ def OffsetOfExpr : StmtNode; def UnaryExprOrTypeTraitExpr : StmtNode; def ArraySubscriptExpr : StmtNode; def OMPArraySectionExpr : StmtNode; -def OMPIteratorExpr : StmtNode; def CallExpr : StmtNode; def MemberExpr : StmtNode; def CastExpr : StmtNode; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index ca0a5fd68994..290da0006116 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3086,11 +3086,6 @@ class Parser : public CodeCompletionHandler { OMPClause *ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, bool ParseOnly); - /// Parses and creates OpenMP 5.0 iterators expression: - /// = 'iterator' '(' { [ ] identifier = - /// }+ ')' - ExprResult ParseOpenMPIteratorsExpr(); - public: /// Parses simple expression in parens for single-expression clauses of OpenMP /// constructs. @@ -3100,7 +3095,7 @@ class Parser : public CodeCompletionHandler { /// Data used for parsing list of variables in OpenMP clauses. struct OpenMPVarListDataTy { - Expr *DepModOrTailExpr = nullptr; + Expr *TailExpr = nullptr; SourceLocation ColonLoc; SourceLocation RLoc; CXXScopeSpec ReductionOrMapperIdScopeSpec; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index e1365e84a0b3..9a41356ddb70 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -25,7 +25,6 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprObjC.h" -#include "clang/AST/ExprOpenMP.h" #include "clang/AST/ExternalASTSource.h" #include "clang/AST/LocInfoType.h" #include "clang/AST/MangleNumberingContext.h" @@ -4905,21 +4904,6 @@ class Sema final { ArrayRef Dims, ArrayRef Brackets); - /// Data structure for iterator expression. - struct OMPIteratorData { - IdentifierInfo *DeclIdent = nullptr; - SourceLocation DeclIdentLoc; - ParsedType Type; - OMPIteratorExpr::IteratorRange Range; - SourceLocation AssignLoc; - SourceLocation ColonLoc; - SourceLocation SecColonLoc; - }; - - ExprResult ActOnOMPIteratorExpr(Scope *S, SourceLocation IteratorKwLoc, - SourceLocation LLoc, SourceLocation RLoc, - ArrayRef Data); - // This struct is for use by ActOnMemberAccess to allow // BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after // changing the access operator from a '.' to a '->' (to see if that is the @@ -10588,7 +10572,7 @@ class Sema final { SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); OMPClause *ActOnOpenMPVarListClause( - OpenMPClauseKind Kind, ArrayRef Vars, Expr *DepModOrTailExpr, + OpenMPClauseKind Kind, ArrayRef Vars, Expr *TailExpr, const OMPVarListLocTy &Locs, SourceLocation ColonLoc, CXXScopeSpec &ReductionOrMapperIdScopeSpec, DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, @@ -10686,10 +10670,10 @@ class Sema final { SourceLocation EndLoc); /// Called on well-formed 'depend' clause. OMPClause * - ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, - SourceLocation DepLoc, SourceLocation ColonLoc, - ArrayRef VarList, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc); + ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, + SourceLocation ColonLoc, ArrayRef VarList, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc); /// Called on well-formed 'device' clause. OMPClause *ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *Device, SourceLocation StartLoc, diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index e6e9c8570cc8..68bcb26b6df5 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1019,9 +1019,6 @@ namespace serialization { /// The placeholder type for OpenMP array shaping operation. PREDEF_TYPE_OMP_ARRAY_SHAPING = 70, - /// The placeholder type for OpenMP iterator expression. - PREDEF_TYPE_OMP_ITERATOR = 71, - /// OpenCL image types with auto numeration #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ PREDEF_TYPE_##Id##_ID, @@ -1875,7 +1872,6 @@ namespace serialization { STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE, EXPR_OMP_ARRAY_SECTION, EXPR_OMP_ARRAY_SHAPING, - EXPR_OMP_ITERATOR, // ARC EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 1e81e0a67b4d..8bee34e65754 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1389,7 +1389,6 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target, if (LangOpts.OpenMP) { InitBuiltinType(OMPArraySectionTy, BuiltinType::OMPArraySection); InitBuiltinType(OMPArrayShapingTy, BuiltinType::OMPArrayShaping); - InitBuiltinType(OMPIteratorTy, BuiltinType::OMPIterator); } // C99 6.2.5p11. diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp index 3a326f62a2ec..a023ed173184 100644 --- a/clang/lib/AST/ComputeDependence.cpp +++ b/clang/lib/AST/ComputeDependence.cpp @@ -372,22 +372,6 @@ ExprDependence clang::computeDependence(OMPArrayShapingExpr *E) { return D; } -ExprDependence clang::computeDependence(OMPIteratorExpr *E) { - auto D = toExprDependence(E->getType()->getDependence()); - for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) { - if (auto *VD = cast_or_null(E->getIteratorDecl(I))) - D |= toExprDependence(VD->getType()->getDependence()); - OMPIteratorExpr::IteratorRange IR = E->getIteratorRange(I); - if (Expr *BE = IR.Begin) - D |= BE->getDependence(); - if (Expr *EE = IR.End) - D |= EE->getDependence(); - if (Expr *SE = IR.Step) - D |= SE->getDependence(); - } - return D; -} - /// Compute the type-, value-, and instantiation-dependence of a /// declaration reference /// based on the declaration being referenced. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 53ec3b7a93db..fb63897d871f 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -3399,7 +3399,6 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, case ArraySubscriptExprClass: case OMPArraySectionExprClass: case OMPArrayShapingExprClass: - case OMPIteratorExprClass: case MemberExprClass: case ConditionalOperatorClass: case BinaryConditionalOperatorClass: @@ -4618,118 +4617,3 @@ OMPArrayShapingExpr *OMPArrayShapingExpr::CreateEmpty(const ASTContext &Context, alignof(OMPArrayShapingExpr)); return new (Mem) OMPArrayShapingExpr(EmptyShell(), NumDims); } - -void OMPIteratorExpr::setIteratorDeclaration(unsigned I, Decl *D) { - assert(I < NumIterators && - "Idx is greater or equal the number of iterators definitions."); - getTrailingObjects()[I] = D; -} - -void OMPIteratorExpr::setAssignmentLoc(unsigned I, SourceLocation Loc) { - assert(I < NumIterators && - "Idx is greater or equal the number of iterators definitions."); - getTrailingObjects< - SourceLocation>()[I * static_cast(RangeLocOffset::Total) + - static_cast(RangeLocOffset::AssignLoc)] = Loc; -} - -void OMPIteratorExpr::setIteratorRange(unsigned I, Expr *Begin, - SourceLocation ColonLoc, Expr *End, - SourceLocation SecondColonLoc, - Expr *Step) { - assert(I < NumIterators && - "Idx is greater or equal the number of iterators definitions."); - getTrailingObjects()[I * static_cast(RangeExprOffset::Total) + - static_cast(RangeExprOffset::Begin)] = - Begin; - getTrailingObjects()[I * static_cast(RangeExprOffset::Total) + - static_cast(RangeExprOffset::End)] = End; - getTrailingObjects()[I * static_cast(RangeExprOffset::Total) + - static_cast(RangeExprOffset::Step)] = Step; - getTrailingObjects< - SourceLocation>()[I * static_cast(RangeLocOffset::Total) + - static_cast(RangeLocOffset::FirstColonLoc)] = - ColonLoc; - getTrailingObjects< - SourceLocation>()[I * static_cast(RangeLocOffset::Total) + - static_cast(RangeLocOffset::SecondColonLoc)] = - SecondColonLoc; -} - -Decl *OMPIteratorExpr::getIteratorDecl(unsigned I) { - return getTrailingObjects()[I]; -} - -OMPIteratorExpr::IteratorRange OMPIteratorExpr::getIteratorRange(unsigned I) { - IteratorRange Res; - Res.Begin = - getTrailingObjects()[I * static_cast( - RangeExprOffset::Total) + - static_cast(RangeExprOffset::Begin)]; - Res.End = - getTrailingObjects()[I * static_cast( - RangeExprOffset::Total) + - static_cast(RangeExprOffset::End)]; - Res.Step = - getTrailingObjects()[I * static_cast( - RangeExprOffset::Total) + - static_cast(RangeExprOffset::Step)]; - return Res; -} - -SourceLocation OMPIteratorExpr::getAssignLoc(unsigned I) const { - return getTrailingObjects< - SourceLocation>()[I * static_cast(RangeLocOffset::Total) + - static_cast(RangeLocOffset::AssignLoc)]; -} - -SourceLocation OMPIteratorExpr::getColonLoc(unsigned I) const { - return getTrailingObjects< - SourceLocation>()[I * static_cast(RangeLocOffset::Total) + - static_cast(RangeLocOffset::FirstColonLoc)]; -} - -SourceLocation OMPIteratorExpr::getSecondColonLoc(unsigned I) const { - return getTrailingObjects< - SourceLocation>()[I * static_cast(RangeLocOffset::Total) + - static_cast(RangeLocOffset::SecondColonLoc)]; -} - -OMPIteratorExpr::OMPIteratorExpr( - QualType ExprTy, SourceLocation IteratorKwLoc, SourceLocation L, - SourceLocation R, ArrayRef Data) - : Expr(OMPIteratorExprClass, ExprTy, VK_LValue, OK_Ordinary), - IteratorKwLoc(IteratorKwLoc), LPLoc(L), RPLoc(R), - NumIterators(Data.size()) { - for (unsigned I = 0, End = Data.size(); I < End; ++I) { - const IteratorDefinition &D = Data[I]; - setIteratorDeclaration(I, D.IteratorDecl); - setIteratorRange(I, D.Range.Begin, D.ColonLoc, D.Range.End, - D.SecondColonLoc, D.Range.Step); - } - setDependence(computeDependence(this)); -} - -OMPIteratorExpr * -OMPIteratorExpr::Create(const ASTContext &Context, QualType T, - SourceLocation IteratorKwLoc, SourceLocation L, - SourceLocation R, - ArrayRef Data) { - void *Mem = Context.Allocate( - totalSizeToAlloc( - Data.size(), Data.size() * static_cast(RangeExprOffset::Total), - Data.size() * static_cast(RangeLocOffset::Total)), - alignof(OMPIteratorExpr)); - auto *E = new (Mem) OMPIteratorExpr(T, IteratorKwLoc, L, R, Data); - return E; -} - -OMPIteratorExpr *OMPIteratorExpr::CreateEmpty(const ASTContext &Context, - unsigned NumIterators) { - void *Mem = Context.Allocate( - totalSizeToAlloc( - NumIterators, NumIterators * static_cast(RangeExprOffset::Total), - NumIterators * static_cast(RangeLocOffset::Total)), - alignof(OMPIteratorExpr)); - return new (Mem) OMPIteratorExpr(EmptyShell(), NumIterators); -} diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 8587a476a5d9..4505626bb61f 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -141,7 +141,6 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::MSPropertySubscriptExprClass: case Expr::OMPArraySectionExprClass: case Expr::OMPArrayShapingExprClass: - case Expr::OMPIteratorExprClass: return Cl::CL_LValue; // C99 6.5.2.5p5 says that compound literals are lvalues. diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index c6e1cc7b67df..4a11c846f4ab 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -14181,7 +14181,6 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { case Expr::ArraySubscriptExprClass: case Expr::OMPArraySectionExprClass: case Expr::OMPArrayShapingExprClass: - case Expr::OMPIteratorExprClass: case Expr::MemberExprClass: case Expr::CompoundAssignOperatorClass: case Expr::CompoundLiteralExprClass: diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index cb7bd61574ef..4c05990ee410 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3715,7 +3715,6 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { case Expr::RecoveryExprClass: case Expr::OMPArraySectionExprClass: case Expr::OMPArrayShapingExprClass: - case Expr::OMPIteratorExprClass: case Expr::CXXInheritedCtorInitExprClass: llvm_unreachable("unexpected statement kind"); diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp index 3bb3605ea936..2bfe977a5ba5 100644 --- a/clang/lib/AST/NSAPI.cpp +++ b/clang/lib/AST/NSAPI.cpp @@ -484,7 +484,6 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const { case BuiltinType::BuiltinFn: case BuiltinType::OMPArraySection: case BuiltinType::OMPArrayShaping: - case BuiltinType::OMPIterator: break; } diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index eeb690750fb7..4b7ebbb3c26d 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -900,19 +900,16 @@ OMPDepobjClause *OMPDepobjClause::CreateEmpty(const ASTContext &C) { OMPDependClause * OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, - Expr *DepModifier, OpenMPDependClauseKind DepKind, - SourceLocation DepLoc, SourceLocation ColonLoc, - ArrayRef VL, unsigned NumLoops) { - void *Mem = C.Allocate( - totalSizeToAlloc(VL.size() + /*depend-modifier*/ 1 + NumLoops), - alignof(OMPDependClause)); + OpenMPDependClauseKind DepKind, SourceLocation DepLoc, + SourceLocation ColonLoc, ArrayRef VL, + unsigned NumLoops) { + void *Mem = C.Allocate(totalSizeToAlloc(VL.size() + NumLoops)); OMPDependClause *Clause = new (Mem) OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops); Clause->setVarRefs(VL); Clause->setDependencyKind(DepKind); Clause->setDependencyLoc(DepLoc); Clause->setColonLoc(ColonLoc); - Clause->setModifier(DepModifier); for (unsigned I = 0 ; I < NumLoops; ++I) Clause->setLoopData(I, nullptr); return Clause; @@ -920,9 +917,7 @@ OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc, OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N, unsigned NumLoops) { - void *Mem = - C.Allocate(totalSizeToAlloc(N + /*depend-modifier*/ 1 + NumLoops), - alignof(OMPDependClause)); + void *Mem = C.Allocate(totalSizeToAlloc(N + NumLoops)); return new (Mem) OMPDependClause(N, NumLoops); } @@ -932,7 +927,7 @@ void OMPDependClause::setLoopData(unsigned NumLoop, Expr *Cnt) { NumLoop < NumLoops && "Expected sink or source depend + loop index must be less number of " "loops."); - auto *It = std::next(getVarRefs().end(), NumLoop + 1); + auto It = std::next(getVarRefs().end(), NumLoop); *It = Cnt; } @@ -942,7 +937,7 @@ Expr *OMPDependClause::getLoopData(unsigned NumLoop) { NumLoop < NumLoops && "Expected sink or source depend + loop index must be less number of " "loops."); - auto *It = std::next(getVarRefs().end(), NumLoop + 1); + auto It = std::next(getVarRefs().end(), NumLoop); return *It; } @@ -952,15 +947,10 @@ const Expr *OMPDependClause::getLoopData(unsigned NumLoop) const { NumLoop < NumLoops && "Expected sink or source depend + loop index must be less number of " "loops."); - const auto *It = std::next(getVarRefs().end(), NumLoop + 1); + auto It = std::next(getVarRefs().end(), NumLoop); return *It; } -void OMPDependClause::setModifier(Expr *DepModifier) { - *getVarRefs().end() = DepModifier; -} -Expr *OMPDependClause::getModifier() { return *getVarRefs().end(); } - unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber( MappableExprComponentListsRef ComponentLists) { unsigned TotalNum = 0u; @@ -1737,10 +1727,6 @@ void OMPClausePrinter::VisitOMPDepobjClause(OMPDepobjClause *Node) { void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) { OS << "depend("; - if (Expr *DepModifier = Node->getModifier()) { - DepModifier->printPretty(OS, nullptr, Policy); - OS << ", "; - } OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Node->getDependencyKind()); if (!Node->varlist_empty()) { diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 26e1a5009565..3d03f3902d61 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1361,24 +1361,6 @@ void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) { PrintExpr(Node->getBase()); } -void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) { - OS << "iterator("; - for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) { - auto *VD = cast(Node->getIteratorDecl(I)); - VD->getType().print(OS, Policy); - const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I); - OS << " " << VD->getName() << " = "; - PrintExpr(Range.Begin); - OS << ":"; - PrintExpr(Range.End); - if (Node->getSecondColonLoc(I).isValid()) - PrintExpr(Range.Step); - if (I < E - 1) - OS << ", "; - } - OS << ")"; -} - void StmtPrinter::PrintCallArgs(CallExpr *Call) { for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { if (isa(Call->getArg(i))) { diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index fec12ac98b4e..054276a98424 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -1198,12 +1198,6 @@ void StmtProfiler::VisitOMPArrayShapingExpr(const OMPArrayShapingExpr *S) { VisitExpr(S); } -void StmtProfiler::VisitOMPIteratorExpr(const OMPIteratorExpr *S) { - VisitExpr(S); - for (unsigned I = 0, E = S->numOfIterators(); I < E; ++I) - VisitDecl(S->getIteratorDecl(I)); -} - void StmtProfiler::VisitCallExpr(const CallExpr *S) { VisitExpr(S); } diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index dc0dd92f09df..6a6d8692228a 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1086,23 +1086,6 @@ void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) { OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); } -void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) { - OS << " "; - for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) { - Visit(Node->getIteratorDecl(I)); - OS << " = "; - const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I); - OS << " begin "; - Visit(Range.Begin); - OS << " end "; - Visit(Range.End); - if (Range.Step) { - OS << " step "; - Visit(Range.Step); - } - } -} - void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) { if (T->isSpelledAsLValue()) OS << " written as lvalue reference"; diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 3428437c3146..f90eb5cb9c92 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2910,8 +2910,6 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { return ""; case OMPArrayShaping: return ""; - case OMPIterator: - return ""; #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ case Id: \ return #ExtType; @@ -3919,7 +3917,6 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const { case BuiltinType::NullPtr: case BuiltinType::OMPArraySection: case BuiltinType::OMPArrayShaping: - case BuiltinType::OMPIterator: return false; } llvm_unreachable("unknown builtin type"); diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index 50391dba2a05..dd48ae3fc262 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -405,7 +405,6 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const { case BuiltinType::BuiltinFn: case BuiltinType::OMPArraySection: case BuiltinType::OMPArrayShaping: - case BuiltinType::OMPIterator: return TST_unspecified; } diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 42083b8b921e..147d1b271d0c 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -755,8 +755,7 @@ static bool parseDeclareSimdClauses( getOpenMPClauseKind(ClauseName), *Vars, Data)) IsError = true; if (CKind == OMPC_aligned) { - Alignments.append(Aligneds.size() - Alignments.size(), - Data.DepModOrTailExpr); + Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr); } else if (CKind == OMPC_linear) { assert(0 <= Data.ExtraModifier && Data.ExtraModifier <= OMPC_LINEAR_unknown && @@ -767,7 +766,7 @@ static bool parseDeclareSimdClauses( Data.ExtraModifier = OMPC_LINEAR_val; LinModifiers.append(Linears.size() - LinModifiers.size(), Data.ExtraModifier); - Steps.append(Linears.size() - Steps.size(), Data.DepModOrTailExpr); + Steps.append(Linears.size() - Steps.size(), Data.TailExpr); } } else // TODO: add parsing of other clauses. @@ -3055,114 +3054,6 @@ static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) { P.ConsumeToken(); } -/// Parses simple expression in parens for single-expression clauses of OpenMP -/// constructs. -/// \param RLoc Returned location of right paren. -ExprResult Parser::ParseOpenMPIteratorsExpr() { - assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator" && - "Expected 'iterator' token."); - SourceLocation IteratorKwLoc = ConsumeToken(); - - BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); - if (T.expectAndConsume(diag::err_expected_lparen_after, "iterator")) - return ExprError(); - - SourceLocation LLoc = T.getOpenLocation(); - SmallVector Data; - while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) { - // Check if the type parsing is required. - ParsedType IteratorType; - if (Tok.isNot(tok::identifier) || NextToken().isNot(tok::equal)) { - // identifier '=' is not found - parse type. - TypeResult TR = ParseTypeName(); - if (TR.isInvalid()) { - T.skipToEnd(); - return ExprError(); - } - IteratorType = TR.get(); - } - - // Parse identifier. - IdentifierInfo *II = nullptr; - SourceLocation IdLoc; - if (Tok.is(tok::identifier)) { - II = Tok.getIdentifierInfo(); - IdLoc = ConsumeToken(); - } else { - Diag(Tok, diag::err_expected_unqualified_id) << 0; - } - - // Parse '='. - SourceLocation AssignLoc; - if (Tok.is(tok::equal)) - AssignLoc = ConsumeToken(); - else - Diag(Tok, diag::err_omp_expected_equal_in_iterator); - - // Parse range-specification - ':' [ ':' ] - ColonProtectionRAIIObject ColonRAII(*this); - // Parse - SourceLocation Loc = Tok.getLocation(); - ExprResult LHS = ParseCastExpression(AnyCastExpr); - ExprResult Begin = Actions.CorrectDelayedTyposInExpr( - ParseRHSOfBinaryExpression(LHS, prec::Conditional)); - Begin = Actions.ActOnFinishFullExpr(Begin.get(), Loc, - /*DiscardedValue=*/false); - // Parse ':'. - SourceLocation ColonLoc; - if (Tok.is(tok::colon)) - ColonLoc = ConsumeToken(); - - // Parse - Loc = Tok.getLocation(); - LHS = ParseCastExpression(AnyCastExpr); - ExprResult End = Actions.CorrectDelayedTyposInExpr( - ParseRHSOfBinaryExpression(LHS, prec::Conditional)); - End = Actions.ActOnFinishFullExpr(End.get(), Loc, - /*DiscardedValue=*/false); - - SourceLocation SecColonLoc; - ExprResult Step; - // Parse optional step. - if (Tok.is(tok::colon)) { - // Parse ':' - ColonLoc = ConsumeToken(); - // Parse - Loc = Tok.getLocation(); - LHS = ParseCastExpression(AnyCastExpr); - Step = Actions.CorrectDelayedTyposInExpr( - ParseRHSOfBinaryExpression(LHS, prec::Conditional)); - Step = Actions.ActOnFinishFullExpr(Step.get(), Loc, - /*DiscardedValue=*/false); - } - - // Parse ',' or ')' - if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren)) - Diag(Tok, diag::err_omp_expected_punc_after_iterator); - if (Tok.is(tok::comma)) - ConsumeToken(); - - Sema::OMPIteratorData &D = Data.emplace_back(); - D.DeclIdent = II; - D.DeclIdentLoc = IdLoc; - D.Type = IteratorType; - D.AssignLoc = AssignLoc; - D.ColonLoc = ColonLoc; - D.SecColonLoc = SecColonLoc; - D.Range.Begin = Begin.get(); - D.Range.End = End.get(); - D.Range.Step = Step.get(); - } - - // Parse ')'. - SourceLocation RLoc = Tok.getLocation(); - if (!T.consumeClose()) - RLoc = T.getCloseLocation(); - - return Actions.ActOnOMPIteratorExpr(getCurScope(), IteratorKwLoc, LLoc, RLoc, - Data); -} - /// Parses clauses with list. bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, @@ -3178,7 +3069,6 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, getOpenMPClauseName(Kind))) return true; - bool DependWithIterator = false; bool NeedRParenForLinear = false; BalancedDelimiterTracker LinearT(*this, tok::l_paren, tok::annot_pragma_openmp_end); @@ -3216,22 +3106,6 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Data.ReductionOrMapperId = Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId); } else if (Kind == OMPC_depend) { - if (getLangOpts().OpenMP >= 50) { - if (Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator") { - // Handle optional dependence modifier. - // iterator(iterators-definition) - // where iterators-definition is iterator-specifier [, - // iterators-definition ] - // where iterator-specifier is [ iterator-type ] identifier = - // range-specification - DependWithIterator = true; - EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope); - ExprResult IteratorRes = ParseOpenMPIteratorsExpr(); - Data.DepModOrTailExpr = IteratorRes.get(); - // Parse ',' - ExpectAndConsume(tok::comma); - } - } // Handle dependency type for depend clause. ColonProtectionRAIIObject ColonRAII(*this); Data.ExtraModifier = getOpenMPSimpleClauseType( @@ -3353,7 +3227,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, /*DiscardedValue=*/false); if (Tail.isUsable()) { if (Tok.is(tok::colon)) { - Data.DepModOrTailExpr = Tail.get(); + Data.TailExpr = Tail.get(); Data.ColonLoc = ConsumeToken(); TPA.Commit(); } else { @@ -3379,7 +3253,6 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned); while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) && Tok.isNot(tok::annot_pragma_openmp_end))) { - ParseScope OMPListScope(this, Scope::OpenMPDirectiveScope); ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail); // Parse variable ExprResult VarExpr = @@ -3416,7 +3289,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false); if (Tail.isUsable()) - Data.DepModOrTailExpr = Tail.get(); + Data.TailExpr = Tail.get(); else SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); @@ -3426,11 +3299,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Data.RLoc = Tok.getLocation(); if (!T.consumeClose()) Data.RLoc = T.getCloseLocation(); - // Exit from scope when the iterator is used in depend clause. - if (DependWithIterator) - ExitScope(); return (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) || - (MustHaveTail && !Data.DepModOrTailExpr) || InvalidReductionId || + (MustHaveTail && !Data.TailExpr) || InvalidReductionId || IsInvalidMapperModifier; } @@ -3502,7 +3372,7 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, return nullptr; OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc); return Actions.ActOnOpenMPVarListClause( - Kind, Vars, Data.DepModOrTailExpr, Locs, Data.ColonLoc, + Kind, Vars, Data.TailExpr, Locs, Data.ColonLoc, Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, Data.ExtraModifier, Data.MapTypeModifiers, Data.MapTypeModifiersLoc, Data.IsMapTypeImplicit, Data.ExtraModifierLoc); diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 0dc0c68205fb..fad2ae1cc066 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1300,7 +1300,6 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Expr::ArraySubscriptExprClass: case Expr::OMPArraySectionExprClass: case Expr::OMPArrayShapingExprClass: - case Expr::OMPIteratorExprClass: case Expr::BinaryOperatorClass: case Expr::DependentCoawaitExprClass: case Expr::CompoundAssignOperatorClass: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8d0e97c85771..c0f8600aa0cc 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4873,131 +4873,6 @@ ExprResult Sema::ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, LParenLoc, RParenLoc, NewDims, Brackets); } -ExprResult Sema::ActOnOMPIteratorExpr(Scope *S, SourceLocation IteratorKwLoc, - SourceLocation LLoc, SourceLocation RLoc, - ArrayRef Data) { - SmallVector ID; - bool IsCorrect = true; - for (const OMPIteratorData &D : Data) { - TypeSourceInfo *TInfo = nullptr; - SourceLocation StartLoc; - QualType DeclTy; - if (!D.Type.getAsOpaquePtr()) { - // OpenMP 5.0, 2.1.6 Iterators - // In an iterator-specifier, if the iterator-type is not specified then - // the type of that iterator is of int type. - DeclTy = Context.IntTy; - StartLoc = D.DeclIdentLoc; - } else { - DeclTy = GetTypeFromParser(D.Type, &TInfo); - StartLoc = TInfo->getTypeLoc().getBeginLoc(); - } - - bool IsDeclTyDependent = DeclTy->isDependentType() || - DeclTy->containsUnexpandedParameterPack() || - DeclTy->isInstantiationDependentType(); - if (!IsDeclTyDependent) { - if (!DeclTy->isIntegralType(Context) && !DeclTy->isAnyPointerType()) { - // OpenMP 5.0, 2.1.6 Iterators, Restrictions, C/C++ - // The iterator-type must be an integral or pointer type. - Diag(StartLoc, diag::err_omp_iterator_not_integral_or_pointer) - << DeclTy; - IsCorrect = false; - continue; - } - if (DeclTy.isConstant(Context)) { - // OpenMP 5.0, 2.1.6 Iterators, Restrictions, C/C++ - // The iterator-type must not be const qualified. - Diag(StartLoc, diag::err_omp_iterator_not_integral_or_pointer) - << DeclTy; - IsCorrect = false; - continue; - } - } - - // Iterator declaration. - assert(D.DeclIdent && "Identifier expected."); - // Always try to create iterator declarator to avoid extra error messages - // about unknown declarations use. - auto *VD = VarDecl::Create(Context, CurContext, StartLoc, D.DeclIdentLoc, - D.DeclIdent, DeclTy, TInfo, SC_None); - VD->setImplicit(); - if (S) { - // Check for conflicting previous declaration. - DeclarationNameInfo NameInfo(VD->getDeclName(), D.DeclIdentLoc); - LookupResult Previous(*this, NameInfo, LookupOrdinaryName, - ForVisibleRedeclaration); - Previous.suppressDiagnostics(); - LookupName(Previous, S); - - FilterLookupForScope(Previous, CurContext, S, /*ConsiderLinkage=*/false, - /*AllowInlineNamespace=*/false); - if (!Previous.empty()) { - NamedDecl *Old = Previous.getRepresentativeDecl(); - Diag(D.DeclIdentLoc, diag::err_redefinition) << VD->getDeclName(); - Diag(Old->getLocation(), diag::note_previous_definition); - } else { - PushOnScopeChains(VD, S); - } - } else { - CurContext->addDecl(VD); - } - Expr *Begin = D.Range.Begin; - if (!IsDeclTyDependent && Begin && !Begin->isTypeDependent()) { - ExprResult BeginRes = - PerformImplicitConversion(Begin, DeclTy, AA_Converting); - Begin = BeginRes.get(); - } - Expr *End = D.Range.End; - if (!IsDeclTyDependent && End && !End->isTypeDependent()) { - ExprResult EndRes = PerformImplicitConversion(End, DeclTy, AA_Converting); - End = EndRes.get(); - } - Expr *Step = D.Range.Step; - if (!IsDeclTyDependent && Step && !Step->isTypeDependent()) { - if (!Step->getType()->isIntegralType(Context)) { - Diag(Step->getExprLoc(), diag::err_omp_iterator_step_not_integral) - << Step << Step->getSourceRange(); - IsCorrect = false; - continue; - } - llvm::APSInt Result; - bool IsConstant = Step->isIntegerConstantExpr(Result, Context); - // OpenMP 5.0, 2.1.6 Iterators, Restrictions - // If the step expression of a range-specification equals zero, the - // behavior is unspecified. - if (IsConstant && Result.isNullValue()) { - Diag(Step->getExprLoc(), diag::err_omp_iterator_step_constant_zero) - << Step << Step->getSourceRange(); - IsCorrect = false; - continue; - } - } - if (!Begin || !End || !IsCorrect) { - IsCorrect = false; - continue; - } - OMPIteratorExpr::IteratorDefinition &IDElem = ID.emplace_back(); - IDElem.IteratorDecl = VD; - IDElem.AssignmentLoc = D.AssignLoc; - IDElem.Range.Begin = Begin; - IDElem.Range.End = End; - IDElem.Range.Step = Step; - IDElem.ColonLoc = D.ColonLoc; - IDElem.SecondColonLoc = D.SecColonLoc; - } - if (!IsCorrect) { - // Invalidate all created iterator declarations if error is found. - for (const OMPIteratorExpr::IteratorDefinition &D : ID) { - if (Decl *ID = D.IteratorDecl) - ID->setInvalidDecl(); - } - return ExprError(); - } - return OMPIteratorExpr::Create(Context, Context.OMPIteratorTy, IteratorKwLoc, - LLoc, RLoc, ID); -} - ExprResult Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc) { @@ -5759,7 +5634,6 @@ static bool isPlaceholderToRemoveAsArg(QualType type) { case BuiltinType::BuiltinFn: case BuiltinType::OMPArraySection: case BuiltinType::OMPArrayShaping: - case BuiltinType::OMPIterator: return true; } @@ -18639,9 +18513,6 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { case BuiltinType::OMPArrayShaping: return ExprError(Diag(E->getBeginLoc(), diag::err_omp_array_shaping_use)); - case BuiltinType::OMPIterator: - return ExprError(Diag(E->getBeginLoc(), diag::err_omp_iterator_use)); - // Everything else should be impossible. #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ case BuiltinType::Id: diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index df56c3be43fc..7d2ae172fe4d 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -13053,7 +13053,7 @@ OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, } OMPClause *Sema::ActOnOpenMPVarListClause( - OpenMPClauseKind Kind, ArrayRef VarList, Expr *DepModOrTailExpr, + OpenMPClauseKind Kind, ArrayRef VarList, Expr *TailExpr, const OMPVarListLocTy &Locs, SourceLocation ColonLoc, CXXScopeSpec &ReductionOrMapperIdScopeSpec, DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, @@ -13103,13 +13103,13 @@ OMPClause *Sema::ActOnOpenMPVarListClause( assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && "Unexpected linear modifier."); Res = ActOnOpenMPLinearClause( - VarList, DepModOrTailExpr, StartLoc, LParenLoc, + VarList, TailExpr, StartLoc, LParenLoc, static_cast(ExtraModifier), ExtraModifierLoc, ColonLoc, EndLoc); break; case OMPC_aligned: - Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, - LParenLoc, ColonLoc, EndLoc); + Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, + ColonLoc, EndLoc); break; case OMPC_copyin: Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); @@ -13124,8 +13124,8 @@ OMPClause *Sema::ActOnOpenMPVarListClause( assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && "Unexpected depend modifier."); Res = ActOnOpenMPDependClause( - DepModOrTailExpr, static_cast(ExtraModifier), - ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); + static_cast(ExtraModifier), ExtraModifierLoc, + ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); break; case OMPC_map: assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && @@ -13150,8 +13150,8 @@ OMPClause *Sema::ActOnOpenMPVarListClause( Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); break; case OMPC_allocate: - Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, - LParenLoc, ColonLoc, EndLoc); + Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, + ColonLoc, EndLoc); break; case OMPC_nontemporal: Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); @@ -15642,7 +15642,7 @@ OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, } OMPClause * -Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, +Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { @@ -15664,26 +15664,12 @@ Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, Except.push_back(OMPC_DEPEND_sink); if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) Except.push_back(OMPC_DEPEND_depobj); - std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) - ? "depend modifier(iterator) or " - : ""; Diag(DepLoc, diag::err_omp_unexpected_clause_value) - << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, - /*Last=*/OMPC_DEPEND_unknown, - Except) + << getListOfPossibleValues(OMPC_depend, /*First=*/0, + /*Last=*/OMPC_DEPEND_unknown, Except) << getOpenMPClauseName(OMPC_depend); return nullptr; } - if (DepModifier && - (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { - Diag(DepModifier->getExprLoc(), - diag::err_omp_depend_sink_source_with_modifier); - return nullptr; - } - if (DepModifier && - !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) - Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); - SmallVector Vars; DSAStackTy::OperatorOffsetTy OpsOffs; llvm::APSInt DepCounter(/*BitWidth=*/32); @@ -15892,8 +15878,8 @@ Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, return nullptr; auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, - DepModifier, DepKind, DepLoc, ColonLoc, - Vars, TotalDepCount.getZExtValue()); + DepKind, DepLoc, ColonLoc, Vars, + TotalDepCount.getZExtValue()); if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && DSAStack->isParentOrderedRegion()) DSAStack->addDoacrossDependClause(C, OpsOffs); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index de05d436d3b9..82cfa246e3f7 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1842,13 +1842,12 @@ class TreeTransform { /// By default, performs semantic analysis to build the new OpenMP clause. /// Subclasses may override this routine to provide diff erent behavior. OMPClause * - RebuildOMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, - SourceLocation DepLoc, SourceLocation ColonLoc, - ArrayRef VarList, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc) { - return getSema().ActOnOpenMPDependClause(DepModifier, DepKind, DepLoc, - ColonLoc, VarList, StartLoc, - LParenLoc, EndLoc); + RebuildOMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, + SourceLocation ColonLoc, ArrayRef VarList, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) { + return getSema().ActOnOpenMPDependClause(DepKind, DepLoc, ColonLoc, VarList, + StartLoc, LParenLoc, EndLoc); } /// Build a new OpenMP 'device' clause. @@ -2392,17 +2391,6 @@ class TreeTransform { BracketsRanges); } - /// Build a new iterator expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide diff erent behavior. - ExprResult RebuildOMPIteratorExpr( - SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc, - ArrayRef Data) { - return getSema().ActOnOMPIteratorExpr(/*Scope=*/nullptr, IteratorKwLoc, - LLoc, RLoc, Data); - } - /// Build a new call expression. /// /// By default, performs semantic analysis to build the new expression. @@ -9303,13 +9291,6 @@ template OMPClause * TreeTransform::TransformOMPDependClause(OMPDependClause *C) { llvm::SmallVector Vars; - Expr *DepModifier = C->getModifier(); - if (DepModifier) { - ExprResult DepModRes = getDerived().TransformExpr(DepModifier); - if (DepModRes.isInvalid()) - return nullptr; - DepModifier = DepModRes.get(); - } Vars.reserve(C->varlist_size()); for (auto *VE : C->varlists()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); @@ -9318,9 +9299,8 @@ TreeTransform::TransformOMPDependClause(OMPDependClause *C) { Vars.push_back(EVar.get()); } return getDerived().RebuildOMPDependClause( - DepModifier, C->getDependencyKind(), C->getDependencyLoc(), - C->getColonLoc(), Vars, C->getBeginLoc(), C->getLParenLoc(), - C->getEndLoc()); + C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(), Vars, + C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); } template @@ -10074,65 +10054,6 @@ TreeTransform::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) { E->getBracketsRanges()); } -template -ExprResult -TreeTransform::TransformOMPIteratorExpr(OMPIteratorExpr *E) { - unsigned NumIterators = E->numOfIterators(); - SmallVector Data(NumIterators); - - bool ErrorFound = false; - bool NeedToRebuild = getDerived().AlwaysRebuild(); - for (unsigned I = 0; I < NumIterators; ++I) { - auto *D = cast(E->getIteratorDecl(I)); - Data[I].DeclIdent = D->getIdentifier(); - Data[I].DeclIdentLoc = D->getLocation(); - if (D->getLocation() == D->getBeginLoc()) { - assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) && - "Implicit type must be int."); - } else { - TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo()); - QualType DeclTy = getDerived().TransformType(D->getType()); - Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI); - } - OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I); - ExprResult Begin = getDerived().TransformExpr(Range.Begin); - ExprResult End = getDerived().TransformExpr(Range.End); - ExprResult Step = getDerived().TransformExpr(Range.Step); - ErrorFound = ErrorFound || - !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() && - !Data[I].Type.get().isNull())) || - Begin.isInvalid() || End.isInvalid() || Step.isInvalid(); - if (ErrorFound) - continue; - Data[I].Range.Begin = Begin.get(); - Data[I].Range.End = End.get(); - Data[I].Range.Step = Step.get(); - Data[I].AssignLoc = E->getAssignLoc(I); - Data[I].ColonLoc = E->getColonLoc(I); - Data[I].SecColonLoc = E->getSecondColonLoc(I); - NeedToRebuild = - NeedToRebuild || - (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() != - D->getType().getTypePtrOrNull()) || - Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End || - Range.Step != Data[I].Range.Step; - } - if (ErrorFound) - return ExprError(); - if (!NeedToRebuild) - return E; - - ExprResult Res = getDerived().RebuildOMPIteratorExpr( - E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data); - if (!Res.isUsable()) - return Res; - auto *IE = cast(Res.get()); - for (unsigned I = 0; I < NumIterators; ++I) - getDerived().transformedLocalDecl(E->getIteratorDecl(I), - IE->getIteratorDecl(I)); - return Res; -} - template ExprResult TreeTransform::TransformCallExpr(CallExpr *E) { diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp index 566bda2d71f7..158a12f0329d 100644 --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -246,9 +246,6 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) { case BuiltinType::OMPArrayShaping: ID = PREDEF_TYPE_OMP_ARRAY_SHAPING; break; - case BuiltinType::OMPIterator: - ID = PREDEF_TYPE_OMP_ITERATOR; - break; } return TypeIdx(ID); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index d4764229abfc..7437f649a090 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -6960,9 +6960,6 @@ QualType ASTReader::GetType(TypeID ID) { case PREDEF_TYPE_OMP_ARRAY_SHAPING: T = Context.OMPArraySectionTy; break; - case PREDEF_TYPE_OMP_ITERATOR: - T = Context.OMPIteratorTy; - break; #define SVE_TYPE(Name, Id, SingletonId) \ case PREDEF_TYPE_##Id##_ID: \ T = Context.SingletonId; \ @@ -12310,7 +12307,6 @@ void OMPClauseReader::VisitOMPDepobjClause(OMPDepobjClause *C) { void OMPClauseReader::VisitOMPDependClause(OMPDependClause *C) { C->setLParenLoc(Record.readSourceLocation()); - C->setModifier(Record.readSubExpr()); C->setDependencyKind( static_cast(Record.readInt())); C->setDependencyLoc(Record.readSourceLocation()); diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index d5f2213aaabe..bc8c231731e8 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -927,24 +927,6 @@ void ASTStmtReader::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { E->setRParenLoc(readSourceLocation()); } -void ASTStmtReader::VisitOMPIteratorExpr(OMPIteratorExpr *E) { - VisitExpr(E); - unsigned NumIterators = Record.readInt(); - E->setIteratorKwLoc(readSourceLocation()); - E->setLParenLoc(readSourceLocation()); - E->setRParenLoc(readSourceLocation()); - for (unsigned I = 0; I < NumIterators; ++I) { - E->setIteratorDeclaration(I, Record.readDeclRef()); - E->setAssignmentLoc(I, readSourceLocation()); - Expr *Begin = Record.readSubExpr(); - Expr *End = Record.readSubExpr(); - Expr *Step = Record.readSubExpr(); - SourceLocation ColonLoc = readSourceLocation(); - SourceLocation SecColonLoc = readSourceLocation(); - E->setIteratorRange(I, Begin, ColonLoc, End, SecColonLoc, Step); - } -} - void ASTStmtReader::VisitCallExpr(CallExpr *E) { VisitExpr(E); unsigned NumArgs = Record.readInt(); @@ -2905,11 +2887,6 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Context, Record[ASTStmtReader::NumExprFields]); break; - case EXPR_OMP_ITERATOR: - S = OMPIteratorExpr::CreateEmpty(Context, - Record[ASTStmtReader::NumExprFields]); - break; - case EXPR_CALL: S = CallExpr::CreateEmpty( Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 27f44a706f9f..f7c58ed11d9f 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6379,7 +6379,6 @@ void OMPClauseWriter::VisitOMPDependClause(OMPDependClause *C) { Record.push_back(C->varlist_size()); Record.push_back(C->getNumLoops()); Record.AddSourceLocation(C->getLParenLoc()); - Record.AddStmt(C->getModifier()); Record.push_back(C->getDependencyKind()); Record.AddSourceLocation(C->getDependencyLoc()); Record.AddSourceLocation(C->getColonLoc()); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 5a56b265b781..840823298be7 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -787,25 +787,6 @@ void ASTStmtWriter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { Code = serialization::EXPR_OMP_ARRAY_SHAPING; } -void ASTStmtWriter::VisitOMPIteratorExpr(OMPIteratorExpr *E) { - VisitExpr(E); - Record.push_back(E->numOfIterators()); - Record.AddSourceLocation(E->getIteratorKwLoc()); - Record.AddSourceLocation(E->getLParenLoc()); - Record.AddSourceLocation(E->getRParenLoc()); - for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) { - Record.AddDeclRef(E->getIteratorDecl(I)); - Record.AddSourceLocation(E->getAssignLoc(I)); - OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I); - Record.AddStmt(Range.Begin); - Record.AddStmt(Range.End); - Record.AddStmt(Range.Step); - Record.AddSourceLocation(E->getColonLoc(I)); - Record.AddSourceLocation(E->getSecondColonLoc(I)); - } - Code = serialization::EXPR_OMP_ITERATOR; -} - void ASTStmtWriter::VisitCallExpr(CallExpr *E) { VisitExpr(E); Record.push_back(E->getNumArgs()); diff --git a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp index 1cf81b54e77d..d16410a19b97 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp @@ -352,7 +352,6 @@ static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1, case Stmt::ArraySubscriptExprClass: case Stmt::OMPArraySectionExprClass: case Stmt::OMPArrayShapingExprClass: - case Stmt::OMPIteratorExprClass: case Stmt::ImplicitCastExprClass: case Stmt::ParenExprClass: case Stmt::BreakStmtClass: diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 1f0d89d59120..4c0914628a0d 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1414,7 +1414,6 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::CXXNullPtrLiteralExprClass: case Stmt::OMPArraySectionExprClass: case Stmt::OMPArrayShapingExprClass: - case Stmt::OMPIteratorExprClass: case Stmt::TypeTraitExprClass: { Bldr.takeNodes(Pred); ExplodedNodeSet preVisit; diff --git a/clang/test/OpenMP/depobj_messages.cpp b/clang/test/OpenMP/depobj_messages.cpp index 1b20b1c525e7..a33b16f985a0 100644 --- a/clang/test/OpenMP/depobj_messages.cpp +++ b/clang/test/OpenMP/depobj_messages.cpp @@ -142,7 +142,7 @@ label1 : { #pragma omp parallel depobj(argc) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}} ; #pragma omp depobj(x) seq_cst // expected-error {{unexpected OpenMP clause 'seq_cst' in directive '#pragma omp depobj'}} -#pragma omp depobj(x) depend(source: x) // expected-error {{expected depend modifier(iterator) or 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp depobj(x) depend(source: x) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} #pragma omp depobj(x) update // expected-error {{expected '(' after 'update'}} #pragma omp depobj(x) update( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'update'}} #pragma omp depobj(x) update(sink // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'update'}} diff --git a/clang/test/OpenMP/task_ast_print.cpp b/clang/test/OpenMP/task_ast_print.cpp index c465a1b1b07f..1da6c5045934 100644 --- a/clang/test/OpenMP/task_ast_print.cpp +++ b/clang/test/OpenMP/task_ast_print.cpp @@ -26,7 +26,7 @@ struct S1 { template class S7 : public T { protected: - T a, b, c[10], d[10]; + T a, b; S7() : a(0) {} public: @@ -34,7 +34,7 @@ class S7 : public T { omp_depend_t x; omp_event_handle_t evt; #pragma omp taskgroup allocate(b) task_reduction(+:b) -#pragma omp task private(a) private(this->a) private(T::a) in_reduction(+:this->b) allocate(b) depend(depobj:x) detach(evt) depend(iterator(i=0:10:1, T *k = &a:&b), in: c[i], d[(int)(k-&a)]) +#pragma omp task private(a) private(this->a) private(T::a) in_reduction(+:this->b) allocate(b) depend(depobj:x) detach(evt) for (int k = 0; k < a.a; ++k) ++this->a.a; } @@ -47,9 +47,9 @@ class S7 : public T { }; // CHECK: #pragma omp taskgroup allocate(this->b) task_reduction(+: this->b) -// CHECK: #pragma omp task private(this->a) private(this->a) private(T::a) in_reduction(+: this->b) allocate(this->b) depend(depobj : x) detach(evt) depend(iterator(int i = 0:10, T * k = &this->a:&this->b), in : this->c[i],this->d[(int)(k - &this->a)]){{$}} +// CHECK: #pragma omp task private(this->a) private(this->a) private(T::a) in_reduction(+: this->b) allocate(this->b) depend(depobj : x) detach(evt){{$}} // CHECK: #pragma omp task private(this->a) private(this->a) -// CHECK: #pragma omp task private(this->a) private(this->a) private(this->S1::a) in_reduction(+: this->b) allocate(this->b) depend(depobj : x) detach(evt) depend(iterator(int i = 0:10, S1 * k = &this->a:&this->b), in : this->c[i],this->d[(int)(k - &this->a)]) +// CHECK: #pragma omp task private(this->a) private(this->a) private(this->S1::a) class S8 : public S7 { S8() {} @@ -176,10 +176,10 @@ int main(int argc, char **argv) { // CHECK-NEXT: foo(); #pragma omp taskgroup task_reduction(min: arr1) #pragma omp parallel reduction(+:arr1) -#pragma omp task in_reduction(min: arr1) depend(iterator(i=0:argc, unsigned j=argc:0:a), out: argv[i][j]) +#pragma omp task in_reduction(min: arr1) // CHECK-NEXT: #pragma omp taskgroup task_reduction(min: arr1) // CHECK-NEXT: #pragma omp parallel reduction(+: arr1) - // CHECK-NEXT: #pragma omp task in_reduction(min: arr1) depend(iterator(int i = 0:argc, unsigned int j = argc:0), out : argv[i][j]) + // CHECK-NEXT: #pragma omp task in_reduction(min: arr1) foo(); // CHECK-NEXT: foo(); // CHECK-NEXT: #pragma omp task in_reduction(+: arr1) diff --git a/clang/test/OpenMP/task_depend_messages.cpp b/clang/test/OpenMP/task_depend_messages.cpp index bfb0e771b2ca..f04c167cbdcc 100644 --- a/clang/test/OpenMP/task_depend_messages.cpp +++ b/clang/test/OpenMP/task_depend_messages.cpp @@ -28,11 +28,11 @@ int main(int argc, char **argv, char *env[]) { #pragma omp task depend(in : arr[0]) #pragma omp task depend // expected-error {{expected '(' after 'depend'}} - #pragma omp task depend ( // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} - #pragma omp task depend () // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} - #pragma omp task depend (argc // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} - #pragma omp task depend (source : argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} - #pragma omp task depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend ( // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend () // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend (argc // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend (source : argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} #pragma omp task depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}} #pragma omp task depend (out: ) // expected-error {{expected expression}} #pragma omp task depend (inout : foobool(argc)), depend (in, argc) // omp50-error {{expected addressable lvalue expression, array element, array section or array shaping expression}} omp45-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} @@ -70,19 +70,7 @@ int main(int argc, char **argv, char *env[]) { #pragma omp task depend(in : ([a])a) // omp45-error {{expected body of lambda expression}} omp50-error {{expected expression with a pointer to a complete type as a base of an array shaping operation}} #pragma omp task depend(in : ([a])argc) // omp45-error {{expected body of lambda expression}} omp50-error {{expected expression with a pointer to a complete type as a base of an array shaping operation}} #pragma omp task depend(in : ([-1][0])argv) // omp45-error {{expected variable name or 'this' in lambda capture list}} omp45-error {{expected ')'}} omp45-note {{to match this '('}} omp50-error {{array shaping dimension is evaluated to a non-positive value -1}} omp50-error {{array shaping dimension is evaluated to a non-positive value 0}} - #pragma omp task depend(iterator // expected-error {{expected ')'}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-note {{to match this '('}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} omp50-error {{expected '(' after 'iterator'}} omp50-error {{expected ','}} - #pragma omp task depend(iterator():argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected ','}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} - #pragma omp task depend(iterator(argc // expected-error {{expected ')'}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-note {{to match this '('}} omp50-error {{unknown type name 'argc'}} omp50-error {{expected ')'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} omp50-error {{expected ','}} omp50-note {{to match this '('}} - #pragma omp task depend(iterator(unsigned argc: // expected-error {{expected ')'}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-note {{to match this '('}} omp50-error {{expected '=' in iterator specifier}} omp50-error 2 {{expected expression}} omp50-error {{expected ',' or ')' after iterator specifier}} omp50-error {{expected ')'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} omp50-error {{expected ','}} omp50-note {{to match this '('}} - #pragma omp task depend(iterator(unsigned argc = // expected-error {{expected ')'}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-note {{to match this '('}} omp50-error 2 {{expected expression}} omp50-error {{expected ',' or ')' after iterator specifier}} omp50-error {{expected ')'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} omp50-error {{expected ','}} omp50-note {{to match this '('}} - #pragma omp task depend(iterator(vector argc = 0:2):argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected integral or pointer type as the iterator-type, not 'vector'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} omp50-error {{expected ','}} - #pragma omp task depend(iterator(vector *argc = nullptr:nullptr+2:0), in:argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{invalid operands to binary expression ('nullptr_t' and 'int')}} omp50-error {{iterator step expression 0 evaluates to 0}} - #pragma omp task depend(iterator(vector *argc = 0:vector():argc), in:argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{converting 'vector' to incompatible type 'vector *'}} foo(); -#pragma omp task depend(iterator(unsigned argc = 0:10), in : argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} - argc = 0; -#pragma omp task depend(iterator(i = 0:10, i = 0:10), in : argv[i]) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp45-error {{use of undeclared identifier 'i'}} omp50-error {{redefinition of 'i'}} omp50-note {{previous definition is here}} - i = 0; // expected-error {{use of undeclared identifier 'i'}} return 0; } diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 14814f89d97d..bb9fed165679 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -5185,8 +5185,6 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return cxstring::createRef("OMPArraySectionExpr"); case CXCursor_OMPArrayShapingExpr: return cxstring::createRef("OMPArrayShapingExpr"); - case CXCursor_OMPIteratorExpr: - return cxstring::createRef("OMPIteratorExpr"); case CXCursor_BinaryOperator: return cxstring::createRef("BinaryOperator"); case CXCursor_CompoundAssignOperator: diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index 3bcc7cc7af05..4f4e0c4ea1d5 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -427,10 +427,6 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent, K = CXCursor_OMPArrayShapingExpr; break; - case Stmt::OMPIteratorExprClass: - K = CXCursor_OMPIteratorExpr; - break; - case Stmt::BinaryOperatorClass: K = CXCursor_BinaryOperator; break; From cfe-commits at lists.llvm.org Wed Apr 1 12:04:50 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 19:04:50 +0000 (UTC) Subject: [PATCH] D76937: Fix infinite recursion in deferred diagnostic emitter In-Reply-To: References: Message-ID: <49394daf885d5e23f833c0540ceb776c@localhost.localdomain> rjmccall accepted this revision. rjmccall added a comment. This revision is now accepted and ready to land. Thanks, LGTM. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76937/new/ https://reviews.llvm.org/D76937 From cfe-commits at lists.llvm.org Wed Apr 1 12:04:46 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via cfe-commits) Date: Wed, 1 Apr 2020 21:04:46 +0200 Subject: [clang] 6f428e0 - [AST] Fix crashes on decltype(recovery-expr). In-Reply-To: References: <5e81ec8d.1c69fb81.c6694.8b3c@mx.google.com> Message-ID: Hello Douglas, Thanks for the report. I don't think it is intentional, it is certainly a regression (I'm surprised the patch would lead to such behavior), I will take a look tomorrow. On Wed, Apr 1, 2020 at 8:28 PM Yung, Douglas via cfe-commits < cfe-commits at lists.llvm.org> wrote: > Hi Haojian, > > I noticed that after your change, the compiler is now giving an error when > trying to create a vector of >= 1024 elements when previously it worked, > and gcc has no problem with the same code. Is that intentional? I have put > the details in PR45387, can you take a look? > > Douglas Yung > > -----Original Message----- > From: cfe-commits On Behalf Of > Haojian Wu via cfe-commits > Sent: Monday, March 30, 2020 5:57 > To: cfe-commits at lists.llvm.org > Subject: [clang] 6f428e0 - [AST] Fix crashes on decltype(recovery-expr). > > > Author: Haojian Wu > Date: 2020-03-30T14:56:33+02:00 > New Revision: 6f428e09fbe8ce7e3510ae024031a5fc19653483 > > URL: > https://github.com/llvm/llvm-project/commit/6f428e09fbe8ce7e3510ae024031a5fc19653483 > DIFF: > https://github.com/llvm/llvm-project/commit/6f428e09fbe8ce7e3510ae024031a5fc19653483.diff > > LOG: [AST] Fix crashes on decltype(recovery-expr). > > Summary: We mark these decls as invalid. > > Reviewers: sammccall > > Subscribers: cfe-commits > > Tags: #clang > > Differential Revision: https://reviews.llvm.org/D77037 > > Added: > > > Modified: > clang/include/clang/AST/DependenceFlags.h > clang/include/clang/AST/Type.h > clang/lib/Parse/ParseExprCXX.cpp > clang/lib/Sema/SemaType.cpp > clang/test/AST/ast-dump-expr-errors.cpp > clang/test/Sema/invalid-member.cpp > clang/unittests/Sema/CodeCompleteTest.cpp > > Removed: > > > > > ################################################################################ > diff --git a/clang/include/clang/AST/DependenceFlags.h > b/clang/include/clang/AST/DependenceFlags.h > index 75c9aa1656b8..0b24bae6df9b 100644 > --- a/clang/include/clang/AST/DependenceFlags.h > +++ b/clang/include/clang/AST/DependenceFlags.h > @@ -50,14 +50,16 @@ struct TypeDependenceScope { > /// Whether this type is a variably-modified type (C99 6.7.5). > VariablyModified = 8, > > - // FIXME: add Error bit. > + /// Whether this type references an error, e.g. > decltype(err-expression) > + /// yields an error type. > + Error = 16, > > None = 0, > - All = 15, > + All = 31, > > DependentInstantiation = Dependent | Instantiation, > > - LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified) > + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) > }; > }; > using TypeDependence = TypeDependenceScope::TypeDependence; > @@ -147,6 +149,7 @@ class Dependence { > return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) | > translate(V, Instantiation, TypeDependence::Instantiation) | > translate(V, Dependent, TypeDependence::Dependent) | > + translate(V, Error, TypeDependence::Error) | > translate(V, VariablyModified, > TypeDependence::VariablyModified); > } > > > diff --git a/clang/include/clang/AST/Type.h > b/clang/include/clang/AST/Type.h index 248fbcfba98e..5d2c035ea0fe 100644 > --- a/clang/include/clang/AST/Type.h > +++ b/clang/include/clang/AST/Type.h > @@ -2139,6 +2139,11 @@ class alignas(8) Type : public > ExtQualsTypeCommonBase { > return static_cast(TypeBits.Dependence); > } > > + /// Whether this type is an error type. > + bool containsErrors() const { > + return getDependence() & TypeDependence::Error; } > + > /// Whether this type is a dependent type, meaning that its definition > /// somehow depends on a template parameter (C++ [temp.dep.type]). > bool isDependentType() const { > > diff --git a/clang/lib/Parse/ParseExprCXX.cpp > b/clang/lib/Parse/ParseExprCXX.cpp > index 761fad9456be..4389c8777c6d 100644 > --- a/clang/lib/Parse/ParseExprCXX.cpp > +++ b/clang/lib/Parse/ParseExprCXX.cpp > @@ -3105,10 +3105,14 @@ Parser::ParseCXXNewExpression(bool UseGlobal, > SourceLocation Start) { > auto RunSignatureHelp = [&]() { > ParsedType TypeRep = > Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get(); > - assert(TypeRep && "invalid types should be handled before"); > - QualType PreferredType = Actions.ProduceConstructorSignatureHelp( > - getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), > - DeclaratorInfo.getEndLoc(), ConstructorArgs, > ConstructorLParen); > + QualType PreferredType; > + // ActOnTypeName might adjust DeclaratorInfo and return a null > type even > + // the passing DeclaratorInfo is valid, e.g. running > SignatureHelp on > + // `new decltype(invalid) (^)`. > + if (TypeRep) > + PreferredType = Actions.ProduceConstructorSignatureHelp( > + getCurScope(), TypeRep.get()->getCanonicalTypeInternal(), > + DeclaratorInfo.getEndLoc(), ConstructorArgs, > + ConstructorLParen); > CalledSignatureHelp = true; > return PreferredType; > }; > > diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp > index 55ce028fb8c2..e128ebf31270 100644 > --- a/clang/lib/Sema/SemaType.cpp > +++ b/clang/lib/Sema/SemaType.cpp > @@ -1678,6 +1678,12 @@ static QualType > ConvertDeclSpecToType(TypeProcessingState &state) { > break; > } > > + // FIXME: we want resulting declarations to be marked invalid, but > + claiming // the type is invalid is too strong - e.g. it causes > + ActOnTypeName to return // a null type. > + if (Result->containsErrors()) > + declarator.setInvalidType(); > + > if (S.getLangOpts().OpenCL && > S.checkOpenCLDisabledTypeDeclSpec(DS, Result)) > declarator.setInvalidType(true); > > diff --git a/clang/test/AST/ast-dump-expr-errors.cpp > b/clang/test/AST/ast-dump-expr-errors.cpp > index e623fad04f4c..9334b73a4354 100644 > --- a/clang/test/AST/ast-dump-expr-errors.cpp > +++ b/clang/test/AST/ast-dump-expr-errors.cpp > @@ -42,5 +42,9 @@ int d = static_cast(bar() + 1); > > // FIXME: store initializer even when 'auto' could not be deduced. > // Expressions with errors currently do not keep initializers around. > -// CHECK: `-VarDecl {{.*}} invalid e 'auto' > +// CHECK: -VarDecl {{.*}} invalid e 'auto' > auto e = bar(); > + > +// Error type should result in an invalid decl. > +// CHECK: -VarDecl {{.*}} invalid f 'decltype((bar))' > +decltype(bar()) f; > > diff --git a/clang/test/Sema/invalid-member.cpp > b/clang/test/Sema/invalid-member.cpp > index 5475157e936e..544979980fc9 100644 > --- a/clang/test/Sema/invalid-member.cpp > +++ b/clang/test/Sema/invalid-member.cpp > @@ -1,7 +1,15 @@ > -// RUN: %clang_cc1 -verify -fsyntax-only %s -void foo(); // expected-note > {{requires 0 arguments}} > +// RUN: %clang_cc1 -verify -fsyntax-only -fno-recovery-ast %s // RUN: > +%clang_cc1 -verify -fsyntax-only -frecovery-ast %s > + > +void foo(); // expected-note 2{{requires 0 arguments}} > class X { > decltype(foo(42)) invalid; // expected-error {{no matching function}} > }; // Should be able to evaluate sizeof without crashing. > static_assert(sizeof(X) == 1, "No valid members"); > + > +class Y { > + typeof(foo(42)) invalid; // expected-error {{no matching function}} > +}; // Should be able to evaluate sizeof without crashing. > +static_assert(sizeof(Y) == 1, "No valid members"); > > diff --git a/clang/unittests/Sema/CodeCompleteTest.cpp > b/clang/unittests/Sema/CodeCompleteTest.cpp > index a9441a679cac..d8b303d77bb9 100644 > --- a/clang/unittests/Sema/CodeCompleteTest.cpp > +++ b/clang/unittests/Sema/CodeCompleteTest.cpp > @@ -486,7 +486,10 @@ TEST(PreferredTypeTest, NoCrashOnInvalidTypes) { > StringRef Code = R"cpp( > auto x = decltype(&1)(^); > auto y = new decltype(&1)(^); > + // GNU decimal type extension is not supported in clang. > + auto z = new _Decimal128(^); > )cpp"; > EXPECT_THAT(collectPreferredTypes(Code), Each("NULL TYPE")); } > + > } // namespace > > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > _______________________________________________ > cfe-commits mailing list > cfe-commits at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cfe-commits at lists.llvm.org Wed Apr 1 12:22:35 2020 From: cfe-commits at lists.llvm.org (Jian Cai via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 19:22:35 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: jcai19 added a comment. In D77168#1955312 , @jfb wrote: > Do you not think `pragma` is a more general approach? That's what's used in a bunch of other cases, and I'd like to see it attempted here. Yes I absolutely agree pragma is a great way to bisect and will work in many scenarios, and the result is clear once the bisection is done. But like @srhines said, doing this one function at a time is preferable but not always possible (or maybe we can wrap consecutive functions within the same pragma push/pop pair? I tried to verify but ran into error: attribute 'uninitialized' is not supported by '#pragma clang attribute), and automating it is more difficult. From this perspective, I think the proposed patch is complementary to pragma and not meant to replace it. > If not, I agree with John that just counting up isn't a good bisection experience. I'd rather see a begin / end bound. Thank you for the feedback! I will start looking into it. > You're also missing the auto-init in `initializeAlloca`. Thanks I will address this in next patch. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 From cfe-commits at lists.llvm.org Wed Apr 1 12:36:55 2020 From: cfe-commits at lists.llvm.org (Christopher Tetreault via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 19:36:55 +0000 (UTC) Subject: [PATCH] D77236: [SVE] Cleanup prior to introdution of FixedVectorType Message-ID: ctetreau created this revision. Herald added subscribers: cfe-commits, dantrushin, kerbowa, dmgreen, psnobl, rkruppe, kbarton, hiraditya, tschuett, nhaehnle, jvesely, nemanjai, arsenm. Herald added a reviewer: efriedma. Herald added a project: clang. Remove asserting getters from base Type. The existence of these functions make the VectorTyes refactor more difficult while adding little value. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77236 Files: clang/lib/CodeGen/CGAtomic.cpp clang/lib/CodeGen/CGBuiltin.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprScalar.cpp clang/lib/CodeGen/PatternInit.cpp clang/lib/CodeGen/TargetInfo.cpp llvm/include/llvm/Analysis/Utils/Local.h llvm/include/llvm/CodeGen/BasicTTIImpl.h llvm/include/llvm/IR/DerivedTypes.h llvm/include/llvm/IR/Instructions.h llvm/include/llvm/IR/PatternMatch.h llvm/include/llvm/IR/Type.h llvm/lib/Analysis/ConstantFolding.cpp llvm/lib/Analysis/InstructionSimplify.cpp llvm/lib/Analysis/Loads.cpp llvm/lib/Analysis/MemoryBuiltins.cpp llvm/lib/Analysis/TargetTransformInfo.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/Analysis/VectorUtils.cpp llvm/lib/AsmParser/LLParser.cpp llvm/lib/Bitcode/Reader/BitcodeReader.cpp llvm/lib/CodeGen/CodeGenPrepare.cpp llvm/lib/CodeGen/ExpandReductions.cpp llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp llvm/lib/CodeGen/InterleavedAccessPass.cpp llvm/lib/CodeGen/ScalarizeMaskedMemIntrin.cpp llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp llvm/lib/IR/AsmWriter.cpp llvm/lib/IR/AutoUpgrade.cpp llvm/lib/IR/ConstantFold.cpp llvm/lib/IR/Constants.cpp llvm/lib/IR/ConstantsContext.h llvm/lib/IR/Function.cpp llvm/lib/IR/IRBuilder.cpp llvm/lib/IR/Instructions.cpp llvm/lib/IR/Type.cpp llvm/lib/IR/Verifier.cpp llvm/lib/Target/AArch64/AArch64ISelLowering.cpp llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.cpp llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp llvm/lib/Target/ARM/ARMISelLowering.cpp llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp llvm/lib/Target/ARM/MVEGatherScatterLowering.cpp llvm/lib/Target/Hexagon/HexagonISelLowering.cpp llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.cpp llvm/lib/Target/X86/X86InterleavedAccess.cpp llvm/lib/Target/X86/X86PartialReduction.cpp llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp llvm/lib/Target/X86/X86TargetTransformInfo.cpp llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp llvm/lib/Transforms/InstCombine/InstCombineInternal.h llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp llvm/lib/Transforms/InstCombine/InstructionCombining.cpp llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp llvm/lib/Transforms/Scalar/Scalarizer.cpp llvm/lib/Transforms/Utils/LoopUtils.cpp llvm/lib/Transforms/Vectorize/LoopVectorize.cpp llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp llvm/lib/Transforms/Vectorize/VectorCombine.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77236.254273.patch Type: text/x-patch Size: 245805 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 12:36:58 2020 From: cfe-commits at lists.llvm.org (JF Bastien via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 19:36:58 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: jfb added a comment. In D77168#1955450 , @jcai19 wrote: > In D77168#1955312 , @jfb wrote: > > > Do you not think `pragma` is a more general approach? That's what's used in a bunch of other cases, and I'd like to see it attempted here. > > > Yes I absolutely agree pragma is a great way to bisect and will work in many scenarios, and the result is clear once the bisection is done. But like @srhines said, doing this one function at a time is preferable but not always possible (or maybe we can wrap consecutive functions within the same pragma push/pop pair? I tried to verify but ran into error: attribute 'uninitialized' is not supported by '#pragma clang attribute), and automating it is more difficult. From this perspective, I think the proposed patch is complementary to pragma and not meant to replace it. Right, support needs to be added, and I was wondering if you'd want to do this because it seems like a tool that would help you out. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 From cfe-commits at lists.llvm.org Wed Apr 1 12:57:25 2020 From: cfe-commits at lists.llvm.org (Fangrui Song via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 19:57:25 +0000 (UTC) Subject: [PATCH] D77168: Add a flag to debug automatic variable initialization In-Reply-To: References: Message-ID: <785dfd01a2a67e8420d12a13edb07574@localhost.localdomain> MaskRay added a comment. In D77168#1955500 , @jfb wrote: > In D77168#1955450 , @jcai19 wrote: > > > In D77168#1955312 , @jfb wrote: > > > > > Do you not think `pragma` is a more general approach? That's what's used in a bunch of other cases, and I'd like to see it attempted here. > > > > > > Yes I absolutely agree pragma is a great way to bisect and will work in many scenarios, and the result is clear once the bisection is done. But like @srhines said, doing this one function at a time is preferable but not always possible (or maybe we can wrap consecutive functions within the same pragma push/pop pair? I tried to verify but ran into error: attribute 'uninitialized' is not supported by '#pragma clang attribute), and automating it is more difficult. From this perspective, I think the proposed patch is complementary to pragma and not meant to replace it. > > > Right, support needs to be added, and I was wondering if you'd want to do this because it seems like a tool that would help you out. My understanding is that we can invent a compiler option to add `#pragma clang attribute push` for declarations satisfying some criteria (e.g. first N)? No source is modified. This option can potentially be useful for other attributes which are orthogonal to their functionality (concrete examples: sanitizer/XRay attributes). If we go that route, I agree that this proposed -ftrivial-auto-var-init-stop-after= does not seem that useful. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77168/new/ https://reviews.llvm.org/D77168 From cfe-commits at lists.llvm.org Wed Apr 1 12:57:26 2020 From: cfe-commits at lists.llvm.org (Scott Constable via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 19:57:26 +0000 (UTC) Subject: [PATCH] D76812: [X86] Add Indirect Thunk Support to X86 to mitigate Load Value Injection (LVI) [3/3] In-Reply-To: References: Message-ID: sconstab updated this revision to Diff 254276. sconstab added a comment. @craig.topper I think that removing spurious MBBs is not really necessary because the emitted machine code doesn't contain the spurious MBBs, from what I have observed. I added the check anyways, if only because others may look at this discrepancy and have the same question. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76812/new/ https://reviews.llvm.org/D76812 Files: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Arch/X86.cpp llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86ISelLowering.cpp llvm/lib/Target/X86/X86IndirectThunks.cpp llvm/lib/Target/X86/X86Subtarget.h llvm/test/CodeGen/X86/lvi-hardening-indirectbr.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D76812.254276.patch Type: text/x-patch Size: 18352 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 12:57:29 2020 From: cfe-commits at lists.llvm.org (Christopher Tetreault via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 19:57:29 +0000 (UTC) Subject: [PATCH] D77236: [SVE] Cleanup prior to introdution of FixedVectorType In-Reply-To: References: Message-ID: ctetreau updated this revision to Diff 254279. ctetreau added a comment. Herald added a subscriber: wuzish. run clang-format Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77236/new/ https://reviews.llvm.org/D77236 Files: clang/lib/CodeGen/CGAtomic.cpp clang/lib/CodeGen/CGBuiltin.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprScalar.cpp clang/lib/CodeGen/PatternInit.cpp clang/lib/CodeGen/TargetInfo.cpp llvm/include/llvm/Analysis/Utils/Local.h llvm/include/llvm/CodeGen/BasicTTIImpl.h llvm/include/llvm/IR/DerivedTypes.h llvm/include/llvm/IR/Instructions.h llvm/include/llvm/IR/PatternMatch.h llvm/include/llvm/IR/Type.h llvm/lib/Analysis/ConstantFolding.cpp llvm/lib/Analysis/InstructionSimplify.cpp llvm/lib/Analysis/Loads.cpp llvm/lib/Analysis/MemoryBuiltins.cpp llvm/lib/Analysis/TargetTransformInfo.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/Analysis/VectorUtils.cpp llvm/lib/AsmParser/LLParser.cpp llvm/lib/Bitcode/Reader/BitcodeReader.cpp llvm/lib/CodeGen/CodeGenPrepare.cpp llvm/lib/CodeGen/ExpandReductions.cpp llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp llvm/lib/CodeGen/InterleavedAccessPass.cpp llvm/lib/CodeGen/ScalarizeMaskedMemIntrin.cpp llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp llvm/lib/IR/AsmWriter.cpp llvm/lib/IR/AutoUpgrade.cpp llvm/lib/IR/ConstantFold.cpp llvm/lib/IR/Constants.cpp llvm/lib/IR/ConstantsContext.h llvm/lib/IR/Function.cpp llvm/lib/IR/IRBuilder.cpp llvm/lib/IR/Instructions.cpp llvm/lib/IR/Type.cpp llvm/lib/IR/Verifier.cpp llvm/lib/Target/AArch64/AArch64ISelLowering.cpp llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.cpp llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp llvm/lib/Target/ARM/ARMISelLowering.cpp llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp llvm/lib/Target/ARM/MVEGatherScatterLowering.cpp llvm/lib/Target/Hexagon/HexagonISelLowering.cpp llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.cpp llvm/lib/Target/X86/X86InterleavedAccess.cpp llvm/lib/Target/X86/X86PartialReduction.cpp llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp llvm/lib/Target/X86/X86TargetTransformInfo.cpp llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp llvm/lib/Transforms/InstCombine/InstCombineInternal.h llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp llvm/lib/Transforms/InstCombine/InstructionCombining.cpp llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp llvm/lib/Transforms/Scalar/Scalarizer.cpp llvm/lib/Transforms/Utils/LoopUtils.cpp llvm/lib/Transforms/Vectorize/LoopVectorize.cpp llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp llvm/lib/Transforms/Vectorize/VectorCombine.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77236.254279.patch Type: text/x-patch Size: 248046 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 13:09:30 2020 From: cfe-commits at lists.llvm.org (Frank Derry Wanye via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 20:09:30 +0000 (UTC) Subject: [PATCH] D66564: [clang-tidy] new altera struct pack align check In-Reply-To: References: Message-ID: ffrankies updated this revision to Diff 254277. ffrankies added a comment. Addressed comments by @aaron.ballman You're right, we don't want this to trigger on template instantiations and structs declared in system headers. - Check no longer triggers on template instantiations - Check no longer triggers on structs declared in system headers To add to @Eugene.Zelenko's comment: there are 5 patches for the `altera` module including this one (D72235 , D72218 , D72241 , and D70094 ). We also have 2 checks that have been put on the backlog due to time/funding constraints, but could be resurrected if that changes. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D66564/new/ https://reviews.llvm.org/D66564 Files: clang-tools-extra/clang-tidy/CMakeLists.txt clang-tools-extra/clang-tidy/ClangTidyForceLinker.h clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp clang-tools-extra/clang-tidy/altera/CMakeLists.txt clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.h clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/docs/clang-tidy/checks/altera-struct-pack-align.rst clang-tools-extra/docs/clang-tidy/checks/list.rst clang-tools-extra/docs/clang-tidy/index.rst clang-tools-extra/test/clang-tidy/checkers/altera-struct-pack-align.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D66564.254277.patch Type: text/x-patch Size: 20141 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 13:09:32 2020 From: cfe-commits at lists.llvm.org (Christopher Tetreault via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 20:09:32 +0000 (UTC) Subject: [PATCH] D77236: [SVE] Cleanup prior to introdution of FixedVectorType In-Reply-To: References: Message-ID: ctetreau updated this revision to Diff 254285. ctetreau added a comment. make lints work Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77236/new/ https://reviews.llvm.org/D77236 Files: clang/lib/CodeGen/CGAtomic.cpp clang/lib/CodeGen/CGBuiltin.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprScalar.cpp clang/lib/CodeGen/PatternInit.cpp clang/lib/CodeGen/TargetInfo.cpp llvm/include/llvm/Analysis/Utils/Local.h llvm/include/llvm/CodeGen/BasicTTIImpl.h llvm/include/llvm/IR/DerivedTypes.h llvm/include/llvm/IR/Instructions.h llvm/include/llvm/IR/PatternMatch.h llvm/include/llvm/IR/Type.h llvm/lib/Analysis/ConstantFolding.cpp llvm/lib/Analysis/InstructionSimplify.cpp llvm/lib/Analysis/Loads.cpp llvm/lib/Analysis/MemoryBuiltins.cpp llvm/lib/Analysis/TargetTransformInfo.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/Analysis/VectorUtils.cpp llvm/lib/AsmParser/LLParser.cpp llvm/lib/Bitcode/Reader/BitcodeReader.cpp llvm/lib/CodeGen/CodeGenPrepare.cpp llvm/lib/CodeGen/ExpandReductions.cpp llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp llvm/lib/CodeGen/InterleavedAccessPass.cpp llvm/lib/CodeGen/ScalarizeMaskedMemIntrin.cpp llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp llvm/lib/IR/AsmWriter.cpp llvm/lib/IR/AutoUpgrade.cpp llvm/lib/IR/ConstantFold.cpp llvm/lib/IR/Constants.cpp llvm/lib/IR/ConstantsContext.h llvm/lib/IR/Function.cpp llvm/lib/IR/IRBuilder.cpp llvm/lib/IR/Instructions.cpp llvm/lib/IR/Type.cpp llvm/lib/IR/Verifier.cpp llvm/lib/Target/AArch64/AArch64ISelLowering.cpp llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.cpp llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp llvm/lib/Target/ARM/ARMISelLowering.cpp llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp llvm/lib/Target/ARM/MVEGatherScatterLowering.cpp llvm/lib/Target/Hexagon/HexagonISelLowering.cpp llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.cpp llvm/lib/Target/X86/X86InterleavedAccess.cpp llvm/lib/Target/X86/X86PartialReduction.cpp llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp llvm/lib/Target/X86/X86TargetTransformInfo.cpp llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp llvm/lib/Transforms/InstCombine/InstCombineInternal.h llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp llvm/lib/Transforms/InstCombine/InstructionCombining.cpp llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp llvm/lib/Transforms/Scalar/Scalarizer.cpp llvm/lib/Transforms/Utils/LoopUtils.cpp llvm/lib/Transforms/Vectorize/LoopVectorize.cpp llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp llvm/lib/Transforms/Vectorize/VectorCombine.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77236.254285.patch Type: text/x-patch Size: 248046 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 13:21:22 2020 From: cfe-commits at lists.llvm.org (David Blaikie via cfe-commits) Date: Wed, 01 Apr 2020 13:21:22 -0700 (PDT) Subject: [clang] db92719 - DebugInfo: Defaulted non-type template parameters of bool type Message-ID: <5e84f7c2.1c69fb81.afc27.b3ba@mx.google.com> Author: David Blaikie Date: 2020-04-01T13:21:13-07:00 New Revision: db92719c1d17f5052e7cd1309b0e1e92240f47be URL: https://github.com/llvm/llvm-project/commit/db92719c1d17f5052e7cd1309b0e1e92240f47be DIFF: https://github.com/llvm/llvm-project/commit/db92719c1d17f5052e7cd1309b0e1e92240f47be.diff LOG: DebugInfo: Defaulted non-type template parameters of bool type Caused an assertion due to mismatched bit widths - this seems like the right API to use for a possibly width-varying equality test. Though certainly open to some post-commit review feedback if there's a more suitable way to do this comparison/test. Added: Modified: clang/lib/CodeGen/CGDebugInfo.cpp clang/test/CodeGenCXX/debug-info-template-parameter.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 49c57e9860a6..6d3c2ad66cdc 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1817,9 +1817,10 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList, if (auto *templateType = dyn_cast_or_null(TPList->getParam(i))) if (templateType->hasDefaultArgument()) - defaultParameter = + defaultParameter = llvm::APSInt::isSameValue( templateType->getDefaultArgument()->EvaluateKnownConstInt( - CGM.getContext()) == TA.getAsIntegral(); + CGM.getContext()), + TA.getAsIntegral()); TemplateParams.push_back(DBuilder.createTemplateValueParameter( TheCU, Name, TTy, defaultParameter, diff --git a/clang/test/CodeGenCXX/debug-info-template-parameter.cpp b/clang/test/CodeGenCXX/debug-info-template-parameter.cpp index 95e7a187fe10..c38c535d8b06 100644 --- a/clang/test/CodeGenCXX/debug-info-template-parameter.cpp +++ b/clang/test/CodeGenCXX/debug-info-template-parameter.cpp @@ -8,22 +8,24 @@ // CHECK: DILocalVariable(name: "f1", {{.*}}, type: ![[TEMPLATE_TYPE:[0-9]+]] // CHECK: [[TEMPLATE_TYPE]] = {{.*}}!DICompositeType({{.*}}, templateParams: ![[F1_TYPE:[0-9]+]] -// CHECK: [[F1_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]]} +// CHECK: [[F1_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]], ![[THIRD:[0-9]+]]} // CHECK: [[FIRST]] = !DITemplateTypeParameter(name: "T", type: !{{[0-9]*}}) // CHECK: [[SECOND]] = !DITemplateValueParameter(name: "i", type: !{{[0-9]*}}, value: i32 6) +// CHECK: [[THIRD]] = !DITemplateValueParameter(name: "b", type: !{{[0-9]*}}, value: i8 0) // CHECK: DILocalVariable(name: "f2", {{.*}}, type: ![[TEMPLATE_TYPE:[0-9]+]] // CHECK: [[TEMPLATE_TYPE]] = {{.*}}!DICompositeType({{.*}}, templateParams: ![[F2_TYPE:[0-9]+]] -// CHECK: [[F2_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]]} +// CHECK: [[F2_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]], ![[THIRD:[0-9]+]]} // CHECK: [[FIRST]] = !DITemplateTypeParameter(name: "T", type: !{{[0-9]*}}, defaulted: true) // CHECK: [[SECOND]] = !DITemplateValueParameter(name: "i", type: !{{[0-9]*}}, defaulted: true, value: i32 3) +// CHECK: [[THIRD]] = !DITemplateValueParameter(name: "b", type: !{{[0-9]*}}, defaulted: true, value: i8 1) -template +template class foo { }; int main() { - foo f1; + foo f1; foo<> f2; return 0; } From cfe-commits at lists.llvm.org Wed Apr 1 13:21:48 2020 From: cfe-commits at lists.llvm.org (Aaron Ballman via cfe-commits) Date: Wed, 01 Apr 2020 13:21:48 -0700 (PDT) Subject: [clang] 6e916b5 - Updating the documentation for the noescape attribute. Message-ID: <5e84f7dc.1c69fb81.433e9.bfc8@mx.google.com> Author: Aaron Ballman Date: 2020-04-01T16:21:37-04:00 New Revision: 6e916b5860950fee2661ded847abe551f5259ec4 URL: https://github.com/llvm/llvm-project/commit/6e916b5860950fee2661ded847abe551f5259ec4 DIFF: https://github.com/llvm/llvm-project/commit/6e916b5860950fee2661ded847abe551f5259ec4.diff LOG: Updating the documentation for the noescape attribute. A question came up from a glibc maintainer as to whether it was permissible to free a pointer marked [[clang::noescape]], and after investigation, I determined that this is allowed. This updates the documentation in case others have the same question. Added: Modified: clang/include/clang/Basic/AttrDocs.td Removed: ################################################################################ diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 2c89dc6f4952..bdc47b43c34b 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -140,7 +140,8 @@ def NoEscapeDocs : Documentation { the compiler that the pointer cannot escape: that is, no reference to the object the pointer points to that is derived from the parameter value will survive after the function returns. Users are responsible for making sure parameters -annotated with ``noescape`` do not actuallly escape. +annotated with ``noescape`` do not actuallly escape. Calling ``free()`` on such +a parameter does not constitute an escape. For example: From cfe-commits at lists.llvm.org Wed Apr 1 13:28:31 2020 From: cfe-commits at lists.llvm.org (David Blaikie via cfe-commits) Date: Wed, 1 Apr 2020 13:28:31 -0700 Subject: [clang] db92719 - DebugInfo: Defaulted non-type template parameters of bool type In-Reply-To: <5e84f7c2.1c69fb81.afc27.b3ba@mx.google.com> References: <5e84f7c2.1c69fb81.afc27.b3ba@mx.google.com> Message-ID: On Wed, Apr 1, 2020 at 1:21 PM David Blaikie via cfe-commits < cfe-commits at lists.llvm.org> wrote: > > Author: David Blaikie > Date: 2020-04-01T13:21:13-07:00 > New Revision: db92719c1d17f5052e7cd1309b0e1e92240f47be > > URL: > https://github.com/llvm/llvm-project/commit/db92719c1d17f5052e7cd1309b0e1e92240f47be > DIFF: > https://github.com/llvm/llvm-project/commit/db92719c1d17f5052e7cd1309b0e1e92240f47be.diff > > LOG: DebugInfo: Defaulted non-type template parameters of bool type > > Caused an assertion due to mismatched bit widths - this seems like the > right API to use for a possibly width-varying equality test. Though > certainly open to some post-commit review feedback if there's a more > suitable way to do this comparison/test. > > Added: > > > Modified: > clang/lib/CodeGen/CGDebugInfo.cpp > clang/test/CodeGenCXX/debug-info-template-parameter.cpp > > Removed: > > > > > ################################################################################ > diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp > b/clang/lib/CodeGen/CGDebugInfo.cpp > index 49c57e9860a6..6d3c2ad66cdc 100644 > --- a/clang/lib/CodeGen/CGDebugInfo.cpp > +++ b/clang/lib/CodeGen/CGDebugInfo.cpp > @@ -1817,9 +1817,10 @@ CGDebugInfo::CollectTemplateParams(const > TemplateParameterList *TPList, > if (auto *templateType = > > dyn_cast_or_null(TPList->getParam(i))) > if (templateType->hasDefaultArgument()) > - defaultParameter = > + defaultParameter = llvm::APSInt::isSameValue( > templateType->getDefaultArgument()->EvaluateKnownConstInt( > - CGM.getContext()) == TA.getAsIntegral(); > + CGM.getContext()), > + TA.getAsIntegral()); > Hey Richard - is this the best way to do this? Are there other ways to test if a default argument is the same as the actual template parameter we could/should be doing here? > > TemplateParams.push_back(DBuilder.createTemplateValueParameter( > TheCU, Name, TTy, defaultParameter, > > diff --git a/clang/test/CodeGenCXX/debug-info-template-parameter.cpp > b/clang/test/CodeGenCXX/debug-info-template-parameter.cpp > index 95e7a187fe10..c38c535d8b06 100644 > --- a/clang/test/CodeGenCXX/debug-info-template-parameter.cpp > +++ b/clang/test/CodeGenCXX/debug-info-template-parameter.cpp > @@ -8,22 +8,24 @@ > > // CHECK: DILocalVariable(name: "f1", {{.*}}, type: > ![[TEMPLATE_TYPE:[0-9]+]] > // CHECK: [[TEMPLATE_TYPE]] = {{.*}}!DICompositeType({{.*}}, > templateParams: ![[F1_TYPE:[0-9]+]] > -// CHECK: [[F1_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]]} > +// CHECK: [[F1_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]], > ![[THIRD:[0-9]+]]} > // CHECK: [[FIRST]] = !DITemplateTypeParameter(name: "T", type: > !{{[0-9]*}}) > // CHECK: [[SECOND]] = !DITemplateValueParameter(name: "i", type: > !{{[0-9]*}}, value: i32 6) > +// CHECK: [[THIRD]] = !DITemplateValueParameter(name: "b", type: > !{{[0-9]*}}, value: i8 0) > > // CHECK: DILocalVariable(name: "f2", {{.*}}, type: > ![[TEMPLATE_TYPE:[0-9]+]] > // CHECK: [[TEMPLATE_TYPE]] = {{.*}}!DICompositeType({{.*}}, > templateParams: ![[F2_TYPE:[0-9]+]] > -// CHECK: [[F2_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]]} > +// CHECK: [[F2_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]], > ![[THIRD:[0-9]+]]} > // CHECK: [[FIRST]] = !DITemplateTypeParameter(name: "T", type: > !{{[0-9]*}}, defaulted: true) > // CHECK: [[SECOND]] = !DITemplateValueParameter(name: "i", type: > !{{[0-9]*}}, defaulted: true, value: i32 3) > +// CHECK: [[THIRD]] = !DITemplateValueParameter(name: "b", type: > !{{[0-9]*}}, defaulted: true, value: i8 1) > > -template > +template > class foo { > }; > > int main() { > - foo f1; > + foo f1; > foo<> f2; > return 0; > } > > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cfe-commits at lists.llvm.org Wed Apr 1 13:30:54 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 20:30:54 +0000 (UTC) Subject: [PATCH] D77238: [CUDA][NFC] Split math.h functions out of __clang_cuda_device_functions.h Message-ID: jdoerfert created this revision. jdoerfert added a reviewer: tra. Herald added subscribers: bollu, yaxunl, mgorny. Herald added a project: clang. jdoerfert added a child revision: D77239: [CUDA][NFCI] Use unqualified lookup for math functions. This is not supported to change anything but allow us to reuse the math functions separately from the device functions, e.g., source them at different times. This will be used by the OpenMP overlay. This also adds two `return` keywords that were missing. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77238 Files: clang/lib/Headers/CMakeLists.txt clang/lib/Headers/__clang_cuda_device_functions.h clang/lib/Headers/__clang_cuda_math.h clang/lib/Headers/__clang_cuda_runtime_wrapper.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D77238.254289.patch Type: text/x-patch Size: 35704 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 13:30:56 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 20:30:56 +0000 (UTC) Subject: [PATCH] D77239: [CUDA][NFCI] Use unqualified lookup for math functions Message-ID: jdoerfert created this revision. jdoerfert added a reviewer: tra. Herald added subscribers: bollu, yaxunl. Herald added a project: clang. jdoerfert added a child revision: D77240: [CUDA] Add missing cmath overloads. The other macro uses a unqualified lookup already and the qualified one will cause problems in the OpenMP overlay. Depends on D77238 . Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77239 Files: clang/lib/Headers/__clang_cuda_cmath.h Index: clang/lib/Headers/__clang_cuda_cmath.h =================================================================== --- clang/lib/Headers/__clang_cuda_cmath.h +++ clang/lib/Headers/__clang_cuda_cmath.h @@ -191,7 +191,7 @@ typename __clang_cuda_enable_if::is_integer, \ __retty>::type \ __fn(__T __x) { \ - return ::__fn((double)__x); \ + return __fn((double)__x); \ } // Defines an overload of __fn that accepts one two arithmetic arguments, calls -------------- next part -------------- A non-text attachment was scrubbed... Name: D77239.254290.patch Type: text/x-patch Size: 718 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 13:30:57 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 20:30:57 +0000 (UTC) Subject: [PATCH] D77240: [CUDA] Add missing cmath overloads Message-ID: jdoerfert created this revision. jdoerfert added a reviewer: tra. Herald added subscribers: bollu, yaxunl. Herald added a project: clang. Some function overloads for floats were missing, found by running a test suite [0] with the OpenMP overlay. [0] https://github.com/TApplencourt/OmpVal Depends on D77239 . Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77240 Files: clang/lib/Headers/__clang_cuda_cmath.h Index: clang/lib/Headers/__clang_cuda_cmath.h =================================================================== --- clang/lib/Headers/__clang_cuda_cmath.h +++ clang/lib/Headers/__clang_cuda_cmath.h @@ -57,15 +57,24 @@ __DEVICE__ const double abs(const double __x) { return ::fabs((double)__x); } #endif __DEVICE__ float acos(float __x) { return ::acosf(__x); } +__DEVICE__ float acosh(float __x) { return ::acoshf(__x); } __DEVICE__ float asin(float __x) { return ::asinf(__x); } +__DEVICE__ float asinh(float __x) { return ::asinhf(__x); } __DEVICE__ float atan(float __x) { return ::atanf(__x); } +__DEVICE__ float atanh(float __x) { return ::atanhf(__x); } __DEVICE__ float atan2(float __x, float __y) { return ::atan2f(__x, __y); } +__DEVICE__ float cbrt(float __x) { return ::cbrtf(__x); } __DEVICE__ float ceil(float __x) { return ::ceilf(__x); } __DEVICE__ float cos(float __x) { return ::cosf(__x); } __DEVICE__ float cosh(float __x) { return ::coshf(__x); } +__DEVICE__ float erf(float __x) { return ::erff(__x); } +__DEVICE__ float erfc(float __x) { return ::erfcf(__x); } __DEVICE__ float exp(float __x) { return ::expf(__x); } +__DEVICE__ float exp2(float __x) { return ::exp2f(__x); } +__DEVICE__ float expm1(float __x) { return ::expm1f(__x); } __DEVICE__ float fabs(float __x) __NOEXCEPT { return ::fabsf(__x); } __DEVICE__ float floor(float __x) { return ::floorf(__x); } +__DEVICE__ float fdim(float __x, float __y) { return ::fdimf(__x, __y); } __DEVICE__ float fmod(float __x, float __y) { return ::fmodf(__x, __y); } // TODO: remove when variant is supported #ifndef _OPENMP @@ -82,6 +91,8 @@ return ::frexpf(__arg, __exp); } +__DEVICE__ float hypot(float __x, float __y) { return ::hypotf(__x, __y); } +__DEVICE__ int ilogb(float __x) { return ::ilogbf(__x); } // For inscrutable reasons, the CUDA headers define these functions for us on // Windows. #ifndef _MSC_VER @@ -137,9 +148,18 @@ __DEVICE__ float ldexp(float __arg, int __exp) { return ::ldexpf(__arg, __exp); } +__DEVICE__ float lgamma(float __x) { return ::lgammaf(__x); } +__DEVICE__ long long int llrint(float __x) { return ::llrintf(__x); } +__DEVICE__ long long int llround(float __x) { return ::llroundf(__x); } __DEVICE__ float log(float __x) { return ::logf(__x); } __DEVICE__ float log10(float __x) { return ::log10f(__x); } +__DEVICE__ float log1p(float __x) { return ::log1pf(__x); } +__DEVICE__ float log2(float __x) { return ::log2f(__x); } +__DEVICE__ float logb(float __x) { return ::logbf(__x); } +__DEVICE__ long int lrint(float __x) { return ::lrintf(__x); } +__DEVICE__ long int lround(float __x) { return ::lroundf(__x); } __DEVICE__ float modf(float __x, float *__iptr) { return ::modff(__x, __iptr); } +__DEVICE__ float nextafter(float __x, float __y) { return ::nextafterf(__x, __y); } __DEVICE__ float pow(float __base, float __exp) { return ::powf(__base, __exp); } @@ -149,6 +169,9 @@ __DEVICE__ double pow(double __base, int __iexp) { return ::powi(__base, __iexp); } +__DEVICE__ float remainder(float __x, float __y) { return ::remainderf(__x, __y); } +__DEVICE__ float scalbln(float __x, long int __y) { return ::scalblnf(__x, __y); } +__DEVICE__ float scalbn(float __x, int __y) { return ::scalbnf(__x, __y); } __DEVICE__ bool signbit(float __x) { return ::__signbitf(__x); } __DEVICE__ bool signbit(double __x) { return ::__signbitd(__x); } __DEVICE__ float sin(float __x) { return ::sinf(__x); } @@ -156,6 +179,7 @@ __DEVICE__ float sqrt(float __x) { return ::sqrtf(__x); } __DEVICE__ float tan(float __x) { return ::tanf(__x); } __DEVICE__ float tanh(float __x) { return ::tanhf(__x); } +__DEVICE__ float tgamma(float __x) { return ::tgammaf(__x); } // Notably missing above is nexttoward. We omit it because // libdevice doesn't provide an implementation, and we don't want to be in the -------------- next part -------------- A non-text attachment was scrubbed... Name: D77240.254291.patch Type: text/x-patch Size: 3857 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 13:41:41 2020 From: cfe-commits at lists.llvm.org (Puyan Lotfi via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 20:41:41 +0000 (UTC) Subject: [PATCH] D77233: [NFC] Refactoring PropertyAttributeKind for ObjCPropertyDecl and ObjCDeclSpec. In-Reply-To: References: Message-ID: plotfi updated this revision to Diff 254297. plotfi added a comment. Applying clang-format suggestions. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77233/new/ https://reviews.llvm.org/D77233 Files: clang/include/clang/AST/DeclObjC.h clang/include/clang/AST/DeclObjCCommon.h clang/include/clang/Sema/DeclSpec.h clang/lib/ARCMigrate/TransGCAttrs.cpp clang/lib/ARCMigrate/TransProperties.cpp clang/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp clang/lib/AST/ASTContext.cpp clang/lib/AST/DeclObjC.cpp clang/lib/AST/DeclPrinter.cpp clang/lib/AST/JSONNodeDumper.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/Analysis/BodyFarm.cpp clang/lib/CodeGen/CGObjC.cpp clang/lib/CodeGen/CGObjCGNU.cpp clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp clang/lib/Frontend/Rewrite/RewriteObjC.cpp clang/lib/Parse/ParseObjc.cpp clang/lib/Sema/SemaChecking.cpp clang/lib/Sema/SemaCodeComplete.cpp clang/lib/Sema/SemaExprObjC.cpp clang/lib/Sema/SemaObjCProperty.cpp clang/lib/Sema/SemaPseudoObject.cpp clang/lib/Serialization/ASTReaderDecl.cpp clang/tools/libclang/CIndex.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77233.254297.patch Type: text/x-patch Size: 101969 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 13:41:42 2020 From: cfe-commits at lists.llvm.org (Frank Derry Wanye via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 20:41:42 +0000 (UTC) Subject: [PATCH] D72235: [clang-tidy] new altera unroll loops check In-Reply-To: References: Message-ID: <25ea0949cd35031033d2c5993739abc7@localhost.localdomain> ffrankies updated this revision to Diff 254299. ffrankies added a comment. Addressed comments by @Eugene.Zelenko - Removed braces from one-lien if statements - Release notes on the altera unroll loops check now match the first line of documentation. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72235/new/ https://reviews.llvm.org/D72235 Files: clang-tools-extra/clang-tidy/CMakeLists.txt clang-tools-extra/clang-tidy/ClangTidyForceLinker.h clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp clang-tools-extra/clang-tidy/altera/CMakeLists.txt clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst clang-tools-extra/docs/clang-tidy/checks/list.rst clang-tools-extra/docs/clang-tidy/index.rst clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D72235.254299.patch Type: text/x-patch Size: 30678 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 14:04:58 2020 From: cfe-commits at lists.llvm.org (Frank Derry Wanye via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:04:58 +0000 (UTC) Subject: [PATCH] D72218: [clang-tidy] new altera kernel name restriction check In-Reply-To: References: Message-ID: <9d550e99be6233d244dc2737718d006d@localhost.localdomain> ffrankies updated this revision to Diff 254301. ffrankies added a comment. - Updated underlying repo to https://github.com/llvm/llvm-project - Removed braces from one-line if-statements CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72218/new/ https://reviews.llvm.org/D72218 Files: clang-tools-extra/clang-tidy/CMakeLists.txt clang-tools-extra/clang-tidy/ClangTidyForceLinker.h clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp clang-tools-extra/clang-tidy/altera/CMakeLists.txt clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.cpp clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.h clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/docs/clang-tidy/checks/altera-kernel-name-restriction.rst clang-tools-extra/docs/clang-tidy/checks/list.rst clang-tools-extra/docs/clang-tidy/index.rst clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/KERNEL.cl clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/VHDL.cl clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/Verilog.cl clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/kernel.cl clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/kernel.h clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/other_Verilog.cl clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/otherdir/vhdl.cl clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/otherthing.cl clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some/dir/kernel.cl clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/some_kernel.cl clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/somedir/verilog.cl clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/thing.h clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vERILOG.cl clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/verilog.h clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl.CL clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl.h clang-tools-extra/test/clang-tidy/checkers/Inputs/altera-kernel-name-restriction/vhdl_number_two.cl clang-tools-extra/test/clang-tidy/checkers/altera-kernel-name-restriction.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D72218.254301.patch Type: text/x-patch Size: 21050 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 14:05:00 2020 From: cfe-commits at lists.llvm.org (Frank Derry Wanye via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:05:00 +0000 (UTC) Subject: [PATCH] D72241: [clang-tidy] new altera single work item barrier check In-Reply-To: References: Message-ID: ffrankies updated this revision to Diff 254304. ffrankies added a comment. - Updated underlying repo to https://github.com/llvm/llvm-project - Removed braces from one-line if-statements CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72241/new/ https://reviews.llvm.org/D72241 Files: clang-tools-extra/clang-tidy/CMakeLists.txt clang-tools-extra/clang-tidy/ClangTidyForceLinker.h clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp clang-tools-extra/clang-tidy/altera/CMakeLists.txt clang-tools-extra/clang-tidy/altera/SingleWorkItemBarrierCheck.cpp clang-tools-extra/clang-tidy/altera/SingleWorkItemBarrierCheck.h clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/docs/clang-tidy/checks/altera-single-work-item-barrier.rst clang-tools-extra/docs/clang-tidy/checks/list.rst clang-tools-extra/docs/clang-tidy/index.rst clang-tools-extra/test/clang-tidy/checkers/altera-single-work-item-barrier.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D72241.254304.patch Type: text/x-patch Size: 24220 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 14:05:01 2020 From: cfe-commits at lists.llvm.org (Frank Derry Wanye via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:05:01 +0000 (UTC) Subject: [PATCH] D70094: [clang-tidy] new altera ID dependent backward branch check In-Reply-To: References: Message-ID: <19f571a7f3618d351c866ed129bae662@localhost.localdomain> ffrankies updated this revision to Diff 254305. ffrankies marked 5 inline comments as done. ffrankies added a comment. - Updated underlying repo to https://github.com/llvm/llvm-project - Removed braces from one-line if-statements CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70094/new/ https://reviews.llvm.org/D70094 Files: clang-tools-extra/clang-tidy/CMakeLists.txt clang-tools-extra/clang-tidy/ClangTidyForceLinker.h clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp clang-tools-extra/clang-tidy/altera/CMakeLists.txt clang-tools-extra/clang-tidy/altera/IdDependentBackwardBranchCheck.cpp clang-tools-extra/clang-tidy/altera/IdDependentBackwardBranchCheck.h clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/docs/clang-tidy/checks/altera-id-dependent-backward-branch.rst clang-tools-extra/docs/clang-tidy/checks/list.rst clang-tools-extra/docs/clang-tidy/index.rst clang-tools-extra/test/clang-tidy/checkers/altera-id-dependent-backward-branch.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D70094.254305.patch Type: text/x-patch Size: 27841 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 14:05:04 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:05:04 +0000 (UTC) Subject: [PATCH] D77131: [clang] Move branch-protection from CodeGenOptions to LangOptions In-Reply-To: References: Message-ID: efriedma accepted this revision. efriedma added a comment. This revision is now accepted and ready to land. LGTM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77131/new/ https://reviews.llvm.org/D77131 From cfe-commits at lists.llvm.org Wed Apr 1 14:05:06 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:05:06 +0000 (UTC) Subject: [PATCH] D59321: AMDGPU: Teach toolchain to link rocm device libs In-Reply-To: References: Message-ID: <70caaa84366b4366cfa64187c4438fae@localhost.localdomain> arsenm marked 2 inline comments as done. arsenm added a comment. In D59321#1955405 , @hliao wrote: > Do we have a better way to avoid adding those empty bitcode files? No, we need the files to exist for tests. This is what existing bitcode link tests do ================ Comment at: clang/lib/Driver/ToolChains/AMDGPU.h:44-46 + //RocmVersion Version = RocmVersion::UNKNOWN; + SmallString<0> InstallPath; + //SmallString<0> BinPath; ---------------- hliao wrote: > sounds to me that both `Version` and `BinPath` should be added. They will be used eventually. It's easy to add when needded ================ Comment at: clang/lib/Driver/ToolChains/HIP.h:76 -class LLVM_LIBRARY_VISIBILITY HIPToolChain final : public AMDGPUToolChain { +class LLVM_LIBRARY_VISIBILITY HIPToolChain final : public ROCMToolChain { public: ---------------- hliao wrote: > Do you miss the change in HIP.cpp? That constructor needs revising as the base class is changed. Yes, I fixed this locally already CHANGES SINCE LAST ACTION https://reviews.llvm.org/D59321/new/ https://reviews.llvm.org/D59321 From cfe-commits at lists.llvm.org Wed Apr 1 14:13:44 2020 From: cfe-commits at lists.llvm.org (Artem Belevich via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:13:44 +0000 (UTC) Subject: [PATCH] D77240: [CUDA] Add missing cmath overloads In-Reply-To: References: Message-ID: tra added a comment. We'll need to make sure that all of these new functions are vailable in all supported CUDA versions. E.g. `acoshf` does not seem to be present in CUDA-9. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77240/new/ https://reviews.llvm.org/D77240 From cfe-commits at lists.llvm.org Wed Apr 1 14:38:24 2020 From: cfe-commits at lists.llvm.org (Pratyai Mazumder via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:38:24 +0000 (UTC) Subject: [PATCH] D77244: sancov/inline-bool-flag feature + tests + docs. Message-ID: pratyai created this revision. pratyai added reviewers: kcc, vitalybuka. Herald added subscribers: Sanitizers, cfe-commits, jfb, hiraditya. Herald added projects: clang, Sanitizers. pratyai updated this revision to Diff 254312. pratyai added a comment. Removed some unintentional diffs. Removed some unintentional diffs from clang/lib/Frontend/CompilerInvocation.cpp. New SanitizerCoverage feature `inline-bool-flag` which inserts an atomic store of `1` to a boolean (which is an 8bit integer in practice) flag on every instrumented edge. Implementation-wise it's very similar to `inline-8bit-counters` features. So, much of wiring and test just follows the same pattern. Tested with `cmake --build . -- check-llvm`. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77244 Files: clang/docs/SanitizerCoverage.rst clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/CC1Options.td clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/SanitizerArgs.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/Driver/autocomplete.c clang/test/Driver/fsanitize-coverage.c compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp llvm/include/llvm/Transforms/Instrumentation.h llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp llvm/test/Instrumentation/SanitizerCoverage/coff-pc-table-inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-inline-bool-flag.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D77244.254312.patch Type: text/x-patch Size: 30221 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 14:38:24 2020 From: cfe-commits at lists.llvm.org (Artem Belevich via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:38:24 +0000 (UTC) Subject: [PATCH] D77239: [CUDA][NFCI] Use unqualified lookup for math functions In-Reply-To: References: Message-ID: <0c910eba83846ac5faeb78df8389efac@localhost.localdomain> tra added a subscriber: jlebar. tra added a comment. > The other macro uses a unqualified lookup already and the qualified one > will cause problems in the OpenMP overlay. There's a bit of inconsitency here. While `__CUDA_CLANG_FN_INTEGER_OVERLOAD_2` indeed uses unqualified lookup, pretty much all other functions use qualified global scope lookups, which, I believe is correct, as we want to use the functions defined by CUDA headers there. @jlebar -- WDYT? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77239/new/ https://reviews.llvm.org/D77239 From cfe-commits at lists.llvm.org Wed Apr 1 14:38:25 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:38:25 +0000 (UTC) Subject: [PATCH] D77239: [CUDA][NFCI] Use unqualified lookup for math functions In-Reply-To: References: Message-ID: <845d749ad45b1570ecee44bd7f3c6cbc@localhost.localdomain> jdoerfert abandoned this revision. jdoerfert added a comment. In D77239#1955720 , @tra wrote: > > The other macro uses a unqualified lookup already and the qualified one > > will cause problems in the OpenMP overlay. > > There's a bit of inconsitency here. While `__CUDA_CLANG_FN_INTEGER_OVERLOAD_2` indeed uses unqualified lookup, pretty much all other functions use qualified global scope lookups, which, I believe is correct, as we want to use the functions defined by CUDA headers there. > > @jlebar -- WDYT? It turns out I can disable this entire code region for OpenMP (or have to for c++17 I tihnk), so I'll abandon this revision and you make it consistent in the way that fits your need :) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77239/new/ https://reviews.llvm.org/D77239 From cfe-commits at lists.llvm.org Wed Apr 1 14:38:25 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:38:25 +0000 (UTC) Subject: [PATCH] D77240: [CUDA] Add missing cmath overloads In-Reply-To: References: Message-ID: <6f088e82b5bce309f5922b1659049637@localhost.localdomain> jdoerfert added a comment. In D77240#1955678 , @tra wrote: > We'll need to make sure that all of these new functions are vailable in all supported CUDA versions. > E.g. `acoshf` does not seem to be present in CUDA-9. At least that one is defined in what is "now" `__clang_cuda_math.h`: `__DEVICE__ float acoshf(float __a) { return __nv_acoshf(__a); } ` Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77240/new/ https://reviews.llvm.org/D77240 From cfe-commits at lists.llvm.org Wed Apr 1 14:38:25 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:38:25 +0000 (UTC) Subject: [PATCH] D77238: [CUDA][NFC] Split math.h functions out of __clang_cuda_device_functions.h In-Reply-To: References: Message-ID: <77c6a46cde0ecd9e1a8f7179e250180e@localhost.localdomain> jdoerfert marked an inline comment as done. jdoerfert added inline comments. ================ Comment at: clang/lib/Headers/__clang_cuda_math.h:81 +#endif +__DEVICE__ long long clock64() { return __nvvm_read_ptx_sreg_clock64(); } +__DEVICE__ double copysign(double __a, double __b) { ---------------- I accidentally moved the clock functions and added the openmp ifdef we'll need later. I'll move the clock functions back before I commit. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77238/new/ https://reviews.llvm.org/D77238 From cfe-commits at lists.llvm.org Wed Apr 1 14:38:26 2020 From: cfe-commits at lists.llvm.org (Todd Snider via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:38:26 +0000 (UTC) Subject: [PATCH] D71129: [ARM][CMSE] Implement CMSE attributes In-Reply-To: References: Message-ID: snidertm added inline comments. ================ Comment at: clang/include/clang/AST/Type.h:3588 + NoCallerSavedRegsMask | NoCfCheckMask | CmseNSCallMask), RegParmOffset = 8 }; // Assumed to be the last field ---------------- Shouldn't RegParmOffset be updated to 9, I believe it is used to shift the regParm value so that it encoded in the bits above CmseNSCallMask Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71129/new/ https://reviews.llvm.org/D71129 From cfe-commits at lists.llvm.org Wed Apr 1 14:38:28 2020 From: cfe-commits at lists.llvm.org (Pratyai Mazumder via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:38:28 +0000 (UTC) Subject: [PATCH] D77244: sancov/inline-bool-flag feature + tests + docs. In-Reply-To: References: Message-ID: <3e16f8996b08f73ce0abef169e2d9f68@localhost.localdomain> pratyai updated this revision to Diff 254312. pratyai added a comment. Removed some unintentional diffs. Removed some unintentional diffs from clang/lib/Frontend/CompilerInvocation.cpp. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77244/new/ https://reviews.llvm.org/D77244 Files: clang/docs/SanitizerCoverage.rst clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/CC1Options.td clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/SanitizerArgs.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/Driver/autocomplete.c clang/test/Driver/fsanitize-coverage.c compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp llvm/include/llvm/Transforms/Instrumentation.h llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp llvm/test/Instrumentation/SanitizerCoverage/coff-pc-table-inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-inline-bool-flag.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D77244.254312.patch Type: text/x-patch Size: 30221 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 14:45:44 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:45:44 +0000 (UTC) Subject: [PATCH] D77236: [SVE] Cleanup prior to introdution of FixedVectorType In-Reply-To: References: Message-ID: efriedma added a comment. My thoughts, in no particular order: 1. This is orthogonal to splitting VectorType, as far as I can tell. `Ty->getVectorNumElements()` works equally well whether the implementation asserts it's a VectorType that isn't scalable, or asserts it's a FixedVectorType. 2. This needs to be split up; it's way too long to read, and it's mixing functional and non-functional changes. 3. It might make sense to add helpers to remove the use of cast<> in more places. For example, the inputs of a shufflevector are guaranteed to be vectors. 4. Some of the changes are leading to really crazy indentation because the `cast<>` is more characters. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77236/new/ https://reviews.llvm.org/D77236 From cfe-commits at lists.llvm.org Wed Apr 1 14:45:44 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:45:44 +0000 (UTC) Subject: [PATCH] D59321: AMDGPU: Teach toolchain to link rocm device libs In-Reply-To: References: Message-ID: <50cb9a50d2e37959b963118dd9e248d5@localhost.localdomain> yaxunl added inline comments. ================ Comment at: clang/include/clang/Driver/Options.td:611 def fno_cuda_short_ptr : Flag<["-"], "fno-cuda-short-ptr">; +def rocm_path_EQ : Joined<["--"], "rocm-path=">, Group, + HelpText<"ROCm installation path">; ---------------- HIP toolchain will also use it to add include path for HIP header files, therefore this is more like --cuda-path=. i_Group is more proper. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D59321/new/ https://reviews.llvm.org/D59321 From cfe-commits at lists.llvm.org Wed Apr 1 14:45:45 2020 From: cfe-commits at lists.llvm.org (Pratyai Mazumder via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 21:45:45 +0000 (UTC) Subject: [PATCH] D77244: sancov/inline-bool-flag feature + tests + docs. In-Reply-To: References: Message-ID: <53fc785d19a20cb2220370c90f73cda1@localhost.localdomain> pratyai updated this revision to Diff 254316. pratyai added a comment. Still had a couple of lines of diff left :( Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77244/new/ https://reviews.llvm.org/D77244 Files: clang/docs/SanitizerCoverage.rst clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/CC1Options.td clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/SanitizerArgs.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/Driver/autocomplete.c clang/test/Driver/fsanitize-coverage.c compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp llvm/include/llvm/Transforms/Instrumentation.h llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp llvm/test/Instrumentation/SanitizerCoverage/coff-pc-table-inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-inline-bool-flag.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D77244.254316.patch Type: text/x-patch Size: 29032 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 15:12:09 2020 From: cfe-commits at lists.llvm.org (Artem Belevich via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 22:12:09 +0000 (UTC) Subject: [PATCH] D77240: [CUDA] Add missing cmath overloads In-Reply-To: References: Message-ID: <4d9ecffae7da5cf0ec86b407e06dacf7@localhost.localdomain> tra added a comment. In D77240#1955724 , @jdoerfert wrote: > At least that one is defined in what is "now" `__clang_cuda_math.h`: Cool. We may be OK, but we still need to verify it. Math headers are rather fragile and we need to make sure it all still works two different standard libraries and all CUDA versions. Unfortunately my CUDA build bot has decided to die the day we've started working from home, so it has to be done manually. Let me try patching in your changes and try them with the CUDA versions I have. Stay tuned. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77240/new/ https://reviews.llvm.org/D77240 From cfe-commits at lists.llvm.org Wed Apr 1 15:12:12 2020 From: cfe-commits at lists.llvm.org (David Blaikie via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 22:12:12 +0000 (UTC) Subject: [PATCH] D73462: [dwarf-5] Support DebugInfo for Defaulted parameters for C++ templates In-Reply-To: References: Message-ID: <4c239fd0269fd935e7babf8405b46520@localhost.localdomain> dblaikie added a comment. This wasn't well committed, unfortunately. It seems it was committed in two parts: IR support and clang functionality: https://github.com/llvm/llvm-project/commit/7a42babeb83e3927e89e72a0e7e45be9d41b6c23 (a recommit of https://github.com/llvm/llvm-project/commit/c2b437d53d40b6dc5603c97f527398f477d9c5f1 ) LLVM functionality (lib/CodeGen/AsmPrinter) and a clang test: https://github.com/llvm/llvm-project/commit/1cb0e01e42ca5e9de44d9b7cb03d23552a9a9ae1 It's still missing the LLVM test & this was not the right division for committing them. In the future, perhaps it's best to go through separate reviews to validate the individual commits after the general review is done. The Clang functionality and clang test should've been committed together, but separately from everything else (after the IR support was in) The LLVM functionality should've been committed separately but with testing, which is not present at all. The test file llvm/test/DebugInfo/X86/debug-info-template-parameter.ll that was in the review seems to have never been committed & this might've been more obvious if things were separated as intended/per protocol - please commit it at your earliest convenience. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73462/new/ https://reviews.llvm.org/D73462 From cfe-commits at lists.llvm.org Wed Apr 1 15:12:16 2020 From: cfe-commits at lists.llvm.org (Christopher Tetreault via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 22:12:16 +0000 (UTC) Subject: [PATCH] D77236: [SVE] Cleanup prior to introdution of FixedVectorType In-Reply-To: References: Message-ID: ctetreau updated this revision to Diff 254318. ctetreau added a comment. Herald added subscribers: grosul1, Joonsoo, liufengdb, aartbik, lucyrfox, mgester, arpith-jacob, csigg, nicolasvasilache, antiagainst, shauheen, burmako, jpienaar, rriddle, mehdi_amini. Herald added a reviewer: aartbik. Fix MLIR Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77236/new/ https://reviews.llvm.org/D77236 Files: clang/lib/CodeGen/CGAtomic.cpp clang/lib/CodeGen/CGBuiltin.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprScalar.cpp clang/lib/CodeGen/PatternInit.cpp clang/lib/CodeGen/TargetInfo.cpp llvm/include/llvm/Analysis/Utils/Local.h llvm/include/llvm/CodeGen/BasicTTIImpl.h llvm/include/llvm/IR/DerivedTypes.h llvm/include/llvm/IR/Instructions.h llvm/include/llvm/IR/PatternMatch.h llvm/include/llvm/IR/Type.h llvm/lib/Analysis/ConstantFolding.cpp llvm/lib/Analysis/InstructionSimplify.cpp llvm/lib/Analysis/Loads.cpp llvm/lib/Analysis/MemoryBuiltins.cpp llvm/lib/Analysis/TargetTransformInfo.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/Analysis/VectorUtils.cpp llvm/lib/AsmParser/LLParser.cpp llvm/lib/Bitcode/Reader/BitcodeReader.cpp llvm/lib/CodeGen/CodeGenPrepare.cpp llvm/lib/CodeGen/ExpandReductions.cpp llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp llvm/lib/CodeGen/InterleavedAccessPass.cpp llvm/lib/CodeGen/ScalarizeMaskedMemIntrin.cpp llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp llvm/lib/IR/AsmWriter.cpp llvm/lib/IR/AutoUpgrade.cpp llvm/lib/IR/ConstantFold.cpp llvm/lib/IR/Constants.cpp llvm/lib/IR/ConstantsContext.h llvm/lib/IR/Function.cpp llvm/lib/IR/IRBuilder.cpp llvm/lib/IR/Instructions.cpp llvm/lib/IR/Type.cpp llvm/lib/IR/Verifier.cpp llvm/lib/Target/AArch64/AArch64ISelLowering.cpp llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.cpp llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp llvm/lib/Target/ARM/ARMISelLowering.cpp llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp llvm/lib/Target/ARM/MVEGatherScatterLowering.cpp llvm/lib/Target/Hexagon/HexagonISelLowering.cpp llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.cpp llvm/lib/Target/X86/X86InterleavedAccess.cpp llvm/lib/Target/X86/X86PartialReduction.cpp llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp llvm/lib/Target/X86/X86TargetTransformInfo.cpp llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp llvm/lib/Transforms/InstCombine/InstCombineInternal.h llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp llvm/lib/Transforms/InstCombine/InstructionCombining.cpp llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp llvm/lib/Transforms/Scalar/Scalarizer.cpp llvm/lib/Transforms/Utils/LoopUtils.cpp llvm/lib/Transforms/Vectorize/LoopVectorize.cpp llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp llvm/lib/Transforms/Vectorize/VectorCombine.cpp mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77236.254318.patch Type: text/x-patch Size: 251910 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 15:12:17 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 22:12:17 +0000 (UTC) Subject: [PATCH] D77240: [CUDA] Add missing cmath overloads In-Reply-To: References: Message-ID: jdoerfert added a comment. In D77240#1955755 , @tra wrote: > In D77240#1955724 , @jdoerfert wrote: > > > At least that one is defined in what is "now" `__clang_cuda_math.h`: > > > Cool. We may be OK, but we still need to verify it. Math headers are rather fragile and we need to make sure it all still works two different standard libraries and all CUDA versions. > Unfortunately my CUDA build bot has decided to die the day we've started working from home, so it has to be done manually. > Let me try patching in your changes and try them with the CUDA versions I have. Stay tuned. Thank you very much! I (now) know what pain math headers are... These are almost the last infrastructure changes I need, there is a problem with the include path order on some system but for that I first need to write a patch. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77240/new/ https://reviews.llvm.org/D77240 From cfe-commits at lists.llvm.org Wed Apr 1 15:12:21 2020 From: cfe-commits at lists.llvm.org (Leonard Chan via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 22:12:21 +0000 (UTC) Subject: [PATCH] D72959: Relative VTables ABI on Fuchsia In-Reply-To: References: Message-ID: <4dbd6638d5fd53f837ea8d2856715368@localhost.localdomain> leonardchan updated this revision to Diff 254317. leonardchan edited the summary of this revision. leonardchan added a comment. Herald added subscribers: libcxx-commits, danielkiss. Herald added a project: libc++abi. Herald added a reviewer: libc++abi. I updated the patch such that this everything here allows us to work with RTTI also. Since this is very large and has a lot of refactoring of the ItaniumCXXABI class and llvm changes independent from the FuchsiaCXXABI, I'll do my best to split them into smaller patches then formally ask for reviews on them. Keeping this around for reference as the point of reference I'll keep up to date. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72959/new/ https://reviews.llvm.org/D72959 Files: clang/include/clang/Basic/LangOptions.def clang/include/clang/Driver/Options.td clang/lib/AST/VTableBuilder.cpp clang/lib/CodeGen/CGCXXABI.cpp clang/lib/CodeGen/CGCXXABI.h clang/lib/CodeGen/CGVTables.cpp clang/lib/CodeGen/CGVTables.h clang/lib/CodeGen/ItaniumCXXABI.cpp clang/lib/CodeGen/MicrosoftCXXABI.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGenCXX/Fuchsia/child-inheritted-from-parent-in-comdat.cpp clang/test/CodeGenCXX/Fuchsia/child-vtable-in-comdat.cpp clang/test/CodeGenCXX/Fuchsia/cross-translation-unit-1.cpp clang/test/CodeGenCXX/Fuchsia/cross-translation-unit-2.cpp clang/test/CodeGenCXX/Fuchsia/cross-tu-header.h clang/test/CodeGenCXX/Fuchsia/diamond-inheritance.cpp clang/test/CodeGenCXX/Fuchsia/diamond-virtual-inheritance.cpp clang/test/CodeGenCXX/Fuchsia/dynamic-cast.cpp clang/test/CodeGenCXX/Fuchsia/inheritted-virtual-function.cpp clang/test/CodeGenCXX/Fuchsia/inline-virtual-function.cpp clang/test/CodeGenCXX/Fuchsia/inlined-key-function.cpp clang/test/CodeGenCXX/Fuchsia/member-function-pointer.cpp clang/test/CodeGenCXX/Fuchsia/multiple-inheritance.cpp clang/test/CodeGenCXX/Fuchsia/override-pure-virtual-method.cpp clang/test/CodeGenCXX/Fuchsia/overriden-virtual-function.cpp clang/test/CodeGenCXX/Fuchsia/parent-and-child-in-comdats.cpp clang/test/CodeGenCXX/Fuchsia/parent-vtable-in-comdat.cpp clang/test/CodeGenCXX/Fuchsia/pass-byval-attributes.cpp clang/test/CodeGenCXX/Fuchsia/simple-vtable-definition.cpp clang/test/CodeGenCXX/Fuchsia/stub-linkages.cpp clang/test/CodeGenCXX/Fuchsia/thunk-mangling.cpp clang/test/CodeGenCXX/Fuchsia/type-info.cpp clang/test/CodeGenCXX/Fuchsia/virtual-function-call.cpp clang/test/CodeGenCXX/constructor-destructor-return-this.cpp libcxxabi/src/private_typeinfo.cpp llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/lib/IR/Constants.cpp llvm/test/CodeGen/X86/relptr-rodata.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D72959.254317.patch Type: text/x-patch Size: 111801 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 15:12:25 2020 From: cfe-commits at lists.llvm.org (Momchil Velikov via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 22:12:25 +0000 (UTC) Subject: [PATCH] D71129: [ARM][CMSE] Implement CMSE attributes In-Reply-To: References: Message-ID: <56ee965b7a0938ecfbb2ce06f1601bd8@localhost.localdomain> chill marked 3 inline comments as done. chill added inline comments. ================ Comment at: clang/include/clang/AST/Type.h:3588 + NoCallerSavedRegsMask | NoCfCheckMask | CmseNSCallMask), RegParmOffset = 8 }; // Assumed to be the last field ---------------- snidertm wrote: > Shouldn't RegParmOffset be updated to 9, I believe it is used to shift the regParm value so that it encoded in the bits above CmseNSCallMask Hmm, I think 8 is OK, but we should mask it ... ================ Comment at: clang/include/clang/AST/Type.h:3622 bool getNoCfCheck() const { return Bits & NoCfCheckMask; } bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; } ---------------- ... here. bool getHasRegParm() const { return ((Bits & RegParmMask) >> RegParmOffset) != 0; Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71129/new/ https://reviews.llvm.org/D71129 From cfe-commits at lists.llvm.org Wed Apr 1 15:12:31 2020 From: cfe-commits at lists.llvm.org (Christopher Tetreault via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 22:12:31 +0000 (UTC) Subject: [PATCH] D77236: [SVE] Cleanup prior to introdution of FixedVectorType In-Reply-To: References: Message-ID: ctetreau added a comment. > 1. This is orthogonal to splitting VectorType, as far as I can tell. `Ty->getVectorNumElements()` works equally well whether the implementation asserts it's a VectorType that isn't scalable, or asserts it's a FixedVectorType. While it's not strictly neccesary, the refactor will be more straightforward with this change. Before, we would have: unsigned n = t->getVectorNumElements(); After the VectorTypes refactor, if t is not a FixedLengthVector, then this code will still compile but fail at runtime. However with: unsigned n = cast(t)->getNumElements(); ... it will be a compile time failure. Realistically, it would need to be at least renamed to getFixedVectorNumElements anyways to avoid confusion. > 2. This needs to be split up; it's way too long to read, and it's mixing functional and non-functional changes. I can split it up into a few chunks that make the corrections a bit at a time, then a final change to get rid of the functions > 3. It might make sense to add helpers to remove the use of cast<> in more places. For example, the inputs of a shufflevector are guaranteed to be vectors. It seems to me that we use base Type for basically everything when we could use concrete subclasses. As you can see in my patch, I fixed a few, but ideally functions would just return a VectorType if they have a VectorType. The issue is pervasive, and is enabled by the existence of these functions. This is a deep rabbit hole that I don't really want to go down in this patch. > 4. Some of the changes are leading to really crazy indentation because the `cast<>` is more characters. While I agree, there's not much we can do about that. Really, the problem is that we have these crazy complicated if statements that check 15 things at once. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77236/new/ https://reviews.llvm.org/D77236 From cfe-commits at lists.llvm.org Wed Apr 1 15:45:43 2020 From: cfe-commits at lists.llvm.org (Vy Nguyen via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 22:45:43 +0000 (UTC) Subject: [PATCH] D75951: Keep a list of already-included pragma-once files for mods. In-Reply-To: References: Message-ID: <205a44e6aaa740ff9be53b0a33c6bb01@localhost.localdomain> oontvoo updated this revision to Diff 254321. oontvoo added a comment. clean up ... Ready to review. PTAL! =) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75951/new/ https://reviews.llvm.org/D75951 Files: clang/include/clang/Lex/HeaderSearch.h clang/include/clang/Lex/Preprocessor.h clang/include/clang/Serialization/ASTBitCodes.h clang/include/clang/Serialization/ASTReader.h clang/include/clang/Serialization/ASTWriter.h clang/lib/Lex/HeaderSearch.cpp clang/lib/Lex/PPDirectives.cpp clang/lib/Lex/PPLexerChange.cpp clang/lib/Lex/Preprocessor.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/test/Modules/Inputs/dummy_pragma_once.h clang/test/Modules/Inputs/dummy_textual_header.h clang/test/Modules/Inputs/header_in_imported_module.h clang/test/Modules/Inputs/imported_module.cppm clang/test/Modules/Inputs/module.map clang/test/Modules/header-in-imported-module.c clang/test/Modules/import-pragma-once.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D75951.254321.patch Type: text/x-patch Size: 29315 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 15:45:46 2020 From: cfe-commits at lists.llvm.org (Diab Neiroukh via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 22:45:46 +0000 (UTC) Subject: [PATCH] D77246: Instead of scream, why not roll? Message-ID: lazerl0rd created this revision. lazerl0rd added reviewers: nathanchance, clang. Herald added a project: clang. Herald added a subscriber: cfe-commits. Everyone naturally converts hex to text when they see a long value, so provide clearer information on their bad coding habits with a nice link. If you're still a bit lazy, why not use https://www.browserling.com/tools/hex-to-text? Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77246 Files: clang/lib/CodeGen/PatternInit.cpp Index: clang/lib/CodeGen/PatternInit.cpp =================================================================== --- clang/lib/CodeGen/PatternInit.cpp +++ clang/lib/CodeGen/PatternInit.cpp @@ -24,7 +24,7 @@ const uint64_t IntValue = CGM.getContext().getTargetInfo().getMaxPointerWidth() < 64 ? 0xFFFFFFFFFFFFFFFFull - : 0xAAAAAAAAAAAAAAAAull; + : 0x68747470733a2f2f74696e7975726c2e636f6d2f32666370726536; // Floating-point values are initialized as NaNs because they propagate. Using // a repeated byte pattern means that it will be easier to initialize // all-floating-point aggregates and arrays with memset. Further, aggregates -------------- next part -------------- A non-text attachment was scrubbed... Name: D77246.254322.patch Type: text/x-patch Size: 675 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 15:45:47 2020 From: cfe-commits at lists.llvm.org (Todd Snider via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 22:45:47 +0000 (UTC) Subject: [PATCH] D71129: [ARM][CMSE] Implement CMSE attributes In-Reply-To: References: Message-ID: <1c17d426beb5963a199cac07221d8a17@localhost.localdomain> snidertm added inline comments. ================ Comment at: clang/include/clang/AST/Type.h:3604 + (noCallerSavedRegs ? NoCallerSavedRegsMask : 0) | + (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0) | + (NoCfCheck ? NoCfCheckMask : 0) | ---------------- Wouldn't this overwrite the CmseNSCallMask bit if hasRegParm is true and ((regParm + 1) & 1) is non-zero? ================ Comment at: clang/include/clang/AST/Type.h:3622 bool getNoCfCheck() const { return Bits & NoCfCheckMask; } bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; } ---------------- chill wrote: > ... here. > > bool getHasRegParm() const { return ((Bits & RegParmMask) >> RegParmOffset) != 0; I don't see how this helps. If RegParmOffset is 8 and the CmseNSCall bit is set in Bits, then your proposed getHasRegParm() will return true. Given the above assignment to Bits, we don't know if the CmseNSCall bit was set by cmseNSCall or by regParm. MIght I be missing something? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71129/new/ https://reviews.llvm.org/D71129 From cfe-commits at lists.llvm.org Wed Apr 1 15:45:47 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 22:45:47 +0000 (UTC) Subject: [PATCH] D76389: [NewPM] Run the Speculative Execution Pass only if the target has divergent branches In-Reply-To: References: Message-ID: arsenm added inline comments. ================ Comment at: clang/test/CodeGen/thinlto-distributed-newpm.ll:110 ; CHECK-O: Running analysis: OuterAnalysisManagerProxy -; CHECK-O: Running pass: SpeculativeExecutionPass on main +; CHECK-O: Running pass: SpeculativeExecutionIfHasBranchDivergencePass on main ; CHECK-O: Running pass: JumpThreadingPass on main ---------------- The pass name shouldn't change here? ================ Comment at: llvm/lib/Passes/PassBuilder.cpp:435 if (Level.getSpeedupLevel() > 1) { - FPM.addPass(SpeculativeExecutionPass()); + FPM.addPass(SpeculativeExecutionIfHasBranchDivergencePass()); ---------------- I don't expect this to be a separate pass, just added based on a divergent target Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76389/new/ https://reviews.llvm.org/D76389 From cfe-commits at lists.llvm.org Wed Apr 1 15:45:54 2020 From: cfe-commits at lists.llvm.org (Christopher Tetreault via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 22:45:54 +0000 (UTC) Subject: [PATCH] D77236: [SVE] Cleanup prior to introdution of FixedVectorType In-Reply-To: References: Message-ID: <261f6cf202dd045006bf93ce8a25fd84@localhost.localdomain> ctetreau updated this revision to Diff 254327. ctetreau added a comment. Herald added a project: LLVM. Herald added a subscriber: llvm-commits. Split commit up into multiple smaller commits: 1 commit per llvm library, 1 for clang, and 1 for mlir. Plus one final commit to remove the functions from Type Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77236/new/ https://reviews.llvm.org/D77236 Files: llvm/include/llvm/IR/DerivedTypes.h llvm/include/llvm/IR/Type.h llvm/lib/IR/Type.cpp Index: llvm/lib/IR/Type.cpp =================================================================== --- llvm/lib/IR/Type.cpp +++ llvm/lib/IR/Type.cpp @@ -149,6 +149,12 @@ return -1; } +Type *Type::getScalarType() const { + if (isVectorTy()) + return cast(this)->getElementType(); + return const_cast(this); +} + bool Type::isSizedDerivedType(SmallPtrSetImpl *Visited) const { if (auto *ATy = dyn_cast(this)) return ATy->getElementType()->isSized(Visited); Index: llvm/include/llvm/IR/Type.h =================================================================== --- llvm/include/llvm/IR/Type.h +++ llvm/include/llvm/IR/Type.h @@ -304,11 +304,7 @@ /// If this is a vector type, return the element type, otherwise return /// 'this'. - Type *getScalarType() const { - if (isVectorTy()) - return getVectorElementType(); - return const_cast(this); - } + Type *getScalarType() const; //===--------------------------------------------------------------------===// // Type Iteration support. @@ -343,8 +339,8 @@ //===--------------------------------------------------------------------===// // Helper methods corresponding to subclass methods. This forces a cast to - // the specified subclass and calls its accessor. "getVectorNumElements" (for - // example) is shorthand for cast(Ty)->getNumElements(). This is + // the specified subclass and calls its accessor. "getArrayNumElements" (for + // example) is shorthand for cast(Ty)->getNumElements(). This is // only intended to cover the core methods that are frequently used, helper // methods should not be added here. @@ -370,14 +366,6 @@ return ContainedTys[0]; } - inline bool getVectorIsScalable() const; - inline unsigned getVectorNumElements() const; - inline ElementCount getVectorElementCount() const; - Type *getVectorElementType() const { - assert(getTypeID() == VectorTyID); - return ContainedTys[0]; - } - Type *getPointerElementType() const { assert(getTypeID() == PointerTyID); return ContainedTys[0]; Index: llvm/include/llvm/IR/DerivedTypes.h =================================================================== --- llvm/include/llvm/IR/DerivedTypes.h +++ llvm/include/llvm/IR/DerivedTypes.h @@ -546,18 +546,6 @@ } }; -unsigned Type::getVectorNumElements() const { - return cast(this)->getNumElements(); -} - -bool Type::getVectorIsScalable() const { - return cast(this)->isScalable(); -} - -ElementCount Type::getVectorElementCount() const { - return cast(this)->getElementCount(); -} - /// Class to represent pointers. class PointerType : public Type { explicit PointerType(Type *ElType, unsigned AddrSpace); @@ -610,8 +598,8 @@ isIntOrIntVectorTy() && "Original type expected to be a vector of integers or a scalar integer."); Type *NewType = getIntNTy(getContext(), NewBitWidth); - if (isVectorTy()) - NewType = VectorType::get(NewType, getVectorElementCount()); + if (auto *VTy = dyn_cast(this)) + NewType = VectorType::get(NewType, VTy->getElementCount()); return NewType; } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77236.254327.patch Type: text/x-patch Size: 3204 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 15:50:06 2020 From: cfe-commits at lists.llvm.org (David Li via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 22:50:06 +0000 (UTC) Subject: [PATCH] D73307: Unique Names for Functions with Internal Linkage In-Reply-To: References: Message-ID: <788ae471c5d153959d09d33ab3e630a0@localhost.localdomain> davidxl added inline comments. ================ Comment at: clang/test/CodeGen/unique-internal-linkage-names.cpp:29 +int mver_call() { + return mver(); +} ---------------- [a side note]: interesting, since when Clang had this target attribute based multi-versioning and function overloading ? Sriraman added this support in GCC 8 years ago. Did not realize it is in Clang too :) CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73307/new/ https://reviews.llvm.org/D73307 From cfe-commits at lists.llvm.org Wed Apr 1 16:21:08 2020 From: cfe-commits at lists.llvm.org (Artem Belevich via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 23:21:08 +0000 (UTC) Subject: [PATCH] D77240: [CUDA] Add missing cmath overloads In-Reply-To: References: Message-ID: <559624640706b19a25f87d0ed58ee93f@localhost.localdomain> tra added a comment. We do have a problem. With your patch I see a lot of errors about function redefinitions conflicting with the ones in CUDA's `math_functions.hpp`: E.g: In file included from :1: In file included from /usr/local/google/home/tra/work/llvm/build/release+assert+zapcc/lib/clang/11.0.0/include/__clang_cuda_runtime_wrapper.h:398: /usr/local/google/home/tra/work/llvm/build/release+assert+zapcc/lib/clang/11.0.0/include/__clang_cuda_cmath.h:60:18: error: redefinition of 'acosh' __DEVICE__ float acosh(float __x) { return ::acoshf(__x); } ^ /usr/local/google/home/tra/local/cuda-10.0/include/crt/math_functions.hpp:624:31: note: previous definition is here __MATH_FUNCTIONS_DECL__ float acosh(float a) Full list of conflicting functions in CUDA 9.0, 10.0, 10.1, 10.2 redefinition of 'acosh' redefinition of 'asinh' redefinition of 'atanh' redefinition of 'cbrt' redefinition of 'erf' redefinition of 'erfc' redefinition of 'exp2' redefinition of 'expm1' redefinition of 'fdim' redefinition of 'hypot' redefinition of 'ilogb' redefinition of 'lgamma' redefinition of 'llrint' redefinition of 'llround' redefinition of 'log1p' redefinition of 'log2' redefinition of 'logb' redefinition of 'lrint' redefinition of 'lround' Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77240/new/ https://reviews.llvm.org/D77240 From cfe-commits at lists.llvm.org Wed Apr 1 16:21:15 2020 From: cfe-commits at lists.llvm.org (Christopher Tetreault via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 23:21:15 +0000 (UTC) Subject: [PATCH] D77236: [SVE] Cleanup prior to introdution of FixedVectorType In-Reply-To: References: Message-ID: ctetreau updated this revision to Diff 254331. ctetreau added a comment. attempt to stack all commits Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77236/new/ https://reviews.llvm.org/D77236 Files: clang/lib/CodeGen/CGAtomic.cpp clang/lib/CodeGen/CGBuiltin.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprScalar.cpp clang/lib/CodeGen/PatternInit.cpp clang/lib/CodeGen/TargetInfo.cpp llvm/include/llvm/Analysis/Utils/Local.h llvm/include/llvm/CodeGen/BasicTTIImpl.h llvm/include/llvm/IR/DerivedTypes.h llvm/include/llvm/IR/Instructions.h llvm/include/llvm/IR/PatternMatch.h llvm/include/llvm/IR/Type.h llvm/lib/Analysis/ConstantFolding.cpp llvm/lib/Analysis/InstructionSimplify.cpp llvm/lib/Analysis/Loads.cpp llvm/lib/Analysis/MemoryBuiltins.cpp llvm/lib/Analysis/TargetTransformInfo.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/Analysis/VectorUtils.cpp llvm/lib/AsmParser/LLParser.cpp llvm/lib/Bitcode/Reader/BitcodeReader.cpp llvm/lib/CodeGen/CodeGenPrepare.cpp llvm/lib/CodeGen/ExpandReductions.cpp llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp llvm/lib/CodeGen/InterleavedAccessPass.cpp llvm/lib/CodeGen/ScalarizeMaskedMemIntrin.cpp llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp llvm/lib/IR/AsmWriter.cpp llvm/lib/IR/AutoUpgrade.cpp llvm/lib/IR/ConstantFold.cpp llvm/lib/IR/Constants.cpp llvm/lib/IR/ConstantsContext.h llvm/lib/IR/Function.cpp llvm/lib/IR/IRBuilder.cpp llvm/lib/IR/Instructions.cpp llvm/lib/IR/Type.cpp llvm/lib/IR/Verifier.cpp llvm/lib/Target/AArch64/AArch64ISelLowering.cpp llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h llvm/lib/Target/AMDGPU/AMDGPUHSAMetadataStreamer.cpp llvm/lib/Target/AMDGPU/AMDGPULowerKernelArguments.cpp llvm/lib/Target/ARM/ARMISelLowering.cpp llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp llvm/lib/Target/ARM/MVEGatherScatterLowering.cpp llvm/lib/Target/Hexagon/HexagonISelLowering.cpp llvm/lib/Target/Hexagon/HexagonTargetTransformInfo.cpp llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp llvm/lib/Target/SystemZ/SystemZTargetTransformInfo.cpp llvm/lib/Target/X86/X86InterleavedAccess.cpp llvm/lib/Target/X86/X86PartialReduction.cpp llvm/lib/Target/X86/X86ShuffleDecodeConstantPool.cpp llvm/lib/Target/X86/X86TargetTransformInfo.cpp llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp llvm/lib/Transforms/InstCombine/InstCombineInternal.h llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp llvm/lib/Transforms/InstCombine/InstructionCombining.cpp llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp llvm/lib/Transforms/Scalar/Scalarizer.cpp llvm/lib/Transforms/Utils/LoopUtils.cpp llvm/lib/Transforms/Vectorize/LoopVectorize.cpp llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp llvm/lib/Transforms/Vectorize/VectorCombine.cpp mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77236.254331.patch Type: text/x-patch Size: 251910 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 16:21:16 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 23:21:16 +0000 (UTC) Subject: [PATCH] D77234: clang/AMDGPU: Stop setting old denormal subtarget features In-Reply-To: References: Message-ID: <9c298122468fde3662cedb5b6612cf92@localhost.localdomain> yaxunl accepted this revision. yaxunl added a comment. This revision is now accepted and ready to land. LGTM. Thanks! CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77234/new/ https://reviews.llvm.org/D77234 From cfe-commits at lists.llvm.org Wed Apr 1 16:21:27 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 23:21:27 +0000 (UTC) Subject: [PATCH] D77252: [OpenMP] Try to find an existing base for `omp begin/end declare variant` Message-ID: jdoerfert created this revision. jdoerfert added reviewers: kiranchandramohan, ABataev, RaviNarayanaswamy, gtbercea, grokos, sdmitriev, JonChesterfield, hfinkel, fghanim, aaron.ballman. Herald added subscribers: guansong, bollu, yaxunl. Herald added a project: clang. If we have a function definition in `omp begin/end declare variant` it is a specialization of a base function with the same name and "compatible" type. Before, we just created a declaration for the base. With this patch we try to find an existing declaration first and only create a new one if we did not find any with a compatible type. This is preferable as we can tolerate slight mismatches, especially if the specialized version is "more constrained", e.g., constexpr. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77252 Files: clang/include/clang/AST/ASTContext.h clang/include/clang/Sema/Sema.h clang/lib/AST/ASTContext.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaOpenMP.cpp clang/test/AST/ast-dump-openmp-begin-declare-variant_10.c clang/test/AST/ast-dump-openmp-begin-declare-variant_11.c clang/test/AST/ast-dump-openmp-begin-declare-variant_12.c clang/test/AST/ast-dump-openmp-begin-declare-variant_2.c clang/test/AST/ast-dump-openmp-begin-declare-variant_3.c clang/test/AST/ast-dump-openmp-begin-declare-variant_4.c clang/test/AST/ast-dump-openmp-begin-declare-variant_5.c clang/test/AST/ast-dump-openmp-begin-declare-variant_6.c clang/test/AST/ast-dump-openmp-begin-declare-variant_7.c clang/test/AST/ast-dump-openmp-begin-declare-variant_8.c clang/test/AST/ast-dump-openmp-begin-declare-variant_9.c clang/test/AST/ast-dump-openmp-begin-declare-variant_addr_1.c clang/test/AST/ast-dump-openmp-begin-declare-variant_namespace_1.cpp clang/test/AST/ast-dump-openmp-begin-declare-variant_template_1.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77252.254333.patch Type: text/x-patch Size: 238933 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 16:21:32 2020 From: cfe-commits at lists.llvm.org (Alexander Lanin via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 23:21:32 +0000 (UTC) Subject: [PATCH] D74299: [clang-tidy] extend tests of run-clang-tidy In-Reply-To: References: Message-ID: <5e90bf8cf03e2827269613798c20c7ad@localhost.localdomain> AlexanderLanin added a comment. *ping* CHANGES SINCE LAST ACTION https://reviews.llvm.org/D74299/new/ https://reviews.llvm.org/D74299 From cfe-commits at lists.llvm.org Wed Apr 1 16:21:34 2020 From: cfe-commits at lists.llvm.org (Christopher Tetreault via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 23:21:34 +0000 (UTC) Subject: [PATCH] D77254: Clean up usages of asserting vector getters in Type Message-ID: ctetreau created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Remove usages of asserting vector getters in Type in preparation for the VectorType refactor. The existence of these functions complicates the refactor while adding little value. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77254 Files: clang/lib/CodeGen/CGAtomic.cpp clang/lib/CodeGen/CGBuiltin.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprScalar.cpp clang/lib/CodeGen/PatternInit.cpp clang/lib/CodeGen/TargetInfo.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77254.254335.patch Type: text/x-patch Size: 29730 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 16:54:32 2020 From: cfe-commits at lists.llvm.org (Christopher Tetreault via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 23:54:32 +0000 (UTC) Subject: [PATCH] D77257: Clean up usages of asserting vector getters in Type Message-ID: ctetreau created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Remove usages of asserting vector getters in Type in preparation for the VectorType refactor. The existence of these functions complicates the refactor while adding little value. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77257 Files: clang/lib/CodeGen/CGAtomic.cpp clang/lib/CodeGen/CGBuiltin.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprScalar.cpp clang/lib/CodeGen/PatternInit.cpp clang/lib/CodeGen/TargetInfo.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77257.254340.patch Type: text/x-patch Size: 29730 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 16:54:32 2020 From: cfe-commits at lists.llvm.org (Momchil Velikov via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 23:54:32 +0000 (UTC) Subject: [PATCH] D71129: [ARM][CMSE] Implement CMSE attributes In-Reply-To: References: Message-ID: chill marked 2 inline comments as done. chill added inline comments. ================ Comment at: clang/include/clang/AST/Type.h:3622 bool getNoCfCheck() const { return Bits & NoCfCheckMask; } bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; } ---------------- snidertm wrote: > chill wrote: > > ... here. > > > > bool getHasRegParm() const { return ((Bits & RegParmMask) >> RegParmOffset) != 0; > I don't see how this helps. If RegParmOffset is 8 and the CmseNSCall bit is set in Bits, then your proposed getHasRegParm() will return true. Given the above assignment to Bits, we don't know if the CmseNSCall bit was set by cmseNSCall or by regParm. > > MIght I be missing something? No, it will not return true, because the mask will clear all bits, except bits [8-10,13-31]. Bits [13-31] are unused/zero, and in the patch I'm preparing, the RegParmMask will be simply 0x700, so they will be cleared anyway. CmseNSCall is bit 12, so it will be cleared. Also RegParm + 1 is at most 7, so, it cannot overflow into NoCfCheck of CmseNSCall. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71129/new/ https://reviews.llvm.org/D71129 From cfe-commits at lists.llvm.org Wed Apr 1 16:54:33 2020 From: cfe-commits at lists.llvm.org (Sriraman Tallam via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 23:54:33 +0000 (UTC) Subject: [PATCH] D73307: Unique Names for Functions with Internal Linkage In-Reply-To: References: Message-ID: <6f291e11a68357b2f4e5ff4f7fa976e1@localhost.localdomain> tmsriram updated this revision to Diff 254347. tmsriram added a comment. Rebase and add tests for anonymous namespace symbol and function static global. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73307/new/ https://reviews.llvm.org/D73307 Files: clang/docs/UsersManual.rst clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/lib/CodeGen/CodeGenModule.cpp clang/lib/CodeGen/CodeGenModule.h clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGen/unique-internal-linkage-names.cpp clang/test/Driver/funique-internal-linkage-names.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D73307.254347.patch Type: text/x-patch Size: 9844 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 17:27:06 2020 From: cfe-commits at lists.llvm.org (Todd Snider via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 00:27:06 +0000 (UTC) Subject: [PATCH] D71129: [ARM][CMSE] Implement CMSE attributes In-Reply-To: References: Message-ID: snidertm added inline comments. ================ Comment at: clang/include/clang/AST/Type.h:3622 bool getNoCfCheck() const { return Bits & NoCfCheckMask; } bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; } ---------------- chill wrote: > snidertm wrote: > > chill wrote: > > > ... here. > > > > > > bool getHasRegParm() const { return ((Bits & RegParmMask) >> RegParmOffset) != 0; > > I don't see how this helps. If RegParmOffset is 8 and the CmseNSCall bit is set in Bits, then your proposed getHasRegParm() will return true. Given the above assignment to Bits, we don't know if the CmseNSCall bit was set by cmseNSCall or by regParm. > > > > MIght I be missing something? > No, it will not return true, because the mask will clear all bits, except bits [8-10,13-31]. > Bits [13-31] are unused/zero, and in the patch I'm preparing, the RegParmMask will be simply 0x700, > so they will be cleared anyway. > CmseNSCall is bit 12, so it will be cleared. Also RegParm + 1 is at most 7, so, it cannot overflow into > NoCfCheck of CmseNSCall. Got it, ok. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71129/new/ https://reviews.llvm.org/D71129 From cfe-commits at lists.llvm.org Wed Apr 1 17:27:06 2020 From: cfe-commits at lists.llvm.org (Todd Snider via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 00:27:06 +0000 (UTC) Subject: [PATCH] D71129: [ARM][CMSE] Implement CMSE attributes In-Reply-To: References: Message-ID: snidertm added a comment. Have you already committed support for CMSE attributes to the LLVM backend? Or is that on the way? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71129/new/ https://reviews.llvm.org/D71129 From cfe-commits at lists.llvm.org Wed Apr 1 17:28:12 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 00:28:12 +0000 (UTC) Subject: [PATCH] D75788: [OpenMP] Provide math functions in OpenMP device code via OpenMP variants In-Reply-To: References: Message-ID: <3eeb016122f347f8d985e894e3d6801d@localhost.localdomain> jdoerfert updated this revision to Diff 254375. jdoerfert added a comment. Herald added a subscriber: yaxunl. Rewrite. Wrap math.h, time.h, and cmath. Preload only device functions. Passes all 185 math c++11 tests from [0] which do not deal with long double. [0] https://github.com/TApplencourt/OmpVal Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75788/new/ https://reviews.llvm.org/D75788 Files: clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Headers/CMakeLists.txt clang/lib/Headers/__clang_cuda_cmath.h clang/lib/Headers/__clang_cuda_device_functions.h clang/lib/Headers/__clang_cuda_math.h clang/lib/Headers/__clang_cuda_math_forward_declares.h clang/lib/Headers/openmp_wrappers/__clang_openmp_device_functions.h clang/lib/Headers/openmp_wrappers/__clang_openmp_math.h clang/lib/Headers/openmp_wrappers/__clang_openmp_math_declares.h clang/lib/Headers/openmp_wrappers/cmath clang/lib/Headers/openmp_wrappers/math.h clang/lib/Headers/openmp_wrappers/time.h clang/test/Headers/Inputs/include/climits clang/test/Headers/Inputs/include/cmath clang/test/Headers/Inputs/include/cstdlib clang/test/Headers/Inputs/include/math.h clang/test/Headers/Inputs/include/stdlib.h clang/test/Headers/nvptx_device_cmath_functions.c clang/test/Headers/nvptx_device_cmath_functions.cpp clang/test/Headers/nvptx_device_cmath_functions_cxx17.cpp clang/test/Headers/nvptx_device_math_complex.c clang/test/Headers/nvptx_device_math_functions.c clang/test/Headers/nvptx_device_math_functions.cpp clang/test/Headers/nvptx_device_math_functions_cxx17.cpp clang/test/Headers/nvptx_device_math_macro.cpp clang/test/Headers/nvptx_device_math_modf.cpp clang/test/Headers/nvptx_device_math_sin.c clang/test/Headers/nvptx_device_math_sin.cpp clang/test/Headers/nvptx_device_math_sin_cos.cpp clang/test/Headers/nvptx_device_math_sincos.cpp llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn -------------- next part -------------- A non-text attachment was scrubbed... Name: D75788.254375.patch Type: text/x-patch Size: 53781 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 17:46:31 2020 From: cfe-commits at lists.llvm.org (Adrian Prantl via cfe-commits) Date: Wed, 01 Apr 2020 17:46:31 -0700 (PDT) Subject: [clang] f4754ea - Remove const qualifier from Modules returned by ExternalASTSource. (NFC) Message-ID: <5e8535e7.1c69fb81.854cb.c8b7@mx.google.com> Author: Adrian Prantl Date: 2020-04-01T17:46:02-07:00 New Revision: f4754ea0ed7ddc35042bacbc47d661bfe660f132 URL: https://github.com/llvm/llvm-project/commit/f4754ea0ed7ddc35042bacbc47d661bfe660f132 DIFF: https://github.com/llvm/llvm-project/commit/f4754ea0ed7ddc35042bacbc47d661bfe660f132.diff LOG: Remove const qualifier from Modules returned by ExternalASTSource. (NFC) This API is used by LLDB to attach owning module information to Declarations deserialized from DWARF. Differential Revision: https://reviews.llvm.org/D75561 Added: Modified: clang/include/clang/Basic/Module.h clang/lib/Basic/Module.cpp clang/lib/Serialization/ASTReader.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h index 9c2bc155cd4f..c47eb4587a57 100644 --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -662,7 +662,7 @@ class ASTSourceDescriptor { StringRef Path; StringRef ASTFile; ASTFileSignature Signature; - const Module *ClangModule = nullptr; + Module *ClangModule = nullptr; public: ASTSourceDescriptor() = default; @@ -670,13 +670,13 @@ class ASTSourceDescriptor { ASTFileSignature Signature) : PCHModuleName(std::move(Name)), Path(std::move(Path)), ASTFile(std::move(ASTFile)), Signature(Signature) {} - ASTSourceDescriptor(const Module &M); + ASTSourceDescriptor(Module &M); std::string getModuleName() const; StringRef getPath() const { return Path; } StringRef getASTFile() const { return ASTFile; } ASTFileSignature getSignature() const { return Signature; } - const Module *getModuleOrNull() const { return ClangModule; } + Module *getModuleOrNull() const { return ClangModule; } }; diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp index dd8f11101107..5fd7d304f8f4 100644 --- a/clang/lib/Basic/Module.cpp +++ b/clang/lib/Basic/Module.cpp @@ -659,7 +659,7 @@ void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, VisitModule({M, nullptr}); } -ASTSourceDescriptor::ASTSourceDescriptor(const Module &M) +ASTSourceDescriptor::ASTSourceDescriptor(Module &M) : Signature(M.Signature), ClangModule(&M) { if (M.Directory) Path = M.Directory->getName(); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 7437f649a090..bea9bdd22bab 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -8514,7 +8514,7 @@ unsigned ASTReader::getModuleFileID(ModuleFile *F) { llvm::Optional ASTReader::getSourceDescriptor(unsigned ID) { - if (const Module *M = getSubmodule(ID)) + if (Module *M = getSubmodule(ID)) return ASTSourceDescriptor(*M); // If there is only a single PCH, return it instead. From cfe-commits at lists.llvm.org Wed Apr 1 17:59:06 2020 From: cfe-commits at lists.llvm.org (Paula Toth via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 00:59:06 +0000 (UTC) Subject: [PATCH] D76818: [clang-tidy] Add check llvmlibc-implementation-in-namespace. In-Reply-To: References: Message-ID: <16ba53e08feda23bdfe91b874aa26d3f@localhost.localdomain> PaulkaToast updated this revision to Diff 254376. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76818/new/ https://reviews.llvm.org/D76818 Files: clang-tools-extra/clang-tidy/llvmlibc/CMakeLists.txt clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.h clang-tools-extra/clang-tidy/llvmlibc/LLVMLibcTidyModule.cpp clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/docs/clang-tidy/checks/list.rst clang-tools-extra/docs/clang-tidy/checks/llvmlibc-implementation-in-namespace.rst clang-tools-extra/test/clang-tidy/checkers/llvmlibc-implementation-in-namespace.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76818.254376.patch Type: text/x-patch Size: 9598 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 17:59:10 2020 From: cfe-commits at lists.llvm.org (Alina Sbirlea via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 00:59:10 +0000 (UTC) Subject: [PATCH] D72893: [NewPassManager] Add assertions when getting statefull cached analysis. In-Reply-To: References: Message-ID: <18b9c9a41a10a29a9503d8c50e5b14eb@localhost.localdomain> asbirlea updated this revision to Diff 254378. asbirlea added a comment. Herald added a project: clang. Herald added a subscriber: cfe-commits. Update clang test. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72893/new/ https://reviews.llvm.org/D72893 Files: clang/test/CodeGen/thinlto-distributed-newpm.ll llvm/include/llvm/Analysis/AliasAnalysis.h llvm/include/llvm/Analysis/CGSCCPassManager.h llvm/include/llvm/IR/PassManager.h llvm/include/llvm/Transforms/Utils/CallGraphUpdater.h llvm/lib/Analysis/CGSCCPassManager.cpp llvm/lib/Transforms/Coroutines/CoroSplit.cpp llvm/lib/Transforms/IPO/Inliner.cpp llvm/lib/Transforms/InstCombine/InstructionCombining.cpp llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp llvm/lib/Transforms/Scalar/ConstantHoisting.cpp llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp llvm/lib/Transforms/Scalar/LoopUnrollPass.cpp llvm/lib/Transforms/Utils/CallGraphUpdater.cpp llvm/lib/Transforms/Vectorize/LoopVectorize.cpp llvm/unittests/Analysis/CGSCCPassManagerTest.cpp llvm/unittests/IR/PassManagerTest.cpp llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D72893.254378.patch Type: text/x-patch Size: 56527 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 17:59:11 2020 From: cfe-commits at lists.llvm.org (Atmn Patel via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 00:59:11 +0000 (UTC) Subject: [PATCH] D75591: [OpenMP] Add firstprivate as a default data-sharing attribute to clang In-Reply-To: References: Message-ID: atmnpatel updated this revision to Diff 254379. atmnpatel added a comment. Herald added a subscriber: yaxunl. Fixes to tests. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75591/new/ https://reviews.llvm.org/D75591 Files: clang-tools-extra/docs/clang-tidy/checks/openmp-use-default-none.rst clang-tools-extra/test/clang-tidy/checkers/openmp-use-default-none.cpp clang/docs/LibASTMatchersReference.html clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/ASTMatchers/Dynamic/Registry.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/test/OpenMP/distribute_parallel_for_default_messages.cpp clang/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp clang/test/OpenMP/driver.c clang/test/OpenMP/parallel_default_messages.cpp clang/test/OpenMP/parallel_for_default_messages.cpp clang/test/OpenMP/parallel_for_simd_default_messages.cpp clang/test/OpenMP/parallel_master_codegen.cpp clang/test/OpenMP/parallel_master_default_messages.cpp clang/test/OpenMP/parallel_sections_default_messages.cpp clang/test/OpenMP/target_parallel_default_messages.cpp clang/test/OpenMP/target_parallel_for_default_messages.cpp clang/test/OpenMP/target_parallel_for_simd_default_messages.cpp clang/test/OpenMP/target_teams_default_messages.cpp clang/test/OpenMP/target_teams_distribute_default_messages.cpp clang/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp clang/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp clang/test/OpenMP/task_default_messages.cpp clang/test/OpenMP/task_messages.cpp clang/test/OpenMP/teams_default_messages.cpp clang/test/OpenMP/teams_distribute_default_messages.cpp clang/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp clang/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp clang/test/OpenMP/teams_distribute_simd_default_messages.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp clang/unittests/ASTMatchers/ASTMatchersTest.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def -------------- next part -------------- A non-text attachment was scrubbed... Name: D75591.254379.patch Type: text/x-patch Size: 88700 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 17:59:13 2020 From: cfe-commits at lists.llvm.org (Ryan Gonzalez via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 00:59:13 +0000 (UTC) Subject: [PATCH] D77282: [AST] Fix formatting whitespace-only comments Message-ID: refi64 created this revision. Herald added subscribers: cfe-commits, usaxena95, kadircet, ilya-biryukov. Herald added a project: clang. refi64 added a reviewer: ilya-biryukov. refi64 added a comment. (I manually ran clang-format-diff afterwards, there were no suggested changes.) If a string consisted only of whitespace, the emptiness check in getFormattedText would fail, but DropTrailingNewLines would then call Str.back() on an empty string. In practice, this can easily crash clangd if an editor asks for a declaration comment that is whitespace-only. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77282 Files: clang/lib/AST/RawCommentList.cpp clang/unittests/AST/CommentTextTest.cpp Index: clang/unittests/AST/CommentTextTest.cpp =================================================================== --- clang/unittests/AST/CommentTextTest.cpp +++ clang/unittests/AST/CommentTextTest.cpp @@ -124,4 +124,10 @@ // clang-format on } +TEST_F(CommentTextTest, WorksWithEmptyBlockComments) { + auto ExpectedOutput = ""; + auto Formatted = formatComment(R"(/* */)"); + EXPECT_EQ(ExpectedOutput, Formatted); +} + } // namespace clang Index: clang/lib/AST/RawCommentList.cpp =================================================================== --- clang/lib/AST/RawCommentList.cpp +++ clang/lib/AST/RawCommentList.cpp @@ -431,7 +431,7 @@ }; auto DropTrailingNewLines = [](std::string &Str) { - while (Str.back() == '\n') + while (!Str.empty() && Str.back() == '\n') Str.pop_back(); }; -------------- next part -------------- A non-text attachment was scrubbed... Name: D77282.254380.patch Type: text/x-patch Size: 826 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 17:59:15 2020 From: cfe-commits at lists.llvm.org (Ryan Gonzalez via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 00:59:15 +0000 (UTC) Subject: [PATCH] D77282: [AST] Fix formatting whitespace-only comments In-Reply-To: References: Message-ID: <7e00d8fd93b2b05f77bbeeafd0246c61@localhost.localdomain> refi64 added a comment. (I manually ran clang-format-diff afterwards, there were no suggested changes.) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77282/new/ https://reviews.llvm.org/D77282 From cfe-commits at lists.llvm.org Wed Apr 1 18:00:23 2020 From: cfe-commits at lists.llvm.org (Adrian Prantl via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 01:00:23 +0000 (UTC) Subject: [PATCH] D75561: Remove const qualifier from Modules returned by ExternalASTSource. (NFC) In-Reply-To: References: Message-ID: <3d515083e35216167613e0e3ce6eb48f@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGf4754ea0ed7d: Remove const qualifier from Modules returned by ExternalASTSource. (NFC) (authored by aprantl). Herald added a project: clang. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75561/new/ https://reviews.llvm.org/D75561 Files: clang/include/clang/Basic/Module.h clang/lib/Basic/Module.cpp clang/lib/Serialization/ASTReader.cpp Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -8514,7 +8514,7 @@ llvm::Optional ASTReader::getSourceDescriptor(unsigned ID) { - if (const Module *M = getSubmodule(ID)) + if (Module *M = getSubmodule(ID)) return ASTSourceDescriptor(*M); // If there is only a single PCH, return it instead. Index: clang/lib/Basic/Module.cpp =================================================================== --- clang/lib/Basic/Module.cpp +++ clang/lib/Basic/Module.cpp @@ -659,7 +659,7 @@ VisitModule({M, nullptr}); } -ASTSourceDescriptor::ASTSourceDescriptor(const Module &M) +ASTSourceDescriptor::ASTSourceDescriptor(Module &M) : Signature(M.Signature), ClangModule(&M) { if (M.Directory) Path = M.Directory->getName(); Index: clang/include/clang/Basic/Module.h =================================================================== --- clang/include/clang/Basic/Module.h +++ clang/include/clang/Basic/Module.h @@ -662,7 +662,7 @@ StringRef Path; StringRef ASTFile; ASTFileSignature Signature; - const Module *ClangModule = nullptr; + Module *ClangModule = nullptr; public: ASTSourceDescriptor() = default; @@ -670,13 +670,13 @@ ASTFileSignature Signature) : PCHModuleName(std::move(Name)), Path(std::move(Path)), ASTFile(std::move(ASTFile)), Signature(Signature) {} - ASTSourceDescriptor(const Module &M); + ASTSourceDescriptor(Module &M); std::string getModuleName() const; StringRef getPath() const { return Path; } StringRef getASTFile() const { return ASTFile; } ASTFileSignature getSignature() const { return Signature; } - const Module *getModuleOrNull() const { return ClangModule; } + Module *getModuleOrNull() const { return ClangModule; } }; -------------- next part -------------- A non-text attachment was scrubbed... Name: D75561.254382.patch Type: text/x-patch Size: 1925 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 18:32:26 2020 From: cfe-commits at lists.llvm.org (Vy Nguyen via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 01:32:26 +0000 (UTC) Subject: [PATCH] D75951: Keep a list of already-included pragma-once files for mods. In-Reply-To: References: Message-ID: <4c8c48bea545a8a3c88cfd4fbc2b0bc5@localhost.localdomain> oontvoo updated this revision to Diff 254384. oontvoo added a comment. Update docs. Note: The failure looks spurious ... They seemed to pass locally for me: One eg: [hi on] vyng at vyng:~/repo/llvm-project$ ./build/bin/llvm-lit -v ./clang/test/ClangScanDeps/modules-full.cpp llvm-lit: /usr/local/google/home/vyng/repo/llvm-project/llvm/utils/lit/lit/llvm/config.py:342: note: using clang: /usr/local/google/home/vyng/repo/llvm-project/build/bin/clang - Testing: 1 tests, 1 workers -- PASS: Clang :: ClangScanDeps/modules-full.cpp (1 of 1) Testing Time: 2.75s Expected Passes : 1 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75951/new/ https://reviews.llvm.org/D75951 Files: clang/include/clang/Lex/HeaderSearch.h clang/include/clang/Lex/Preprocessor.h clang/include/clang/Serialization/ASTBitCodes.h clang/include/clang/Serialization/ASTReader.h clang/include/clang/Serialization/ASTWriter.h clang/lib/Lex/HeaderSearch.cpp clang/lib/Lex/PPDirectives.cpp clang/lib/Lex/PPLexerChange.cpp clang/lib/Lex/Preprocessor.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/test/Modules/Inputs/dummy_pragma_once.h clang/test/Modules/Inputs/dummy_textual_header.h clang/test/Modules/Inputs/header_in_imported_module.h clang/test/Modules/Inputs/imported_module.cppm clang/test/Modules/Inputs/module.map clang/test/Modules/header-in-imported-module.c clang/test/Modules/import-pragma-once.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D75951.254384.patch Type: text/x-patch Size: 29130 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 19:04:52 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 02:04:52 +0000 (UTC) Subject: [PATCH] D76184: [OpenMP][NFC] Remove the need to include `OpenMPClause.h` In-Reply-To: References: Message-ID: <4a6cc3bb39d27cdcddce65e2f8209fba@localhost.localdomain> jdoerfert added a comment. Herald added a subscriber: yaxunl. @rnk What is the plan for this one now? Should I abandon it? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76184/new/ https://reviews.llvm.org/D76184 From cfe-commits at lists.llvm.org Wed Apr 1 19:04:52 2020 From: cfe-commits at lists.llvm.org (Atmn Patel via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 02:04:52 +0000 (UTC) Subject: [PATCH] D75591: [OpenMP] Add firstprivate as a default data-sharing attribute to clang In-Reply-To: References: Message-ID: <6f3db9be21d25b9d18f3fe83b223680b@localhost.localdomain> atmnpatel updated this revision to Diff 254392. atmnpatel added a comment. Rebase. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75591/new/ https://reviews.llvm.org/D75591 Files: clang-tools-extra/docs/clang-tidy/checks/openmp-use-default-none.rst clang-tools-extra/test/clang-tidy/checkers/openmp-use-default-none.cpp clang/docs/LibASTMatchersReference.html clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/ASTMatchers/Dynamic/Registry.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/test/OpenMP/distribute_parallel_for_default_messages.cpp clang/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp clang/test/OpenMP/driver.c clang/test/OpenMP/parallel_default_messages.cpp clang/test/OpenMP/parallel_for_default_messages.cpp clang/test/OpenMP/parallel_for_simd_default_messages.cpp clang/test/OpenMP/parallel_master_codegen.cpp clang/test/OpenMP/parallel_master_default_messages.cpp clang/test/OpenMP/parallel_sections_default_messages.cpp clang/test/OpenMP/target_parallel_default_messages.cpp clang/test/OpenMP/target_parallel_for_default_messages.cpp clang/test/OpenMP/target_parallel_for_simd_default_messages.cpp clang/test/OpenMP/target_teams_default_messages.cpp clang/test/OpenMP/target_teams_distribute_default_messages.cpp clang/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp clang/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp clang/test/OpenMP/task_default_messages.cpp clang/test/OpenMP/task_messages.cpp clang/test/OpenMP/teams_default_messages.cpp clang/test/OpenMP/teams_distribute_default_messages.cpp clang/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp clang/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp clang/test/OpenMP/teams_distribute_simd_default_messages.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp clang/unittests/ASTMatchers/ASTMatchersTest.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def -------------- next part -------------- A non-text attachment was scrubbed... Name: D75591.254392.patch Type: text/x-patch Size: 88709 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 19:05:14 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 02:05:14 +0000 (UTC) Subject: [PATCH] D74935: [LangRef][AliasAnalysis] Clarify `noalias` affects only modified objects In-Reply-To: References: Message-ID: <19765a309b20da740af628ea2561e54e@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG6cd673345cfa: [LangRef][AliasAnalysis] Clarify `noalias` affects only modified objects (authored by jdoerfert). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D74935/new/ https://reviews.llvm.org/D74935 Files: llvm/docs/LangRef.rst Index: llvm/docs/LangRef.rst =================================================================== --- llvm/docs/LangRef.rst +++ llvm/docs/LangRef.rst @@ -1107,14 +1107,16 @@ .. _noalias: ``noalias`` - This indicates that objects accessed via pointer values + This indicates that memory locations accessed via pointer values :ref:`based ` on the argument or return value are not also accessed, during the execution of the function, via pointer values not - *based* on the argument or return value. The attribute on a return value - also has additional semantics described below. The caller shares the - responsibility with the callee for ensuring that these requirements are met. - For further details, please see the discussion of the NoAlias response in - :ref:`alias analysis `. + *based* on the argument or return value. This guarantee only holds for + memory locations that are *modified*, by any means, during the execution of + the function. The attribute on a return value also has additional semantics + described below. The caller shares the responsibility with the callee for + ensuring that these requirements are met. For further details, please see + the discussion of the NoAlias response in :ref:`alias analysis `. Note that this definition of ``noalias`` is intentionally similar to the definition of ``restrict`` in C99 for function arguments. -------------- next part -------------- A non-text attachment was scrubbed... Name: D74935.254394.patch Type: text/x-patch Size: 1484 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 19:20:56 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via cfe-commits) Date: Wed, 01 Apr 2020 19:20:56 -0700 (PDT) Subject: [clang] 5767085 - Fix infinite recursion in deferred diag emitter Message-ID: <5e854c08.1c69fb81.b060d.db7f@mx.google.com> Author: Yaxun (Sam) Liu Date: 2020-04-01T22:17:43-04:00 New Revision: 5767085c8de97d15d7fb5433f22bb5b858cc4f3a URL: https://github.com/llvm/llvm-project/commit/5767085c8de97d15d7fb5433f22bb5b858cc4f3a DIFF: https://github.com/llvm/llvm-project/commit/5767085c8de97d15d7fb5433f22bb5b858cc4f3a.diff LOG: Fix infinite recursion in deferred diag emitter Currently deferred diagnostic emitter checks variable decl in DeclRefExpr, which causes infinite recursion for cases like long a = (long)&a;. Deferred diagnostic emitter does not need check variable decls in DeclRefExpr since reference of a variable does not cause emission of functions directly or indirectly. Therefore there is no need to check variable decls in DeclRefExpr. Differential Revision: https://reviews.llvm.org/D76937 Added: Modified: clang/lib/Sema/Sema.cpp clang/lib/Sema/SemaDecl.cpp clang/test/OpenMP/nvptx_target_exceptions_messages.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 03475240f6f9..44b5115d9d2f 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1501,43 +1501,60 @@ class DeferredDiagnosticsEmitter } void visitUsedDecl(SourceLocation Loc, Decl *D) { - if (auto *FD = dyn_cast(D)) { - FunctionDecl *Caller = UseStack.empty() ? nullptr : UseStack.back(); - auto IsKnownEmitted = S.getEmissionStatus(FD, /*Final=*/true) == - Sema::FunctionEmissionStatus::Emitted; - if (!Caller) - ShouldEmit = IsKnownEmitted; - if ((!ShouldEmit && !S.getLangOpts().OpenMP && !Caller) || - S.shouldIgnoreInHostDeviceCheck(FD) || Visited.count(D)) - return; - // Finalize analysis of OpenMP-specific constructs. - if (Caller && S.LangOpts.OpenMP && UseStack.size() == 1) - S.finalizeOpenMPDelayedAnalysis(Caller, FD, Loc); - if (Caller) - S.DeviceKnownEmittedFns[FD] = {Caller, Loc}; - if (ShouldEmit || InOMPDeviceContext) - S.emitDeferredDiags(FD, Caller); - Visited.insert(D); - UseStack.push_back(FD); - if (auto *S = FD->getBody()) { - this->Visit(S); - } - UseStack.pop_back(); - Visited.erase(D); - } else if (auto *VD = dyn_cast(D)) { - if (auto *Init = VD->getInit()) { - auto DevTy = OMPDeclareTargetDeclAttr::getDeviceType(VD); - bool IsDev = DevTy && (*DevTy == OMPDeclareTargetDeclAttr::DT_NoHost || - *DevTy == OMPDeclareTargetDeclAttr::DT_Any); - if (IsDev) - ++InOMPDeviceContext; - this->Visit(Init); - if (IsDev) - --InOMPDeviceContext; - } - } else + if (isa(D)) + return; + if (auto *FD = dyn_cast(D)) + checkFunc(Loc, FD); + else Inherited::visitUsedDecl(Loc, D); } + + void checkVar(VarDecl *VD) { + assert(VD->isFileVarDecl() && + "Should only check file-scope variables"); + if (auto *Init = VD->getInit()) { + auto DevTy = OMPDeclareTargetDeclAttr::getDeviceType(VD); + bool IsDev = DevTy && (*DevTy == OMPDeclareTargetDeclAttr::DT_NoHost || + *DevTy == OMPDeclareTargetDeclAttr::DT_Any); + if (IsDev) + ++InOMPDeviceContext; + this->Visit(Init); + if (IsDev) + --InOMPDeviceContext; + } + } + + void checkFunc(SourceLocation Loc, FunctionDecl *FD) { + FunctionDecl *Caller = UseStack.empty() ? nullptr : UseStack.back(); + auto IsKnownEmitted = S.getEmissionStatus(FD, /*Final=*/true) == + Sema::FunctionEmissionStatus::Emitted; + if (!Caller) + ShouldEmit = IsKnownEmitted; + if ((!ShouldEmit && !S.getLangOpts().OpenMP && !Caller) || + S.shouldIgnoreInHostDeviceCheck(FD) || Visited.count(FD)) + return; + // Finalize analysis of OpenMP-specific constructs. + if (Caller && S.LangOpts.OpenMP && UseStack.size() == 1) + S.finalizeOpenMPDelayedAnalysis(Caller, FD, Loc); + if (Caller) + S.DeviceKnownEmittedFns[FD] = {Caller, Loc}; + if (ShouldEmit || InOMPDeviceContext) + S.emitDeferredDiags(FD, Caller); + Visited.insert(FD); + UseStack.push_back(FD); + if (auto *S = FD->getBody()) { + this->Visit(S); + } + UseStack.pop_back(); + Visited.erase(FD); + } + + void checkRecordedDecl(Decl *D) { + if (auto *FD = dyn_cast(D)) + checkFunc(SourceLocation(), FD); + else + checkVar(cast(D)); + } }; } // namespace @@ -1552,7 +1569,7 @@ void Sema::emitDeferredDiags() { DeferredDiagnosticsEmitter DDE(*this); for (auto D : DeclsToCheckForDeferredDiags) - DDE.visitUsedDecl(SourceLocation(), D); + DDE.checkRecordedDecl(D); } // In CUDA, there are some constructs which may appear in semantically-valid diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index ea3a0c22c401..494a1cd1a685 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -12257,7 +12257,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { VDecl->setInitStyle(VarDecl::ListInit); } - if (LangOpts.OpenMP && VDecl->hasGlobalStorage()) + if (LangOpts.OpenMP && VDecl->isFileVarDecl()) DeclsToCheckForDeferredDiags.push_back(VDecl); CheckCompleteVariableDeclaration(VDecl); } diff --git a/clang/test/OpenMP/nvptx_target_exceptions_messages.cpp b/clang/test/OpenMP/nvptx_target_exceptions_messages.cpp index faff77e0a43b..c71615d2521f 100644 --- a/clang/test/OpenMP/nvptx_target_exceptions_messages.cpp +++ b/clang/test/OpenMP/nvptx_target_exceptions_messages.cpp @@ -1,5 +1,10 @@ -// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -fexceptions -fcxx-exceptions -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -fexceptions -fcxx-exceptions -ferror-limit 100 +// RUN: %clang_cc1 -fopenmp -x c++ -triple powerpc64le-unknown-unknown \ +// RUN: -verify=host -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc \ +// RUN: %s -o %t-ppc-host.bc -fexceptions -fcxx-exceptions +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown \ +// RUN: -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s \ +// RUN: -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - \ +// RUN: -fexceptions -fcxx-exceptions -ferror-limit 100 #ifndef HEADER #define HEADER @@ -81,4 +86,17 @@ int (*B)() = &foobar2; int foobar1() { throw 1; } int foobar2() { throw 1; } // expected-error {{cannot use 'throw' with exceptions disabled}} + +int foobar3(); +int (*C)() = &foobar3; // expected-warning {{declaration is not declared in any declare target region}} + // host-warning at -1 {{declaration is not declared in any declare target region}} +#pragma omp declare target +int (*D)() = C; // expected-note {{used here}} + // host-note at -1 {{used here}} +#pragma omp end declare target +int foobar3() { throw 1; } + +// Check no infinite recursion in deferred diagnostic emitter. +long E = (long)&E; + #endif // HEADER From cfe-commits at lists.llvm.org Wed Apr 1 19:37:55 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 02:37:55 +0000 (UTC) Subject: [PATCH] D76937: Fix infinite recursion in deferred diagnostic emitter In-Reply-To: References: Message-ID: <6d60249ef0fd75d938e87edbc2eff95d@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG5767085c8de9: Fix infinite recursion in deferred diag emitter (authored by yaxunl). Herald added a project: clang. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76937/new/ https://reviews.llvm.org/D76937 Files: clang/lib/Sema/Sema.cpp clang/lib/Sema/SemaDecl.cpp clang/test/OpenMP/nvptx_target_exceptions_messages.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76937.254398.patch Type: text/x-patch Size: 6152 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 20:09:36 2020 From: cfe-commits at lists.llvm.org (Todd Snider via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 03:09:36 +0000 (UTC) Subject: [PATCH] D71129: [ARM][CMSE] Implement CMSE attributes In-Reply-To: References: Message-ID: <1d095a686c28abd0a6920d6b6d745ae6@localhost.localdomain> snidertm added inline comments. ================ Comment at: clang/lib/CodeGen/CGCall.cpp:1882 + if (FI.isCmseNSCall()) + FuncAttrs.addAttribute("cmse_nonsecure_call"); + ---------------- Just curious … Does the LLVM backend have a way to extract a StringRef attribute from a CallInst? I know that you can do that with hasFnAttribute(), but I don't see anything for CallInst objects Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71129/new/ https://reviews.llvm.org/D71129 From cfe-commits at lists.llvm.org Wed Apr 1 20:09:38 2020 From: cfe-commits at lists.llvm.org (Vitaly Buka via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 03:09:38 +0000 (UTC) Subject: [PATCH] D77244: sancov/inline-bool-flag feature + tests + docs. In-Reply-To: References: Message-ID: vitalybuka added a comment. LGTM would it be possible to split into 3 patches 1. Instrumentation 2. clang flags stuff 3. compiler-rt test Btw. is this clang formated? ================ Comment at: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp:482 + Ctor = CreateInitCallsForSections(M, SanCovModuleCtorBoolFlagName, + SanCovBoolFlagInitName, Int8PtrTy, + SanCovBoolFlagSectionName); ---------------- Int1PtrT? ================ Comment at: llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp:918 + auto Store = IRB.CreateStore(ConstantInt::get(Int8Ty, 1), FlagPtr); + Store->setAtomic(AtomicOrdering::Monotonic); + Store->setAlignment(llvm::MaybeAlign(FunctionBoolArray->getAlign())); ---------------- Unordered or even NotAtomic is good enough here Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77244/new/ https://reviews.llvm.org/D77244 From cfe-commits at lists.llvm.org Wed Apr 1 20:42:25 2020 From: cfe-commits at lists.llvm.org (Brad Smith via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 03:42:25 +0000 (UTC) Subject: [PATCH] D73290: [PowerPC] Add clang -msvr4-struct-return for 32-bit ELF In-Reply-To: References: Message-ID: <3f4e01e02f5bf1d49350a35042ae7c54@localhost.localdomain> brad added a comment. Now that 10 is out, any chance of getting some movement on this to resolve this ABI issue with 32-bit PowerPC? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73290/new/ https://reviews.llvm.org/D73290 From cfe-commits at lists.llvm.org Wed Apr 1 20:43:03 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 03:43:03 +0000 (UTC) Subject: [PATCH] D77028: [NFC] Refactor DeferredDiagsEmitter and skip redundant visit In-Reply-To: References: Message-ID: <858da16c99d8aa7826a641d003fd4f70@localhost.localdomain> yaxunl updated this revision to Diff 254407. yaxunl added a comment. rebase CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77028/new/ https://reviews.llvm.org/D77028 Files: clang/include/clang/Sema/Sema.h clang/lib/Sema/Sema.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77028.254407.patch Type: text/x-patch Size: 5354 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 21:46:45 2020 From: cfe-commits at lists.llvm.org (Saleem Abdulrasool via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 04:46:45 +0000 (UTC) Subject: [PATCH] D77233: [NFC] Refactoring PropertyAttributeKind for ObjCPropertyDecl and ObjCDeclSpec. In-Reply-To: References: Message-ID: <5847ef7fa55cd70312c72c0ca652e10d@localhost.localdomain> compnerd added inline comments. ================ Comment at: clang/include/clang/AST/DeclObjCCommon.h:21 +/// Keep this list in sync with LLVM's Dwarf.h ApplePropertyAttributes. +enum ObjCPropertyAttributeKind { + OBJC_PR_noattr = 0x00, ---------------- It seems that you are touching all the sites that use this, so perhaps this is the time to change this to `enum class` and drop the `OBJC_PR_` prefixes and explicitly inherit from `uint16_t`. This should be named `ObjCPropertyAttribute` I think. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77233/new/ https://reviews.llvm.org/D77233 From cfe-commits at lists.llvm.org Wed Apr 1 21:46:46 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 04:46:46 +0000 (UTC) Subject: [PATCH] D76812: [X86] Add Indirect Thunk Support to X86 to mitigate Load Value Injection (LVI) [3/3] In-Reply-To: References: Message-ID: <2d1328e501ff676d3871d533371786b7@localhost.localdomain> craig.topper accepted this revision. craig.topper added a comment. This revision is now accepted and ready to land. LGTM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76812/new/ https://reviews.llvm.org/D76812 From cfe-commits at lists.llvm.org Wed Apr 1 21:47:36 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via cfe-commits) Date: Wed, 01 Apr 2020 21:47:36 -0700 (PDT) Subject: [clang] d1705c1 - [CUDA][NFC] Split math.h functions out of __clang_cuda_device_functions.h Message-ID: <5e856e68.1c69fb81.178d0.e4b2@mx.google.com> Author: Johannes Doerfert Date: 2020-04-01T23:46:27-05:00 New Revision: d1705c1196fedfe927716923ac121f1134924a36 URL: https://github.com/llvm/llvm-project/commit/d1705c1196fedfe927716923ac121f1134924a36 DIFF: https://github.com/llvm/llvm-project/commit/d1705c1196fedfe927716923ac121f1134924a36.diff LOG: [CUDA][NFC] Split math.h functions out of __clang_cuda_device_functions.h This is not supported to change anything but allow us to reuse the math functions separately from the device functions, e.g., source them at different times. This will be used by the OpenMP overlay. This also adds two `return` keywords that were missing. Reviewed By: tra Differential Revision: https://reviews.llvm.org/D77238 Added: clang/lib/Headers/__clang_cuda_math.h Modified: clang/lib/Headers/CMakeLists.txt clang/lib/Headers/__clang_cuda_device_functions.h clang/lib/Headers/__clang_cuda_runtime_wrapper.h Removed: ################################################################################ diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index 8124549bfc48..5ca6f3cca1bc 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -37,6 +37,7 @@ set(files bmi2intrin.h bmiintrin.h __clang_cuda_builtin_vars.h + __clang_cuda_math.h __clang_cuda_cmath.h __clang_cuda_complex_builtins.h __clang_cuda_device_functions.h diff --git a/clang/lib/Headers/__clang_cuda_device_functions.h b/clang/lib/Headers/__clang_cuda_device_functions.h index 50ad674f9483..d15f6b61d6ef 100644 --- a/clang/lib/Headers/__clang_cuda_device_functions.h +++ b/clang/lib/Headers/__clang_cuda_device_functions.h @@ -26,26 +26,6 @@ #define __DEVICE__ static __device__ __forceinline__ #endif -// libdevice provides fast low precision and slow full-recision implementations -// for some functions. Which one gets selected depends on -// __CLANG_CUDA_APPROX_TRANSCENDENTALS__ which gets defined by clang if -// -ffast-math or -fcuda-approx-transcendentals are in effect. -#pragma push_macro("__FAST_OR_SLOW") -#if defined(__CLANG_CUDA_APPROX_TRANSCENDENTALS__) -#define __FAST_OR_SLOW(fast, slow) fast -#else -#define __FAST_OR_SLOW(fast, slow) slow -#endif - -// For C++ 17 we need to include noexcept attribute to be compatible -// with the header-defined version. This may be removed once -// variant is supported. -#if defined(_OPENMP) && defined(__cplusplus) && __cplusplus >= 201703L -#define __NOEXCEPT noexcept -#else -#define __NOEXCEPT -#endif - __DEVICE__ int __all(int __a) { return __nvvm_vote_all(__a); } __DEVICE__ int __any(int __a) { return __nvvm_vote_any(__a); } __DEVICE__ unsigned int __ballot(int __a) { return __nvvm_vote_ballot(__a); } @@ -359,10 +339,10 @@ __DEVICE__ int __iAtomicAdd(int *__p, int __v) { return __nvvm_atom_add_gen_i(__p, __v); } __DEVICE__ int __iAtomicAdd_block(int *__p, int __v) { - __nvvm_atom_cta_add_gen_i(__p, __v); + return __nvvm_atom_cta_add_gen_i(__p, __v); } __DEVICE__ int __iAtomicAdd_system(int *__p, int __v) { - __nvvm_atom_sys_add_gen_i(__p, __v); + return __nvvm_atom_sys_add_gen_i(__p, __v); } __DEVICE__ int __iAtomicAnd(int *__p, int __v) { return __nvvm_atom_and_gen_i(__p, __v); @@ -1483,149 +1463,14 @@ __DEVICE__ unsigned int __vsubus4(unsigned int __a, unsigned int __b) { return r; } #endif // CUDA_VERSION >= 9020 -__DEVICE__ int abs(int __a) __NOEXCEPT { return __nv_abs(__a); } -__DEVICE__ double fabs(double __a) __NOEXCEPT { return __nv_fabs(__a); } -__DEVICE__ double acos(double __a) { return __nv_acos(__a); } -__DEVICE__ float acosf(float __a) { return __nv_acosf(__a); } -__DEVICE__ double acosh(double __a) { return __nv_acosh(__a); } -__DEVICE__ float acoshf(float __a) { return __nv_acoshf(__a); } -__DEVICE__ double asin(double __a) { return __nv_asin(__a); } -__DEVICE__ float asinf(float __a) { return __nv_asinf(__a); } -__DEVICE__ double asinh(double __a) { return __nv_asinh(__a); } -__DEVICE__ float asinhf(float __a) { return __nv_asinhf(__a); } -__DEVICE__ double atan(double __a) { return __nv_atan(__a); } -__DEVICE__ double atan2(double __a, double __b) { return __nv_atan2(__a, __b); } -__DEVICE__ float atan2f(float __a, float __b) { return __nv_atan2f(__a, __b); } -__DEVICE__ float atanf(float __a) { return __nv_atanf(__a); } -__DEVICE__ double atanh(double __a) { return __nv_atanh(__a); } -__DEVICE__ float atanhf(float __a) { return __nv_atanhf(__a); } -__DEVICE__ double cbrt(double __a) { return __nv_cbrt(__a); } -__DEVICE__ float cbrtf(float __a) { return __nv_cbrtf(__a); } -__DEVICE__ double ceil(double __a) { return __nv_ceil(__a); } -__DEVICE__ float ceilf(float __a) { return __nv_ceilf(__a); } + +// For OpenMP we require the user to include as we need to know what +// clock_t is on the system. #ifndef _OPENMP -__DEVICE__ int clock() { return __nvvm_read_ptx_sreg_clock(); } -__DEVICE__ long long clock64() { return __nvvm_read_ptx_sreg_clock64(); } -#endif -__DEVICE__ double copysign(double __a, double __b) { - return __nv_copysign(__a, __b); -} -__DEVICE__ float copysignf(float __a, float __b) { - return __nv_copysignf(__a, __b); -} -__DEVICE__ double cos(double __a) { return __nv_cos(__a); } -__DEVICE__ float cosf(float __a) { - return __FAST_OR_SLOW(__nv_fast_cosf, __nv_cosf)(__a); -} -__DEVICE__ double cosh(double __a) { return __nv_cosh(__a); } -__DEVICE__ float coshf(float __a) { return __nv_coshf(__a); } -__DEVICE__ double cospi(double __a) { return __nv_cospi(__a); } -__DEVICE__ float cospif(float __a) { return __nv_cospif(__a); } -__DEVICE__ double cyl_bessel_i0(double __a) { return __nv_cyl_bessel_i0(__a); } -__DEVICE__ float cyl_bessel_i0f(float __a) { return __nv_cyl_bessel_i0f(__a); } -__DEVICE__ double cyl_bessel_i1(double __a) { return __nv_cyl_bessel_i1(__a); } -__DEVICE__ float cyl_bessel_i1f(float __a) { return __nv_cyl_bessel_i1f(__a); } -__DEVICE__ double erf(double __a) { return __nv_erf(__a); } -__DEVICE__ double erfc(double __a) { return __nv_erfc(__a); } -__DEVICE__ float erfcf(float __a) { return __nv_erfcf(__a); } -__DEVICE__ double erfcinv(double __a) { return __nv_erfcinv(__a); } -__DEVICE__ float erfcinvf(float __a) { return __nv_erfcinvf(__a); } -__DEVICE__ double erfcx(double __a) { return __nv_erfcx(__a); } -__DEVICE__ float erfcxf(float __a) { return __nv_erfcxf(__a); } -__DEVICE__ float erff(float __a) { return __nv_erff(__a); } -__DEVICE__ double erfinv(double __a) { return __nv_erfinv(__a); } -__DEVICE__ float erfinvf(float __a) { return __nv_erfinvf(__a); } -__DEVICE__ double exp(double __a) { return __nv_exp(__a); } -__DEVICE__ double exp10(double __a) { return __nv_exp10(__a); } -__DEVICE__ float exp10f(float __a) { return __nv_exp10f(__a); } -__DEVICE__ double exp2(double __a) { return __nv_exp2(__a); } -__DEVICE__ float exp2f(float __a) { return __nv_exp2f(__a); } -__DEVICE__ float expf(float __a) { return __nv_expf(__a); } -__DEVICE__ double expm1(double __a) { return __nv_expm1(__a); } -__DEVICE__ float expm1f(float __a) { return __nv_expm1f(__a); } -__DEVICE__ float fabsf(float __a) { return __nv_fabsf(__a); } -__DEVICE__ double fdim(double __a, double __b) { return __nv_fdim(__a, __b); } -__DEVICE__ float fdimf(float __a, float __b) { return __nv_fdimf(__a, __b); } -__DEVICE__ double fdivide(double __a, double __b) { return __a / __b; } -__DEVICE__ float fdividef(float __a, float __b) { -#if __FAST_MATH__ && !__CUDA_PREC_DIV - return __nv_fast_fdividef(__a, __b); -#else - return __a / __b; +__DEVICE__ /* clock_t= */ int clock() { return __nvvm_read_ptx_sreg_clock(); } #endif -} -__DEVICE__ double floor(double __f) { return __nv_floor(__f); } -__DEVICE__ float floorf(float __f) { return __nv_floorf(__f); } -__DEVICE__ double fma(double __a, double __b, double __c) { - return __nv_fma(__a, __b, __c); -} -__DEVICE__ float fmaf(float __a, float __b, float __c) { - return __nv_fmaf(__a, __b, __c); -} -__DEVICE__ double fmax(double __a, double __b) { return __nv_fmax(__a, __b); } -__DEVICE__ float fmaxf(float __a, float __b) { return __nv_fmaxf(__a, __b); } -__DEVICE__ double fmin(double __a, double __b) { return __nv_fmin(__a, __b); } -__DEVICE__ float fminf(float __a, float __b) { return __nv_fminf(__a, __b); } -__DEVICE__ double fmod(double __a, double __b) { return __nv_fmod(__a, __b); } -__DEVICE__ float fmodf(float __a, float __b) { return __nv_fmodf(__a, __b); } -__DEVICE__ double frexp(double __a, int *__b) { return __nv_frexp(__a, __b); } -__DEVICE__ float frexpf(float __a, int *__b) { return __nv_frexpf(__a, __b); } -__DEVICE__ double hypot(double __a, double __b) { return __nv_hypot(__a, __b); } -__DEVICE__ float hypotf(float __a, float __b) { return __nv_hypotf(__a, __b); } -__DEVICE__ int ilogb(double __a) { return __nv_ilogb(__a); } -__DEVICE__ int ilogbf(float __a) { return __nv_ilogbf(__a); } -__DEVICE__ double j0(double __a) { return __nv_j0(__a); } -__DEVICE__ float j0f(float __a) { return __nv_j0f(__a); } -__DEVICE__ double j1(double __a) { return __nv_j1(__a); } -__DEVICE__ float j1f(float __a) { return __nv_j1f(__a); } -__DEVICE__ double jn(int __n, double __a) { return __nv_jn(__n, __a); } -__DEVICE__ float jnf(int __n, float __a) { return __nv_jnf(__n, __a); } -#if defined(__LP64__) || defined(_WIN64) -__DEVICE__ long labs(long __a) __NOEXCEPT { return __nv_llabs(__a); }; -#else -__DEVICE__ long labs(long __a) __NOEXCEPT { return __nv_abs(__a); }; -#endif -__DEVICE__ double ldexp(double __a, int __b) { return __nv_ldexp(__a, __b); } -__DEVICE__ float ldexpf(float __a, int __b) { return __nv_ldexpf(__a, __b); } -__DEVICE__ double lgamma(double __a) { return __nv_lgamma(__a); } -__DEVICE__ float lgammaf(float __a) { return __nv_lgammaf(__a); } -__DEVICE__ long long llabs(long long __a) __NOEXCEPT { return __nv_llabs(__a); } -__DEVICE__ long long llmax(long long __a, long long __b) { - return __nv_llmax(__a, __b); -} -__DEVICE__ long long llmin(long long __a, long long __b) { - return __nv_llmin(__a, __b); -} -__DEVICE__ long long llrint(double __a) { return __nv_llrint(__a); } -__DEVICE__ long long llrintf(float __a) { return __nv_llrintf(__a); } -__DEVICE__ long long llround(double __a) { return __nv_llround(__a); } -__DEVICE__ long long llroundf(float __a) { return __nv_llroundf(__a); } -__DEVICE__ double log(double __a) { return __nv_log(__a); } -__DEVICE__ double log10(double __a) { return __nv_log10(__a); } -__DEVICE__ float log10f(float __a) { return __nv_log10f(__a); } -__DEVICE__ double log1p(double __a) { return __nv_log1p(__a); } -__DEVICE__ float log1pf(float __a) { return __nv_log1pf(__a); } -__DEVICE__ double log2(double __a) { return __nv_log2(__a); } -__DEVICE__ float log2f(float __a) { - return __FAST_OR_SLOW(__nv_fast_log2f, __nv_log2f)(__a); -} -__DEVICE__ double logb(double __a) { return __nv_logb(__a); } -__DEVICE__ float logbf(float __a) { return __nv_logbf(__a); } -__DEVICE__ float logf(float __a) { - return __FAST_OR_SLOW(__nv_fast_logf, __nv_logf)(__a); -} -#if defined(__LP64__) || defined(_WIN64) -__DEVICE__ long lrint(double __a) { return llrint(__a); } -__DEVICE__ long lrintf(float __a) { return __float2ll_rn(__a); } -__DEVICE__ long lround(double __a) { return llround(__a); } -__DEVICE__ long lroundf(float __a) { return llroundf(__a); } -#else -__DEVICE__ long lrint(double __a) { return (long)rint(__a); } -__DEVICE__ long lrintf(float __a) { return __float2int_rn(__a); } -__DEVICE__ long lround(double __a) { return round(__a); } -__DEVICE__ long lroundf(float __a) { return roundf(__a); } -#endif -__DEVICE__ int max(int __a, int __b) { return __nv_max(__a, __b); } +__DEVICE__ long long clock64() { return __nvvm_read_ptx_sreg_clock64(); } + // These functions shouldn't be declared when including this header // for math function resolution purposes. #ifndef _OPENMP @@ -1636,158 +1481,6 @@ __DEVICE__ void *memset(void *__a, int __b, size_t __c) { return __builtin_memset(__a, __b, __c); } #endif -__DEVICE__ int min(int __a, int __b) { return __nv_min(__a, __b); } -__DEVICE__ double modf(double __a, double *__b) { return __nv_modf(__a, __b); } -__DEVICE__ float modff(float __a, float *__b) { return __nv_modff(__a, __b); } -__DEVICE__ double nearbyint(double __a) { return __nv_nearbyint(__a); } -__DEVICE__ float nearbyintf(float __a) { return __nv_nearbyintf(__a); } -__DEVICE__ double nextafter(double __a, double __b) { - return __nv_nextafter(__a, __b); -} -__DEVICE__ float nextafterf(float __a, float __b) { - return __nv_nextafterf(__a, __b); -} -__DEVICE__ double norm(int __dim, const double *__t) { - return __nv_norm(__dim, __t); -} -__DEVICE__ double norm3d(double __a, double __b, double __c) { - return __nv_norm3d(__a, __b, __c); -} -__DEVICE__ float norm3df(float __a, float __b, float __c) { - return __nv_norm3df(__a, __b, __c); -} -__DEVICE__ double norm4d(double __a, double __b, double __c, double __d) { - return __nv_norm4d(__a, __b, __c, __d); -} -__DEVICE__ float norm4df(float __a, float __b, float __c, float __d) { - return __nv_norm4df(__a, __b, __c, __d); -} -__DEVICE__ double normcdf(double __a) { return __nv_normcdf(__a); } -__DEVICE__ float normcdff(float __a) { return __nv_normcdff(__a); } -__DEVICE__ double normcdfinv(double __a) { return __nv_normcdfinv(__a); } -__DEVICE__ float normcdfinvf(float __a) { return __nv_normcdfinvf(__a); } -__DEVICE__ float normf(int __dim, const float *__t) { - return __nv_normf(__dim, __t); -} -__DEVICE__ double pow(double __a, double __b) { return __nv_pow(__a, __b); } -__DEVICE__ float powf(float __a, float __b) { return __nv_powf(__a, __b); } -__DEVICE__ double powi(double __a, int __b) { return __nv_powi(__a, __b); } -__DEVICE__ float powif(float __a, int __b) { return __nv_powif(__a, __b); } -__DEVICE__ double rcbrt(double __a) { return __nv_rcbrt(__a); } -__DEVICE__ float rcbrtf(float __a) { return __nv_rcbrtf(__a); } -__DEVICE__ double remainder(double __a, double __b) { - return __nv_remainder(__a, __b); -} -__DEVICE__ float remainderf(float __a, float __b) { - return __nv_remainderf(__a, __b); -} -__DEVICE__ double remquo(double __a, double __b, int *__c) { - return __nv_remquo(__a, __b, __c); -} -__DEVICE__ float remquof(float __a, float __b, int *__c) { - return __nv_remquof(__a, __b, __c); -} -__DEVICE__ double rhypot(double __a, double __b) { - return __nv_rhypot(__a, __b); -} -__DEVICE__ float rhypotf(float __a, float __b) { - return __nv_rhypotf(__a, __b); -} -__DEVICE__ double rint(double __a) { return __nv_rint(__a); } -__DEVICE__ float rintf(float __a) { return __nv_rintf(__a); } -__DEVICE__ double rnorm(int __a, const double *__b) { - return __nv_rnorm(__a, __b); -} -__DEVICE__ double rnorm3d(double __a, double __b, double __c) { - return __nv_rnorm3d(__a, __b, __c); -} -__DEVICE__ float rnorm3df(float __a, float __b, float __c) { - return __nv_rnorm3df(__a, __b, __c); -} -__DEVICE__ double rnorm4d(double __a, double __b, double __c, double __d) { - return __nv_rnorm4d(__a, __b, __c, __d); -} -__DEVICE__ float rnorm4df(float __a, float __b, float __c, float __d) { - return __nv_rnorm4df(__a, __b, __c, __d); -} -__DEVICE__ float rnormf(int __dim, const float *__t) { - return __nv_rnormf(__dim, __t); -} -__DEVICE__ double round(double __a) { return __nv_round(__a); } -__DEVICE__ float roundf(float __a) { return __nv_roundf(__a); } -__DEVICE__ double rsqrt(double __a) { return __nv_rsqrt(__a); } -__DEVICE__ float rsqrtf(float __a) { return __nv_rsqrtf(__a); } -__DEVICE__ double scalbn(double __a, int __b) { return __nv_scalbn(__a, __b); } -__DEVICE__ float scalbnf(float __a, int __b) { return __nv_scalbnf(__a, __b); } -// TODO: remove once variant is supported -#ifndef _OPENMP -__DEVICE__ double scalbln(double __a, long __b) { - if (__b > INT_MAX) - return __a > 0 ? HUGE_VAL : -HUGE_VAL; - if (__b < INT_MIN) - return __a > 0 ? 0.0 : -0.0; - return scalbn(__a, (int)__b); -} -__DEVICE__ float scalblnf(float __a, long __b) { - if (__b > INT_MAX) - return __a > 0 ? HUGE_VALF : -HUGE_VALF; - if (__b < INT_MIN) - return __a > 0 ? 0.f : -0.f; - return scalbnf(__a, (int)__b); -} -#endif -__DEVICE__ double sin(double __a) { return __nv_sin(__a); } -__DEVICE__ void sincos(double __a, double *__s, double *__c) { - return __nv_sincos(__a, __s, __c); -} -__DEVICE__ void sincosf(float __a, float *__s, float *__c) { - return __FAST_OR_SLOW(__nv_fast_sincosf, __nv_sincosf)(__a, __s, __c); -} -__DEVICE__ void sincospi(double __a, double *__s, double *__c) { - return __nv_sincospi(__a, __s, __c); -} -__DEVICE__ void sincospif(float __a, float *__s, float *__c) { - return __nv_sincospif(__a, __s, __c); -} -__DEVICE__ float sinf(float __a) { - return __FAST_OR_SLOW(__nv_fast_sinf, __nv_sinf)(__a); -} -__DEVICE__ double sinh(double __a) { return __nv_sinh(__a); } -__DEVICE__ float sinhf(float __a) { return __nv_sinhf(__a); } -__DEVICE__ double sinpi(double __a) { return __nv_sinpi(__a); } -__DEVICE__ float sinpif(float __a) { return __nv_sinpif(__a); } -__DEVICE__ double sqrt(double __a) { return __nv_sqrt(__a); } -__DEVICE__ float sqrtf(float __a) { return __nv_sqrtf(__a); } -__DEVICE__ double tan(double __a) { return __nv_tan(__a); } -__DEVICE__ float tanf(float __a) { return __nv_tanf(__a); } -__DEVICE__ double tanh(double __a) { return __nv_tanh(__a); } -__DEVICE__ float tanhf(float __a) { return __nv_tanhf(__a); } -__DEVICE__ double tgamma(double __a) { return __nv_tgamma(__a); } -__DEVICE__ float tgammaf(float __a) { return __nv_tgammaf(__a); } -__DEVICE__ double trunc(double __a) { return __nv_trunc(__a); } -__DEVICE__ float truncf(float __a) { return __nv_truncf(__a); } -__DEVICE__ unsigned long long ullmax(unsigned long long __a, - unsigned long long __b) { - return __nv_ullmax(__a, __b); -} -__DEVICE__ unsigned long long ullmin(unsigned long long __a, - unsigned long long __b) { - return __nv_ullmin(__a, __b); -} -__DEVICE__ unsigned int umax(unsigned int __a, unsigned int __b) { - return __nv_umax(__a, __b); -} -__DEVICE__ unsigned int umin(unsigned int __a, unsigned int __b) { - return __nv_umin(__a, __b); -} -__DEVICE__ double y0(double __a) { return __nv_y0(__a); } -__DEVICE__ float y0f(float __a) { return __nv_y0f(__a); } -__DEVICE__ double y1(double __a) { return __nv_y1(__a); } -__DEVICE__ float y1f(float __a) { return __nv_y1f(__a); } -__DEVICE__ double yn(int __a, double __b) { return __nv_yn(__a, __b); } -__DEVICE__ float ynf(int __a, float __b) { return __nv_ynf(__a, __b); } -#undef __NOEXCEPT #pragma pop_macro("__DEVICE__") -#pragma pop_macro("__FAST_OR_SLOW") #endif // __CLANG_CUDA_DEVICE_FUNCTIONS_H__ diff --git a/clang/lib/Headers/__clang_cuda_math.h b/clang/lib/Headers/__clang_cuda_math.h new file mode 100644 index 000000000000..73c2ea93fc66 --- /dev/null +++ b/clang/lib/Headers/__clang_cuda_math.h @@ -0,0 +1,347 @@ +/*===---- __clang_cuda_math.h - Device-side CUDA math support --------------=== + * + * 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 __CLANG_CUDA_MATH_H__ +#define __CLANG_CUDA_MATH_H__ +#ifndef __CUDA__ +#error "This file is for CUDA compilation only." +#endif + +#ifndef _OPENMP +#if CUDA_VERSION < 9000 +#error This file is intended to be used with CUDA-9+ only. +#endif +#endif + +// __DEVICE__ is a helper macro with common set of attributes for the wrappers +// we implement in this file. We need static in order to avoid emitting unused +// functions and __forceinline__ helps inlining these wrappers at -O1. +#pragma push_macro("__DEVICE__") +#ifdef _OPENMP +#define __DEVICE__ static constexpr __attribute__((always_inline, nothrow)) +#else +#define __DEVICE__ static __device__ __forceinline__ +#endif + +// Specialized version of __DEVICE__ for functions with void return type. Needed +// because the OpenMP overlay requires constexpr functions here but prior to +// c++14 void return functions could not be constexpr. +#pragma push_macro("__DEVICE_VOID__") +#ifdef _OPENMP +#if defined(__cplusplus) && __cplusplus >= 201402L +#define __DEVICE_VOID__ static constexpr __attribute__((always_inline, nothrow)) +#else +#define __DEVICE_VOID__ static __attribute__((always_inline, nothrow)) +#endif +#else +#define __DEVICE_VOID__ __DEVICE__ +#endif + +// libdevice provides fast low precision and slow full-recision implementations +// for some functions. Which one gets selected depends on +// __CLANG_CUDA_APPROX_TRANSCENDENTALS__ which gets defined by clang if +// -ffast-math or -fcuda-approx-transcendentals are in effect. +#pragma push_macro("__FAST_OR_SLOW") +#if defined(__CLANG_CUDA_APPROX_TRANSCENDENTALS__) +#define __FAST_OR_SLOW(fast, slow) fast +#else +#define __FAST_OR_SLOW(fast, slow) slow +#endif + +__DEVICE__ int abs(int __a) { return __nv_abs(__a); } +__DEVICE__ double fabs(double __a) { return __nv_fabs(__a); } +__DEVICE__ double acos(double __a) { return __nv_acos(__a); } +__DEVICE__ float acosf(float __a) { return __nv_acosf(__a); } +__DEVICE__ double acosh(double __a) { return __nv_acosh(__a); } +__DEVICE__ float acoshf(float __a) { return __nv_acoshf(__a); } +__DEVICE__ double asin(double __a) { return __nv_asin(__a); } +__DEVICE__ float asinf(float __a) { return __nv_asinf(__a); } +__DEVICE__ double asinh(double __a) { return __nv_asinh(__a); } +__DEVICE__ float asinhf(float __a) { return __nv_asinhf(__a); } +__DEVICE__ double atan(double __a) { return __nv_atan(__a); } +__DEVICE__ double atan2(double __a, double __b) { return __nv_atan2(__a, __b); } +__DEVICE__ float atan2f(float __a, float __b) { return __nv_atan2f(__a, __b); } +__DEVICE__ float atanf(float __a) { return __nv_atanf(__a); } +__DEVICE__ double atanh(double __a) { return __nv_atanh(__a); } +__DEVICE__ float atanhf(float __a) { return __nv_atanhf(__a); } +__DEVICE__ double cbrt(double __a) { return __nv_cbrt(__a); } +__DEVICE__ float cbrtf(float __a) { return __nv_cbrtf(__a); } +__DEVICE__ double ceil(double __a) { return __nv_ceil(__a); } +__DEVICE__ float ceilf(float __a) { return __nv_ceilf(__a); } +__DEVICE__ double copysign(double __a, double __b) { + return __nv_copysign(__a, __b); +} +__DEVICE__ float copysignf(float __a, float __b) { + return __nv_copysignf(__a, __b); +} +__DEVICE__ double cos(double __a) { return __nv_cos(__a); } +__DEVICE__ float cosf(float __a) { + return __FAST_OR_SLOW(__nv_fast_cosf, __nv_cosf)(__a); +} +__DEVICE__ double cosh(double __a) { return __nv_cosh(__a); } +__DEVICE__ float coshf(float __a) { return __nv_coshf(__a); } +__DEVICE__ double cospi(double __a) { return __nv_cospi(__a); } +__DEVICE__ float cospif(float __a) { return __nv_cospif(__a); } +__DEVICE__ double cyl_bessel_i0(double __a) { return __nv_cyl_bessel_i0(__a); } +__DEVICE__ float cyl_bessel_i0f(float __a) { return __nv_cyl_bessel_i0f(__a); } +__DEVICE__ double cyl_bessel_i1(double __a) { return __nv_cyl_bessel_i1(__a); } +__DEVICE__ float cyl_bessel_i1f(float __a) { return __nv_cyl_bessel_i1f(__a); } +__DEVICE__ double erf(double __a) { return __nv_erf(__a); } +__DEVICE__ double erfc(double __a) { return __nv_erfc(__a); } +__DEVICE__ float erfcf(float __a) { return __nv_erfcf(__a); } +__DEVICE__ double erfcinv(double __a) { return __nv_erfcinv(__a); } +__DEVICE__ float erfcinvf(float __a) { return __nv_erfcinvf(__a); } +__DEVICE__ double erfcx(double __a) { return __nv_erfcx(__a); } +__DEVICE__ float erfcxf(float __a) { return __nv_erfcxf(__a); } +__DEVICE__ float erff(float __a) { return __nv_erff(__a); } +__DEVICE__ double erfinv(double __a) { return __nv_erfinv(__a); } +__DEVICE__ float erfinvf(float __a) { return __nv_erfinvf(__a); } +__DEVICE__ double exp(double __a) { return __nv_exp(__a); } +__DEVICE__ double exp10(double __a) { return __nv_exp10(__a); } +__DEVICE__ float exp10f(float __a) { return __nv_exp10f(__a); } +__DEVICE__ double exp2(double __a) { return __nv_exp2(__a); } +__DEVICE__ float exp2f(float __a) { return __nv_exp2f(__a); } +__DEVICE__ float expf(float __a) { return __nv_expf(__a); } +__DEVICE__ double expm1(double __a) { return __nv_expm1(__a); } +__DEVICE__ float expm1f(float __a) { return __nv_expm1f(__a); } +__DEVICE__ float fabsf(float __a) { return __nv_fabsf(__a); } +__DEVICE__ double fdim(double __a, double __b) { return __nv_fdim(__a, __b); } +__DEVICE__ float fdimf(float __a, float __b) { return __nv_fdimf(__a, __b); } +__DEVICE__ double fdivide(double __a, double __b) { return __a / __b; } +__DEVICE__ float fdividef(float __a, float __b) { +#if __FAST_MATH__ && !__CUDA_PREC_DIV + return __nv_fast_fdividef(__a, __b); +#else + return __a / __b; +#endif +} +__DEVICE__ double floor(double __f) { return __nv_floor(__f); } +__DEVICE__ float floorf(float __f) { return __nv_floorf(__f); } +__DEVICE__ double fma(double __a, double __b, double __c) { + return __nv_fma(__a, __b, __c); +} +__DEVICE__ float fmaf(float __a, float __b, float __c) { + return __nv_fmaf(__a, __b, __c); +} +__DEVICE__ double fmax(double __a, double __b) { return __nv_fmax(__a, __b); } +__DEVICE__ float fmaxf(float __a, float __b) { return __nv_fmaxf(__a, __b); } +__DEVICE__ double fmin(double __a, double __b) { return __nv_fmin(__a, __b); } +__DEVICE__ float fminf(float __a, float __b) { return __nv_fminf(__a, __b); } +__DEVICE__ double fmod(double __a, double __b) { return __nv_fmod(__a, __b); } +__DEVICE__ float fmodf(float __a, float __b) { return __nv_fmodf(__a, __b); } +__DEVICE__ double frexp(double __a, int *__b) { return __nv_frexp(__a, __b); } +__DEVICE__ float frexpf(float __a, int *__b) { return __nv_frexpf(__a, __b); } +__DEVICE__ double hypot(double __a, double __b) { return __nv_hypot(__a, __b); } +__DEVICE__ float hypotf(float __a, float __b) { return __nv_hypotf(__a, __b); } +__DEVICE__ int ilogb(double __a) { return __nv_ilogb(__a); } +__DEVICE__ int ilogbf(float __a) { return __nv_ilogbf(__a); } +__DEVICE__ double j0(double __a) { return __nv_j0(__a); } +__DEVICE__ float j0f(float __a) { return __nv_j0f(__a); } +__DEVICE__ double j1(double __a) { return __nv_j1(__a); } +__DEVICE__ float j1f(float __a) { return __nv_j1f(__a); } +__DEVICE__ double jn(int __n, double __a) { return __nv_jn(__n, __a); } +__DEVICE__ float jnf(int __n, float __a) { return __nv_jnf(__n, __a); } +#if defined(__LP64__) || defined(_WIN64) +__DEVICE__ long labs(long __a) { return __nv_llabs(__a); }; +#else +__DEVICE__ long labs(long __a) { return __nv_abs(__a); }; +#endif +__DEVICE__ double ldexp(double __a, int __b) { return __nv_ldexp(__a, __b); } +__DEVICE__ float ldexpf(float __a, int __b) { return __nv_ldexpf(__a, __b); } +__DEVICE__ double lgamma(double __a) { return __nv_lgamma(__a); } +__DEVICE__ float lgammaf(float __a) { return __nv_lgammaf(__a); } +__DEVICE__ long long llabs(long long __a) { return __nv_llabs(__a); } +__DEVICE__ long long llmax(long long __a, long long __b) { + return __nv_llmax(__a, __b); +} +__DEVICE__ long long llmin(long long __a, long long __b) { + return __nv_llmin(__a, __b); +} +__DEVICE__ long long llrint(double __a) { return __nv_llrint(__a); } +__DEVICE__ long long llrintf(float __a) { return __nv_llrintf(__a); } +__DEVICE__ long long llround(double __a) { return __nv_llround(__a); } +__DEVICE__ long long llroundf(float __a) { return __nv_llroundf(__a); } +__DEVICE__ double log(double __a) { return __nv_log(__a); } +__DEVICE__ double log10(double __a) { return __nv_log10(__a); } +__DEVICE__ float log10f(float __a) { return __nv_log10f(__a); } +__DEVICE__ double log1p(double __a) { return __nv_log1p(__a); } +__DEVICE__ float log1pf(float __a) { return __nv_log1pf(__a); } +__DEVICE__ double log2(double __a) { return __nv_log2(__a); } +__DEVICE__ float log2f(float __a) { + return __FAST_OR_SLOW(__nv_fast_log2f, __nv_log2f)(__a); +} +__DEVICE__ double logb(double __a) { return __nv_logb(__a); } +__DEVICE__ float logbf(float __a) { return __nv_logbf(__a); } +__DEVICE__ float logf(float __a) { + return __FAST_OR_SLOW(__nv_fast_logf, __nv_logf)(__a); +} +#if defined(__LP64__) || defined(_WIN64) +__DEVICE__ long lrint(double __a) { return llrint(__a); } +__DEVICE__ long lrintf(float __a) { return __float2ll_rn(__a); } +__DEVICE__ long lround(double __a) { return llround(__a); } +__DEVICE__ long lroundf(float __a) { return llroundf(__a); } +#else +__DEVICE__ long lrint(double __a) { return (long)rint(__a); } +__DEVICE__ long lrintf(float __a) { return __float2int_rn(__a); } +__DEVICE__ long lround(double __a) { return round(__a); } +__DEVICE__ long lroundf(float __a) { return roundf(__a); } +#endif +__DEVICE__ int max(int __a, int __b) { return __nv_max(__a, __b); } +__DEVICE__ int min(int __a, int __b) { return __nv_min(__a, __b); } +__DEVICE__ double modf(double __a, double *__b) { return __nv_modf(__a, __b); } +__DEVICE__ float modff(float __a, float *__b) { return __nv_modff(__a, __b); } +__DEVICE__ double nearbyint(double __a) { return __nv_nearbyint(__a); } +__DEVICE__ float nearbyintf(float __a) { return __nv_nearbyintf(__a); } +__DEVICE__ double nextafter(double __a, double __b) { + return __nv_nextafter(__a, __b); +} +__DEVICE__ float nextafterf(float __a, float __b) { + return __nv_nextafterf(__a, __b); +} +__DEVICE__ double norm(int __dim, const double *__t) { + return __nv_norm(__dim, __t); +} +__DEVICE__ double norm3d(double __a, double __b, double __c) { + return __nv_norm3d(__a, __b, __c); +} +__DEVICE__ float norm3df(float __a, float __b, float __c) { + return __nv_norm3df(__a, __b, __c); +} +__DEVICE__ double norm4d(double __a, double __b, double __c, double __d) { + return __nv_norm4d(__a, __b, __c, __d); +} +__DEVICE__ float norm4df(float __a, float __b, float __c, float __d) { + return __nv_norm4df(__a, __b, __c, __d); +} +__DEVICE__ double normcdf(double __a) { return __nv_normcdf(__a); } +__DEVICE__ float normcdff(float __a) { return __nv_normcdff(__a); } +__DEVICE__ double normcdfinv(double __a) { return __nv_normcdfinv(__a); } +__DEVICE__ float normcdfinvf(float __a) { return __nv_normcdfinvf(__a); } +__DEVICE__ float normf(int __dim, const float *__t) { + return __nv_normf(__dim, __t); +} +__DEVICE__ double pow(double __a, double __b) { return __nv_pow(__a, __b); } +__DEVICE__ float powf(float __a, float __b) { return __nv_powf(__a, __b); } +__DEVICE__ double powi(double __a, int __b) { return __nv_powi(__a, __b); } +__DEVICE__ float powif(float __a, int __b) { return __nv_powif(__a, __b); } +__DEVICE__ double rcbrt(double __a) { return __nv_rcbrt(__a); } +__DEVICE__ float rcbrtf(float __a) { return __nv_rcbrtf(__a); } +__DEVICE__ double remainder(double __a, double __b) { + return __nv_remainder(__a, __b); +} +__DEVICE__ float remainderf(float __a, float __b) { + return __nv_remainderf(__a, __b); +} +__DEVICE__ double remquo(double __a, double __b, int *__c) { + return __nv_remquo(__a, __b, __c); +} +__DEVICE__ float remquof(float __a, float __b, int *__c) { + return __nv_remquof(__a, __b, __c); +} +__DEVICE__ double rhypot(double __a, double __b) { + return __nv_rhypot(__a, __b); +} +__DEVICE__ float rhypotf(float __a, float __b) { + return __nv_rhypotf(__a, __b); +} +__DEVICE__ double rint(double __a) { return __nv_rint(__a); } +__DEVICE__ float rintf(float __a) { return __nv_rintf(__a); } +__DEVICE__ double rnorm(int __a, const double *__b) { + return __nv_rnorm(__a, __b); +} +__DEVICE__ double rnorm3d(double __a, double __b, double __c) { + return __nv_rnorm3d(__a, __b, __c); +} +__DEVICE__ float rnorm3df(float __a, float __b, float __c) { + return __nv_rnorm3df(__a, __b, __c); +} +__DEVICE__ double rnorm4d(double __a, double __b, double __c, double __d) { + return __nv_rnorm4d(__a, __b, __c, __d); +} +__DEVICE__ float rnorm4df(float __a, float __b, float __c, float __d) { + return __nv_rnorm4df(__a, __b, __c, __d); +} +__DEVICE__ float rnormf(int __dim, const float *__t) { + return __nv_rnormf(__dim, __t); +} +__DEVICE__ double round(double __a) { return __nv_round(__a); } +__DEVICE__ float roundf(float __a) { return __nv_roundf(__a); } +__DEVICE__ double rsqrt(double __a) { return __nv_rsqrt(__a); } +__DEVICE__ float rsqrtf(float __a) { return __nv_rsqrtf(__a); } +__DEVICE__ double scalbn(double __a, int __b) { return __nv_scalbn(__a, __b); } +__DEVICE__ float scalbnf(float __a, int __b) { return __nv_scalbnf(__a, __b); } +__DEVICE__ double scalbln(double __a, long __b) { + if (__b > INT_MAX) + return __a > 0 ? HUGE_VAL : -HUGE_VAL; + if (__b < INT_MIN) + return __a > 0 ? 0.0 : -0.0; + return scalbn(__a, (int)__b); +} +__DEVICE__ float scalblnf(float __a, long __b) { + if (__b > INT_MAX) + return __a > 0 ? HUGE_VALF : -HUGE_VALF; + if (__b < INT_MIN) + return __a > 0 ? 0.f : -0.f; + return scalbnf(__a, (int)__b); +} +__DEVICE__ double sin(double __a) { return __nv_sin(__a); } +__DEVICE_VOID__ void sincos(double __a, double *__s, double *__c) { + return __nv_sincos(__a, __s, __c); +} +__DEVICE_VOID__ void sincosf(float __a, float *__s, float *__c) { + return __FAST_OR_SLOW(__nv_fast_sincosf, __nv_sincosf)(__a, __s, __c); +} +__DEVICE_VOID__ void sincospi(double __a, double *__s, double *__c) { + return __nv_sincospi(__a, __s, __c); +} +__DEVICE_VOID__ void sincospif(float __a, float *__s, float *__c) { + return __nv_sincospif(__a, __s, __c); +} +__DEVICE__ float sinf(float __a) { + return __FAST_OR_SLOW(__nv_fast_sinf, __nv_sinf)(__a); +} +__DEVICE__ double sinh(double __a) { return __nv_sinh(__a); } +__DEVICE__ float sinhf(float __a) { return __nv_sinhf(__a); } +__DEVICE__ double sinpi(double __a) { return __nv_sinpi(__a); } +__DEVICE__ float sinpif(float __a) { return __nv_sinpif(__a); } +__DEVICE__ double sqrt(double __a) { return __nv_sqrt(__a); } +__DEVICE__ float sqrtf(float __a) { return __nv_sqrtf(__a); } +__DEVICE__ double tan(double __a) { return __nv_tan(__a); } +__DEVICE__ float tanf(float __a) { return __nv_tanf(__a); } +__DEVICE__ double tanh(double __a) { return __nv_tanh(__a); } +__DEVICE__ float tanhf(float __a) { return __nv_tanhf(__a); } +__DEVICE__ double tgamma(double __a) { return __nv_tgamma(__a); } +__DEVICE__ float tgammaf(float __a) { return __nv_tgammaf(__a); } +__DEVICE__ double trunc(double __a) { return __nv_trunc(__a); } +__DEVICE__ float truncf(float __a) { return __nv_truncf(__a); } +__DEVICE__ unsigned long long ullmax(unsigned long long __a, + unsigned long long __b) { + return __nv_ullmax(__a, __b); +} +__DEVICE__ unsigned long long ullmin(unsigned long long __a, + unsigned long long __b) { + return __nv_ullmin(__a, __b); +} +__DEVICE__ unsigned int umax(unsigned int __a, unsigned int __b) { + return __nv_umax(__a, __b); +} +__DEVICE__ unsigned int umin(unsigned int __a, unsigned int __b) { + return __nv_umin(__a, __b); +} +__DEVICE__ double y0(double __a) { return __nv_y0(__a); } +__DEVICE__ float y0f(float __a) { return __nv_y0f(__a); } +__DEVICE__ double y1(double __a) { return __nv_y1(__a); } +__DEVICE__ float y1f(float __a) { return __nv_y1f(__a); } +__DEVICE__ double yn(int __a, double __b) { return __nv_yn(__a, __b); } +__DEVICE__ float ynf(int __a, float __b) { return __nv_ynf(__a, __b); } + +#pragma pop_macro("__DEVICE__") +#pragma pop_macro("__DEVICE_VOID__") +#pragma pop_macro("__FAST_OR_SLOW") + +#endif // __CLANG_CUDA_DEVICE_FUNCTIONS_H__ diff --git a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h index 349a4c759bca..63404c9bdeb5 100644 --- a/clang/lib/Headers/__clang_cuda_runtime_wrapper.h +++ b/clang/lib/Headers/__clang_cuda_runtime_wrapper.h @@ -143,11 +143,12 @@ inline __host__ double __signbitd(double x) { // to provide our own. #include <__clang_cuda_libdevice_declares.h> -// Wrappers for many device-side standard library functions became compiler -// builtins in CUDA-9 and have been removed from the CUDA headers. Clang now -// provides its own implementation of the wrappers. +// Wrappers for many device-side standard library functions, incl. math +// functions, became compiler builtins in CUDA-9 and have been removed from the +// CUDA headers. Clang now provides its own implementation of the wrappers. #if CUDA_VERSION >= 9000 #include <__clang_cuda_device_functions.h> +#include <__clang_cuda_math.h> #endif // __THROW is redefined to be empty by device_functions_decls.h in CUDA. Clang's From cfe-commits at lists.llvm.org Wed Apr 1 22:18:47 2020 From: cfe-commits at lists.llvm.org (Pratyai Mazumder via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 05:18:47 +0000 (UTC) Subject: [PATCH] D77244: sancov/inline-bool-flag feature + tests + docs. In-Reply-To: References: Message-ID: <0eeb62fc493948a31dc13059c951a327@localhost.localdomain> pratyai updated this revision to Diff 254418. pratyai added a comment. - Switched to Int1Ty. - Switched Atomic::NonAtomic (same as just dropping the two lines?) - C++ files were clang-formatted, but arc lint couldn't find clang-format-diff before. Now it seems to have formatted the lit tests. - Will split the patch later (i.e. remove all non-instrumentation stuff from this patch, then move flags & compiler-rt tests into two other patches). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77244/new/ https://reviews.llvm.org/D77244 Files: clang/docs/SanitizerCoverage.rst clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/CC1Options.td clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/SanitizerArgs.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/Driver/autocomplete.c clang/test/Driver/fsanitize-coverage.c compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp llvm/include/llvm/Transforms/Instrumentation.h llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp llvm/test/Instrumentation/SanitizerCoverage/coff-pc-table-inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-inline-bool-flag.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D77244.254418.patch Type: text/x-patch Size: 34515 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 22:18:48 2020 From: cfe-commits at lists.llvm.org (Saleem Abdulrasool via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 05:18:48 +0000 (UTC) Subject: [PATCH] D75453: [Driver][ARM] fix undefined behaviour when checking architecture version In-Reply-To: References: Message-ID: <852f67971fd83f4bebfe4cde10ba240e@localhost.localdomain> compnerd requested changes to this revision. compnerd added a comment. This revision now requires changes to proceed. Herald added a subscriber: danielkiss. Seems reasonable, though this isn't UB, its just use of an uninitialized variable. Please add a test case. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75453/new/ https://reviews.llvm.org/D75453 From cfe-commits at lists.llvm.org Wed Apr 1 22:18:48 2020 From: cfe-commits at lists.llvm.org (Puyan Lotfi via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 05:18:48 +0000 (UTC) Subject: [PATCH] D77233: [NFC] Refactoring PropertyAttributeKind for ObjCPropertyDecl and ObjCDeclSpec. In-Reply-To: References: Message-ID: plotfi marked an inline comment as done. plotfi added inline comments. ================ Comment at: clang/include/clang/AST/DeclObjCCommon.h:21 +/// Keep this list in sync with LLVM's Dwarf.h ApplePropertyAttributes. +enum ObjCPropertyAttributeKind { + OBJC_PR_noattr = 0x00, ---------------- compnerd wrote: > It seems that you are touching all the sites that use this, so perhaps this is the time to change this to `enum class` and drop the `OBJC_PR_` prefixes and explicitly inherit from `uint16_t`. This should be named `ObjCPropertyAttribute` I think. Ah yeah, that sounds pretty good. Will do. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77233/new/ https://reviews.llvm.org/D77233 From cfe-commits at lists.llvm.org Wed Apr 1 22:18:49 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 05:18:49 +0000 (UTC) Subject: [PATCH] D77028: [NFC] Refactor DeferredDiagsEmitter and skip redundant visit In-Reply-To: References: Message-ID: <0cdebc9c7672baddd85e6bc1e212640e@localhost.localdomain> rjmccall added inline comments. ================ Comment at: clang/lib/Sema/Sema.cpp:1508 void checkFunc(SourceLocation Loc, FunctionDecl *FD) { + auto DiagsCountIt = DiagsCount.find(FD); FunctionDecl *Caller = UseStack.empty() ? nullptr : UseStack.back(); ---------------- It makes me a little uncomfortable to be holding an iterator this long while calling a fair amount of other stuff in the meantime. Your use of DiagsCount is subtle enough that it really needs to be explained in some comments. You're doing stuff conditionally based on both whether the entry exists but also whether it's non-zero. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77028/new/ https://reviews.llvm.org/D77028 From cfe-commits at lists.llvm.org Wed Apr 1 22:18:49 2020 From: cfe-commits at lists.llvm.org (Csaba Dabis via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 05:18:49 +0000 (UTC) Subject: [PATCH] D70411: [analyzer] CERT: STR31-C In-Reply-To: References: Message-ID: Charusso added a comment. Thanks for the review, hopefully if I ping @NoQ in every round, it will be green-marked soon. ================ Comment at: clang/lib/StaticAnalyzer/Checkers/cert/StrChecker.cpp:55 + // they can cause a not null-terminated string. In this case we store the + // string is being not null-terminated in the 'NullTerminationMap'. + // ---------------- balazske wrote: > The functions `gets`, `strcpy` return a null-terminated string according to standard, probably `sprintf` too, and the `fscanf` `%s` output is null-terminated too even if no length is specified (maybe it writes outside of the specified buffer but null terminated). >From where do you observe such information? I have not seen anything `strcpy()`-specific in the standard. My observation clearly says that, if there is not enough space for the data you *could* even write to overlapping memory, or as people says, you could meet nasal demons. It is called *undefined* behavior. ================ Comment at: clang/test/Analysis/cert/str31-c.cpp:117 + if (editor != NULL) { + size_t len = strlen(editor) + 1; + buff2 = (char *)malloc(len); ---------------- balazske wrote: > Do we get a warning if the `+1` above is missing? Test added. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70411/new/ https://reviews.llvm.org/D70411 From cfe-commits at lists.llvm.org Wed Apr 1 22:18:49 2020 From: cfe-commits at lists.llvm.org (Csaba Dabis via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 05:18:49 +0000 (UTC) Subject: [PATCH] D70411: [analyzer] CERT: STR31-C In-Reply-To: References: Message-ID: <34f638d1cb0360ad7d0b58736a92190e@localhost.localdomain> Charusso updated this revision to Diff 254420. Charusso marked 4 inline comments as done. Charusso added a comment. - Simplify tests. - Remove dead code, they are far away to being used. - Add an extra test case. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70411/new/ https://reviews.llvm.org/D70411 Files: clang/docs/analyzer/checkers.rst clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/lib/StaticAnalyzer/Checkers/AllocationState.h clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp clang/lib/StaticAnalyzer/Checkers/cert/StrChecker.cpp clang/test/Analysis/Inputs/system-header-simulator.h clang/test/Analysis/cert/str31-c-false-positive-suppression.cpp clang/test/Analysis/cert/str31-c-notes.cpp clang/test/Analysis/cert/str31-c.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D70411.254420.patch Type: text/x-patch Size: 24725 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 22:18:50 2020 From: cfe-commits at lists.llvm.org (Csaba Dabis via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 05:18:50 +0000 (UTC) Subject: [PATCH] D70411: [analyzer] CERT: STR31-C In-Reply-To: References: Message-ID: <643512f9ce7a1af6cc43bf573fcaf83c@localhost.localdomain> Charusso updated this revision to Diff 254423. Charusso added a comment. - Remove the last dead comment. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70411/new/ https://reviews.llvm.org/D70411 Files: clang/docs/analyzer/checkers.rst clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/lib/StaticAnalyzer/Checkers/AllocationState.h clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp clang/lib/StaticAnalyzer/Checkers/cert/StrChecker.cpp clang/test/Analysis/Inputs/system-header-simulator.h clang/test/Analysis/cert/str31-c-false-positive-suppression.cpp clang/test/Analysis/cert/str31-c-notes.cpp clang/test/Analysis/cert/str31-c.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D70411.254423.patch Type: text/x-patch Size: 24598 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 22:18:50 2020 From: cfe-commits at lists.llvm.org (Michael Liao via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 05:18:50 +0000 (UTC) Subject: [PATCH] D77238: [CUDA][NFC] Split math.h functions out of __clang_cuda_device_functions.h In-Reply-To: References: Message-ID: hliao added a comment. this patch breaks the test clang/test/Headers/nvptx_device_cmath_functions.cpp, could you please fix it ASAP? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77238/new/ https://reviews.llvm.org/D77238 From cfe-commits at lists.llvm.org Wed Apr 1 22:18:50 2020 From: cfe-commits at lists.llvm.org (Louis Dionne via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 05:18:50 +0000 (UTC) Subject: [PATCH] D72959: Relative VTables ABI on Fuchsia In-Reply-To: References: Message-ID: ldionne requested changes to this revision. ldionne added inline comments. ================ Comment at: libcxxabi/src/private_typeinfo.cpp:617 // Get (dynamic_ptr, dynamic_type) from static_ptr +#ifndef __Fuchsia__ void **vtable = *static_cast(static_ptr); ---------------- Please introduce a macro that generically expresses that relative vtables are enabled, and explain what it is. You can then enable that macro only on `__Fuchsia__`. I'd like to avoid freely adding platform-specific `#ifdef`s in the code when it's easy to avoid. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72959/new/ https://reviews.llvm.org/D72959 From cfe-commits at lists.llvm.org Wed Apr 1 22:19:02 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 05:19:02 +0000 (UTC) Subject: [PATCH] D77238: [CUDA][NFC] Split math.h functions out of __clang_cuda_device_functions.h In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rGd1705c1196fe: [CUDA][NFC] Split math.h functions out of __clang_cuda_device_functions.h (authored by jdoerfert). Changed prior to commit: https://reviews.llvm.org/D77238?vs=254289&id=254426#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77238/new/ https://reviews.llvm.org/D77238 Files: clang/lib/Headers/CMakeLists.txt clang/lib/Headers/__clang_cuda_device_functions.h clang/lib/Headers/__clang_cuda_math.h clang/lib/Headers/__clang_cuda_runtime_wrapper.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D77238.254426.patch Type: text/x-patch Size: 35181 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 22:31:27 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via cfe-commits) Date: Wed, 01 Apr 2020 22:31:27 -0700 (PDT) Subject: [clang] 410cfc4 - [OpenMP][FIX] Add second include after header was split in d1705c1196 Message-ID: <5e8578af.1c69fb81.957f0.ddd7@mx.google.com> Author: Johannes Doerfert Date: 2020-04-02T00:20:23-05:00 New Revision: 410cfc478f3540d3f07bba920fa3bf99409f6bda URL: https://github.com/llvm/llvm-project/commit/410cfc478f3540d3f07bba920fa3bf99409f6bda DIFF: https://github.com/llvm/llvm-project/commit/410cfc478f3540d3f07bba920fa3bf99409f6bda.diff LOG: [OpenMP][FIX] Add second include after header was split in d1705c1196 The math wrapper handling is going to be replaced shortly and d1705c1196fedfe927716923ac121f1134924a36 was actually a precursor for that. Added: Modified: clang/lib/Headers/openmp_wrappers/__clang_openmp_math_declares.h Removed: ################################################################################ diff --git a/clang/lib/Headers/openmp_wrappers/__clang_openmp_math_declares.h b/clang/lib/Headers/openmp_wrappers/__clang_openmp_math_declares.h index a422c98bf97d..dd97faca6932 100644 --- a/clang/lib/Headers/openmp_wrappers/__clang_openmp_math_declares.h +++ b/clang/lib/Headers/openmp_wrappers/__clang_openmp_math_declares.h @@ -26,6 +26,7 @@ #include <__clang_cuda_libdevice_declares.h> /// Provide definitions for these functions. #include <__clang_cuda_device_functions.h> +#include <__clang_cuda_math.h> #undef __CUDA__ From cfe-commits at lists.llvm.org Wed Apr 1 23:23:22 2020 From: cfe-commits at lists.llvm.org (Fangrui Song via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 06:23:22 +0000 (UTC) Subject: [PATCH] D68049: Propeller: Clang options for basic block sections In-Reply-To: References: Message-ID: <8a36aa7e664868b102ad0a9781b320c7@localhost.localdomain> MaskRay added inline comments. ================ Comment at: clang/lib/Driver/ToolChains/Clang.cpp:4858 + if (Arg *A = Args.getLastArg(options::OPT_fbasicblock_sections_EQ)) { + CmdArgs.push_back( ---------------- If we want to pass the option verbatim, `A->render(Args, CmdArgs);` However, we actually want (a convention) to catch the error at the driver level. So the value checking in Frontend/CompilerInvocation.cpp should be moved here. (Note that you used `err_drv_invalid_value` in Frontend/CompilerInvocation.cpp . drv is short for driver) ================ Comment at: clang/test/CodeGen/basicblock-sections.c:35 +// +// BB_WORLD: .section .text.world,"ax", at progbits +// BB_WORLD: world ---------------- I haven't read through the previous threads whether we should use a .c -> .s test here. Assume we've decided to do that, `@progbits` should be followed by `{{$}}` to ensure there is no unique assembly linkage. ================ Comment at: clang/test/CodeGen/basicblock-sections.c:38 +// BB_WORLD: .section .text.world,"ax", at progbits,unique +// BB_WORLD: a.BB.world +// BB_WORLD: .section .text.another,"ax", at progbits ---------------- If `world` is followed by a colon, the colon should be added. The little detail will make it clear that this is a label. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68049/new/ https://reviews.llvm.org/D68049 From cfe-commits at lists.llvm.org Wed Apr 1 23:34:50 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via cfe-commits) Date: Wed, 01 Apr 2020 23:34:50 -0700 (PDT) Subject: [clang] b0b5f04 - [OpenMP][FIX] Undo changes accidentally already introduced in NFC commit Message-ID: <5e85878a.1c69fb81.fa882.f3ef@mx.google.com> Author: Johannes Doerfert Date: 2020-04-02T01:33:39-05:00 New Revision: b0b5f0416be60152ddc8d606b1720daba0005518 URL: https://github.com/llvm/llvm-project/commit/b0b5f0416be60152ddc8d606b1720daba0005518 DIFF: https://github.com/llvm/llvm-project/commit/b0b5f0416be60152ddc8d606b1720daba0005518.diff LOG: [OpenMP][FIX] Undo changes accidentally already introduced in NFC commit In d1705c1196fe (D77238) we accidentally included subsequent changes and did not only move the code into a new file (which was the intention). We undo the changes now and re-introduce them with the appropriate test changes later. Added: Modified: clang/lib/Headers/__clang_cuda_math.h Removed: ################################################################################ diff --git a/clang/lib/Headers/__clang_cuda_math.h b/clang/lib/Headers/__clang_cuda_math.h index 73c2ea93fc66..7956135bfad5 100644 --- a/clang/lib/Headers/__clang_cuda_math.h +++ b/clang/lib/Headers/__clang_cuda_math.h @@ -23,25 +23,11 @@ // functions and __forceinline__ helps inlining these wrappers at -O1. #pragma push_macro("__DEVICE__") #ifdef _OPENMP -#define __DEVICE__ static constexpr __attribute__((always_inline, nothrow)) +#define __DEVICE__ static __inline__ __attribute__((always_inline)) #else #define __DEVICE__ static __device__ __forceinline__ #endif -// Specialized version of __DEVICE__ for functions with void return type. Needed -// because the OpenMP overlay requires constexpr functions here but prior to -// c++14 void return functions could not be constexpr. -#pragma push_macro("__DEVICE_VOID__") -#ifdef _OPENMP -#if defined(__cplusplus) && __cplusplus >= 201402L -#define __DEVICE_VOID__ static constexpr __attribute__((always_inline, nothrow)) -#else -#define __DEVICE_VOID__ static __attribute__((always_inline, nothrow)) -#endif -#else -#define __DEVICE_VOID__ __DEVICE__ -#endif - // libdevice provides fast low precision and slow full-recision implementations // for some functions. Which one gets selected depends on // __CLANG_CUDA_APPROX_TRANSCENDENTALS__ which gets defined by clang if @@ -53,8 +39,17 @@ #define __FAST_OR_SLOW(fast, slow) slow #endif -__DEVICE__ int abs(int __a) { return __nv_abs(__a); } -__DEVICE__ double fabs(double __a) { return __nv_fabs(__a); } +// For C++ 17 we need to include noexcept attribute to be compatible +// with the header-defined version. This may be removed once +// variant is supported. +#if defined(_OPENMP) && defined(__cplusplus) && __cplusplus >= 201703L +#define __NOEXCEPT noexcept +#else +#define __NOEXCEPT +#endif + +__DEVICE__ int abs(int __a) __NOEXCEPT { return __nv_abs(__a); } +__DEVICE__ double fabs(double __a) __NOEXCEPT { return __nv_fabs(__a); } __DEVICE__ double acos(double __a) { return __nv_acos(__a); } __DEVICE__ float acosf(float __a) { return __nv_acosf(__a); } __DEVICE__ double acosh(double __a) { return __nv_acosh(__a); } @@ -109,7 +104,7 @@ __DEVICE__ float exp2f(float __a) { return __nv_exp2f(__a); } __DEVICE__ float expf(float __a) { return __nv_expf(__a); } __DEVICE__ double expm1(double __a) { return __nv_expm1(__a); } __DEVICE__ float expm1f(float __a) { return __nv_expm1f(__a); } -__DEVICE__ float fabsf(float __a) { return __nv_fabsf(__a); } +__DEVICE__ float fabsf(float __a) __NOEXCEPT { return __nv_fabsf(__a); } __DEVICE__ double fdim(double __a, double __b) { return __nv_fdim(__a, __b); } __DEVICE__ float fdimf(float __a, float __b) { return __nv_fdimf(__a, __b); } __DEVICE__ double fdivide(double __a, double __b) { return __a / __b; } @@ -147,15 +142,15 @@ __DEVICE__ float j1f(float __a) { return __nv_j1f(__a); } __DEVICE__ double jn(int __n, double __a) { return __nv_jn(__n, __a); } __DEVICE__ float jnf(int __n, float __a) { return __nv_jnf(__n, __a); } #if defined(__LP64__) || defined(_WIN64) -__DEVICE__ long labs(long __a) { return __nv_llabs(__a); }; +__DEVICE__ long labs(long __a) __NOEXCEPT { return __nv_llabs(__a); }; #else -__DEVICE__ long labs(long __a) { return __nv_abs(__a); }; +__DEVICE__ long labs(long __a) __NOEXCEPT { return __nv_abs(__a); }; #endif __DEVICE__ double ldexp(double __a, int __b) { return __nv_ldexp(__a, __b); } __DEVICE__ float ldexpf(float __a, int __b) { return __nv_ldexpf(__a, __b); } __DEVICE__ double lgamma(double __a) { return __nv_lgamma(__a); } __DEVICE__ float lgammaf(float __a) { return __nv_lgammaf(__a); } -__DEVICE__ long long llabs(long long __a) { return __nv_llabs(__a); } +__DEVICE__ long long llabs(long long __a) __NOEXCEPT { return __nv_llabs(__a); } __DEVICE__ long long llmax(long long __a, long long __b) { return __nv_llmax(__a, __b); } @@ -275,6 +270,8 @@ __DEVICE__ double rsqrt(double __a) { return __nv_rsqrt(__a); } __DEVICE__ float rsqrtf(float __a) { return __nv_rsqrtf(__a); } __DEVICE__ double scalbn(double __a, int __b) { return __nv_scalbn(__a, __b); } __DEVICE__ float scalbnf(float __a, int __b) { return __nv_scalbnf(__a, __b); } +// TODO: remove once variant is supported +#ifndef _OPENMP __DEVICE__ double scalbln(double __a, long __b) { if (__b > INT_MAX) return __a > 0 ? HUGE_VAL : -HUGE_VAL; @@ -289,17 +286,18 @@ __DEVICE__ float scalblnf(float __a, long __b) { return __a > 0 ? 0.f : -0.f; return scalbnf(__a, (int)__b); } +#endif __DEVICE__ double sin(double __a) { return __nv_sin(__a); } -__DEVICE_VOID__ void sincos(double __a, double *__s, double *__c) { +__DEVICE__ void sincos(double __a, double *__s, double *__c) { return __nv_sincos(__a, __s, __c); } -__DEVICE_VOID__ void sincosf(float __a, float *__s, float *__c) { +__DEVICE__ void sincosf(float __a, float *__s, float *__c) { return __FAST_OR_SLOW(__nv_fast_sincosf, __nv_sincosf)(__a, __s, __c); } -__DEVICE_VOID__ void sincospi(double __a, double *__s, double *__c) { +__DEVICE__ void sincospi(double __a, double *__s, double *__c) { return __nv_sincospi(__a, __s, __c); } -__DEVICE_VOID__ void sincospif(float __a, float *__s, float *__c) { +__DEVICE__ void sincospif(float __a, float *__s, float *__c) { return __nv_sincospif(__a, __s, __c); } __DEVICE__ float sinf(float __a) { @@ -341,7 +339,7 @@ __DEVICE__ double yn(int __a, double __b) { return __nv_yn(__a, __b); } __DEVICE__ float ynf(int __a, float __b) { return __nv_ynf(__a, __b); } #pragma pop_macro("__DEVICE__") -#pragma pop_macro("__DEVICE_VOID__") #pragma pop_macro("__FAST_OR_SLOW") +#undef __NOEXCEPT #endif // __CLANG_CUDA_DEVICE_FUNCTIONS_H__ From cfe-commits at lists.llvm.org Wed Apr 1 23:57:48 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 06:57:48 +0000 (UTC) Subject: [PATCH] D77238: [CUDA][NFC] Split math.h functions out of __clang_cuda_device_functions.h In-Reply-To: References: Message-ID: <888ed4e84cd08041a01baff7ffb1e5ea@localhost.localdomain> jdoerfert added a comment. In D77238#1956547 , @hliao wrote: > this patch breaks the test clang/test/Headers/nvptx_device_cmath_functions.cpp, could you please fix it ASAP? > Once NVPTX target is enabled, the following tests failed: > > Failing Tests (6): > > Clang :: Headers/nvptx_device_cmath_functions.c > Clang :: Headers/nvptx_device_cmath_functions.cpp > Clang :: Headers/nvptx_device_cmath_functions_cxx17.cpp > Clang :: Headers/nvptx_device_math_functions.c > Clang :: Headers/nvptx_device_math_functions.cpp > Clang :: Headers/nvptx_device_math_functions_cxx17.cpp Aware, should be fixed by b0b5f0416be60152ddc8d606b1720daba0005518 . Apologies for the noise. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77238/new/ https://reviews.llvm.org/D77238 From cfe-commits at lists.llvm.org Thu Apr 2 00:04:52 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via cfe-commits) Date: Thu, 02 Apr 2020 00:04:52 -0700 (PDT) Subject: [clang] c18d559 - [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` Message-ID: <5e858e94.1c69fb81.13316.f22f@mx.google.com> Author: Johannes Doerfert Date: 2020-04-02T01:39:07-05:00 New Revision: c18d55998b3352e6ec92ccb8a3240a16a57c61e6 URL: https://github.com/llvm/llvm-project/commit/c18d55998b3352e6ec92ccb8a3240a16a57c61e6 DIFF: https://github.com/llvm/llvm-project/commit/c18d55998b3352e6ec92ccb8a3240a16a57c61e6.diff LOG: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` This is a cleanup and normalization patch that also enables reuse with Flang later on. A follow up will clean up and move the directive -> clauses mapping. Differential Revision: https://reviews.llvm.org/D77112 Added: Modified: clang/include/clang/AST/ASTFwd.h clang/include/clang/AST/ASTTypeTraits.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/Basic/Attr.td clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Basic/OpenMPKinds.h clang/lib/AST/ASTTypeTraits.cpp clang/lib/AST/AttrImpl.cpp clang/lib/AST/OpenMPClause.cpp clang/lib/AST/StmtProfile.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/ASTMatchers/CMakeLists.txt clang/lib/ASTMatchers/Dynamic/Marshallers.h clang/lib/Analysis/CMakeLists.txt clang/lib/Basic/OpenMPKinds.cpp clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt clang/lib/StaticAnalyzer/Core/CMakeLists.txt clang/tools/libclang/CIndex.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp llvm/include/llvm/Frontend/OpenMP/OMPConstants.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPConstants.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/ASTFwd.h b/clang/include/clang/AST/ASTFwd.h index 5a891817b336..65319a19728b 100644 --- a/clang/include/clang/AST/ASTFwd.h +++ b/clang/include/clang/AST/ASTFwd.h @@ -27,8 +27,8 @@ class Type; #include "clang/AST/TypeNodes.inc" class CXXCtorInitializer; class OMPClause; -#define OPENMP_CLAUSE(KIND, CLASSNAME) class CLASSNAME; -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) class Class; +#include "llvm/Frontend/OpenMP/OMPKinds.def" } // end namespace clang diff --git a/clang/include/clang/AST/ASTTypeTraits.h b/clang/include/clang/AST/ASTTypeTraits.h index a9c2e334a29e..cd80e9bc3808 100644 --- a/clang/include/clang/AST/ASTTypeTraits.h +++ b/clang/include/clang/AST/ASTTypeTraits.h @@ -148,8 +148,8 @@ class ASTNodeKind { #define TYPE(DERIVED, BASE) NKI_##DERIVED##Type, #include "clang/AST/TypeNodes.inc" NKI_OMPClause, -#define OPENMP_CLAUSE(TextualSpelling, Class) NKI_##Class, -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) NKI_##Class, +#include "llvm/Frontend/OpenMP/OMPKinds.def" NKI_NumberOfKinds }; @@ -204,8 +204,8 @@ KIND_TO_KIND_ID(OMPClause) #include "clang/AST/StmtNodes.inc" #define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type) #include "clang/AST/TypeNodes.inc" -#define OPENMP_CLAUSE(TextualSpelling, Class) KIND_TO_KIND_ID(Class) -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class) +#include "llvm/Frontend/OpenMP/OMPKinds.def" #undef KIND_TO_KIND_ID inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) { diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 0d4b69911f19..7718c2707474 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -285,12 +285,13 @@ class OMPAllocatorClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_allocator, StartLoc, EndLoc), LParenLoc(LParenLoc), - Allocator(A) {} + : OMPClause(llvm::omp::OMPC_allocator, StartLoc, EndLoc), + LParenLoc(LParenLoc), Allocator(A) {} /// Build an empty clause. OMPAllocatorClause() - : OMPClause(OMPC_allocator, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_allocator, SourceLocation(), + SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -315,7 +316,7 @@ class OMPAllocatorClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_allocator; + return T->getClauseKind() == llvm::omp::OMPC_allocator; } }; @@ -350,17 +351,17 @@ class OMPAllocateClause final OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc, Expr *Allocator, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_allocate, StartLoc, LParenLoc, - EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_allocate, StartLoc, + LParenLoc, EndLoc, N), Allocator(Allocator), ColonLoc(ColonLoc) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPAllocateClause(unsigned N) - : OMPVarListClause(OMPC_allocate, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_allocate, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} /// Sets location of ':' symbol in clause. void setColonLoc(SourceLocation CL) { ColonLoc = CL; } @@ -412,7 +413,7 @@ class OMPAllocateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_allocate; + return T->getClauseKind() == llvm::omp::OMPC_allocate; } }; @@ -470,15 +471,16 @@ class OMPIfClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc) - : OMPClause(OMPC_if, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Condition(Cond), ColonLoc(ColonLoc), - NameModifier(NameModifier), NameModifierLoc(NameModifierLoc) { + : OMPClause(llvm::omp::OMPC_if, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond), + ColonLoc(ColonLoc), NameModifier(NameModifier), + NameModifierLoc(NameModifierLoc) { setPreInitStmt(HelperCond, CaptureRegion); } /// Build an empty clause. OMPIfClause() - : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_if, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -512,7 +514,7 @@ class OMPIfClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_if; + return T->getClauseKind() == llvm::omp::OMPC_if; } }; @@ -548,14 +550,14 @@ class OMPFinalClause : public OMPClause, public OMPClauseWithPreInit { OMPFinalClause(Expr *Cond, Stmt *HelperCond, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_final, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Condition(Cond) { + : OMPClause(llvm::omp::OMPC_final, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) { setPreInitStmt(HelperCond, CaptureRegion); } /// Build an empty clause. OMPFinalClause() - : OMPClause(OMPC_final, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_final, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -580,7 +582,7 @@ class OMPFinalClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_final; + return T->getClauseKind() == llvm::omp::OMPC_final; } }; @@ -618,7 +620,7 @@ class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_threads, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_num_threads, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumThreads(NumThreads) { setPreInitStmt(HelperNumThreads, CaptureRegion); @@ -626,7 +628,8 @@ class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit { /// Build an empty clause. OMPNumThreadsClause() - : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_num_threads, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -652,7 +655,7 @@ class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_num_threads; + return T->getClauseKind() == llvm::omp::OMPC_num_threads; } }; @@ -688,12 +691,13 @@ class OMPSafelenClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc), - Safelen(Len) {} + : OMPClause(llvm::omp::OMPC_safelen, StartLoc, EndLoc), + LParenLoc(LParenLoc), Safelen(Len) {} /// Build an empty clause. explicit OMPSafelenClause() - : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_safelen, SourceLocation(), SourceLocation()) { + } /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -718,7 +722,7 @@ class OMPSafelenClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_safelen; + return T->getClauseKind() == llvm::omp::OMPC_safelen; } }; @@ -753,12 +757,13 @@ class OMPSimdlenClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_simdlen, StartLoc, EndLoc), LParenLoc(LParenLoc), - Simdlen(Len) {} + : OMPClause(llvm::omp::OMPC_simdlen, StartLoc, EndLoc), + LParenLoc(LParenLoc), Simdlen(Len) {} /// Build an empty clause. explicit OMPSimdlenClause() - : OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_simdlen, SourceLocation(), SourceLocation()) { + } /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -783,7 +788,7 @@ class OMPSimdlenClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_simdlen; + return T->getClauseKind() == llvm::omp::OMPC_simdlen; } }; @@ -819,12 +824,13 @@ class OMPCollapseClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPCollapseClause(Expr *Num, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc), - NumForLoops(Num) {} + : OMPClause(llvm::omp::OMPC_collapse, StartLoc, EndLoc), + LParenLoc(LParenLoc), NumForLoops(Num) {} /// Build an empty clause. explicit OMPCollapseClause() - : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_collapse, SourceLocation(), + SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -849,7 +855,7 @@ class OMPCollapseClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_collapse; + return T->getClauseKind() == llvm::omp::OMPC_collapse; } }; @@ -893,12 +899,13 @@ class OMPDefaultClause : public OMPClause { OMPDefaultClause(llvm::omp::DefaultKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(A), KindKwLoc(ALoc) {} + : OMPClause(llvm::omp::OMPC_default, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPDefaultClause() - : OMPClause(OMPC_default, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_default, SourceLocation(), SourceLocation()) { + } /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -928,7 +935,7 @@ class OMPDefaultClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_default; + return T->getClauseKind() == llvm::omp::OMPC_default; } }; @@ -974,12 +981,13 @@ class OMPProcBindClause : public OMPClause { OMPProcBindClause(llvm::omp::ProcBindKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(A), KindKwLoc(ALoc) {} + : OMPClause(llvm::omp::OMPC_proc_bind, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPProcBindClause() - : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_proc_bind, SourceLocation(), + SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -1009,7 +1017,7 @@ class OMPProcBindClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_proc_bind; + return T->getClauseKind() == llvm::omp::OMPC_proc_bind; } }; @@ -1029,11 +1037,12 @@ class OMPUnifiedAddressClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_unified_address, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_unified_address, StartLoc, EndLoc) {} /// Build an empty clause. OMPUnifiedAddressClause() - : OMPClause(OMPC_unified_address, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_unified_address, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1051,7 +1060,7 @@ class OMPUnifiedAddressClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_unified_address; + return T->getClauseKind() == llvm::omp::OMPC_unified_address; } }; @@ -1071,11 +1080,12 @@ class OMPUnifiedSharedMemoryClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_unified_shared_memory, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_unified_shared_memory, StartLoc, EndLoc) {} /// Build an empty clause. OMPUnifiedSharedMemoryClause() - : OMPClause(OMPC_unified_shared_memory, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_unified_shared_memory, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1093,7 +1103,7 @@ class OMPUnifiedSharedMemoryClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_unified_shared_memory; + return T->getClauseKind() == llvm::omp::OMPC_unified_shared_memory; } }; @@ -1113,11 +1123,12 @@ class OMPReverseOffloadClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_reverse_offload, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_reverse_offload, StartLoc, EndLoc) {} /// Build an empty clause. OMPReverseOffloadClause() - : OMPClause(OMPC_reverse_offload, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_reverse_offload, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1135,7 +1146,7 @@ class OMPReverseOffloadClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_reverse_offload; + return T->getClauseKind() == llvm::omp::OMPC_reverse_offload; } }; @@ -1155,12 +1166,12 @@ class OMPDynamicAllocatorsClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_dynamic_allocators, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_dynamic_allocators, StartLoc, EndLoc) {} /// Build an empty clause. OMPDynamicAllocatorsClause() - : OMPClause(OMPC_dynamic_allocators, SourceLocation(), SourceLocation()) { - } + : OMPClause(llvm::omp::OMPC_dynamic_allocators, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1178,7 +1189,7 @@ class OMPDynamicAllocatorsClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_dynamic_allocators; + return T->getClauseKind() == llvm::omp::OMPC_dynamic_allocators; } }; @@ -1230,12 +1241,12 @@ class OMPAtomicDefaultMemOrderClause final : public OMPClause { SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_atomic_default_mem_order, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, StartLoc, EndLoc), LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPAtomicDefaultMemOrderClause() - : OMPClause(OMPC_atomic_default_mem_order, SourceLocation(), + : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. @@ -1268,7 +1279,7 @@ class OMPAtomicDefaultMemOrderClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_atomic_default_mem_order; + return T->getClauseKind() == llvm::omp::OMPC_atomic_default_mem_order; } }; @@ -1387,9 +1398,9 @@ class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { Expr *ChunkSize, Stmt *HelperChunkSize, OpenMPScheduleClauseModifier M1, SourceLocation M1Loc, OpenMPScheduleClauseModifier M2, SourceLocation M2Loc) - : OMPClause(OMPC_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), - ChunkSize(ChunkSize) { + : OMPClause(llvm::omp::OMPC_schedule, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), + KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { setPreInitStmt(HelperChunkSize); Modifiers[FIRST] = M1; Modifiers[SECOND] = M2; @@ -1399,7 +1410,7 @@ class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { /// Build an empty clause. explicit OMPScheduleClause() - : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_schedule, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) { Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown; Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown; @@ -1461,7 +1472,7 @@ class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_schedule; + return T->getClauseKind() == llvm::omp::OMPC_schedule; } }; @@ -1496,12 +1507,12 @@ class OMPOrderedClause final /// \param EndLoc Ending location of the clause. OMPOrderedClause(Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_ordered, StartLoc, EndLoc), LParenLoc(LParenLoc), - NumForLoops(Num), NumberOfLoops(NumLoops) {} + : OMPClause(llvm::omp::OMPC_ordered, StartLoc, EndLoc), + LParenLoc(LParenLoc), NumForLoops(Num), NumberOfLoops(NumLoops) {} /// Build an empty clause. explicit OMPOrderedClause(unsigned NumLoops) - : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_ordered, SourceLocation(), SourceLocation()), NumberOfLoops(NumLoops) {} /// Set the number of associated for-loops. @@ -1557,7 +1568,7 @@ class OMPOrderedClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_ordered; + return T->getClauseKind() == llvm::omp::OMPC_ordered; } }; @@ -1574,11 +1585,11 @@ class OMPNowaitClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_nowait, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_nowait, StartLoc, EndLoc) {} /// Build an empty clause. OMPNowaitClause() - : OMPClause(OMPC_nowait, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_nowait, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1596,7 +1607,7 @@ class OMPNowaitClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_nowait; + return T->getClauseKind() == llvm::omp::OMPC_nowait; } }; @@ -1613,11 +1624,11 @@ class OMPUntiedClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_untied, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_untied, StartLoc, EndLoc) {} /// Build an empty clause. OMPUntiedClause() - : OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_untied, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1635,7 +1646,7 @@ class OMPUntiedClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_untied; + return T->getClauseKind() == llvm::omp::OMPC_untied; } }; @@ -1653,11 +1664,12 @@ class OMPMergeableClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_mergeable, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_mergeable, StartLoc, EndLoc) {} /// Build an empty clause. OMPMergeableClause() - : OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_mergeable, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1675,7 +1687,7 @@ class OMPMergeableClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_mergeable; + return T->getClauseKind() == llvm::omp::OMPC_mergeable; } }; @@ -1692,10 +1704,11 @@ class OMPReadClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_read, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_read, StartLoc, EndLoc) {} /// Build an empty clause. - OMPReadClause() : OMPClause(OMPC_read, SourceLocation(), SourceLocation()) {} + OMPReadClause() + : OMPClause(llvm::omp::OMPC_read, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1713,7 +1726,7 @@ class OMPReadClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_read; + return T->getClauseKind() == llvm::omp::OMPC_read; } }; @@ -1730,11 +1743,11 @@ class OMPWriteClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_write, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_write, StartLoc, EndLoc) {} /// Build an empty clause. OMPWriteClause() - : OMPClause(OMPC_write, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_write, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1752,7 +1765,7 @@ class OMPWriteClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_write; + return T->getClauseKind() == llvm::omp::OMPC_write; } }; @@ -1812,11 +1825,12 @@ class OMPUpdateClause final /// \param EndLoc Ending location of the clause. OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc, bool IsExtended) - : OMPClause(OMPC_update, StartLoc, EndLoc), IsExtended(IsExtended) {} + : OMPClause(llvm::omp::OMPC_update, StartLoc, EndLoc), + IsExtended(IsExtended) {} /// Build an empty clause. OMPUpdateClause(bool IsExtended) - : OMPClause(OMPC_update, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_update, SourceLocation(), SourceLocation()), IsExtended(IsExtended) {} public: @@ -1886,7 +1900,7 @@ class OMPUpdateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_update; + return T->getClauseKind() == llvm::omp::OMPC_update; } }; @@ -1904,11 +1918,12 @@ class OMPCaptureClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_capture, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_capture, StartLoc, EndLoc) {} /// Build an empty clause. OMPCaptureClause() - : OMPClause(OMPC_capture, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_capture, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1926,7 +1941,7 @@ class OMPCaptureClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_capture; + return T->getClauseKind() == llvm::omp::OMPC_capture; } }; @@ -1944,11 +1959,12 @@ class OMPSeqCstClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_seq_cst, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_seq_cst, StartLoc, EndLoc) {} /// Build an empty clause. OMPSeqCstClause() - : OMPClause(OMPC_seq_cst, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_seq_cst, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1966,7 +1982,7 @@ class OMPSeqCstClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_seq_cst; + return T->getClauseKind() == llvm::omp::OMPC_seq_cst; } }; @@ -1984,11 +2000,12 @@ class OMPAcqRelClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_acq_rel, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_acq_rel, StartLoc, EndLoc) {} /// Build an empty clause. OMPAcqRelClause() - : OMPClause(OMPC_acq_rel, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_acq_rel, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2006,7 +2023,7 @@ class OMPAcqRelClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_acq_rel; + return T->getClauseKind() == llvm::omp::OMPC_acq_rel; } }; @@ -2024,11 +2041,12 @@ class OMPAcquireClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_acquire, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_acquire, StartLoc, EndLoc) {} /// Build an empty clause. OMPAcquireClause() - : OMPClause(OMPC_acquire, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_acquire, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2046,7 +2064,7 @@ class OMPAcquireClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_acquire; + return T->getClauseKind() == llvm::omp::OMPC_acquire; } }; @@ -2064,11 +2082,12 @@ class OMPReleaseClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReleaseClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_release, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_release, StartLoc, EndLoc) {} /// Build an empty clause. OMPReleaseClause() - : OMPClause(OMPC_release, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_release, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2086,7 +2105,7 @@ class OMPReleaseClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_release; + return T->getClauseKind() == llvm::omp::OMPC_release; } }; @@ -2104,11 +2123,12 @@ class OMPRelaxedClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_relaxed, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_relaxed, StartLoc, EndLoc) {} /// Build an empty clause. OMPRelaxedClause() - : OMPClause(OMPC_relaxed, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_relaxed, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2126,7 +2146,7 @@ class OMPRelaxedClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_relaxed; + return T->getClauseKind() == llvm::omp::OMPC_relaxed; } }; @@ -2152,16 +2172,16 @@ class OMPPrivateClause final /// \param N Number of the variables in the clause. OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_private, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_private, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPPrivateClause(unsigned N) - : OMPVarListClause(OMPC_private, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_private, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} /// Sets the list of references to private copies with initializers for /// new private variables. @@ -2231,7 +2251,7 @@ class OMPPrivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_private; + return T->getClauseKind() == llvm::omp::OMPC_private; } }; @@ -2259,8 +2279,8 @@ class OMPFirstprivateClause final /// \param N Number of the variables in the clause. OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_firstprivate, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_firstprivate, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPreInit(this) {} /// Build an empty clause. @@ -2268,7 +2288,7 @@ class OMPFirstprivateClause final /// \param N Number of variables. explicit OMPFirstprivateClause(unsigned N) : OMPVarListClause( - OMPC_firstprivate, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_firstprivate, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPreInit(this) {} @@ -2372,7 +2392,7 @@ class OMPFirstprivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_firstprivate; + return T->getClauseKind() == llvm::omp::OMPC_firstprivate; } }; @@ -2425,8 +2445,8 @@ class OMPLastprivateClause final SourceLocation EndLoc, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, unsigned N) - : OMPVarListClause(OMPC_lastprivate, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_lastprivate, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), LPKind(LPKind), LPKindLoc(LPKindLoc), ColonLoc(ColonLoc) {} @@ -2435,7 +2455,7 @@ class OMPLastprivateClause final /// \param N Number of variables. explicit OMPLastprivateClause(unsigned N) : OMPVarListClause( - OMPC_lastprivate, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_lastprivate, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -2611,7 +2631,7 @@ class OMPLastprivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_lastprivate; + return T->getClauseKind() == llvm::omp::OMPC_lastprivate; } }; @@ -2636,16 +2656,16 @@ class OMPSharedClause final /// \param N Number of the variables in the clause. OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_shared, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_shared, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPSharedClause(unsigned N) - : OMPVarListClause(OMPC_shared, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_shared, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -2683,7 +2703,7 @@ class OMPSharedClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_shared; + return T->getClauseKind() == llvm::omp::OMPC_shared; } }; @@ -2734,8 +2754,8 @@ class OMPReductionClause final OpenMPReductionClauseModifier Modifier, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause(OMPC_reduction, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_reduction, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -2744,9 +2764,9 @@ class OMPReductionClause final /// /// \param N Number of variables. explicit OMPReductionClause(unsigned N) - : OMPVarListClause(OMPC_reduction, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_reduction, SourceLocation(), SourceLocation(), - N), + SourceLocation(), N), OMPClauseWithPostUpdate(this) {} /// Sets reduction modifier. @@ -2943,7 +2963,7 @@ class OMPReductionClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_reduction; + return T->getClauseKind() == llvm::omp::OMPC_reduction; } }; @@ -2985,8 +3005,8 @@ class OMPTaskReductionClause final SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause(OMPC_task_reduction, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause( + llvm::omp::OMPC_task_reduction, StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -2995,7 +3015,7 @@ class OMPTaskReductionClause final /// \param N Number of variables. explicit OMPTaskReductionClause(unsigned N) : OMPVarListClause( - OMPC_task_reduction, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_task_reduction, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -3175,7 +3195,7 @@ class OMPTaskReductionClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_task_reduction; + return T->getClauseKind() == llvm::omp::OMPC_task_reduction; } }; @@ -3216,8 +3236,8 @@ class OMPInReductionClause final SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause(OMPC_in_reduction, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_in_reduction, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -3226,7 +3246,7 @@ class OMPInReductionClause final /// \param N Number of variables. explicit OMPInReductionClause(unsigned N) : OMPVarListClause( - OMPC_in_reduction, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_in_reduction, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -3430,7 +3450,7 @@ class OMPInReductionClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_in_reduction; + return T->getClauseKind() == llvm::omp::OMPC_in_reduction; } }; @@ -3476,8 +3496,8 @@ class OMPLinearClause final OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned NumVars) - : OMPVarListClause(OMPC_linear, StartLoc, LParenLoc, - EndLoc, NumVars), + : OMPVarListClause(llvm::omp::OMPC_linear, StartLoc, + LParenLoc, EndLoc, NumVars), OMPClauseWithPostUpdate(this), Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {} @@ -3485,9 +3505,9 @@ class OMPLinearClause final /// /// \param NumVars Number of variables. explicit OMPLinearClause(unsigned NumVars) - : OMPVarListClause(OMPC_linear, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_linear, SourceLocation(), SourceLocation(), - NumVars), + SourceLocation(), NumVars), OMPClauseWithPostUpdate(this) {} /// Gets the list of initial values for linear variables. @@ -3707,7 +3727,7 @@ class OMPLinearClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_linear; + return T->getClauseKind() == llvm::omp::OMPC_linear; } }; @@ -3742,17 +3762,17 @@ class OMPAlignedClause final OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned NumVars) - : OMPVarListClause(OMPC_aligned, StartLoc, LParenLoc, - EndLoc, NumVars), + : OMPVarListClause(llvm::omp::OMPC_aligned, StartLoc, + LParenLoc, EndLoc, NumVars), ColonLoc(ColonLoc) {} /// Build an empty clause. /// /// \param NumVars Number of variables. explicit OMPAlignedClause(unsigned NumVars) - : OMPVarListClause(OMPC_aligned, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_aligned, SourceLocation(), SourceLocation(), - NumVars) {} + SourceLocation(), NumVars) {} public: /// Creates clause with a list of variables \a VL and alignment \a A. @@ -3806,7 +3826,7 @@ class OMPAlignedClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_aligned; + return T->getClauseKind() == llvm::omp::OMPC_aligned; } }; @@ -3845,16 +3865,16 @@ class OMPCopyinClause final /// \param N Number of the variables in the clause. OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_copyin, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_copyin, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPCopyinClause(unsigned N) - : OMPVarListClause(OMPC_copyin, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_copyin, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} /// Set list of helper expressions, required for proper codegen of the /// clause. These expressions represent source expression in the final @@ -3982,7 +4002,7 @@ class OMPCopyinClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_copyin; + return T->getClauseKind() == llvm::omp::OMPC_copyin; } }; @@ -4009,15 +4029,16 @@ class OMPCopyprivateClause final /// \param N Number of the variables in the clause. OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_copyprivate, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_copyprivate, + StartLoc, LParenLoc, EndLoc, N) { + } /// Build an empty clause. /// /// \param N Number of variables. explicit OMPCopyprivateClause(unsigned N) : OMPVarListClause( - OMPC_copyprivate, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_copyprivate, SourceLocation(), SourceLocation(), SourceLocation(), N) {} /// Set list of helper expressions, required for proper codegen of the @@ -4145,7 +4166,7 @@ class OMPCopyprivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_copyprivate; + return T->getClauseKind() == llvm::omp::OMPC_copyprivate; } }; @@ -4175,16 +4196,16 @@ class OMPFlushClause final /// \param N Number of the variables in the clause. OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_flush, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_flush, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPFlushClause(unsigned N) - : OMPVarListClause(OMPC_flush, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_flush, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -4222,7 +4243,7 @@ class OMPFlushClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_flush; + return T->getClauseKind() == llvm::omp::OMPC_flush; } }; @@ -4254,12 +4275,13 @@ class OMPDepobjClause final : public OMPClause { /// \param EndLoc Ending location of the clause. OMPDepobjClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_depobj, StartLoc, EndLoc), LParenLoc(LParenLoc) {} + : OMPClause(llvm::omp::OMPC_depobj, StartLoc, EndLoc), + LParenLoc(LParenLoc) {} /// Build an empty clause. /// explicit OMPDepobjClause() - : OMPClause(OMPC_depobj, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_depobj, SourceLocation(), SourceLocation()) {} void setDepobj(Expr *E) { Depobj = E; } @@ -4308,7 +4330,7 @@ class OMPDepobjClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_depobj; + return T->getClauseKind() == llvm::omp::OMPC_depobj; } }; @@ -4349,8 +4371,9 @@ class OMPDependClause final /// clause. OMPDependClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N, unsigned NumLoops) - : OMPVarListClause(OMPC_depend, StartLoc, LParenLoc, - EndLoc, N), NumLoops(NumLoops) {} + : OMPVarListClause(llvm::omp::OMPC_depend, StartLoc, + LParenLoc, EndLoc, N), + NumLoops(NumLoops) {} /// Build an empty clause. /// @@ -4358,9 +4381,9 @@ class OMPDependClause final /// \param NumLoops Number of loops that is associated with this depend /// clause. explicit OMPDependClause(unsigned N, unsigned NumLoops) - : OMPVarListClause(OMPC_depend, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_depend, SourceLocation(), SourceLocation(), - N), + SourceLocation(), N), NumLoops(NumLoops) {} /// Set dependency kind. @@ -4439,7 +4462,7 @@ class OMPDependClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_depend; + return T->getClauseKind() == llvm::omp::OMPC_depend; } }; @@ -4492,15 +4515,15 @@ class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc) - : OMPClause(OMPC_device, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Modifier(Modifier), ModifierLoc(ModifierLoc), - Device(E) { + : OMPClause(llvm::omp::OMPC_device, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier), + ModifierLoc(ModifierLoc), Device(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPDeviceClause() - : OMPClause(OMPC_device, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_device, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -4535,7 +4558,7 @@ class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_device; + return T->getClauseKind() == llvm::omp::OMPC_device; } }; @@ -4552,11 +4575,12 @@ class OMPThreadsClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_threads, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_threads, StartLoc, EndLoc) {} /// Build an empty clause. OMPThreadsClause() - : OMPClause(OMPC_threads, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_threads, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -4574,7 +4598,7 @@ class OMPThreadsClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_threads; + return T->getClauseKind() == llvm::omp::OMPC_threads; } }; @@ -4591,10 +4615,11 @@ class OMPSIMDClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_simd, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_simd, StartLoc, EndLoc) {} /// Build an empty clause. - OMPSIMDClause() : OMPClause(OMPC_simd, SourceLocation(), SourceLocation()) {} + OMPSIMDClause() + : OMPClause(llvm::omp::OMPC_simd, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -4612,7 +4637,7 @@ class OMPSIMDClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_simd; + return T->getClauseKind() == llvm::omp::OMPC_simd; } }; @@ -5293,8 +5318,8 @@ class OMPMapClause final : public OMPMappableExprListClause, OpenMPMapClauseKind MapType, bool MapTypeIsImplicit, SourceLocation MapLoc, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_map, Locs, Sizes, &MapperQualifierLoc, - &MapperIdInfo), + : OMPMappableExprListClause(llvm::omp::OMPC_map, Locs, Sizes, + &MapperQualifierLoc, &MapperIdInfo), MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) { assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() && "Unexpected number of map type modifiers."); @@ -5314,7 +5339,8 @@ class OMPMapClause final : public OMPMappableExprListClause, /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPMapClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_map, OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_map, OMPVarListLocTy(), + Sizes) {} /// Set map-type-modifier for the clause. /// @@ -5461,7 +5487,7 @@ class OMPMapClause final : public OMPMappableExprListClause, static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_map; + return T->getClauseKind() == llvm::omp::OMPC_map; } }; @@ -5500,14 +5526,15 @@ class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit { OMPNumTeamsClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_teams, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), NumTeams(E) { + : OMPClause(llvm::omp::OMPC_num_teams, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTeams(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPNumTeamsClause() - : OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_num_teams, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5536,7 +5563,7 @@ class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_num_teams; + return T->getClauseKind() == llvm::omp::OMPC_num_teams; } }; @@ -5576,14 +5603,15 @@ class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_thread_limit, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_thread_limit, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadLimit(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPThreadLimitClause() - : OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_thread_limit, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5612,7 +5640,7 @@ class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_thread_limit; + return T->getClauseKind() == llvm::omp::OMPC_thread_limit; } }; @@ -5651,14 +5679,14 @@ class OMPPriorityClause : public OMPClause, public OMPClauseWithPreInit { OMPPriorityClause(Expr *Priority, Stmt *HelperPriority, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_priority, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Priority(Priority) { + : OMPClause(llvm::omp::OMPC_priority, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Priority(Priority) { setPreInitStmt(HelperPriority, CaptureRegion); } /// Build an empty clause. OMPPriorityClause() - : OMPClause(OMPC_priority, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_priority, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5686,7 +5714,7 @@ class OMPPriorityClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_priority; + return T->getClauseKind() == llvm::omp::OMPC_priority; } }; @@ -5722,14 +5750,15 @@ class OMPGrainsizeClause : public OMPClause, public OMPClauseWithPreInit { OMPGrainsizeClause(Expr *Size, Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_grainsize, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Grainsize(Size) { + : OMPClause(llvm::omp::OMPC_grainsize, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Grainsize(Size) { setPreInitStmt(HelperSize, CaptureRegion); } /// Build an empty clause. explicit OMPGrainsizeClause() - : OMPClause(OMPC_grainsize, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_grainsize, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5754,7 +5783,7 @@ class OMPGrainsizeClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_grainsize; + return T->getClauseKind() == llvm::omp::OMPC_grainsize; } }; @@ -5771,11 +5800,12 @@ class OMPNogroupClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_nogroup, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_nogroup, StartLoc, EndLoc) {} /// Build an empty clause. OMPNogroupClause() - : OMPClause(OMPC_nogroup, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_nogroup, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -5793,7 +5823,7 @@ class OMPNogroupClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_nogroup; + return T->getClauseKind() == llvm::omp::OMPC_nogroup; } }; @@ -5829,14 +5859,15 @@ class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit { OMPNumTasksClause(Expr *Size, Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_tasks, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), NumTasks(Size) { + : OMPClause(llvm::omp::OMPC_num_tasks, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTasks(Size) { setPreInitStmt(HelperSize, CaptureRegion); } /// Build an empty clause. explicit OMPNumTasksClause() - : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_num_tasks, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5861,7 +5892,7 @@ class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_num_tasks; + return T->getClauseKind() == llvm::omp::OMPC_num_tasks; } }; @@ -5893,11 +5924,12 @@ class OMPHintClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc), + : OMPClause(llvm::omp::OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc), Hint(Hint) {} /// Build an empty clause. - OMPHintClause() : OMPClause(OMPC_hint, SourceLocation(), SourceLocation()) {} + OMPHintClause() + : OMPClause(llvm::omp::OMPC_hint, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -5922,7 +5954,7 @@ class OMPHintClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_hint; + return T->getClauseKind() == llvm::omp::OMPC_hint; } }; @@ -5994,7 +6026,7 @@ class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { SourceLocation EndLoc, OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, Stmt *HelperChunkSize) - : OMPClause(OMPC_dist_schedule, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_dist_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { setPreInitStmt(HelperChunkSize); @@ -6002,7 +6034,8 @@ class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { /// Build an empty clause. explicit OMPDistScheduleClause() - : OMPClause(OMPC_dist_schedule, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_dist_schedule, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Get kind of the clause. @@ -6041,7 +6074,7 @@ class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_dist_schedule; + return T->getClauseKind() == llvm::omp::OMPC_dist_schedule; } }; @@ -6111,12 +6144,14 @@ class OMPDefaultmapClause : public OMPClause { SourceLocation MLoc, SourceLocation KLoc, SourceLocation EndLoc, OpenMPDefaultmapClauseKind Kind, OpenMPDefaultmapClauseModifier M) - : OMPClause(OMPC_defaultmap, StartLoc, EndLoc), LParenLoc(LParenLoc), - Modifier(M), ModifierLoc(MLoc), Kind(Kind), KindLoc(KLoc) {} + : OMPClause(llvm::omp::OMPC_defaultmap, StartLoc, EndLoc), + LParenLoc(LParenLoc), Modifier(M), ModifierLoc(MLoc), Kind(Kind), + KindLoc(KLoc) {} /// Build an empty clause. explicit OMPDefaultmapClause() - : OMPClause(OMPC_defaultmap, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_defaultmap, SourceLocation(), + SourceLocation()) {} /// Get kind of the clause. OpenMPDefaultmapClauseKind getDefaultmapKind() const { return Kind; } @@ -6153,7 +6188,7 @@ class OMPDefaultmapClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_defaultmap; + return T->getClauseKind() == llvm::omp::OMPC_defaultmap; } }; @@ -6191,8 +6226,8 @@ class OMPToClause final : public OMPMappableExprListClause, DeclarationNameInfo MapperIdInfo, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_to, Locs, Sizes, &MapperQualifierLoc, - &MapperIdInfo) {} + : OMPMappableExprListClause(llvm::omp::OMPC_to, Locs, Sizes, + &MapperQualifierLoc, &MapperIdInfo) {} /// Build an empty clause. /// @@ -6202,7 +6237,8 @@ class OMPToClause final : public OMPMappableExprListClause, /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPToClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_to, OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_to, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6270,7 +6306,7 @@ class OMPToClause final : public OMPMappableExprListClause, } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_to; + return T->getClauseKind() == llvm::omp::OMPC_to; } }; @@ -6309,8 +6345,8 @@ class OMPFromClause final DeclarationNameInfo MapperIdInfo, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_from, Locs, Sizes, &MapperQualifierLoc, - &MapperIdInfo) {} + : OMPMappableExprListClause(llvm::omp::OMPC_from, Locs, Sizes, + &MapperQualifierLoc, &MapperIdInfo) {} /// Build an empty clause. /// @@ -6320,7 +6356,8 @@ class OMPFromClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPFromClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_from, OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_from, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6388,7 +6425,7 @@ class OMPFromClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_from; + return T->getClauseKind() == llvm::omp::OMPC_from; } }; @@ -6422,7 +6459,8 @@ class OMPUseDevicePtrClause final /// NumComponents: total number of expression components in the clause. explicit OMPUseDevicePtrClause(const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_use_device_ptr, Locs, Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, Locs, Sizes) { + } /// Build an empty clause. /// @@ -6432,8 +6470,8 @@ class OMPUseDevicePtrClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPUseDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_use_device_ptr, OMPVarListLocTy(), - Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, + OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6551,7 +6589,7 @@ class OMPUseDevicePtrClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_use_device_ptr; + return T->getClauseKind() == llvm::omp::OMPC_use_device_ptr; } }; @@ -6585,7 +6623,7 @@ class OMPIsDevicePtrClause final /// NumComponents: total number of expression components in the clause. explicit OMPIsDevicePtrClause(const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_is_device_ptr, Locs, Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, Locs, Sizes) {} /// Build an empty clause. /// @@ -6595,8 +6633,8 @@ class OMPIsDevicePtrClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPIsDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_is_device_ptr, OMPVarListLocTy(), - Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, + OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6654,7 +6692,7 @@ class OMPIsDevicePtrClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_is_device_ptr; + return T->getClauseKind() == llvm::omp::OMPC_is_device_ptr; } }; @@ -6680,15 +6718,16 @@ class OMPNontemporalClause final /// \param N Number of the variables in the clause. OMPNontemporalClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_nontemporal, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_nontemporal, + StartLoc, LParenLoc, EndLoc, N) { + } /// Build an empty clause. /// /// \param N Number of variables. explicit OMPNontemporalClause(unsigned N) : OMPVarListClause( - OMPC_nontemporal, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_nontemporal, SourceLocation(), SourceLocation(), SourceLocation(), N) {} /// Get the list of privatied copies if the member expression was captured by @@ -6750,7 +6789,7 @@ class OMPNontemporalClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_nontemporal; + return T->getClauseKind() == llvm::omp::OMPC_nontemporal; } }; @@ -6794,12 +6833,12 @@ class OMPOrderClause final : public OMPClause { OMPOrderClause(OpenMPOrderClauseKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_order, StartLoc, EndLoc), LParenLoc(LParenLoc), Kind(A), - KindKwLoc(ALoc) {} + : OMPClause(llvm::omp::OMPC_order, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPOrderClause() - : OMPClause(OMPC_order, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_order, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -6829,7 +6868,7 @@ class OMPOrderClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_order; + return T->getClauseKind() == llvm::omp::OMPC_order; } }; @@ -6847,11 +6886,12 @@ class OMPDestroyClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPDestroyClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_destroy, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_destroy, StartLoc, EndLoc) {} /// Build an empty clause. OMPDestroyClause() - : OMPClause(OMPC_destroy, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_destroy, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -6869,7 +6909,7 @@ class OMPDestroyClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_destroy; + return T->getClauseKind() == llvm::omp::OMPC_destroy; } }; @@ -6904,12 +6944,12 @@ class OMPDetachClause final : public OMPClause { /// \param EndLoc Ending location of the clause. OMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_detach, StartLoc, EndLoc), LParenLoc(LParenLoc), - Evt(Evt) {} + : OMPClause(llvm::omp::OMPC_detach, StartLoc, EndLoc), + LParenLoc(LParenLoc), Evt(Evt) {} /// Build an empty clause. OMPDetachClause() - : OMPClause(OMPC_detach, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_detach, SourceLocation(), SourceLocation()) {} /// Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } @@ -6931,7 +6971,7 @@ class OMPDetachClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_detach; + return T->getClauseKind() == llvm::omp::OMPC_detach; } }; @@ -6957,16 +6997,16 @@ class OMPInclusiveClause final /// \param N Number of the variables in the clause. OMPInclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_inclusive, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_inclusive, + StartLoc, LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPInclusiveClause(unsigned N) - : OMPVarListClause(OMPC_inclusive, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_inclusive, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -7005,7 +7045,7 @@ class OMPInclusiveClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_inclusive; + return T->getClauseKind() == llvm::omp::OMPC_inclusive; } }; @@ -7031,16 +7071,16 @@ class OMPExclusiveClause final /// \param N Number of the variables in the clause. OMPExclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_exclusive, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_exclusive, + StartLoc, LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPExclusiveClause(unsigned N) - : OMPVarListClause(OMPC_exclusive, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_exclusive, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -7079,7 +7119,7 @@ class OMPExclusiveClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_exclusive; + return T->getClauseKind() == llvm::omp::OMPC_exclusive; } }; @@ -7092,17 +7132,20 @@ class OMPClauseVisitorBase { #define DISPATCH(CLASS) \ return static_cast(this)->Visit##CLASS(static_cast(S)) -#define OPENMP_CLAUSE(Name, Class) \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); } -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" RetTy Visit(PTR(OMPClause) S) { // Top switch clause: visit each OMPClause. switch (S->getClauseKind()) { - default: llvm_unreachable("Unknown clause kind!"); -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_ ## Name : return Visit ## Class(static_cast(S)); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case llvm::omp::Clause::Enum: \ + return Visit##Class(static_cast(S)); +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Clause::Enum: \ + break; +#include "llvm/Frontend/OpenMP/OMPKinds.def" } } // Base case, ignore it. :) @@ -7131,8 +7174,9 @@ class OMPClausePrinter final : public OMPClauseVisitor { OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy) : OS(OS), Policy(Policy) {} -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + void Visit##Class(Class *S); +#include "llvm/Frontend/OpenMP/OMPKinds.def" }; /// Helper data structure representing the traits in a match clause of an diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 46661e59f181..476e910e8888 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -534,8 +534,8 @@ template class RecursiveASTVisitor { bool TraverseOMPExecutableDirective(OMPExecutableDirective *S); bool TraverseOMPLoopDirective(OMPLoopDirective *S); bool TraverseOMPClause(OMPClause *C); -#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C); +#include "llvm/Frontend/OpenMP/OMPKinds.def" /// Process clauses with list of variables. template bool VisitOMPClauseList(T *Node); /// Process clauses with pre-initis. @@ -2956,17 +2956,14 @@ bool RecursiveASTVisitor::TraverseOMPClause(OMPClause *C) { if (!C) return true; switch (C->getClauseKind()) { -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case llvm::omp::Clause::Enum: \ TRY_TO(Visit##Class(static_cast(C))); \ break; -#include "clang/Basic/OpenMPKinds.def" - case OMPC_threadprivate: - case OMPC_uniform: - case OMPC_device_type: - case OMPC_match: - case OMPC_unknown: +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Clause::Enum: \ break; +#include "llvm/Frontend/OpenMP/OMPKinds.def" } return true; } diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 96bfdd313f47..f55ce2cc84dd 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3242,8 +3242,13 @@ def OMPCaptureKind : Attr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let SemaHandler = 0; - let Args = [UnsignedArgument<"CaptureKind">]; + let Args = [UnsignedArgument<"CaptureKindVal">]; let Documentation = [Undocumented]; + let AdditionalMembers = [{ + llvm::omp::Clause getCaptureKind() const { + return static_cast(getCaptureKindVal()); + } + }]; } def OMPReferencedVar : Attr { diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index 3cf92ead9560..4a4e6c6cb4c3 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -222,74 +222,6 @@ #define OPENMP_REDUCTION_MODIFIER(Name) #endif -// OpenMP clauses. -OPENMP_CLAUSE(allocator, OMPAllocatorClause) -OPENMP_CLAUSE(if, OMPIfClause) -OPENMP_CLAUSE(final, OMPFinalClause) -OPENMP_CLAUSE(num_threads, OMPNumThreadsClause) -OPENMP_CLAUSE(safelen, OMPSafelenClause) -OPENMP_CLAUSE(simdlen, OMPSimdlenClause) -OPENMP_CLAUSE(collapse, OMPCollapseClause) -OPENMP_CLAUSE(default, OMPDefaultClause) -OPENMP_CLAUSE(private, OMPPrivateClause) -OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause) -OPENMP_CLAUSE(lastprivate, OMPLastprivateClause) -OPENMP_CLAUSE(shared, OMPSharedClause) -OPENMP_CLAUSE(reduction, OMPReductionClause) -OPENMP_CLAUSE(linear, OMPLinearClause) -OPENMP_CLAUSE(aligned, OMPAlignedClause) -OPENMP_CLAUSE(copyin, OMPCopyinClause) -OPENMP_CLAUSE(copyprivate, OMPCopyprivateClause) -OPENMP_CLAUSE(proc_bind, OMPProcBindClause) -OPENMP_CLAUSE(schedule, OMPScheduleClause) -OPENMP_CLAUSE(ordered, OMPOrderedClause) -OPENMP_CLAUSE(nowait, OMPNowaitClause) -OPENMP_CLAUSE(untied, OMPUntiedClause) -OPENMP_CLAUSE(mergeable, OMPMergeableClause) -OPENMP_CLAUSE(flush, OMPFlushClause) -OPENMP_CLAUSE(read, OMPReadClause) -OPENMP_CLAUSE(write, OMPWriteClause) -OPENMP_CLAUSE(update, OMPUpdateClause) -OPENMP_CLAUSE(capture, OMPCaptureClause) -OPENMP_CLAUSE(seq_cst, OMPSeqCstClause) -OPENMP_CLAUSE(acq_rel, OMPAcqRelClause) -OPENMP_CLAUSE(acquire, OMPAcquireClause) -OPENMP_CLAUSE(release, OMPReleaseClause) -OPENMP_CLAUSE(relaxed, OMPRelaxedClause) -OPENMP_CLAUSE(depend, OMPDependClause) -OPENMP_CLAUSE(device, OMPDeviceClause) -OPENMP_CLAUSE(threads, OMPThreadsClause) -OPENMP_CLAUSE(simd, OMPSIMDClause) -OPENMP_CLAUSE(map, OMPMapClause) -OPENMP_CLAUSE(num_teams, OMPNumTeamsClause) -OPENMP_CLAUSE(thread_limit, OMPThreadLimitClause) -OPENMP_CLAUSE(priority, OMPPriorityClause) -OPENMP_CLAUSE(grainsize, OMPGrainsizeClause) -OPENMP_CLAUSE(nogroup, OMPNogroupClause) -OPENMP_CLAUSE(num_tasks, OMPNumTasksClause) -OPENMP_CLAUSE(hint, OMPHintClause) -OPENMP_CLAUSE(dist_schedule, OMPDistScheduleClause) -OPENMP_CLAUSE(defaultmap, OMPDefaultmapClause) -OPENMP_CLAUSE(to, OMPToClause) -OPENMP_CLAUSE(from, OMPFromClause) -OPENMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause) -OPENMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause) -OPENMP_CLAUSE(task_reduction, OMPTaskReductionClause) -OPENMP_CLAUSE(in_reduction, OMPInReductionClause) -OPENMP_CLAUSE(unified_address, OMPUnifiedAddressClause) -OPENMP_CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause) -OPENMP_CLAUSE(reverse_offload, OMPReverseOffloadClause) -OPENMP_CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause) -OPENMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause) -OPENMP_CLAUSE(allocate, OMPAllocateClause) -OPENMP_CLAUSE(nontemporal, OMPNontemporalClause) -OPENMP_CLAUSE(order, OMPOrderClause) -OPENMP_CLAUSE(depobj, OMPDepobjClause) -OPENMP_CLAUSE(destroy, OMPDestroyClause) -OPENMP_CLAUSE(detach, OMPDetachClause) -OPENMP_CLAUSE(inclusive, OMPInclusiveClause) -OPENMP_CLAUSE(exclusive, OMPExclusiveClause) - // Clauses allowed for OpenMP directive 'scan'. OPENMP_SCAN_CLAUSE(inclusive) OPENMP_SCAN_CLAUSE(exclusive) diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index b567f89b986e..4064cb2757d9 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -23,16 +23,7 @@ namespace clang { using OpenMPDirectiveKind = llvm::omp::Directive; /// OpenMP clauses. -enum OpenMPClauseKind { -#define OPENMP_CLAUSE(Name, Class) \ - OMPC_##Name, -#include "clang/Basic/OpenMPKinds.def" - OMPC_threadprivate, - OMPC_uniform, - OMPC_device_type, - OMPC_match, - OMPC_unknown -}; +using OpenMPClauseKind = llvm::omp::Clause; /// OpenMP attributes for 'schedule' clause. enum OpenMPScheduleClauseKind { @@ -175,9 +166,6 @@ enum OpenMPReductionClauseModifier { OMPC_REDUCTION_unknown, }; -OpenMPClauseKind getOpenMPClauseKind(llvm::StringRef Str); -const char *getOpenMPClauseName(OpenMPClauseKind Kind); - unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str); const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type); diff --git a/clang/lib/AST/ASTTypeTraits.cpp b/clang/lib/AST/ASTTypeTraits.cpp index e4ea3f41af36..6404edd79679 100644 --- a/clang/lib/AST/ASTTypeTraits.cpp +++ b/clang/lib/AST/ASTTypeTraits.cpp @@ -39,8 +39,8 @@ const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = { #define TYPE(DERIVED, BASE) { NKI_##BASE, #DERIVED "Type" }, #include "clang/AST/TypeNodes.inc" { NKI_None, "OMPClause" }, -#define OPENMP_CLAUSE(TextualSpelling, Class) {NKI_OMPClause, #Class}, -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) {NKI_OMPClause, #Class}, +#include "llvm/Frontend/OpenMP/OMPKinds.def" }; bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const { @@ -111,15 +111,13 @@ ASTNodeKind ASTNodeKind::getFromNode(const Type &T) { ASTNodeKind ASTNodeKind::getFromNode(const OMPClause &C) { switch (C.getClauseKind()) { -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: return ASTNodeKind(NKI_##Class); -#include "clang/Basic/OpenMPKinds.def" - case OMPC_threadprivate: - case OMPC_uniform: - case OMPC_device_type: - case OMPC_match: - case OMPC_unknown: +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case llvm::omp::Clause::Enum: \ + return ASTNodeKind(NKI_##Class); +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Clause::Enum: \ llvm_unreachable("unexpected OpenMP clause kind"); +#include "llvm/Frontend/OpenMP/OMPKinds.def" } llvm_unreachable("invalid stmt kind"); } diff --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp index a5ff68c18778..7d3a2903bd2e 100644 --- a/clang/lib/AST/AttrImpl.cpp +++ b/clang/lib/AST/AttrImpl.cpp @@ -108,7 +108,8 @@ void OMPDeclareSimdDeclAttr::printPrettyPragma( for (auto *E : linears()) { OS << " linear("; if (*MI != OMPC_LINEAR_unknown) - OS << getOpenMPSimpleClauseTypeName(OMPC_linear, *MI) << "("; + OS << getOpenMPSimpleClauseTypeName(llvm::omp::Clause::OMPC_linear, *MI) + << "("; E->printPretty(OS, nullptr, Policy); if (*MI != OMPC_LINEAR_unknown) OS << ")"; diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 4b7ebbb3c26d..1cd178cc27ce 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -31,20 +31,20 @@ OMPClause::child_range OMPClause::children() { switch (getClauseKind()) { default: break; -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case Enum: \ return static_cast(this)->children(); -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" } llvm_unreachable("unknown OMPClause"); } OMPClause::child_range OMPClause::used_children() { switch (getClauseKind()) { -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case Enum: \ return static_cast(this)->used_children(); -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" case OMPC_threadprivate: case OMPC_uniform: case OMPC_device_type: diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 054276a98424..1bb1b16418b3 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -414,9 +414,8 @@ class OMPClauseProfiler : public ConstOMPClauseVisitor { public: OMPClauseProfiler(StmtProfiler *P) : Profiler(P) { } -#define OPENMP_CLAUSE(Name, Class) \ - void Visit##Class(const Class *C); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C); +#include "llvm/Frontend/OpenMP/OMPKinds.def" void VistOMPClauseWithPreInit(const OMPClauseWithPreInit *C); void VistOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C); }; diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 6a6d8692228a..29e16d4ff3c2 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -314,7 +314,7 @@ void TextNodeDumper::Visit(const OMPClause *C) { } { ColorScope Color(OS, ShowColors, AttrColor); - StringRef ClauseName(getOpenMPClauseName(C->getClauseKind())); + StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind())); OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() << ClauseName.drop_front() << "Clause"; } @@ -1517,7 +1517,8 @@ void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) { } { ColorScope Color(OS, ShowColors, AttrColor); - StringRef ClauseName(getOpenMPClauseName(C->getClauseKind())); + StringRef ClauseName( + llvm::omp::getOpenMPClauseName(C->getClauseKind())); OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() << ClauseName.drop_front() << "Clause"; } diff --git a/clang/lib/ASTMatchers/CMakeLists.txt b/clang/lib/ASTMatchers/CMakeLists.txt index 8f700ca3226b..cde871cd31ca 100644 --- a/clang/lib/ASTMatchers/CMakeLists.txt +++ b/clang/lib/ASTMatchers/CMakeLists.txt @@ -1,6 +1,9 @@ add_subdirectory(Dynamic) -set(LLVM_LINK_COMPONENTS support) +set(LLVM_LINK_COMPONENTS + FrontendOpenMP + Support +) add_clang_library(clangASTMatchers ASTMatchFinder.cpp diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h index 48a454e3397e..db9122acede7 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -170,9 +170,8 @@ template <> struct ArgTypeTraits { private: static Optional getClauseKind(llvm::StringRef ClauseKind) { return llvm::StringSwitch>(ClauseKind) -#define OPENMP_CLAUSE(TextualSpelling, Class) \ - .Case("OMPC_" #TextualSpelling, OMPC_##TextualSpelling) -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) .Case(#Enum, llvm::omp::Clause::Enum) +#include "llvm/Frontend/OpenMP/OMPKinds.def" .Default(llvm::None); } diff --git a/clang/lib/Analysis/CMakeLists.txt b/clang/lib/Analysis/CMakeLists.txt index c1d0d6ed62c5..3333eab3b96d 100644 --- a/clang/lib/Analysis/CMakeLists.txt +++ b/clang/lib/Analysis/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 7a7c66c8e587..981bd7adbe9b 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -20,50 +20,6 @@ using namespace clang; using namespace llvm::omp; -OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) { - // 'flush' clause cannot be specified explicitly, because this is an implicit - // clause for 'flush' directive. If the 'flush' clause is explicitly specified - // the Parser should generate a warning about extra tokens at the end of the - // directive. - // 'depobj' clause cannot be specified explicitly, because this is an implicit - // clause for 'depobj' directive. If the 'depobj' clause is explicitly - // specified the Parser should generate a warning about extra tokens at the - // end of the directive. - if (llvm::StringSwitch(Str) - .Case("flush", true) - .Case("depobj", true) - .Default(false)) - return OMPC_unknown; - return llvm::StringSwitch(Str) -#define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name) -#include "clang/Basic/OpenMPKinds.def" - .Case("uniform", OMPC_uniform) - .Case("device_type", OMPC_device_type) - .Case("match", OMPC_match) - .Default(OMPC_unknown); -} - -const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) { - assert(Kind <= OMPC_unknown); - switch (Kind) { - case OMPC_unknown: - return "unknown"; -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ - return #Name; -#include "clang/Basic/OpenMPKinds.def" - case OMPC_uniform: - return "uniform"; - case OMPC_threadprivate: - return "threadprivate or thread local"; - case OMPC_device_type: - return "device_type"; - case OMPC_match: - return "match"; - } - llvm_unreachable("Invalid OpenMP clause kind"); -} - unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str) { switch (Kind) { diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp index aa6b6bc64c32..b6db63545c2c 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -341,8 +341,7 @@ class CheckVarsEscapingDeclContext final if (!Attr) return; if (((Attr->getCaptureKind() != OMPC_map) && - !isOpenMPPrivate( - static_cast(Attr->getCaptureKind()))) || + !isOpenMPPrivate(Attr->getCaptureKind())) || ((Attr->getCaptureKind() == OMPC_map) && !FD->getType()->isAnyPointerType())) return; diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 147d1b271d0c..af4ea4cb06cf 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -1387,7 +1387,7 @@ bool Parser::parseOMPDeclareVariantMatchClause(SourceLocation Loc, // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(OMPC_match))) { + getOpenMPClauseName(OMPC_match).data())) { while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch)) ; // Skip the last annot_pragma_openmp_end. @@ -1434,7 +1434,7 @@ parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind) { // Parse '('. BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(Kind))) + getOpenMPClauseName(Kind).data())) return llvm::None; unsigned Type = getOpenMPSimpleClauseType( @@ -1673,18 +1673,18 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( SmallVector Clauses; if (Tok.isNot(tok::annot_pragma_openmp_end)) { SmallVector, - OMPC_unknown + 1> - FirstClauses(OMPC_unknown + 1); + unsigned(OMPC_unknown) + 1> + FirstClauses(unsigned(OMPC_unknown) + 1); while (Tok.isNot(tok::annot_pragma_openmp_end)) { OpenMPClauseKind CKind = Tok.isAnnotation() ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind, - !FirstClauses[CKind].getInt()); + OMPClause *Clause = ParseOpenMPClause( + OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt()); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[CKind].setInt(true); + FirstClauses[unsigned(CKind)].setInt(true); if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -1708,8 +1708,9 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( case OMPD_requires: { SourceLocation StartLoc = ConsumeToken(); SmallVector Clauses; - SmallVector, OMPC_unknown + 1> - FirstClauses(OMPC_unknown + 1); + SmallVector, + unsigned(OMPC_unknown) + 1> + FirstClauses(unsigned(OMPC_unknown) + 1); if (Tok.is(tok::annot_pragma_openmp_end)) { Diag(Tok, diag::err_omp_expected_clause) << getOpenMPDirectiveName(OMPD_requires); @@ -1720,11 +1721,11 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind, - !FirstClauses[CKind].getInt()); + OMPClause *Clause = ParseOpenMPClause( + OMPD_requires, CKind, !FirstClauses[unsigned(CKind)].getInt()); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[CKind].setInt(true); + FirstClauses[unsigned(CKind)].setInt(true); if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -2023,8 +2024,9 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { ParsingOpenMPDirectiveRAII DirScope(*this); ParenBraceBracketBalancer BalancerRAIIObj(*this); SmallVector Clauses; - SmallVector, OMPC_unknown + 1> - FirstClauses(OMPC_unknown + 1); + SmallVector, + unsigned(OMPC_unknown) + 1> + FirstClauses(unsigned(OMPC_unknown) + 1); unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope; SourceLocation Loc = ConsumeAnnotationToken(), EndLoc; @@ -2069,18 +2071,18 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { SmallVector Clauses; if (Tok.isNot(tok::annot_pragma_openmp_end)) { SmallVector, - OMPC_unknown + 1> - FirstClauses(OMPC_unknown + 1); + unsigned(OMPC_unknown) + 1> + FirstClauses(unsigned(OMPC_unknown) + 1); while (Tok.isNot(tok::annot_pragma_openmp_end)) { OpenMPClauseKind CKind = Tok.isAnnotation() ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind, - !FirstClauses[CKind].getInt()); + OMPClause *Clause = ParseOpenMPClause( + OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt()); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[CKind].setInt(true); + FirstClauses[unsigned(CKind)].setInt(true); if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -2248,11 +2250,11 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { ImplicitClauseAllowed = false; Actions.StartOpenMPClause(CKind); HasImplicitClause = false; - OMPClause *Clause = - ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt()); - FirstClauses[CKind].setInt(true); + OMPClause *Clause = ParseOpenMPClause( + DKind, CKind, !FirstClauses[unsigned(CKind)].getInt()); + FirstClauses[unsigned(CKind)].setInt(true); if (Clause) { - FirstClauses[CKind].setPointer(Clause); + FirstClauses[unsigned(CKind)].setPointer(Clause); Clauses.push_back(Clause); } @@ -2269,7 +2271,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { // OpenMP [2.13.8, ordered Construct, Syntax] // If the depend clause is specified, the ordered construct is a stand-alone // directive. - if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) { + if (DKind == OMPD_ordered && FirstClauses[unsigned(OMPC_depend)].getInt()) { if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) == ParsedStmtContext()) { Diag(Loc, diag::err_omp_immediate_directive) @@ -2754,7 +2756,7 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind, // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(Kind))) + getOpenMPClauseName(Kind).data())) return nullptr; ExprResult Val; @@ -3066,7 +3068,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(Kind))) + getOpenMPClauseName(Kind).data())) return true; bool NeedRParenForLinear = false; diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 7d2ae172fe4d..20b6ce452c2a 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -2231,7 +2231,7 @@ void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, } } if (OMPC != OMPC_unknown) - FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); + FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); } bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 82cfa246e3f7..795a2a4c4415 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -730,10 +730,10 @@ class TreeTransform { #define ABSTRACT_STMT(Stmt) #include "clang/AST/StmtNodes.inc" -#define OPENMP_CLAUSE(Name, Class) \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ LLVM_ATTRIBUTE_NOINLINE \ OMPClause *Transform ## Class(Class *S); -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" /// Build a new qualified type given its unqualified type and type location. /// @@ -3585,10 +3585,10 @@ OMPClause *TreeTransform::TransformOMPClause(OMPClause *S) { switch (S->getClauseKind()) { default: break; // Transform individual clause nodes -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_ ## Name : \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case Enum: \ return getDerived().Transform ## Class(cast(S)); -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" } return S; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index bea9bdd22bab..f01b64bcdd8e 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -11613,8 +11613,8 @@ class OMPClauseReader : public OMPClauseVisitor { OMPClauseReader(ASTRecordReader &Record) : Record(Record), Context(Record.getContext()) {} -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *C); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *C); +#include "llvm/Frontend/OpenMP/OMPKinds.def" OMPClause *readClause(); void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C); void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C); @@ -11628,149 +11628,149 @@ OMPClause *ASTRecordReader::readOMPClause() { OMPClause *OMPClauseReader::readClause() { OMPClause *C = nullptr; - switch (Record.readInt()) { - case OMPC_if: + switch (llvm::omp::Clause(Record.readInt())) { + case llvm::omp::OMPC_if: C = new (Context) OMPIfClause(); break; - case OMPC_final: + case llvm::omp::OMPC_final: C = new (Context) OMPFinalClause(); break; - case OMPC_num_threads: + case llvm::omp::OMPC_num_threads: C = new (Context) OMPNumThreadsClause(); break; - case OMPC_safelen: + case llvm::omp::OMPC_safelen: C = new (Context) OMPSafelenClause(); break; - case OMPC_simdlen: + case llvm::omp::OMPC_simdlen: C = new (Context) OMPSimdlenClause(); break; - case OMPC_allocator: + case llvm::omp::OMPC_allocator: C = new (Context) OMPAllocatorClause(); break; - case OMPC_collapse: + case llvm::omp::OMPC_collapse: C = new (Context) OMPCollapseClause(); break; - case OMPC_default: + case llvm::omp::OMPC_default: C = new (Context) OMPDefaultClause(); break; - case OMPC_proc_bind: + case llvm::omp::OMPC_proc_bind: C = new (Context) OMPProcBindClause(); break; - case OMPC_schedule: + case llvm::omp::OMPC_schedule: C = new (Context) OMPScheduleClause(); break; - case OMPC_ordered: + case llvm::omp::OMPC_ordered: C = OMPOrderedClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_nowait: + case llvm::omp::OMPC_nowait: C = new (Context) OMPNowaitClause(); break; - case OMPC_untied: + case llvm::omp::OMPC_untied: C = new (Context) OMPUntiedClause(); break; - case OMPC_mergeable: + case llvm::omp::OMPC_mergeable: C = new (Context) OMPMergeableClause(); break; - case OMPC_read: + case llvm::omp::OMPC_read: C = new (Context) OMPReadClause(); break; - case OMPC_write: + case llvm::omp::OMPC_write: C = new (Context) OMPWriteClause(); break; - case OMPC_update: + case llvm::omp::OMPC_update: C = OMPUpdateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_capture: + case llvm::omp::OMPC_capture: C = new (Context) OMPCaptureClause(); break; - case OMPC_seq_cst: + case llvm::omp::OMPC_seq_cst: C = new (Context) OMPSeqCstClause(); break; - case OMPC_acq_rel: + case llvm::omp::OMPC_acq_rel: C = new (Context) OMPAcqRelClause(); break; - case OMPC_acquire: + case llvm::omp::OMPC_acquire: C = new (Context) OMPAcquireClause(); break; - case OMPC_release: + case llvm::omp::OMPC_release: C = new (Context) OMPReleaseClause(); break; - case OMPC_relaxed: + case llvm::omp::OMPC_relaxed: C = new (Context) OMPRelaxedClause(); break; - case OMPC_threads: + case llvm::omp::OMPC_threads: C = new (Context) OMPThreadsClause(); break; - case OMPC_simd: + case llvm::omp::OMPC_simd: C = new (Context) OMPSIMDClause(); break; - case OMPC_nogroup: + case llvm::omp::OMPC_nogroup: C = new (Context) OMPNogroupClause(); break; - case OMPC_unified_address: + case llvm::omp::OMPC_unified_address: C = new (Context) OMPUnifiedAddressClause(); break; - case OMPC_unified_shared_memory: + case llvm::omp::OMPC_unified_shared_memory: C = new (Context) OMPUnifiedSharedMemoryClause(); break; - case OMPC_reverse_offload: + case llvm::omp::OMPC_reverse_offload: C = new (Context) OMPReverseOffloadClause(); break; - case OMPC_dynamic_allocators: + case llvm::omp::OMPC_dynamic_allocators: C = new (Context) OMPDynamicAllocatorsClause(); break; - case OMPC_atomic_default_mem_order: + case llvm::omp::OMPC_atomic_default_mem_order: C = new (Context) OMPAtomicDefaultMemOrderClause(); break; - case OMPC_private: + case llvm::omp::OMPC_private: C = OMPPrivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_firstprivate: + case llvm::omp::OMPC_firstprivate: C = OMPFirstprivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_lastprivate: + case llvm::omp::OMPC_lastprivate: C = OMPLastprivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_shared: + case llvm::omp::OMPC_shared: C = OMPSharedClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_reduction: + case llvm::omp::OMPC_reduction: C = OMPReductionClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_task_reduction: + case llvm::omp::OMPC_task_reduction: C = OMPTaskReductionClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_in_reduction: + case llvm::omp::OMPC_in_reduction: C = OMPInReductionClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_linear: + case llvm::omp::OMPC_linear: C = OMPLinearClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_aligned: + case llvm::omp::OMPC_aligned: C = OMPAlignedClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_copyin: + case llvm::omp::OMPC_copyin: C = OMPCopyinClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_copyprivate: + case llvm::omp::OMPC_copyprivate: C = OMPCopyprivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_flush: + case llvm::omp::OMPC_flush: C = OMPFlushClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_depobj: + case llvm::omp::OMPC_depobj: C = OMPDepobjClause::CreateEmpty(Context); break; - case OMPC_depend: { + case llvm::omp::OMPC_depend: { unsigned NumVars = Record.readInt(); unsigned NumLoops = Record.readInt(); C = OMPDependClause::CreateEmpty(Context, NumVars, NumLoops); break; } - case OMPC_device: + case llvm::omp::OMPC_device: C = new (Context) OMPDeviceClause(); break; - case OMPC_map: { + case llvm::omp::OMPC_map: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11779,31 +11779,31 @@ OMPClause *OMPClauseReader::readClause() { C = OMPMapClause::CreateEmpty(Context, Sizes); break; } - case OMPC_num_teams: + case llvm::omp::OMPC_num_teams: C = new (Context) OMPNumTeamsClause(); break; - case OMPC_thread_limit: + case llvm::omp::OMPC_thread_limit: C = new (Context) OMPThreadLimitClause(); break; - case OMPC_priority: + case llvm::omp::OMPC_priority: C = new (Context) OMPPriorityClause(); break; - case OMPC_grainsize: + case llvm::omp::OMPC_grainsize: C = new (Context) OMPGrainsizeClause(); break; - case OMPC_num_tasks: + case llvm::omp::OMPC_num_tasks: C = new (Context) OMPNumTasksClause(); break; - case OMPC_hint: + case llvm::omp::OMPC_hint: C = new (Context) OMPHintClause(); break; - case OMPC_dist_schedule: + case llvm::omp::OMPC_dist_schedule: C = new (Context) OMPDistScheduleClause(); break; - case OMPC_defaultmap: + case llvm::omp::OMPC_defaultmap: C = new (Context) OMPDefaultmapClause(); break; - case OMPC_to: { + case llvm::omp::OMPC_to: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11812,7 +11812,7 @@ OMPClause *OMPClauseReader::readClause() { C = OMPToClause::CreateEmpty(Context, Sizes); break; } - case OMPC_from: { + case llvm::omp::OMPC_from: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11821,7 +11821,7 @@ OMPClause *OMPClauseReader::readClause() { C = OMPFromClause::CreateEmpty(Context, Sizes); break; } - case OMPC_use_device_ptr: { + case llvm::omp::OMPC_use_device_ptr: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11830,7 +11830,7 @@ OMPClause *OMPClauseReader::readClause() { C = OMPUseDevicePtrClause::CreateEmpty(Context, Sizes); break; } - case OMPC_is_device_ptr: { + case llvm::omp::OMPC_is_device_ptr: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11839,27 +11839,31 @@ OMPClause *OMPClauseReader::readClause() { C = OMPIsDevicePtrClause::CreateEmpty(Context, Sizes); break; } - case OMPC_allocate: + case llvm::omp::OMPC_allocate: C = OMPAllocateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_nontemporal: + case llvm::omp::OMPC_nontemporal: C = OMPNontemporalClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_inclusive: + case llvm::omp::OMPC_inclusive: C = OMPInclusiveClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_exclusive: + case llvm::omp::OMPC_exclusive: C = OMPExclusiveClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_order: + case llvm::omp::OMPC_order: C = new (Context) OMPOrderClause(); break; - case OMPC_destroy: + case llvm::omp::OMPC_destroy: C = new (Context) OMPDestroyClause(); break; - case OMPC_detach: + case llvm::omp::OMPC_detach: C = new (Context) OMPDetachClause(); break; +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Enum: \ + break; +#include "llvm/Frontend/OpenMP/OMPKinds.def" } assert(C && "Unknown OMPClause type"); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index f7c58ed11d9f..76e2dd609f92 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6037,8 +6037,8 @@ class OMPClauseWriter : public OMPClauseVisitor { public: OMPClauseWriter(ASTRecordWriter &Record) : Record(Record) {} -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *S); +#include "llvm/Frontend/OpenMP/OMPKinds.def" void writeClause(OMPClause *C); void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C); void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C); @@ -6051,7 +6051,7 @@ void ASTRecordWriter::writeOMPClause(OMPClause *C) { } void OMPClauseWriter::writeClause(OMPClause *C) { - Record.push_back(C->getClauseKind()); + Record.push_back(unsigned(C->getClauseKind())); Visit(C); Record.AddSourceLocation(C->getBeginLoc()); Record.AddSourceLocation(C->getEndLoc()); diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt index b7fb0d90c980..bcf2dfdb8326 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt index dc2a6279b737..057cdd4bb18a 100644 --- a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt @@ -1,4 +1,7 @@ -set(LLVM_LINK_COMPONENTS support) +set(LLVM_LINK_COMPONENTS + FrontendOpenMP + Support +) add_clang_library(clangStaticAnalyzerCore APSIntType.cpp diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index bb9fed165679..1267b9b50fd3 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2153,8 +2153,8 @@ class OMPClauseEnqueue : public ConstOMPClauseVisitor { public: OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {} -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(const Class *C); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C); +#include "llvm/Frontend/OpenMP/OMPKinds.def" void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C); void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C); }; diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index fbf2ff130785..428879d0695c 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -2612,7 +2612,7 @@ TEST(HasExternalFormalLinkage, Basic) { } TEST(HasDefaultArgument, Basic) { - EXPECT_TRUE(matches("void x(int val = 0) {}", + EXPECT_TRUE(matches("void x(int val = 0) {}", parmVarDecl(hasDefaultArgument()))); EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(hasDefaultArgument()))); @@ -2665,7 +2665,7 @@ TEST(HasTrailingReturn, MatchesTrailingReturn) { EXPECT_TRUE(matches("auto Y() -> int { return 0; }", functionDecl(hasTrailingReturn()))); EXPECT_TRUE(matches("auto X() -> int;", functionDecl(hasTrailingReturn()))); - EXPECT_TRUE(notMatches("int X() { return 0; }", + EXPECT_TRUE(notMatches("int X() { return 0; }", functionDecl(hasTrailingReturn()))); EXPECT_TRUE(notMatches("int X();", functionDecl(hasTrailingReturn()))); EXPECT_TRUE(notMatchesC("void X();", functionDecl(hasTrailingReturn()))); @@ -2891,8 +2891,8 @@ void x(int x) { } TEST(OMPExecutableDirective, isAllowedToContainClauseKind) { - auto Matcher = - ompExecutableDirective(isAllowedToContainClauseKind(OMPC_default)); + auto Matcher = ompExecutableDirective( + isAllowedToContainClauseKind(llvm::omp::OMPC_default)); const std::string Source0 = R"( void x() { diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h index 7cda3197473f..d32fa8dc98ef 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h @@ -34,11 +34,18 @@ enum class Directive { #include "llvm/Frontend/OpenMP/OMPKinds.def" }; +/// IDs for all OpenMP clauses. +enum class Clause { +#define OMP_CLAUSE(Enum, ...) Enum, +#include "llvm/Frontend/OpenMP/OMPKinds.def" +}; + /// Make the enum values available in the llvm::omp namespace. This allows us to /// write something like OMPD_parallel if we have a `using namespace omp`. At /// the same time we do not loose the strong type guarantees of the enum class, /// that is we cannot pass an unsigned as Directive without an explicit cast. #define OMP_DIRECTIVE(Enum, ...) constexpr auto Enum = omp::Directive::Enum; +#define OMP_CLAUSE(Enum, ...) constexpr auto Enum = omp::Clause::Enum; #include "llvm/Frontend/OpenMP/OMPKinds.def" /// IDs for all omp runtime library (RTL) functions. @@ -87,6 +94,12 @@ Directive getOpenMPDirectiveKind(StringRef Str); /// Return a textual representation of the directive \p D. StringRef getOpenMPDirectiveName(Directive D); +/// Parse \p Str and return the clause it matches or OMPC_unknown if none. +Clause getOpenMPClauseKind(StringRef Str); + +/// Return a textual representation of the clause \p C. +StringRef getOpenMPClauseName(Clause C); + /// Forward declarations for LLVM-IR types (simple, function and structure) are /// generated below. Their names are defined and used in OpenMP/OMPKinds.def. /// Here we provide the forward declarations, the initializeTypes function will diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def index c80ecc7cbf77..09468358415f 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -105,6 +105,117 @@ __OMP_DIRECTIVE(unknown) ///} +/// OpenMP Clauses +/// +///{ + +#ifndef OMP_CLAUSE +#define OMP_CLAUSE(Enum, Str, Implicit) +#endif +#ifndef OMP_CLAUSE_CLASS +#define OMP_CLAUSE_CLASS(Enum, Str, Class) +#endif +#ifndef OMP_CLAUSE_NO_CLASS +#define OMP_CLAUSE_NO_CLASS(Enum, Str) +#endif + +#define __OMP_CLAUSE(Name, Class) \ + OMP_CLAUSE(OMPC_##Name, #Name, /* Implicit */ false) \ + OMP_CLAUSE_CLASS(OMPC_##Name, #Name, Class) +#define __OMP_CLAUSE_NO_CLASS(Name) \ + OMP_CLAUSE(OMPC_##Name, #Name, /* Implicit */ false) \ + OMP_CLAUSE_NO_CLASS(OMPC_##Name, #Name) +#define __OMP_IMPLICIT_CLAUSE_CLASS(Name, Str, Class) \ + OMP_CLAUSE(OMPC_##Name, Str, /* Implicit */ true) \ + OMP_CLAUSE_CLASS(OMPC_##Name, Str, Class) +#define __OMP_IMPLICIT_CLAUSE_NO_CLASS(Name, Str) \ + OMP_CLAUSE(OMPC_##Name, Str, /* Implicit */ true) \ + OMP_CLAUSE_NO_CLASS(OMPC_##Name, Str) + +__OMP_CLAUSE(allocator, OMPAllocatorClause) +__OMP_CLAUSE(if, OMPIfClause) +__OMP_CLAUSE(final, OMPFinalClause) +__OMP_CLAUSE(num_threads, OMPNumThreadsClause) +__OMP_CLAUSE(safelen, OMPSafelenClause) +__OMP_CLAUSE(simdlen, OMPSimdlenClause) +__OMP_CLAUSE(collapse, OMPCollapseClause) +__OMP_CLAUSE(default, OMPDefaultClause) +__OMP_CLAUSE(private, OMPPrivateClause) +__OMP_CLAUSE(firstprivate, OMPFirstprivateClause) +__OMP_CLAUSE(lastprivate, OMPLastprivateClause) +__OMP_CLAUSE(shared, OMPSharedClause) +__OMP_CLAUSE(reduction, OMPReductionClause) +__OMP_CLAUSE(linear, OMPLinearClause) +__OMP_CLAUSE(aligned, OMPAlignedClause) +__OMP_CLAUSE(copyin, OMPCopyinClause) +__OMP_CLAUSE(copyprivate, OMPCopyprivateClause) +__OMP_CLAUSE(proc_bind, OMPProcBindClause) +__OMP_CLAUSE(schedule, OMPScheduleClause) +__OMP_CLAUSE(ordered, OMPOrderedClause) +__OMP_CLAUSE(nowait, OMPNowaitClause) +__OMP_CLAUSE(untied, OMPUntiedClause) +__OMP_CLAUSE(mergeable, OMPMergeableClause) +__OMP_CLAUSE(read, OMPReadClause) +__OMP_CLAUSE(write, OMPWriteClause) +__OMP_CLAUSE(update, OMPUpdateClause) +__OMP_CLAUSE(capture, OMPCaptureClause) +__OMP_CLAUSE(seq_cst, OMPSeqCstClause) +__OMP_CLAUSE(acq_rel, OMPAcqRelClause) +__OMP_CLAUSE(acquire, OMPAcquireClause) +__OMP_CLAUSE(release, OMPReleaseClause) +__OMP_CLAUSE(relaxed, OMPRelaxedClause) +__OMP_CLAUSE(depend, OMPDependClause) +__OMP_CLAUSE(device, OMPDeviceClause) +__OMP_CLAUSE(threads, OMPThreadsClause) +__OMP_CLAUSE(simd, OMPSIMDClause) +__OMP_CLAUSE(map, OMPMapClause) +__OMP_CLAUSE(num_teams, OMPNumTeamsClause) +__OMP_CLAUSE(thread_limit, OMPThreadLimitClause) +__OMP_CLAUSE(priority, OMPPriorityClause) +__OMP_CLAUSE(grainsize, OMPGrainsizeClause) +__OMP_CLAUSE(nogroup, OMPNogroupClause) +__OMP_CLAUSE(num_tasks, OMPNumTasksClause) +__OMP_CLAUSE(hint, OMPHintClause) +__OMP_CLAUSE(dist_schedule, OMPDistScheduleClause) +__OMP_CLAUSE(defaultmap, OMPDefaultmapClause) +__OMP_CLAUSE(to, OMPToClause) +__OMP_CLAUSE(from, OMPFromClause) +__OMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause) +__OMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause) +__OMP_CLAUSE(task_reduction, OMPTaskReductionClause) +__OMP_CLAUSE(in_reduction, OMPInReductionClause) +__OMP_CLAUSE(unified_address, OMPUnifiedAddressClause) +__OMP_CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause) +__OMP_CLAUSE(reverse_offload, OMPReverseOffloadClause) +__OMP_CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause) +__OMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause) +__OMP_CLAUSE(allocate, OMPAllocateClause) +__OMP_CLAUSE(nontemporal, OMPNontemporalClause) +__OMP_CLAUSE(order, OMPOrderClause) +__OMP_CLAUSE(destroy, OMPDestroyClause) +__OMP_CLAUSE(detach, OMPDetachClause) +__OMP_CLAUSE(inclusive, OMPInclusiveClause) +__OMP_CLAUSE(exclusive, OMPExclusiveClause) + +__OMP_CLAUSE_NO_CLASS(uniform) +__OMP_CLAUSE_NO_CLASS(device_type) +__OMP_CLAUSE_NO_CLASS(match) + +__OMP_IMPLICIT_CLAUSE_CLASS(depobj, "depobj", OMPDepobjClause) +__OMP_IMPLICIT_CLAUSE_CLASS(flush, "flush", OMPFlushClause) + +__OMP_IMPLICIT_CLAUSE_NO_CLASS(threadprivate, "threadprivate or thread local") +__OMP_IMPLICIT_CLAUSE_NO_CLASS(unknown, "unknown") + +#undef __OMP_IMPLICIT_CLAUSE_NO_CLASS +#undef __OMP_IMPLICIT_CLAUSE_CLASS +#undef __OMP_CLAUSE +#undef OMP_CLAUSE_NO_CLASS +#undef OMP_CLAUSE_CLASS +#undef OMP_CLAUSE + +///} + /// Types used in runtime structs or runtime functions /// ///{ @@ -232,8 +343,10 @@ __OMP_RTL(omp_set_max_active_levels, false, Void, Int32) __OMP_RTL(__kmpc_master, false, Int32, IdentPtr, Int32) __OMP_RTL(__kmpc_end_master, false, Void, IdentPtr, Int32) __OMP_RTL(__kmpc_critical, false, Void, IdentPtr, Int32, KmpCriticalNamePtrTy) -__OMP_RTL(__kmpc_critical_with_hint, false, Void, IdentPtr, Int32, KmpCriticalNamePtrTy, Int32) -__OMP_RTL(__kmpc_end_critical, false, Void, IdentPtr, Int32, KmpCriticalNamePtrTy) +__OMP_RTL(__kmpc_critical_with_hint, false, Void, IdentPtr, Int32, + KmpCriticalNamePtrTy, Int32) +__OMP_RTL(__kmpc_end_critical, false, Void, IdentPtr, Int32, + KmpCriticalNamePtrTy) __OMP_RTL(__last, false, Void, ) diff --git a/llvm/lib/Frontend/OpenMP/OMPConstants.cpp b/llvm/lib/Frontend/OpenMP/OMPConstants.cpp index 6ee44958d1c7..edd857d7b250 100644 --- a/llvm/lib/Frontend/OpenMP/OMPConstants.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPConstants.cpp @@ -36,6 +36,24 @@ StringRef llvm::omp::getOpenMPDirectiveName(Directive Kind) { llvm_unreachable("Invalid OpenMP directive kind"); } +Clause llvm::omp::getOpenMPClauseKind(StringRef Str) { + return llvm::StringSwitch(Str) +#define OMP_CLAUSE(Enum, Str, Implicit) \ + .Case(Str, Implicit ? OMPC_unknown : Enum) +#include "llvm/Frontend/OpenMP/OMPKinds.def" + .Default(OMPC_unknown); +} + +StringRef llvm::omp::getOpenMPClauseName(Clause C) { + switch (C) { +#define OMP_CLAUSE(Enum, Str, ...) \ + case Enum: \ + return Str; +#include "llvm/Frontend/OpenMP/OMPKinds.def" + } + llvm_unreachable("Invalid OpenMP clause kind"); +} + /// Declarations for LLVM-IR types (simple, array, function and structure) are /// generated below. Their names are defined and used in OpenMPKinds.def. Here /// we provide the declarations, the initializeTypes function will provide the From cfe-commits at lists.llvm.org Thu Apr 2 00:25:33 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via cfe-commits) Date: Thu, 02 Apr 2020 00:25:33 -0700 (PDT) Subject: [clang] 1858f4b - Revert "[OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP`" Message-ID: <5e85936d.1c69fb81.360e2.e8cc@mx.google.com> Author: Johannes Doerfert Date: 2020-04-02T02:23:22-05:00 New Revision: 1858f4b50dd35c28b377ba5dbc572fed43a5d38a URL: https://github.com/llvm/llvm-project/commit/1858f4b50dd35c28b377ba5dbc572fed43a5d38a DIFF: https://github.com/llvm/llvm-project/commit/1858f4b50dd35c28b377ba5dbc572fed43a5d38a.diff LOG: Revert "[OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP`" This reverts commit c18d55998b3352e6ec92ccb8a3240a16a57c61e6. Bots have reported uses that need changing, e.g., clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cp as reported by http://lab.llvm.org:8011/builders/clang-ppc64be-linux/builds/46591 Added: Modified: clang/include/clang/AST/ASTFwd.h clang/include/clang/AST/ASTTypeTraits.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/Basic/Attr.td clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Basic/OpenMPKinds.h clang/lib/AST/ASTTypeTraits.cpp clang/lib/AST/AttrImpl.cpp clang/lib/AST/OpenMPClause.cpp clang/lib/AST/StmtProfile.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/ASTMatchers/CMakeLists.txt clang/lib/ASTMatchers/Dynamic/Marshallers.h clang/lib/Analysis/CMakeLists.txt clang/lib/Basic/OpenMPKinds.cpp clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt clang/lib/StaticAnalyzer/Core/CMakeLists.txt clang/tools/libclang/CIndex.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp llvm/include/llvm/Frontend/OpenMP/OMPConstants.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPConstants.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/ASTFwd.h b/clang/include/clang/AST/ASTFwd.h index 65319a19728b..5a891817b336 100644 --- a/clang/include/clang/AST/ASTFwd.h +++ b/clang/include/clang/AST/ASTFwd.h @@ -27,8 +27,8 @@ class Type; #include "clang/AST/TypeNodes.inc" class CXXCtorInitializer; class OMPClause; -#define OMP_CLAUSE_CLASS(Enum, Str, Class) class Class; -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#define OPENMP_CLAUSE(KIND, CLASSNAME) class CLASSNAME; +#include "clang/Basic/OpenMPKinds.def" } // end namespace clang diff --git a/clang/include/clang/AST/ASTTypeTraits.h b/clang/include/clang/AST/ASTTypeTraits.h index cd80e9bc3808..a9c2e334a29e 100644 --- a/clang/include/clang/AST/ASTTypeTraits.h +++ b/clang/include/clang/AST/ASTTypeTraits.h @@ -148,8 +148,8 @@ class ASTNodeKind { #define TYPE(DERIVED, BASE) NKI_##DERIVED##Type, #include "clang/AST/TypeNodes.inc" NKI_OMPClause, -#define OMP_CLAUSE_CLASS(Enum, Str, Class) NKI_##Class, -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#define OPENMP_CLAUSE(TextualSpelling, Class) NKI_##Class, +#include "clang/Basic/OpenMPKinds.def" NKI_NumberOfKinds }; @@ -204,8 +204,8 @@ KIND_TO_KIND_ID(OMPClause) #include "clang/AST/StmtNodes.inc" #define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type) #include "clang/AST/TypeNodes.inc" -#define OMP_CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class) -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#define OPENMP_CLAUSE(TextualSpelling, Class) KIND_TO_KIND_ID(Class) +#include "clang/Basic/OpenMPKinds.def" #undef KIND_TO_KIND_ID inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) { diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 7718c2707474..0d4b69911f19 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -285,13 +285,12 @@ class OMPAllocatorClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_allocator, StartLoc, EndLoc), - LParenLoc(LParenLoc), Allocator(A) {} + : OMPClause(OMPC_allocator, StartLoc, EndLoc), LParenLoc(LParenLoc), + Allocator(A) {} /// Build an empty clause. OMPAllocatorClause() - : OMPClause(llvm::omp::OMPC_allocator, SourceLocation(), - SourceLocation()) {} + : OMPClause(OMPC_allocator, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -316,7 +315,7 @@ class OMPAllocatorClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_allocator; + return T->getClauseKind() == OMPC_allocator; } }; @@ -351,17 +350,17 @@ class OMPAllocateClause final OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc, Expr *Allocator, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(llvm::omp::OMPC_allocate, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(OMPC_allocate, StartLoc, LParenLoc, + EndLoc, N), Allocator(Allocator), ColonLoc(ColonLoc) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPAllocateClause(unsigned N) - : OMPVarListClause(llvm::omp::OMPC_allocate, + : OMPVarListClause(OMPC_allocate, SourceLocation(), SourceLocation(), SourceLocation(), - SourceLocation(), N) {} + N) {} /// Sets location of ':' symbol in clause. void setColonLoc(SourceLocation CL) { ColonLoc = CL; } @@ -413,7 +412,7 @@ class OMPAllocateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_allocate; + return T->getClauseKind() == OMPC_allocate; } }; @@ -471,16 +470,15 @@ class OMPIfClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_if, StartLoc, EndLoc), - OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond), - ColonLoc(ColonLoc), NameModifier(NameModifier), - NameModifierLoc(NameModifierLoc) { + : OMPClause(OMPC_if, StartLoc, EndLoc), OMPClauseWithPreInit(this), + LParenLoc(LParenLoc), Condition(Cond), ColonLoc(ColonLoc), + NameModifier(NameModifier), NameModifierLoc(NameModifierLoc) { setPreInitStmt(HelperCond, CaptureRegion); } /// Build an empty clause. OMPIfClause() - : OMPClause(llvm::omp::OMPC_if, SourceLocation(), SourceLocation()), + : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -514,7 +512,7 @@ class OMPIfClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_if; + return T->getClauseKind() == OMPC_if; } }; @@ -550,14 +548,14 @@ class OMPFinalClause : public OMPClause, public OMPClauseWithPreInit { OMPFinalClause(Expr *Cond, Stmt *HelperCond, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_final, StartLoc, EndLoc), - OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) { + : OMPClause(OMPC_final, StartLoc, EndLoc), OMPClauseWithPreInit(this), + LParenLoc(LParenLoc), Condition(Cond) { setPreInitStmt(HelperCond, CaptureRegion); } /// Build an empty clause. OMPFinalClause() - : OMPClause(llvm::omp::OMPC_final, SourceLocation(), SourceLocation()), + : OMPClause(OMPC_final, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -582,7 +580,7 @@ class OMPFinalClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_final; + return T->getClauseKind() == OMPC_final; } }; @@ -620,7 +618,7 @@ class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_num_threads, StartLoc, EndLoc), + : OMPClause(OMPC_num_threads, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumThreads(NumThreads) { setPreInitStmt(HelperNumThreads, CaptureRegion); @@ -628,8 +626,7 @@ class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit { /// Build an empty clause. OMPNumThreadsClause() - : OMPClause(llvm::omp::OMPC_num_threads, SourceLocation(), - SourceLocation()), + : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -655,7 +652,7 @@ class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_num_threads; + return T->getClauseKind() == OMPC_num_threads; } }; @@ -691,13 +688,12 @@ class OMPSafelenClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_safelen, StartLoc, EndLoc), - LParenLoc(LParenLoc), Safelen(Len) {} + : OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc), + Safelen(Len) {} /// Build an empty clause. explicit OMPSafelenClause() - : OMPClause(llvm::omp::OMPC_safelen, SourceLocation(), SourceLocation()) { - } + : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -722,7 +718,7 @@ class OMPSafelenClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_safelen; + return T->getClauseKind() == OMPC_safelen; } }; @@ -757,13 +753,12 @@ class OMPSimdlenClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_simdlen, StartLoc, EndLoc), - LParenLoc(LParenLoc), Simdlen(Len) {} + : OMPClause(OMPC_simdlen, StartLoc, EndLoc), LParenLoc(LParenLoc), + Simdlen(Len) {} /// Build an empty clause. explicit OMPSimdlenClause() - : OMPClause(llvm::omp::OMPC_simdlen, SourceLocation(), SourceLocation()) { - } + : OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -788,7 +783,7 @@ class OMPSimdlenClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_simdlen; + return T->getClauseKind() == OMPC_simdlen; } }; @@ -824,13 +819,12 @@ class OMPCollapseClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPCollapseClause(Expr *Num, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_collapse, StartLoc, EndLoc), - LParenLoc(LParenLoc), NumForLoops(Num) {} + : OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc), + NumForLoops(Num) {} /// Build an empty clause. explicit OMPCollapseClause() - : OMPClause(llvm::omp::OMPC_collapse, SourceLocation(), - SourceLocation()) {} + : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -855,7 +849,7 @@ class OMPCollapseClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_collapse; + return T->getClauseKind() == OMPC_collapse; } }; @@ -899,13 +893,12 @@ class OMPDefaultClause : public OMPClause { OMPDefaultClause(llvm::omp::DefaultKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_default, StartLoc, EndLoc), - LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} + : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc), + Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPDefaultClause() - : OMPClause(llvm::omp::OMPC_default, SourceLocation(), SourceLocation()) { - } + : OMPClause(OMPC_default, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -935,7 +928,7 @@ class OMPDefaultClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_default; + return T->getClauseKind() == OMPC_default; } }; @@ -981,13 +974,12 @@ class OMPProcBindClause : public OMPClause { OMPProcBindClause(llvm::omp::ProcBindKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_proc_bind, StartLoc, EndLoc), - LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} + : OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc), + Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPProcBindClause() - : OMPClause(llvm::omp::OMPC_proc_bind, SourceLocation(), - SourceLocation()) {} + : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -1017,7 +1009,7 @@ class OMPProcBindClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_proc_bind; + return T->getClauseKind() == OMPC_proc_bind; } }; @@ -1037,12 +1029,11 @@ class OMPUnifiedAddressClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_unified_address, StartLoc, EndLoc) {} + : OMPClause(OMPC_unified_address, StartLoc, EndLoc) {} /// Build an empty clause. OMPUnifiedAddressClause() - : OMPClause(llvm::omp::OMPC_unified_address, SourceLocation(), - SourceLocation()) {} + : OMPClause(OMPC_unified_address, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1060,7 +1051,7 @@ class OMPUnifiedAddressClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_unified_address; + return T->getClauseKind() == OMPC_unified_address; } }; @@ -1080,12 +1071,11 @@ class OMPUnifiedSharedMemoryClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_unified_shared_memory, StartLoc, EndLoc) {} + : OMPClause(OMPC_unified_shared_memory, StartLoc, EndLoc) {} /// Build an empty clause. OMPUnifiedSharedMemoryClause() - : OMPClause(llvm::omp::OMPC_unified_shared_memory, SourceLocation(), - SourceLocation()) {} + : OMPClause(OMPC_unified_shared_memory, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1103,7 +1093,7 @@ class OMPUnifiedSharedMemoryClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_unified_shared_memory; + return T->getClauseKind() == OMPC_unified_shared_memory; } }; @@ -1123,12 +1113,11 @@ class OMPReverseOffloadClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_reverse_offload, StartLoc, EndLoc) {} + : OMPClause(OMPC_reverse_offload, StartLoc, EndLoc) {} /// Build an empty clause. OMPReverseOffloadClause() - : OMPClause(llvm::omp::OMPC_reverse_offload, SourceLocation(), - SourceLocation()) {} + : OMPClause(OMPC_reverse_offload, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1146,7 +1135,7 @@ class OMPReverseOffloadClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_reverse_offload; + return T->getClauseKind() == OMPC_reverse_offload; } }; @@ -1166,12 +1155,12 @@ class OMPDynamicAllocatorsClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_dynamic_allocators, StartLoc, EndLoc) {} + : OMPClause(OMPC_dynamic_allocators, StartLoc, EndLoc) {} /// Build an empty clause. OMPDynamicAllocatorsClause() - : OMPClause(llvm::omp::OMPC_dynamic_allocators, SourceLocation(), - SourceLocation()) {} + : OMPClause(OMPC_dynamic_allocators, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1189,7 +1178,7 @@ class OMPDynamicAllocatorsClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_dynamic_allocators; + return T->getClauseKind() == OMPC_dynamic_allocators; } }; @@ -1241,12 +1230,12 @@ class OMPAtomicDefaultMemOrderClause final : public OMPClause { SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, StartLoc, EndLoc), + : OMPClause(OMPC_atomic_default_mem_order, StartLoc, EndLoc), LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPAtomicDefaultMemOrderClause() - : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, SourceLocation(), + : OMPClause(OMPC_atomic_default_mem_order, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. @@ -1279,7 +1268,7 @@ class OMPAtomicDefaultMemOrderClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_atomic_default_mem_order; + return T->getClauseKind() == OMPC_atomic_default_mem_order; } }; @@ -1398,9 +1387,9 @@ class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { Expr *ChunkSize, Stmt *HelperChunkSize, OpenMPScheduleClauseModifier M1, SourceLocation M1Loc, OpenMPScheduleClauseModifier M2, SourceLocation M2Loc) - : OMPClause(llvm::omp::OMPC_schedule, StartLoc, EndLoc), - OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), - KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { + : OMPClause(OMPC_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this), + LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), + ChunkSize(ChunkSize) { setPreInitStmt(HelperChunkSize); Modifiers[FIRST] = M1; Modifiers[SECOND] = M2; @@ -1410,7 +1399,7 @@ class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { /// Build an empty clause. explicit OMPScheduleClause() - : OMPClause(llvm::omp::OMPC_schedule, SourceLocation(), SourceLocation()), + : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) { Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown; Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown; @@ -1472,7 +1461,7 @@ class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_schedule; + return T->getClauseKind() == OMPC_schedule; } }; @@ -1507,12 +1496,12 @@ class OMPOrderedClause final /// \param EndLoc Ending location of the clause. OMPOrderedClause(Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_ordered, StartLoc, EndLoc), - LParenLoc(LParenLoc), NumForLoops(Num), NumberOfLoops(NumLoops) {} + : OMPClause(OMPC_ordered, StartLoc, EndLoc), LParenLoc(LParenLoc), + NumForLoops(Num), NumberOfLoops(NumLoops) {} /// Build an empty clause. explicit OMPOrderedClause(unsigned NumLoops) - : OMPClause(llvm::omp::OMPC_ordered, SourceLocation(), SourceLocation()), + : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()), NumberOfLoops(NumLoops) {} /// Set the number of associated for-loops. @@ -1568,7 +1557,7 @@ class OMPOrderedClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_ordered; + return T->getClauseKind() == OMPC_ordered; } }; @@ -1585,11 +1574,11 @@ class OMPNowaitClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_nowait, StartLoc, EndLoc) {} + : OMPClause(OMPC_nowait, StartLoc, EndLoc) {} /// Build an empty clause. OMPNowaitClause() - : OMPClause(llvm::omp::OMPC_nowait, SourceLocation(), SourceLocation()) {} + : OMPClause(OMPC_nowait, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1607,7 +1596,7 @@ class OMPNowaitClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_nowait; + return T->getClauseKind() == OMPC_nowait; } }; @@ -1624,11 +1613,11 @@ class OMPUntiedClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_untied, StartLoc, EndLoc) {} + : OMPClause(OMPC_untied, StartLoc, EndLoc) {} /// Build an empty clause. OMPUntiedClause() - : OMPClause(llvm::omp::OMPC_untied, SourceLocation(), SourceLocation()) {} + : OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1646,7 +1635,7 @@ class OMPUntiedClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_untied; + return T->getClauseKind() == OMPC_untied; } }; @@ -1664,12 +1653,11 @@ class OMPMergeableClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_mergeable, StartLoc, EndLoc) {} + : OMPClause(OMPC_mergeable, StartLoc, EndLoc) {} /// Build an empty clause. OMPMergeableClause() - : OMPClause(llvm::omp::OMPC_mergeable, SourceLocation(), - SourceLocation()) {} + : OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1687,7 +1675,7 @@ class OMPMergeableClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_mergeable; + return T->getClauseKind() == OMPC_mergeable; } }; @@ -1704,11 +1692,10 @@ class OMPReadClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_read, StartLoc, EndLoc) {} + : OMPClause(OMPC_read, StartLoc, EndLoc) {} /// Build an empty clause. - OMPReadClause() - : OMPClause(llvm::omp::OMPC_read, SourceLocation(), SourceLocation()) {} + OMPReadClause() : OMPClause(OMPC_read, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1726,7 +1713,7 @@ class OMPReadClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_read; + return T->getClauseKind() == OMPC_read; } }; @@ -1743,11 +1730,11 @@ class OMPWriteClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_write, StartLoc, EndLoc) {} + : OMPClause(OMPC_write, StartLoc, EndLoc) {} /// Build an empty clause. OMPWriteClause() - : OMPClause(llvm::omp::OMPC_write, SourceLocation(), SourceLocation()) {} + : OMPClause(OMPC_write, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1765,7 +1752,7 @@ class OMPWriteClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_write; + return T->getClauseKind() == OMPC_write; } }; @@ -1825,12 +1812,11 @@ class OMPUpdateClause final /// \param EndLoc Ending location of the clause. OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc, bool IsExtended) - : OMPClause(llvm::omp::OMPC_update, StartLoc, EndLoc), - IsExtended(IsExtended) {} + : OMPClause(OMPC_update, StartLoc, EndLoc), IsExtended(IsExtended) {} /// Build an empty clause. OMPUpdateClause(bool IsExtended) - : OMPClause(llvm::omp::OMPC_update, SourceLocation(), SourceLocation()), + : OMPClause(OMPC_update, SourceLocation(), SourceLocation()), IsExtended(IsExtended) {} public: @@ -1900,7 +1886,7 @@ class OMPUpdateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_update; + return T->getClauseKind() == OMPC_update; } }; @@ -1918,12 +1904,11 @@ class OMPCaptureClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_capture, StartLoc, EndLoc) {} + : OMPClause(OMPC_capture, StartLoc, EndLoc) {} /// Build an empty clause. OMPCaptureClause() - : OMPClause(llvm::omp::OMPC_capture, SourceLocation(), SourceLocation()) { - } + : OMPClause(OMPC_capture, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1941,7 +1926,7 @@ class OMPCaptureClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_capture; + return T->getClauseKind() == OMPC_capture; } }; @@ -1959,12 +1944,11 @@ class OMPSeqCstClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_seq_cst, StartLoc, EndLoc) {} + : OMPClause(OMPC_seq_cst, StartLoc, EndLoc) {} /// Build an empty clause. OMPSeqCstClause() - : OMPClause(llvm::omp::OMPC_seq_cst, SourceLocation(), SourceLocation()) { - } + : OMPClause(OMPC_seq_cst, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1982,7 +1966,7 @@ class OMPSeqCstClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_seq_cst; + return T->getClauseKind() == OMPC_seq_cst; } }; @@ -2000,12 +1984,11 @@ class OMPAcqRelClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_acq_rel, StartLoc, EndLoc) {} + : OMPClause(OMPC_acq_rel, StartLoc, EndLoc) {} /// Build an empty clause. OMPAcqRelClause() - : OMPClause(llvm::omp::OMPC_acq_rel, SourceLocation(), SourceLocation()) { - } + : OMPClause(OMPC_acq_rel, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2023,7 +2006,7 @@ class OMPAcqRelClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_acq_rel; + return T->getClauseKind() == OMPC_acq_rel; } }; @@ -2041,12 +2024,11 @@ class OMPAcquireClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_acquire, StartLoc, EndLoc) {} + : OMPClause(OMPC_acquire, StartLoc, EndLoc) {} /// Build an empty clause. OMPAcquireClause() - : OMPClause(llvm::omp::OMPC_acquire, SourceLocation(), SourceLocation()) { - } + : OMPClause(OMPC_acquire, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2064,7 +2046,7 @@ class OMPAcquireClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_acquire; + return T->getClauseKind() == OMPC_acquire; } }; @@ -2082,12 +2064,11 @@ class OMPReleaseClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReleaseClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_release, StartLoc, EndLoc) {} + : OMPClause(OMPC_release, StartLoc, EndLoc) {} /// Build an empty clause. OMPReleaseClause() - : OMPClause(llvm::omp::OMPC_release, SourceLocation(), SourceLocation()) { - } + : OMPClause(OMPC_release, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2105,7 +2086,7 @@ class OMPReleaseClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_release; + return T->getClauseKind() == OMPC_release; } }; @@ -2123,12 +2104,11 @@ class OMPRelaxedClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_relaxed, StartLoc, EndLoc) {} + : OMPClause(OMPC_relaxed, StartLoc, EndLoc) {} /// Build an empty clause. OMPRelaxedClause() - : OMPClause(llvm::omp::OMPC_relaxed, SourceLocation(), SourceLocation()) { - } + : OMPClause(OMPC_relaxed, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2146,7 +2126,7 @@ class OMPRelaxedClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_relaxed; + return T->getClauseKind() == OMPC_relaxed; } }; @@ -2172,16 +2152,16 @@ class OMPPrivateClause final /// \param N Number of the variables in the clause. OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(llvm::omp::OMPC_private, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(OMPC_private, StartLoc, LParenLoc, + EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPPrivateClause(unsigned N) - : OMPVarListClause(llvm::omp::OMPC_private, + : OMPVarListClause(OMPC_private, SourceLocation(), SourceLocation(), SourceLocation(), - SourceLocation(), N) {} + N) {} /// Sets the list of references to private copies with initializers for /// new private variables. @@ -2251,7 +2231,7 @@ class OMPPrivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_private; + return T->getClauseKind() == OMPC_private; } }; @@ -2279,8 +2259,8 @@ class OMPFirstprivateClause final /// \param N Number of the variables in the clause. OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(llvm::omp::OMPC_firstprivate, - StartLoc, LParenLoc, EndLoc, N), + : OMPVarListClause(OMPC_firstprivate, StartLoc, + LParenLoc, EndLoc, N), OMPClauseWithPreInit(this) {} /// Build an empty clause. @@ -2288,7 +2268,7 @@ class OMPFirstprivateClause final /// \param N Number of variables. explicit OMPFirstprivateClause(unsigned N) : OMPVarListClause( - llvm::omp::OMPC_firstprivate, SourceLocation(), SourceLocation(), + OMPC_firstprivate, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPreInit(this) {} @@ -2392,7 +2372,7 @@ class OMPFirstprivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_firstprivate; + return T->getClauseKind() == OMPC_firstprivate; } }; @@ -2445,8 +2425,8 @@ class OMPLastprivateClause final SourceLocation EndLoc, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, unsigned N) - : OMPVarListClause(llvm::omp::OMPC_lastprivate, - StartLoc, LParenLoc, EndLoc, N), + : OMPVarListClause(OMPC_lastprivate, StartLoc, + LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), LPKind(LPKind), LPKindLoc(LPKindLoc), ColonLoc(ColonLoc) {} @@ -2455,7 +2435,7 @@ class OMPLastprivateClause final /// \param N Number of variables. explicit OMPLastprivateClause(unsigned N) : OMPVarListClause( - llvm::omp::OMPC_lastprivate, SourceLocation(), SourceLocation(), + OMPC_lastprivate, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -2631,7 +2611,7 @@ class OMPLastprivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_lastprivate; + return T->getClauseKind() == OMPC_lastprivate; } }; @@ -2656,16 +2636,16 @@ class OMPSharedClause final /// \param N Number of the variables in the clause. OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(llvm::omp::OMPC_shared, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(OMPC_shared, StartLoc, LParenLoc, + EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPSharedClause(unsigned N) - : OMPVarListClause(llvm::omp::OMPC_shared, + : OMPVarListClause(OMPC_shared, SourceLocation(), SourceLocation(), SourceLocation(), - SourceLocation(), N) {} + N) {} public: /// Creates clause with a list of variables \a VL. @@ -2703,7 +2683,7 @@ class OMPSharedClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_shared; + return T->getClauseKind() == OMPC_shared; } }; @@ -2754,8 +2734,8 @@ class OMPReductionClause final OpenMPReductionClauseModifier Modifier, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause(llvm::omp::OMPC_reduction, - StartLoc, LParenLoc, EndLoc, N), + : OMPVarListClause(OMPC_reduction, StartLoc, + LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -2764,9 +2744,9 @@ class OMPReductionClause final /// /// \param N Number of variables. explicit OMPReductionClause(unsigned N) - : OMPVarListClause(llvm::omp::OMPC_reduction, + : OMPVarListClause(OMPC_reduction, SourceLocation(), SourceLocation(), SourceLocation(), - SourceLocation(), N), + N), OMPClauseWithPostUpdate(this) {} /// Sets reduction modifier. @@ -2963,7 +2943,7 @@ class OMPReductionClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_reduction; + return T->getClauseKind() == OMPC_reduction; } }; @@ -3005,8 +2985,8 @@ class OMPTaskReductionClause final SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause( - llvm::omp::OMPC_task_reduction, StartLoc, LParenLoc, EndLoc, N), + : OMPVarListClause(OMPC_task_reduction, StartLoc, + LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -3015,7 +2995,7 @@ class OMPTaskReductionClause final /// \param N Number of variables. explicit OMPTaskReductionClause(unsigned N) : OMPVarListClause( - llvm::omp::OMPC_task_reduction, SourceLocation(), SourceLocation(), + OMPC_task_reduction, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -3195,7 +3175,7 @@ class OMPTaskReductionClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_task_reduction; + return T->getClauseKind() == OMPC_task_reduction; } }; @@ -3236,8 +3216,8 @@ class OMPInReductionClause final SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause(llvm::omp::OMPC_in_reduction, - StartLoc, LParenLoc, EndLoc, N), + : OMPVarListClause(OMPC_in_reduction, StartLoc, + LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -3246,7 +3226,7 @@ class OMPInReductionClause final /// \param N Number of variables. explicit OMPInReductionClause(unsigned N) : OMPVarListClause( - llvm::omp::OMPC_in_reduction, SourceLocation(), SourceLocation(), + OMPC_in_reduction, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -3450,7 +3430,7 @@ class OMPInReductionClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_in_reduction; + return T->getClauseKind() == OMPC_in_reduction; } }; @@ -3496,8 +3476,8 @@ class OMPLinearClause final OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned NumVars) - : OMPVarListClause(llvm::omp::OMPC_linear, StartLoc, - LParenLoc, EndLoc, NumVars), + : OMPVarListClause(OMPC_linear, StartLoc, LParenLoc, + EndLoc, NumVars), OMPClauseWithPostUpdate(this), Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {} @@ -3505,9 +3485,9 @@ class OMPLinearClause final /// /// \param NumVars Number of variables. explicit OMPLinearClause(unsigned NumVars) - : OMPVarListClause(llvm::omp::OMPC_linear, + : OMPVarListClause(OMPC_linear, SourceLocation(), SourceLocation(), SourceLocation(), - SourceLocation(), NumVars), + NumVars), OMPClauseWithPostUpdate(this) {} /// Gets the list of initial values for linear variables. @@ -3727,7 +3707,7 @@ class OMPLinearClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_linear; + return T->getClauseKind() == OMPC_linear; } }; @@ -3762,17 +3742,17 @@ class OMPAlignedClause final OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned NumVars) - : OMPVarListClause(llvm::omp::OMPC_aligned, StartLoc, - LParenLoc, EndLoc, NumVars), + : OMPVarListClause(OMPC_aligned, StartLoc, LParenLoc, + EndLoc, NumVars), ColonLoc(ColonLoc) {} /// Build an empty clause. /// /// \param NumVars Number of variables. explicit OMPAlignedClause(unsigned NumVars) - : OMPVarListClause(llvm::omp::OMPC_aligned, + : OMPVarListClause(OMPC_aligned, SourceLocation(), SourceLocation(), SourceLocation(), - SourceLocation(), NumVars) {} + NumVars) {} public: /// Creates clause with a list of variables \a VL and alignment \a A. @@ -3826,7 +3806,7 @@ class OMPAlignedClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_aligned; + return T->getClauseKind() == OMPC_aligned; } }; @@ -3865,16 +3845,16 @@ class OMPCopyinClause final /// \param N Number of the variables in the clause. OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(llvm::omp::OMPC_copyin, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(OMPC_copyin, StartLoc, LParenLoc, + EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPCopyinClause(unsigned N) - : OMPVarListClause(llvm::omp::OMPC_copyin, + : OMPVarListClause(OMPC_copyin, SourceLocation(), SourceLocation(), SourceLocation(), - SourceLocation(), N) {} + N) {} /// Set list of helper expressions, required for proper codegen of the /// clause. These expressions represent source expression in the final @@ -4002,7 +3982,7 @@ class OMPCopyinClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_copyin; + return T->getClauseKind() == OMPC_copyin; } }; @@ -4029,16 +4009,15 @@ class OMPCopyprivateClause final /// \param N Number of the variables in the clause. OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(llvm::omp::OMPC_copyprivate, - StartLoc, LParenLoc, EndLoc, N) { - } + : OMPVarListClause(OMPC_copyprivate, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPCopyprivateClause(unsigned N) : OMPVarListClause( - llvm::omp::OMPC_copyprivate, SourceLocation(), SourceLocation(), + OMPC_copyprivate, SourceLocation(), SourceLocation(), SourceLocation(), N) {} /// Set list of helper expressions, required for proper codegen of the @@ -4166,7 +4145,7 @@ class OMPCopyprivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_copyprivate; + return T->getClauseKind() == OMPC_copyprivate; } }; @@ -4196,16 +4175,16 @@ class OMPFlushClause final /// \param N Number of the variables in the clause. OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(llvm::omp::OMPC_flush, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(OMPC_flush, StartLoc, LParenLoc, + EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPFlushClause(unsigned N) - : OMPVarListClause(llvm::omp::OMPC_flush, + : OMPVarListClause(OMPC_flush, SourceLocation(), SourceLocation(), SourceLocation(), - SourceLocation(), N) {} + N) {} public: /// Creates clause with a list of variables \a VL. @@ -4243,7 +4222,7 @@ class OMPFlushClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_flush; + return T->getClauseKind() == OMPC_flush; } }; @@ -4275,13 +4254,12 @@ class OMPDepobjClause final : public OMPClause { /// \param EndLoc Ending location of the clause. OMPDepobjClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_depobj, StartLoc, EndLoc), - LParenLoc(LParenLoc) {} + : OMPClause(OMPC_depobj, StartLoc, EndLoc), LParenLoc(LParenLoc) {} /// Build an empty clause. /// explicit OMPDepobjClause() - : OMPClause(llvm::omp::OMPC_depobj, SourceLocation(), SourceLocation()) {} + : OMPClause(OMPC_depobj, SourceLocation(), SourceLocation()) {} void setDepobj(Expr *E) { Depobj = E; } @@ -4330,7 +4308,7 @@ class OMPDepobjClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_depobj; + return T->getClauseKind() == OMPC_depobj; } }; @@ -4371,9 +4349,8 @@ class OMPDependClause final /// clause. OMPDependClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N, unsigned NumLoops) - : OMPVarListClause(llvm::omp::OMPC_depend, StartLoc, - LParenLoc, EndLoc, N), - NumLoops(NumLoops) {} + : OMPVarListClause(OMPC_depend, StartLoc, LParenLoc, + EndLoc, N), NumLoops(NumLoops) {} /// Build an empty clause. /// @@ -4381,9 +4358,9 @@ class OMPDependClause final /// \param NumLoops Number of loops that is associated with this depend /// clause. explicit OMPDependClause(unsigned N, unsigned NumLoops) - : OMPVarListClause(llvm::omp::OMPC_depend, + : OMPVarListClause(OMPC_depend, SourceLocation(), SourceLocation(), SourceLocation(), - SourceLocation(), N), + N), NumLoops(NumLoops) {} /// Set dependency kind. @@ -4462,7 +4439,7 @@ class OMPDependClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_depend; + return T->getClauseKind() == OMPC_depend; } }; @@ -4515,15 +4492,15 @@ class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_device, StartLoc, EndLoc), - OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier), - ModifierLoc(ModifierLoc), Device(E) { + : OMPClause(OMPC_device, StartLoc, EndLoc), OMPClauseWithPreInit(this), + LParenLoc(LParenLoc), Modifier(Modifier), ModifierLoc(ModifierLoc), + Device(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPDeviceClause() - : OMPClause(llvm::omp::OMPC_device, SourceLocation(), SourceLocation()), + : OMPClause(OMPC_device, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -4558,7 +4535,7 @@ class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_device; + return T->getClauseKind() == OMPC_device; } }; @@ -4575,12 +4552,11 @@ class OMPThreadsClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_threads, StartLoc, EndLoc) {} + : OMPClause(OMPC_threads, StartLoc, EndLoc) {} /// Build an empty clause. OMPThreadsClause() - : OMPClause(llvm::omp::OMPC_threads, SourceLocation(), SourceLocation()) { - } + : OMPClause(OMPC_threads, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -4598,7 +4574,7 @@ class OMPThreadsClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_threads; + return T->getClauseKind() == OMPC_threads; } }; @@ -4615,11 +4591,10 @@ class OMPSIMDClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_simd, StartLoc, EndLoc) {} + : OMPClause(OMPC_simd, StartLoc, EndLoc) {} /// Build an empty clause. - OMPSIMDClause() - : OMPClause(llvm::omp::OMPC_simd, SourceLocation(), SourceLocation()) {} + OMPSIMDClause() : OMPClause(OMPC_simd, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -4637,7 +4612,7 @@ class OMPSIMDClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_simd; + return T->getClauseKind() == OMPC_simd; } }; @@ -5318,8 +5293,8 @@ class OMPMapClause final : public OMPMappableExprListClause, OpenMPMapClauseKind MapType, bool MapTypeIsImplicit, SourceLocation MapLoc, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(llvm::omp::OMPC_map, Locs, Sizes, - &MapperQualifierLoc, &MapperIdInfo), + : OMPMappableExprListClause(OMPC_map, Locs, Sizes, &MapperQualifierLoc, + &MapperIdInfo), MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) { assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() && "Unexpected number of map type modifiers."); @@ -5339,8 +5314,7 @@ class OMPMapClause final : public OMPMappableExprListClause, /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPMapClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(llvm::omp::OMPC_map, OMPVarListLocTy(), - Sizes) {} + : OMPMappableExprListClause(OMPC_map, OMPVarListLocTy(), Sizes) {} /// Set map-type-modifier for the clause. /// @@ -5487,7 +5461,7 @@ class OMPMapClause final : public OMPMappableExprListClause, static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_map; + return T->getClauseKind() == OMPC_map; } }; @@ -5526,15 +5500,14 @@ class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit { OMPNumTeamsClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_num_teams, StartLoc, EndLoc), - OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTeams(E) { + : OMPClause(OMPC_num_teams, StartLoc, EndLoc), OMPClauseWithPreInit(this), + LParenLoc(LParenLoc), NumTeams(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPNumTeamsClause() - : OMPClause(llvm::omp::OMPC_num_teams, SourceLocation(), - SourceLocation()), + : OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5563,7 +5536,7 @@ class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_num_teams; + return T->getClauseKind() == OMPC_num_teams; } }; @@ -5603,15 +5576,14 @@ class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_thread_limit, StartLoc, EndLoc), + : OMPClause(OMPC_thread_limit, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadLimit(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPThreadLimitClause() - : OMPClause(llvm::omp::OMPC_thread_limit, SourceLocation(), - SourceLocation()), + : OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5640,7 +5612,7 @@ class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_thread_limit; + return T->getClauseKind() == OMPC_thread_limit; } }; @@ -5679,14 +5651,14 @@ class OMPPriorityClause : public OMPClause, public OMPClauseWithPreInit { OMPPriorityClause(Expr *Priority, Stmt *HelperPriority, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_priority, StartLoc, EndLoc), - OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Priority(Priority) { + : OMPClause(OMPC_priority, StartLoc, EndLoc), OMPClauseWithPreInit(this), + LParenLoc(LParenLoc), Priority(Priority) { setPreInitStmt(HelperPriority, CaptureRegion); } /// Build an empty clause. OMPPriorityClause() - : OMPClause(llvm::omp::OMPC_priority, SourceLocation(), SourceLocation()), + : OMPClause(OMPC_priority, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5714,7 +5686,7 @@ class OMPPriorityClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_priority; + return T->getClauseKind() == OMPC_priority; } }; @@ -5750,15 +5722,14 @@ class OMPGrainsizeClause : public OMPClause, public OMPClauseWithPreInit { OMPGrainsizeClause(Expr *Size, Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_grainsize, StartLoc, EndLoc), - OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Grainsize(Size) { + : OMPClause(OMPC_grainsize, StartLoc, EndLoc), OMPClauseWithPreInit(this), + LParenLoc(LParenLoc), Grainsize(Size) { setPreInitStmt(HelperSize, CaptureRegion); } /// Build an empty clause. explicit OMPGrainsizeClause() - : OMPClause(llvm::omp::OMPC_grainsize, SourceLocation(), - SourceLocation()), + : OMPClause(OMPC_grainsize, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5783,7 +5754,7 @@ class OMPGrainsizeClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_grainsize; + return T->getClauseKind() == OMPC_grainsize; } }; @@ -5800,12 +5771,11 @@ class OMPNogroupClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_nogroup, StartLoc, EndLoc) {} + : OMPClause(OMPC_nogroup, StartLoc, EndLoc) {} /// Build an empty clause. OMPNogroupClause() - : OMPClause(llvm::omp::OMPC_nogroup, SourceLocation(), SourceLocation()) { - } + : OMPClause(OMPC_nogroup, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -5823,7 +5793,7 @@ class OMPNogroupClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_nogroup; + return T->getClauseKind() == OMPC_nogroup; } }; @@ -5859,15 +5829,14 @@ class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit { OMPNumTasksClause(Expr *Size, Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_num_tasks, StartLoc, EndLoc), - OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTasks(Size) { + : OMPClause(OMPC_num_tasks, StartLoc, EndLoc), OMPClauseWithPreInit(this), + LParenLoc(LParenLoc), NumTasks(Size) { setPreInitStmt(HelperSize, CaptureRegion); } /// Build an empty clause. explicit OMPNumTasksClause() - : OMPClause(llvm::omp::OMPC_num_tasks, SourceLocation(), - SourceLocation()), + : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5892,7 +5861,7 @@ class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_num_tasks; + return T->getClauseKind() == OMPC_num_tasks; } }; @@ -5924,12 +5893,11 @@ class OMPHintClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc), + : OMPClause(OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc), Hint(Hint) {} /// Build an empty clause. - OMPHintClause() - : OMPClause(llvm::omp::OMPC_hint, SourceLocation(), SourceLocation()) {} + OMPHintClause() : OMPClause(OMPC_hint, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -5954,7 +5922,7 @@ class OMPHintClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_hint; + return T->getClauseKind() == OMPC_hint; } }; @@ -6026,7 +5994,7 @@ class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { SourceLocation EndLoc, OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, Stmt *HelperChunkSize) - : OMPClause(llvm::omp::OMPC_dist_schedule, StartLoc, EndLoc), + : OMPClause(OMPC_dist_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { setPreInitStmt(HelperChunkSize); @@ -6034,8 +6002,7 @@ class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { /// Build an empty clause. explicit OMPDistScheduleClause() - : OMPClause(llvm::omp::OMPC_dist_schedule, SourceLocation(), - SourceLocation()), + : OMPClause(OMPC_dist_schedule, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Get kind of the clause. @@ -6074,7 +6041,7 @@ class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_dist_schedule; + return T->getClauseKind() == OMPC_dist_schedule; } }; @@ -6144,14 +6111,12 @@ class OMPDefaultmapClause : public OMPClause { SourceLocation MLoc, SourceLocation KLoc, SourceLocation EndLoc, OpenMPDefaultmapClauseKind Kind, OpenMPDefaultmapClauseModifier M) - : OMPClause(llvm::omp::OMPC_defaultmap, StartLoc, EndLoc), - LParenLoc(LParenLoc), Modifier(M), ModifierLoc(MLoc), Kind(Kind), - KindLoc(KLoc) {} + : OMPClause(OMPC_defaultmap, StartLoc, EndLoc), LParenLoc(LParenLoc), + Modifier(M), ModifierLoc(MLoc), Kind(Kind), KindLoc(KLoc) {} /// Build an empty clause. explicit OMPDefaultmapClause() - : OMPClause(llvm::omp::OMPC_defaultmap, SourceLocation(), - SourceLocation()) {} + : OMPClause(OMPC_defaultmap, SourceLocation(), SourceLocation()) {} /// Get kind of the clause. OpenMPDefaultmapClauseKind getDefaultmapKind() const { return Kind; } @@ -6188,7 +6153,7 @@ class OMPDefaultmapClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_defaultmap; + return T->getClauseKind() == OMPC_defaultmap; } }; @@ -6226,8 +6191,8 @@ class OMPToClause final : public OMPMappableExprListClause, DeclarationNameInfo MapperIdInfo, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(llvm::omp::OMPC_to, Locs, Sizes, - &MapperQualifierLoc, &MapperIdInfo) {} + : OMPMappableExprListClause(OMPC_to, Locs, Sizes, &MapperQualifierLoc, + &MapperIdInfo) {} /// Build an empty clause. /// @@ -6237,8 +6202,7 @@ class OMPToClause final : public OMPMappableExprListClause, /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPToClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(llvm::omp::OMPC_to, OMPVarListLocTy(), - Sizes) {} + : OMPMappableExprListClause(OMPC_to, OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6306,7 +6270,7 @@ class OMPToClause final : public OMPMappableExprListClause, } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_to; + return T->getClauseKind() == OMPC_to; } }; @@ -6345,8 +6309,8 @@ class OMPFromClause final DeclarationNameInfo MapperIdInfo, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(llvm::omp::OMPC_from, Locs, Sizes, - &MapperQualifierLoc, &MapperIdInfo) {} + : OMPMappableExprListClause(OMPC_from, Locs, Sizes, &MapperQualifierLoc, + &MapperIdInfo) {} /// Build an empty clause. /// @@ -6356,8 +6320,7 @@ class OMPFromClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPFromClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(llvm::omp::OMPC_from, OMPVarListLocTy(), - Sizes) {} + : OMPMappableExprListClause(OMPC_from, OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6425,7 +6388,7 @@ class OMPFromClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_from; + return T->getClauseKind() == OMPC_from; } }; @@ -6459,8 +6422,7 @@ class OMPUseDevicePtrClause final /// NumComponents: total number of expression components in the clause. explicit OMPUseDevicePtrClause(const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, Locs, Sizes) { - } + : OMPMappableExprListClause(OMPC_use_device_ptr, Locs, Sizes) {} /// Build an empty clause. /// @@ -6470,8 +6432,8 @@ class OMPUseDevicePtrClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPUseDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, - OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(OMPC_use_device_ptr, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6589,7 +6551,7 @@ class OMPUseDevicePtrClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_use_device_ptr; + return T->getClauseKind() == OMPC_use_device_ptr; } }; @@ -6623,7 +6585,7 @@ class OMPIsDevicePtrClause final /// NumComponents: total number of expression components in the clause. explicit OMPIsDevicePtrClause(const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, Locs, Sizes) {} + : OMPMappableExprListClause(OMPC_is_device_ptr, Locs, Sizes) {} /// Build an empty clause. /// @@ -6633,8 +6595,8 @@ class OMPIsDevicePtrClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPIsDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, - OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(OMPC_is_device_ptr, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6692,7 +6654,7 @@ class OMPIsDevicePtrClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_is_device_ptr; + return T->getClauseKind() == OMPC_is_device_ptr; } }; @@ -6718,16 +6680,15 @@ class OMPNontemporalClause final /// \param N Number of the variables in the clause. OMPNontemporalClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(llvm::omp::OMPC_nontemporal, - StartLoc, LParenLoc, EndLoc, N) { - } + : OMPVarListClause(OMPC_nontemporal, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPNontemporalClause(unsigned N) : OMPVarListClause( - llvm::omp::OMPC_nontemporal, SourceLocation(), SourceLocation(), + OMPC_nontemporal, SourceLocation(), SourceLocation(), SourceLocation(), N) {} /// Get the list of privatied copies if the member expression was captured by @@ -6789,7 +6750,7 @@ class OMPNontemporalClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_nontemporal; + return T->getClauseKind() == OMPC_nontemporal; } }; @@ -6833,12 +6794,12 @@ class OMPOrderClause final : public OMPClause { OMPOrderClause(OpenMPOrderClauseKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_order, StartLoc, EndLoc), - LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} + : OMPClause(OMPC_order, StartLoc, EndLoc), LParenLoc(LParenLoc), Kind(A), + KindKwLoc(ALoc) {} /// Build an empty clause. OMPOrderClause() - : OMPClause(llvm::omp::OMPC_order, SourceLocation(), SourceLocation()) {} + : OMPClause(OMPC_order, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -6868,7 +6829,7 @@ class OMPOrderClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_order; + return T->getClauseKind() == OMPC_order; } }; @@ -6886,12 +6847,11 @@ class OMPDestroyClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPDestroyClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_destroy, StartLoc, EndLoc) {} + : OMPClause(OMPC_destroy, StartLoc, EndLoc) {} /// Build an empty clause. OMPDestroyClause() - : OMPClause(llvm::omp::OMPC_destroy, SourceLocation(), SourceLocation()) { - } + : OMPClause(OMPC_destroy, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -6909,7 +6869,7 @@ class OMPDestroyClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_destroy; + return T->getClauseKind() == OMPC_destroy; } }; @@ -6944,12 +6904,12 @@ class OMPDetachClause final : public OMPClause { /// \param EndLoc Ending location of the clause. OMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(llvm::omp::OMPC_detach, StartLoc, EndLoc), - LParenLoc(LParenLoc), Evt(Evt) {} + : OMPClause(OMPC_detach, StartLoc, EndLoc), LParenLoc(LParenLoc), + Evt(Evt) {} /// Build an empty clause. OMPDetachClause() - : OMPClause(llvm::omp::OMPC_detach, SourceLocation(), SourceLocation()) {} + : OMPClause(OMPC_detach, SourceLocation(), SourceLocation()) {} /// Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } @@ -6971,7 +6931,7 @@ class OMPDetachClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_detach; + return T->getClauseKind() == OMPC_detach; } }; @@ -6997,16 +6957,16 @@ class OMPInclusiveClause final /// \param N Number of the variables in the clause. OMPInclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(llvm::omp::OMPC_inclusive, - StartLoc, LParenLoc, EndLoc, N) {} + : OMPVarListClause(OMPC_inclusive, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPInclusiveClause(unsigned N) - : OMPVarListClause(llvm::omp::OMPC_inclusive, + : OMPVarListClause(OMPC_inclusive, SourceLocation(), SourceLocation(), SourceLocation(), - SourceLocation(), N) {} + N) {} public: /// Creates clause with a list of variables \a VL. @@ -7045,7 +7005,7 @@ class OMPInclusiveClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_inclusive; + return T->getClauseKind() == OMPC_inclusive; } }; @@ -7071,16 +7031,16 @@ class OMPExclusiveClause final /// \param N Number of the variables in the clause. OMPExclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(llvm::omp::OMPC_exclusive, - StartLoc, LParenLoc, EndLoc, N) {} + : OMPVarListClause(OMPC_exclusive, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPExclusiveClause(unsigned N) - : OMPVarListClause(llvm::omp::OMPC_exclusive, + : OMPVarListClause(OMPC_exclusive, SourceLocation(), SourceLocation(), SourceLocation(), - SourceLocation(), N) {} + N) {} public: /// Creates clause with a list of variables \a VL. @@ -7119,7 +7079,7 @@ class OMPExclusiveClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == llvm::omp::OMPC_exclusive; + return T->getClauseKind() == OMPC_exclusive; } }; @@ -7132,20 +7092,17 @@ class OMPClauseVisitorBase { #define DISPATCH(CLASS) \ return static_cast(this)->Visit##CLASS(static_cast(S)) -#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ +#define OPENMP_CLAUSE(Name, Class) \ RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); } -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#include "clang/Basic/OpenMPKinds.def" RetTy Visit(PTR(OMPClause) S) { // Top switch clause: visit each OMPClause. switch (S->getClauseKind()) { -#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ - case llvm::omp::Clause::Enum: \ - return Visit##Class(static_cast(S)); -#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ - case llvm::omp::Clause::Enum: \ - break; -#include "llvm/Frontend/OpenMP/OMPKinds.def" + default: llvm_unreachable("Unknown clause kind!"); +#define OPENMP_CLAUSE(Name, Class) \ + case OMPC_ ## Name : return Visit ## Class(static_cast(S)); +#include "clang/Basic/OpenMPKinds.def" } } // Base case, ignore it. :) @@ -7174,9 +7131,8 @@ class OMPClausePrinter final : public OMPClauseVisitor { OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy) : OS(OS), Policy(Policy) {} -#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ - void Visit##Class(Class *S); -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S); +#include "clang/Basic/OpenMPKinds.def" }; /// Helper data structure representing the traits in a match clause of an diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 476e910e8888..46661e59f181 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -534,8 +534,8 @@ template class RecursiveASTVisitor { bool TraverseOMPExecutableDirective(OMPExecutableDirective *S); bool TraverseOMPLoopDirective(OMPLoopDirective *S); bool TraverseOMPClause(OMPClause *C); -#define OMP_CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C); -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C); +#include "clang/Basic/OpenMPKinds.def" /// Process clauses with list of variables. template bool VisitOMPClauseList(T *Node); /// Process clauses with pre-initis. @@ -2956,14 +2956,17 @@ bool RecursiveASTVisitor::TraverseOMPClause(OMPClause *C) { if (!C) return true; switch (C->getClauseKind()) { -#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ - case llvm::omp::Clause::Enum: \ +#define OPENMP_CLAUSE(Name, Class) \ + case OMPC_##Name: \ TRY_TO(Visit##Class(static_cast(C))); \ break; -#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ - case llvm::omp::Clause::Enum: \ +#include "clang/Basic/OpenMPKinds.def" + case OMPC_threadprivate: + case OMPC_uniform: + case OMPC_device_type: + case OMPC_match: + case OMPC_unknown: break; -#include "llvm/Frontend/OpenMP/OMPKinds.def" } return true; } diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index f55ce2cc84dd..96bfdd313f47 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3242,13 +3242,8 @@ def OMPCaptureKind : Attr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let SemaHandler = 0; - let Args = [UnsignedArgument<"CaptureKindVal">]; + let Args = [UnsignedArgument<"CaptureKind">]; let Documentation = [Undocumented]; - let AdditionalMembers = [{ - llvm::omp::Clause getCaptureKind() const { - return static_cast(getCaptureKindVal()); - } - }]; } def OMPReferencedVar : Attr { diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index 4a4e6c6cb4c3..3cf92ead9560 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -222,6 +222,74 @@ #define OPENMP_REDUCTION_MODIFIER(Name) #endif +// OpenMP clauses. +OPENMP_CLAUSE(allocator, OMPAllocatorClause) +OPENMP_CLAUSE(if, OMPIfClause) +OPENMP_CLAUSE(final, OMPFinalClause) +OPENMP_CLAUSE(num_threads, OMPNumThreadsClause) +OPENMP_CLAUSE(safelen, OMPSafelenClause) +OPENMP_CLAUSE(simdlen, OMPSimdlenClause) +OPENMP_CLAUSE(collapse, OMPCollapseClause) +OPENMP_CLAUSE(default, OMPDefaultClause) +OPENMP_CLAUSE(private, OMPPrivateClause) +OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause) +OPENMP_CLAUSE(lastprivate, OMPLastprivateClause) +OPENMP_CLAUSE(shared, OMPSharedClause) +OPENMP_CLAUSE(reduction, OMPReductionClause) +OPENMP_CLAUSE(linear, OMPLinearClause) +OPENMP_CLAUSE(aligned, OMPAlignedClause) +OPENMP_CLAUSE(copyin, OMPCopyinClause) +OPENMP_CLAUSE(copyprivate, OMPCopyprivateClause) +OPENMP_CLAUSE(proc_bind, OMPProcBindClause) +OPENMP_CLAUSE(schedule, OMPScheduleClause) +OPENMP_CLAUSE(ordered, OMPOrderedClause) +OPENMP_CLAUSE(nowait, OMPNowaitClause) +OPENMP_CLAUSE(untied, OMPUntiedClause) +OPENMP_CLAUSE(mergeable, OMPMergeableClause) +OPENMP_CLAUSE(flush, OMPFlushClause) +OPENMP_CLAUSE(read, OMPReadClause) +OPENMP_CLAUSE(write, OMPWriteClause) +OPENMP_CLAUSE(update, OMPUpdateClause) +OPENMP_CLAUSE(capture, OMPCaptureClause) +OPENMP_CLAUSE(seq_cst, OMPSeqCstClause) +OPENMP_CLAUSE(acq_rel, OMPAcqRelClause) +OPENMP_CLAUSE(acquire, OMPAcquireClause) +OPENMP_CLAUSE(release, OMPReleaseClause) +OPENMP_CLAUSE(relaxed, OMPRelaxedClause) +OPENMP_CLAUSE(depend, OMPDependClause) +OPENMP_CLAUSE(device, OMPDeviceClause) +OPENMP_CLAUSE(threads, OMPThreadsClause) +OPENMP_CLAUSE(simd, OMPSIMDClause) +OPENMP_CLAUSE(map, OMPMapClause) +OPENMP_CLAUSE(num_teams, OMPNumTeamsClause) +OPENMP_CLAUSE(thread_limit, OMPThreadLimitClause) +OPENMP_CLAUSE(priority, OMPPriorityClause) +OPENMP_CLAUSE(grainsize, OMPGrainsizeClause) +OPENMP_CLAUSE(nogroup, OMPNogroupClause) +OPENMP_CLAUSE(num_tasks, OMPNumTasksClause) +OPENMP_CLAUSE(hint, OMPHintClause) +OPENMP_CLAUSE(dist_schedule, OMPDistScheduleClause) +OPENMP_CLAUSE(defaultmap, OMPDefaultmapClause) +OPENMP_CLAUSE(to, OMPToClause) +OPENMP_CLAUSE(from, OMPFromClause) +OPENMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause) +OPENMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause) +OPENMP_CLAUSE(task_reduction, OMPTaskReductionClause) +OPENMP_CLAUSE(in_reduction, OMPInReductionClause) +OPENMP_CLAUSE(unified_address, OMPUnifiedAddressClause) +OPENMP_CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause) +OPENMP_CLAUSE(reverse_offload, OMPReverseOffloadClause) +OPENMP_CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause) +OPENMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause) +OPENMP_CLAUSE(allocate, OMPAllocateClause) +OPENMP_CLAUSE(nontemporal, OMPNontemporalClause) +OPENMP_CLAUSE(order, OMPOrderClause) +OPENMP_CLAUSE(depobj, OMPDepobjClause) +OPENMP_CLAUSE(destroy, OMPDestroyClause) +OPENMP_CLAUSE(detach, OMPDetachClause) +OPENMP_CLAUSE(inclusive, OMPInclusiveClause) +OPENMP_CLAUSE(exclusive, OMPExclusiveClause) + // Clauses allowed for OpenMP directive 'scan'. OPENMP_SCAN_CLAUSE(inclusive) OPENMP_SCAN_CLAUSE(exclusive) diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index 4064cb2757d9..b567f89b986e 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -23,7 +23,16 @@ namespace clang { using OpenMPDirectiveKind = llvm::omp::Directive; /// OpenMP clauses. -using OpenMPClauseKind = llvm::omp::Clause; +enum OpenMPClauseKind { +#define OPENMP_CLAUSE(Name, Class) \ + OMPC_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_threadprivate, + OMPC_uniform, + OMPC_device_type, + OMPC_match, + OMPC_unknown +}; /// OpenMP attributes for 'schedule' clause. enum OpenMPScheduleClauseKind { @@ -166,6 +175,9 @@ enum OpenMPReductionClauseModifier { OMPC_REDUCTION_unknown, }; +OpenMPClauseKind getOpenMPClauseKind(llvm::StringRef Str); +const char *getOpenMPClauseName(OpenMPClauseKind Kind); + unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str); const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type); diff --git a/clang/lib/AST/ASTTypeTraits.cpp b/clang/lib/AST/ASTTypeTraits.cpp index 6404edd79679..e4ea3f41af36 100644 --- a/clang/lib/AST/ASTTypeTraits.cpp +++ b/clang/lib/AST/ASTTypeTraits.cpp @@ -39,8 +39,8 @@ const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = { #define TYPE(DERIVED, BASE) { NKI_##BASE, #DERIVED "Type" }, #include "clang/AST/TypeNodes.inc" { NKI_None, "OMPClause" }, -#define OMP_CLAUSE_CLASS(Enum, Str, Class) {NKI_OMPClause, #Class}, -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#define OPENMP_CLAUSE(TextualSpelling, Class) {NKI_OMPClause, #Class}, +#include "clang/Basic/OpenMPKinds.def" }; bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const { @@ -111,13 +111,15 @@ ASTNodeKind ASTNodeKind::getFromNode(const Type &T) { ASTNodeKind ASTNodeKind::getFromNode(const OMPClause &C) { switch (C.getClauseKind()) { -#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ - case llvm::omp::Clause::Enum: \ - return ASTNodeKind(NKI_##Class); -#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ - case llvm::omp::Clause::Enum: \ +#define OPENMP_CLAUSE(Name, Class) \ + case OMPC_##Name: return ASTNodeKind(NKI_##Class); +#include "clang/Basic/OpenMPKinds.def" + case OMPC_threadprivate: + case OMPC_uniform: + case OMPC_device_type: + case OMPC_match: + case OMPC_unknown: llvm_unreachable("unexpected OpenMP clause kind"); -#include "llvm/Frontend/OpenMP/OMPKinds.def" } llvm_unreachable("invalid stmt kind"); } diff --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp index 7d3a2903bd2e..a5ff68c18778 100644 --- a/clang/lib/AST/AttrImpl.cpp +++ b/clang/lib/AST/AttrImpl.cpp @@ -108,8 +108,7 @@ void OMPDeclareSimdDeclAttr::printPrettyPragma( for (auto *E : linears()) { OS << " linear("; if (*MI != OMPC_LINEAR_unknown) - OS << getOpenMPSimpleClauseTypeName(llvm::omp::Clause::OMPC_linear, *MI) - << "("; + OS << getOpenMPSimpleClauseTypeName(OMPC_linear, *MI) << "("; E->printPretty(OS, nullptr, Policy); if (*MI != OMPC_LINEAR_unknown) OS << ")"; diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 1cd178cc27ce..4b7ebbb3c26d 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -31,20 +31,20 @@ OMPClause::child_range OMPClause::children() { switch (getClauseKind()) { default: break; -#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ - case Enum: \ +#define OPENMP_CLAUSE(Name, Class) \ + case OMPC_##Name: \ return static_cast(this)->children(); -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#include "clang/Basic/OpenMPKinds.def" } llvm_unreachable("unknown OMPClause"); } OMPClause::child_range OMPClause::used_children() { switch (getClauseKind()) { -#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ - case Enum: \ +#define OPENMP_CLAUSE(Name, Class) \ + case OMPC_##Name: \ return static_cast(this)->used_children(); -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#include "clang/Basic/OpenMPKinds.def" case OMPC_threadprivate: case OMPC_uniform: case OMPC_device_type: diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 1bb1b16418b3..054276a98424 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -414,8 +414,9 @@ class OMPClauseProfiler : public ConstOMPClauseVisitor { public: OMPClauseProfiler(StmtProfiler *P) : Profiler(P) { } -#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C); -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#define OPENMP_CLAUSE(Name, Class) \ + void Visit##Class(const Class *C); +#include "clang/Basic/OpenMPKinds.def" void VistOMPClauseWithPreInit(const OMPClauseWithPreInit *C); void VistOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C); }; diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 29e16d4ff3c2..6a6d8692228a 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -314,7 +314,7 @@ void TextNodeDumper::Visit(const OMPClause *C) { } { ColorScope Color(OS, ShowColors, AttrColor); - StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind())); + StringRef ClauseName(getOpenMPClauseName(C->getClauseKind())); OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() << ClauseName.drop_front() << "Clause"; } @@ -1517,8 +1517,7 @@ void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) { } { ColorScope Color(OS, ShowColors, AttrColor); - StringRef ClauseName( - llvm::omp::getOpenMPClauseName(C->getClauseKind())); + StringRef ClauseName(getOpenMPClauseName(C->getClauseKind())); OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() << ClauseName.drop_front() << "Clause"; } diff --git a/clang/lib/ASTMatchers/CMakeLists.txt b/clang/lib/ASTMatchers/CMakeLists.txt index cde871cd31ca..8f700ca3226b 100644 --- a/clang/lib/ASTMatchers/CMakeLists.txt +++ b/clang/lib/ASTMatchers/CMakeLists.txt @@ -1,9 +1,6 @@ add_subdirectory(Dynamic) -set(LLVM_LINK_COMPONENTS - FrontendOpenMP - Support -) +set(LLVM_LINK_COMPONENTS support) add_clang_library(clangASTMatchers ASTMatchFinder.cpp diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h index db9122acede7..48a454e3397e 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -170,8 +170,9 @@ template <> struct ArgTypeTraits { private: static Optional getClauseKind(llvm::StringRef ClauseKind) { return llvm::StringSwitch>(ClauseKind) -#define OMP_CLAUSE_CLASS(Enum, Str, Class) .Case(#Enum, llvm::omp::Clause::Enum) -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#define OPENMP_CLAUSE(TextualSpelling, Class) \ + .Case("OMPC_" #TextualSpelling, OMPC_##TextualSpelling) +#include "clang/Basic/OpenMPKinds.def" .Default(llvm::None); } diff --git a/clang/lib/Analysis/CMakeLists.txt b/clang/lib/Analysis/CMakeLists.txt index 3333eab3b96d..c1d0d6ed62c5 100644 --- a/clang/lib/Analysis/CMakeLists.txt +++ b/clang/lib/Analysis/CMakeLists.txt @@ -1,5 +1,4 @@ set(LLVM_LINK_COMPONENTS - FrontendOpenMP Support ) diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 981bd7adbe9b..7a7c66c8e587 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -20,6 +20,50 @@ using namespace clang; using namespace llvm::omp; +OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) { + // 'flush' clause cannot be specified explicitly, because this is an implicit + // clause for 'flush' directive. If the 'flush' clause is explicitly specified + // the Parser should generate a warning about extra tokens at the end of the + // directive. + // 'depobj' clause cannot be specified explicitly, because this is an implicit + // clause for 'depobj' directive. If the 'depobj' clause is explicitly + // specified the Parser should generate a warning about extra tokens at the + // end of the directive. + if (llvm::StringSwitch(Str) + .Case("flush", true) + .Case("depobj", true) + .Default(false)) + return OMPC_unknown; + return llvm::StringSwitch(Str) +#define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Case("uniform", OMPC_uniform) + .Case("device_type", OMPC_device_type) + .Case("match", OMPC_match) + .Default(OMPC_unknown); +} + +const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) { + assert(Kind <= OMPC_unknown); + switch (Kind) { + case OMPC_unknown: + return "unknown"; +#define OPENMP_CLAUSE(Name, Class) \ + case OMPC_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + case OMPC_uniform: + return "uniform"; + case OMPC_threadprivate: + return "threadprivate or thread local"; + case OMPC_device_type: + return "device_type"; + case OMPC_match: + return "match"; + } + llvm_unreachable("Invalid OpenMP clause kind"); +} + unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str) { switch (Kind) { diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp index b6db63545c2c..aa6b6bc64c32 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -341,7 +341,8 @@ class CheckVarsEscapingDeclContext final if (!Attr) return; if (((Attr->getCaptureKind() != OMPC_map) && - !isOpenMPPrivate(Attr->getCaptureKind())) || + !isOpenMPPrivate( + static_cast(Attr->getCaptureKind()))) || ((Attr->getCaptureKind() == OMPC_map) && !FD->getType()->isAnyPointerType())) return; diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index af4ea4cb06cf..147d1b271d0c 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -1387,7 +1387,7 @@ bool Parser::parseOMPDeclareVariantMatchClause(SourceLocation Loc, // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(OMPC_match).data())) { + getOpenMPClauseName(OMPC_match))) { while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch)) ; // Skip the last annot_pragma_openmp_end. @@ -1434,7 +1434,7 @@ parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind) { // Parse '('. BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(Kind).data())) + getOpenMPClauseName(Kind))) return llvm::None; unsigned Type = getOpenMPSimpleClauseType( @@ -1673,18 +1673,18 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( SmallVector Clauses; if (Tok.isNot(tok::annot_pragma_openmp_end)) { SmallVector, - unsigned(OMPC_unknown) + 1> - FirstClauses(unsigned(OMPC_unknown) + 1); + OMPC_unknown + 1> + FirstClauses(OMPC_unknown + 1); while (Tok.isNot(tok::annot_pragma_openmp_end)) { OpenMPClauseKind CKind = Tok.isAnnotation() ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause( - OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt()); + OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind, + !FirstClauses[CKind].getInt()); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[unsigned(CKind)].setInt(true); + FirstClauses[CKind].setInt(true); if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -1708,9 +1708,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( case OMPD_requires: { SourceLocation StartLoc = ConsumeToken(); SmallVector Clauses; - SmallVector, - unsigned(OMPC_unknown) + 1> - FirstClauses(unsigned(OMPC_unknown) + 1); + SmallVector, OMPC_unknown + 1> + FirstClauses(OMPC_unknown + 1); if (Tok.is(tok::annot_pragma_openmp_end)) { Diag(Tok, diag::err_omp_expected_clause) << getOpenMPDirectiveName(OMPD_requires); @@ -1721,11 +1720,11 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause( - OMPD_requires, CKind, !FirstClauses[unsigned(CKind)].getInt()); + OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind, + !FirstClauses[CKind].getInt()); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[unsigned(CKind)].setInt(true); + FirstClauses[CKind].setInt(true); if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -2024,9 +2023,8 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { ParsingOpenMPDirectiveRAII DirScope(*this); ParenBraceBracketBalancer BalancerRAIIObj(*this); SmallVector Clauses; - SmallVector, - unsigned(OMPC_unknown) + 1> - FirstClauses(unsigned(OMPC_unknown) + 1); + SmallVector, OMPC_unknown + 1> + FirstClauses(OMPC_unknown + 1); unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope; SourceLocation Loc = ConsumeAnnotationToken(), EndLoc; @@ -2071,18 +2069,18 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { SmallVector Clauses; if (Tok.isNot(tok::annot_pragma_openmp_end)) { SmallVector, - unsigned(OMPC_unknown) + 1> - FirstClauses(unsigned(OMPC_unknown) + 1); + OMPC_unknown + 1> + FirstClauses(OMPC_unknown + 1); while (Tok.isNot(tok::annot_pragma_openmp_end)) { OpenMPClauseKind CKind = Tok.isAnnotation() ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause( - OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt()); + OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind, + !FirstClauses[CKind].getInt()); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[unsigned(CKind)].setInt(true); + FirstClauses[CKind].setInt(true); if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -2250,11 +2248,11 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { ImplicitClauseAllowed = false; Actions.StartOpenMPClause(CKind); HasImplicitClause = false; - OMPClause *Clause = ParseOpenMPClause( - DKind, CKind, !FirstClauses[unsigned(CKind)].getInt()); - FirstClauses[unsigned(CKind)].setInt(true); + OMPClause *Clause = + ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt()); + FirstClauses[CKind].setInt(true); if (Clause) { - FirstClauses[unsigned(CKind)].setPointer(Clause); + FirstClauses[CKind].setPointer(Clause); Clauses.push_back(Clause); } @@ -2271,7 +2269,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { // OpenMP [2.13.8, ordered Construct, Syntax] // If the depend clause is specified, the ordered construct is a stand-alone // directive. - if (DKind == OMPD_ordered && FirstClauses[unsigned(OMPC_depend)].getInt()) { + if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) { if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) == ParsedStmtContext()) { Diag(Loc, diag::err_omp_immediate_directive) @@ -2756,7 +2754,7 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind, // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(Kind).data())) + getOpenMPClauseName(Kind))) return nullptr; ExprResult Val; @@ -3068,7 +3066,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(Kind).data())) + getOpenMPClauseName(Kind))) return true; bool NeedRParenForLinear = false; diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 20b6ce452c2a..7d2ae172fe4d 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -2231,7 +2231,7 @@ void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, } } if (OMPC != OMPC_unknown) - FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); + FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); } bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 795a2a4c4415..82cfa246e3f7 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -730,10 +730,10 @@ class TreeTransform { #define ABSTRACT_STMT(Stmt) #include "clang/AST/StmtNodes.inc" -#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ +#define OPENMP_CLAUSE(Name, Class) \ LLVM_ATTRIBUTE_NOINLINE \ OMPClause *Transform ## Class(Class *S); -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#include "clang/Basic/OpenMPKinds.def" /// Build a new qualified type given its unqualified type and type location. /// @@ -3585,10 +3585,10 @@ OMPClause *TreeTransform::TransformOMPClause(OMPClause *S) { switch (S->getClauseKind()) { default: break; // Transform individual clause nodes -#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ - case Enum: \ +#define OPENMP_CLAUSE(Name, Class) \ + case OMPC_ ## Name : \ return getDerived().Transform ## Class(cast(S)); -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#include "clang/Basic/OpenMPKinds.def" } return S; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index f01b64bcdd8e..bea9bdd22bab 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -11613,8 +11613,8 @@ class OMPClauseReader : public OMPClauseVisitor { OMPClauseReader(ASTRecordReader &Record) : Record(Record), Context(Record.getContext()) {} -#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *C); -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *C); +#include "clang/Basic/OpenMPKinds.def" OMPClause *readClause(); void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C); void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C); @@ -11628,149 +11628,149 @@ OMPClause *ASTRecordReader::readOMPClause() { OMPClause *OMPClauseReader::readClause() { OMPClause *C = nullptr; - switch (llvm::omp::Clause(Record.readInt())) { - case llvm::omp::OMPC_if: + switch (Record.readInt()) { + case OMPC_if: C = new (Context) OMPIfClause(); break; - case llvm::omp::OMPC_final: + case OMPC_final: C = new (Context) OMPFinalClause(); break; - case llvm::omp::OMPC_num_threads: + case OMPC_num_threads: C = new (Context) OMPNumThreadsClause(); break; - case llvm::omp::OMPC_safelen: + case OMPC_safelen: C = new (Context) OMPSafelenClause(); break; - case llvm::omp::OMPC_simdlen: + case OMPC_simdlen: C = new (Context) OMPSimdlenClause(); break; - case llvm::omp::OMPC_allocator: + case OMPC_allocator: C = new (Context) OMPAllocatorClause(); break; - case llvm::omp::OMPC_collapse: + case OMPC_collapse: C = new (Context) OMPCollapseClause(); break; - case llvm::omp::OMPC_default: + case OMPC_default: C = new (Context) OMPDefaultClause(); break; - case llvm::omp::OMPC_proc_bind: + case OMPC_proc_bind: C = new (Context) OMPProcBindClause(); break; - case llvm::omp::OMPC_schedule: + case OMPC_schedule: C = new (Context) OMPScheduleClause(); break; - case llvm::omp::OMPC_ordered: + case OMPC_ordered: C = OMPOrderedClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_nowait: + case OMPC_nowait: C = new (Context) OMPNowaitClause(); break; - case llvm::omp::OMPC_untied: + case OMPC_untied: C = new (Context) OMPUntiedClause(); break; - case llvm::omp::OMPC_mergeable: + case OMPC_mergeable: C = new (Context) OMPMergeableClause(); break; - case llvm::omp::OMPC_read: + case OMPC_read: C = new (Context) OMPReadClause(); break; - case llvm::omp::OMPC_write: + case OMPC_write: C = new (Context) OMPWriteClause(); break; - case llvm::omp::OMPC_update: + case OMPC_update: C = OMPUpdateClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_capture: + case OMPC_capture: C = new (Context) OMPCaptureClause(); break; - case llvm::omp::OMPC_seq_cst: + case OMPC_seq_cst: C = new (Context) OMPSeqCstClause(); break; - case llvm::omp::OMPC_acq_rel: + case OMPC_acq_rel: C = new (Context) OMPAcqRelClause(); break; - case llvm::omp::OMPC_acquire: + case OMPC_acquire: C = new (Context) OMPAcquireClause(); break; - case llvm::omp::OMPC_release: + case OMPC_release: C = new (Context) OMPReleaseClause(); break; - case llvm::omp::OMPC_relaxed: + case OMPC_relaxed: C = new (Context) OMPRelaxedClause(); break; - case llvm::omp::OMPC_threads: + case OMPC_threads: C = new (Context) OMPThreadsClause(); break; - case llvm::omp::OMPC_simd: + case OMPC_simd: C = new (Context) OMPSIMDClause(); break; - case llvm::omp::OMPC_nogroup: + case OMPC_nogroup: C = new (Context) OMPNogroupClause(); break; - case llvm::omp::OMPC_unified_address: + case OMPC_unified_address: C = new (Context) OMPUnifiedAddressClause(); break; - case llvm::omp::OMPC_unified_shared_memory: + case OMPC_unified_shared_memory: C = new (Context) OMPUnifiedSharedMemoryClause(); break; - case llvm::omp::OMPC_reverse_offload: + case OMPC_reverse_offload: C = new (Context) OMPReverseOffloadClause(); break; - case llvm::omp::OMPC_dynamic_allocators: + case OMPC_dynamic_allocators: C = new (Context) OMPDynamicAllocatorsClause(); break; - case llvm::omp::OMPC_atomic_default_mem_order: + case OMPC_atomic_default_mem_order: C = new (Context) OMPAtomicDefaultMemOrderClause(); break; - case llvm::omp::OMPC_private: + case OMPC_private: C = OMPPrivateClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_firstprivate: + case OMPC_firstprivate: C = OMPFirstprivateClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_lastprivate: + case OMPC_lastprivate: C = OMPLastprivateClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_shared: + case OMPC_shared: C = OMPSharedClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_reduction: + case OMPC_reduction: C = OMPReductionClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_task_reduction: + case OMPC_task_reduction: C = OMPTaskReductionClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_in_reduction: + case OMPC_in_reduction: C = OMPInReductionClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_linear: + case OMPC_linear: C = OMPLinearClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_aligned: + case OMPC_aligned: C = OMPAlignedClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_copyin: + case OMPC_copyin: C = OMPCopyinClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_copyprivate: + case OMPC_copyprivate: C = OMPCopyprivateClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_flush: + case OMPC_flush: C = OMPFlushClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_depobj: + case OMPC_depobj: C = OMPDepobjClause::CreateEmpty(Context); break; - case llvm::omp::OMPC_depend: { + case OMPC_depend: { unsigned NumVars = Record.readInt(); unsigned NumLoops = Record.readInt(); C = OMPDependClause::CreateEmpty(Context, NumVars, NumLoops); break; } - case llvm::omp::OMPC_device: + case OMPC_device: C = new (Context) OMPDeviceClause(); break; - case llvm::omp::OMPC_map: { + case OMPC_map: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11779,31 +11779,31 @@ OMPClause *OMPClauseReader::readClause() { C = OMPMapClause::CreateEmpty(Context, Sizes); break; } - case llvm::omp::OMPC_num_teams: + case OMPC_num_teams: C = new (Context) OMPNumTeamsClause(); break; - case llvm::omp::OMPC_thread_limit: + case OMPC_thread_limit: C = new (Context) OMPThreadLimitClause(); break; - case llvm::omp::OMPC_priority: + case OMPC_priority: C = new (Context) OMPPriorityClause(); break; - case llvm::omp::OMPC_grainsize: + case OMPC_grainsize: C = new (Context) OMPGrainsizeClause(); break; - case llvm::omp::OMPC_num_tasks: + case OMPC_num_tasks: C = new (Context) OMPNumTasksClause(); break; - case llvm::omp::OMPC_hint: + case OMPC_hint: C = new (Context) OMPHintClause(); break; - case llvm::omp::OMPC_dist_schedule: + case OMPC_dist_schedule: C = new (Context) OMPDistScheduleClause(); break; - case llvm::omp::OMPC_defaultmap: + case OMPC_defaultmap: C = new (Context) OMPDefaultmapClause(); break; - case llvm::omp::OMPC_to: { + case OMPC_to: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11812,7 +11812,7 @@ OMPClause *OMPClauseReader::readClause() { C = OMPToClause::CreateEmpty(Context, Sizes); break; } - case llvm::omp::OMPC_from: { + case OMPC_from: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11821,7 +11821,7 @@ OMPClause *OMPClauseReader::readClause() { C = OMPFromClause::CreateEmpty(Context, Sizes); break; } - case llvm::omp::OMPC_use_device_ptr: { + case OMPC_use_device_ptr: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11830,7 +11830,7 @@ OMPClause *OMPClauseReader::readClause() { C = OMPUseDevicePtrClause::CreateEmpty(Context, Sizes); break; } - case llvm::omp::OMPC_is_device_ptr: { + case OMPC_is_device_ptr: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11839,31 +11839,27 @@ OMPClause *OMPClauseReader::readClause() { C = OMPIsDevicePtrClause::CreateEmpty(Context, Sizes); break; } - case llvm::omp::OMPC_allocate: + case OMPC_allocate: C = OMPAllocateClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_nontemporal: + case OMPC_nontemporal: C = OMPNontemporalClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_inclusive: + case OMPC_inclusive: C = OMPInclusiveClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_exclusive: + case OMPC_exclusive: C = OMPExclusiveClause::CreateEmpty(Context, Record.readInt()); break; - case llvm::omp::OMPC_order: + case OMPC_order: C = new (Context) OMPOrderClause(); break; - case llvm::omp::OMPC_destroy: + case OMPC_destroy: C = new (Context) OMPDestroyClause(); break; - case llvm::omp::OMPC_detach: + case OMPC_detach: C = new (Context) OMPDetachClause(); break; -#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ - case llvm::omp::Enum: \ - break; -#include "llvm/Frontend/OpenMP/OMPKinds.def" } assert(C && "Unknown OMPClause type"); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 76e2dd609f92..f7c58ed11d9f 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6037,8 +6037,8 @@ class OMPClauseWriter : public OMPClauseVisitor { public: OMPClauseWriter(ASTRecordWriter &Record) : Record(Record) {} -#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *S); -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S); +#include "clang/Basic/OpenMPKinds.def" void writeClause(OMPClause *C); void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C); void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C); @@ -6051,7 +6051,7 @@ void ASTRecordWriter::writeOMPClause(OMPClause *C) { } void OMPClauseWriter::writeClause(OMPClause *C) { - Record.push_back(unsigned(C->getClauseKind())); + Record.push_back(C->getClauseKind()); Visit(C); Record.AddSourceLocation(C->getBeginLoc()); Record.AddSourceLocation(C->getEndLoc()); diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt index bcf2dfdb8326..b7fb0d90c980 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -1,5 +1,4 @@ set(LLVM_LINK_COMPONENTS - FrontendOpenMP Support ) diff --git a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt index 057cdd4bb18a..dc2a6279b737 100644 --- a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt @@ -1,7 +1,4 @@ -set(LLVM_LINK_COMPONENTS - FrontendOpenMP - Support -) +set(LLVM_LINK_COMPONENTS support) add_clang_library(clangStaticAnalyzerCore APSIntType.cpp diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 1267b9b50fd3..bb9fed165679 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2153,8 +2153,8 @@ class OMPClauseEnqueue : public ConstOMPClauseVisitor { public: OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {} -#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C); -#include "llvm/Frontend/OpenMP/OMPKinds.def" +#define OPENMP_CLAUSE(Name, Class) void Visit##Class(const Class *C); +#include "clang/Basic/OpenMPKinds.def" void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C); void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C); }; diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index 428879d0695c..fbf2ff130785 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -2612,7 +2612,7 @@ TEST(HasExternalFormalLinkage, Basic) { } TEST(HasDefaultArgument, Basic) { - EXPECT_TRUE(matches("void x(int val = 0) {}", + EXPECT_TRUE(matches("void x(int val = 0) {}", parmVarDecl(hasDefaultArgument()))); EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(hasDefaultArgument()))); @@ -2665,7 +2665,7 @@ TEST(HasTrailingReturn, MatchesTrailingReturn) { EXPECT_TRUE(matches("auto Y() -> int { return 0; }", functionDecl(hasTrailingReturn()))); EXPECT_TRUE(matches("auto X() -> int;", functionDecl(hasTrailingReturn()))); - EXPECT_TRUE(notMatches("int X() { return 0; }", + EXPECT_TRUE(notMatches("int X() { return 0; }", functionDecl(hasTrailingReturn()))); EXPECT_TRUE(notMatches("int X();", functionDecl(hasTrailingReturn()))); EXPECT_TRUE(notMatchesC("void X();", functionDecl(hasTrailingReturn()))); @@ -2891,8 +2891,8 @@ void x(int x) { } TEST(OMPExecutableDirective, isAllowedToContainClauseKind) { - auto Matcher = ompExecutableDirective( - isAllowedToContainClauseKind(llvm::omp::OMPC_default)); + auto Matcher = + ompExecutableDirective(isAllowedToContainClauseKind(OMPC_default)); const std::string Source0 = R"( void x() { diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h index d32fa8dc98ef..7cda3197473f 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h @@ -34,18 +34,11 @@ enum class Directive { #include "llvm/Frontend/OpenMP/OMPKinds.def" }; -/// IDs for all OpenMP clauses. -enum class Clause { -#define OMP_CLAUSE(Enum, ...) Enum, -#include "llvm/Frontend/OpenMP/OMPKinds.def" -}; - /// Make the enum values available in the llvm::omp namespace. This allows us to /// write something like OMPD_parallel if we have a `using namespace omp`. At /// the same time we do not loose the strong type guarantees of the enum class, /// that is we cannot pass an unsigned as Directive without an explicit cast. #define OMP_DIRECTIVE(Enum, ...) constexpr auto Enum = omp::Directive::Enum; -#define OMP_CLAUSE(Enum, ...) constexpr auto Enum = omp::Clause::Enum; #include "llvm/Frontend/OpenMP/OMPKinds.def" /// IDs for all omp runtime library (RTL) functions. @@ -94,12 +87,6 @@ Directive getOpenMPDirectiveKind(StringRef Str); /// Return a textual representation of the directive \p D. StringRef getOpenMPDirectiveName(Directive D); -/// Parse \p Str and return the clause it matches or OMPC_unknown if none. -Clause getOpenMPClauseKind(StringRef Str); - -/// Return a textual representation of the clause \p C. -StringRef getOpenMPClauseName(Clause C); - /// Forward declarations for LLVM-IR types (simple, function and structure) are /// generated below. Their names are defined and used in OpenMP/OMPKinds.def. /// Here we provide the forward declarations, the initializeTypes function will diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def index 09468358415f..c80ecc7cbf77 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -105,117 +105,6 @@ __OMP_DIRECTIVE(unknown) ///} -/// OpenMP Clauses -/// -///{ - -#ifndef OMP_CLAUSE -#define OMP_CLAUSE(Enum, Str, Implicit) -#endif -#ifndef OMP_CLAUSE_CLASS -#define OMP_CLAUSE_CLASS(Enum, Str, Class) -#endif -#ifndef OMP_CLAUSE_NO_CLASS -#define OMP_CLAUSE_NO_CLASS(Enum, Str) -#endif - -#define __OMP_CLAUSE(Name, Class) \ - OMP_CLAUSE(OMPC_##Name, #Name, /* Implicit */ false) \ - OMP_CLAUSE_CLASS(OMPC_##Name, #Name, Class) -#define __OMP_CLAUSE_NO_CLASS(Name) \ - OMP_CLAUSE(OMPC_##Name, #Name, /* Implicit */ false) \ - OMP_CLAUSE_NO_CLASS(OMPC_##Name, #Name) -#define __OMP_IMPLICIT_CLAUSE_CLASS(Name, Str, Class) \ - OMP_CLAUSE(OMPC_##Name, Str, /* Implicit */ true) \ - OMP_CLAUSE_CLASS(OMPC_##Name, Str, Class) -#define __OMP_IMPLICIT_CLAUSE_NO_CLASS(Name, Str) \ - OMP_CLAUSE(OMPC_##Name, Str, /* Implicit */ true) \ - OMP_CLAUSE_NO_CLASS(OMPC_##Name, Str) - -__OMP_CLAUSE(allocator, OMPAllocatorClause) -__OMP_CLAUSE(if, OMPIfClause) -__OMP_CLAUSE(final, OMPFinalClause) -__OMP_CLAUSE(num_threads, OMPNumThreadsClause) -__OMP_CLAUSE(safelen, OMPSafelenClause) -__OMP_CLAUSE(simdlen, OMPSimdlenClause) -__OMP_CLAUSE(collapse, OMPCollapseClause) -__OMP_CLAUSE(default, OMPDefaultClause) -__OMP_CLAUSE(private, OMPPrivateClause) -__OMP_CLAUSE(firstprivate, OMPFirstprivateClause) -__OMP_CLAUSE(lastprivate, OMPLastprivateClause) -__OMP_CLAUSE(shared, OMPSharedClause) -__OMP_CLAUSE(reduction, OMPReductionClause) -__OMP_CLAUSE(linear, OMPLinearClause) -__OMP_CLAUSE(aligned, OMPAlignedClause) -__OMP_CLAUSE(copyin, OMPCopyinClause) -__OMP_CLAUSE(copyprivate, OMPCopyprivateClause) -__OMP_CLAUSE(proc_bind, OMPProcBindClause) -__OMP_CLAUSE(schedule, OMPScheduleClause) -__OMP_CLAUSE(ordered, OMPOrderedClause) -__OMP_CLAUSE(nowait, OMPNowaitClause) -__OMP_CLAUSE(untied, OMPUntiedClause) -__OMP_CLAUSE(mergeable, OMPMergeableClause) -__OMP_CLAUSE(read, OMPReadClause) -__OMP_CLAUSE(write, OMPWriteClause) -__OMP_CLAUSE(update, OMPUpdateClause) -__OMP_CLAUSE(capture, OMPCaptureClause) -__OMP_CLAUSE(seq_cst, OMPSeqCstClause) -__OMP_CLAUSE(acq_rel, OMPAcqRelClause) -__OMP_CLAUSE(acquire, OMPAcquireClause) -__OMP_CLAUSE(release, OMPReleaseClause) -__OMP_CLAUSE(relaxed, OMPRelaxedClause) -__OMP_CLAUSE(depend, OMPDependClause) -__OMP_CLAUSE(device, OMPDeviceClause) -__OMP_CLAUSE(threads, OMPThreadsClause) -__OMP_CLAUSE(simd, OMPSIMDClause) -__OMP_CLAUSE(map, OMPMapClause) -__OMP_CLAUSE(num_teams, OMPNumTeamsClause) -__OMP_CLAUSE(thread_limit, OMPThreadLimitClause) -__OMP_CLAUSE(priority, OMPPriorityClause) -__OMP_CLAUSE(grainsize, OMPGrainsizeClause) -__OMP_CLAUSE(nogroup, OMPNogroupClause) -__OMP_CLAUSE(num_tasks, OMPNumTasksClause) -__OMP_CLAUSE(hint, OMPHintClause) -__OMP_CLAUSE(dist_schedule, OMPDistScheduleClause) -__OMP_CLAUSE(defaultmap, OMPDefaultmapClause) -__OMP_CLAUSE(to, OMPToClause) -__OMP_CLAUSE(from, OMPFromClause) -__OMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause) -__OMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause) -__OMP_CLAUSE(task_reduction, OMPTaskReductionClause) -__OMP_CLAUSE(in_reduction, OMPInReductionClause) -__OMP_CLAUSE(unified_address, OMPUnifiedAddressClause) -__OMP_CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause) -__OMP_CLAUSE(reverse_offload, OMPReverseOffloadClause) -__OMP_CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause) -__OMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause) -__OMP_CLAUSE(allocate, OMPAllocateClause) -__OMP_CLAUSE(nontemporal, OMPNontemporalClause) -__OMP_CLAUSE(order, OMPOrderClause) -__OMP_CLAUSE(destroy, OMPDestroyClause) -__OMP_CLAUSE(detach, OMPDetachClause) -__OMP_CLAUSE(inclusive, OMPInclusiveClause) -__OMP_CLAUSE(exclusive, OMPExclusiveClause) - -__OMP_CLAUSE_NO_CLASS(uniform) -__OMP_CLAUSE_NO_CLASS(device_type) -__OMP_CLAUSE_NO_CLASS(match) - -__OMP_IMPLICIT_CLAUSE_CLASS(depobj, "depobj", OMPDepobjClause) -__OMP_IMPLICIT_CLAUSE_CLASS(flush, "flush", OMPFlushClause) - -__OMP_IMPLICIT_CLAUSE_NO_CLASS(threadprivate, "threadprivate or thread local") -__OMP_IMPLICIT_CLAUSE_NO_CLASS(unknown, "unknown") - -#undef __OMP_IMPLICIT_CLAUSE_NO_CLASS -#undef __OMP_IMPLICIT_CLAUSE_CLASS -#undef __OMP_CLAUSE -#undef OMP_CLAUSE_NO_CLASS -#undef OMP_CLAUSE_CLASS -#undef OMP_CLAUSE - -///} - /// Types used in runtime structs or runtime functions /// ///{ @@ -343,10 +232,8 @@ __OMP_RTL(omp_set_max_active_levels, false, Void, Int32) __OMP_RTL(__kmpc_master, false, Int32, IdentPtr, Int32) __OMP_RTL(__kmpc_end_master, false, Void, IdentPtr, Int32) __OMP_RTL(__kmpc_critical, false, Void, IdentPtr, Int32, KmpCriticalNamePtrTy) -__OMP_RTL(__kmpc_critical_with_hint, false, Void, IdentPtr, Int32, - KmpCriticalNamePtrTy, Int32) -__OMP_RTL(__kmpc_end_critical, false, Void, IdentPtr, Int32, - KmpCriticalNamePtrTy) +__OMP_RTL(__kmpc_critical_with_hint, false, Void, IdentPtr, Int32, KmpCriticalNamePtrTy, Int32) +__OMP_RTL(__kmpc_end_critical, false, Void, IdentPtr, Int32, KmpCriticalNamePtrTy) __OMP_RTL(__last, false, Void, ) diff --git a/llvm/lib/Frontend/OpenMP/OMPConstants.cpp b/llvm/lib/Frontend/OpenMP/OMPConstants.cpp index edd857d7b250..6ee44958d1c7 100644 --- a/llvm/lib/Frontend/OpenMP/OMPConstants.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPConstants.cpp @@ -36,24 +36,6 @@ StringRef llvm::omp::getOpenMPDirectiveName(Directive Kind) { llvm_unreachable("Invalid OpenMP directive kind"); } -Clause llvm::omp::getOpenMPClauseKind(StringRef Str) { - return llvm::StringSwitch(Str) -#define OMP_CLAUSE(Enum, Str, Implicit) \ - .Case(Str, Implicit ? OMPC_unknown : Enum) -#include "llvm/Frontend/OpenMP/OMPKinds.def" - .Default(OMPC_unknown); -} - -StringRef llvm::omp::getOpenMPClauseName(Clause C) { - switch (C) { -#define OMP_CLAUSE(Enum, Str, ...) \ - case Enum: \ - return Str; -#include "llvm/Frontend/OpenMP/OMPKinds.def" - } - llvm_unreachable("Invalid OpenMP clause kind"); -} - /// Declarations for LLVM-IR types (simple, array, function and structure) are /// generated below. Their names are defined and used in OpenMPKinds.def. Here /// we provide the declarations, the initializeTypes function will provide the From cfe-commits at lists.llvm.org Thu Apr 2 00:30:14 2020 From: cfe-commits at lists.llvm.org (Vitaly Buka via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 07:30:14 +0000 (UTC) Subject: [PATCH] D77244: sancov/inline-bool-flag feature + tests + docs. In-Reply-To: References: Message-ID: <1d4de8897567fca5ab5a9e46413c8e7c@localhost.localdomain> vitalybuka added inline comments. ================ Comment at: clang/test/Driver/autocomplete.c:49 +// RUN: %clang --autocomplete=-fno-sanitize-coverage=,f | FileCheck %s +// -check-prefix=FNOSANICOVER FNOSANICOVER: func RUN: %clang +// --autocomplete=-fno-sanitize-coverage= | FileCheck %s ---------------- probably you didn't add "--style=file" this dir should not enforce line length Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77244/new/ https://reviews.llvm.org/D77244 From cfe-commits at lists.llvm.org Thu Apr 2 00:30:16 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 07:30:16 +0000 (UTC) Subject: [PATCH] D77112: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` In-Reply-To: References: Message-ID: <4712634490260e194e34d3bda7478dff@localhost.localdomain> jdoerfert added a comment. Herald added a subscriber: yaxunl. NOTE: I mixed this one up with the follow up that was approved already (D77113 ) and committed it. If it turns out to be problematic we revert but I'll leave it for now as there was a positive review from @fghanim . Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77112/new/ https://reviews.llvm.org/D77112 From cfe-commits at lists.llvm.org Thu Apr 2 00:30:17 2020 From: cfe-commits at lists.llvm.org (MyDeveloperDay via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 07:30:17 +0000 (UTC) Subject: [PATCH] D75034: [clang-format] use spaces for alignment with UT_ForContinuationAndIndentation In-Reply-To: References: Message-ID: <17e22c6f40517487d30b5efe50a24a7d@localhost.localdomain> MyDeveloperDay accepted this revision. MyDeveloperDay added a comment. This revision is now accepted and ready to land. This LGTM, thank you Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75034/new/ https://reviews.llvm.org/D75034 From cfe-commits at lists.llvm.org Thu Apr 2 00:30:18 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 07:30:18 +0000 (UTC) Subject: [PATCH] D77290: [OpenMP] Specialize OpenMP calls after template instantiation Message-ID: jdoerfert created this revision. jdoerfert added reviewers: kiranchandramohan, ABataev, RaviNarayanaswamy, gtbercea, grokos, sdmitriev, JonChesterfield, hfinkel, fghanim, aaron.ballman. Herald added subscribers: guansong, bollu, yaxunl. Herald added a project: clang. jdoerfert removed a parent revision: D77113: [OpenMP][NFC] Move and simplify directive -> allowed clause mapping. jdoerfert edited the summary of this revision. jdoerfert added a child revision: D77252: [OpenMP] Try to find an existing base for `omp begin/end declare variant`. As with regular calls, we want to specialize a call that went through template instantiation if it has an applicable OpenMP declare variant. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77290 Files: clang/lib/Sema/SemaTemplateInstantiate.cpp clang/test/AST/ast-dump-openmp-begin-declare-variant_template_1.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77290.254438.patch Type: text/x-patch Size: 13638 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 00:30:20 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 07:30:20 +0000 (UTC) Subject: [PATCH] D76725: [clangd] Build ASTs only with fresh preambles or after building a new preamble In-Reply-To: References: Message-ID: kadircet updated this revision to Diff 254439. kadircet marked 31 inline comments as done. kadircet added a comment. - Update comments and re-order functions Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76725/new/ https://reviews.llvm.org/D76725 Files: clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Preamble.h clang-tools-extra/clangd/TUScheduler.cpp clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp clang-tools-extra/clangd/unittests/FileIndexTests.cpp clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp clang-tools-extra/clangd/unittests/TestTU.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76725.254439.patch Type: text/x-patch Size: 49466 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 00:30:22 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 07:30:22 +0000 (UTC) Subject: [PATCH] D77112: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` In-Reply-To: References: Message-ID: <713ce0e43227ea3e77ba645cab662112@localhost.localdomain> jdoerfert added a comment. Reverted in 1858f4b50dd35c28b377ba5dbc572fed43a5d38a as some uses need fixing, didn't build clang-tidy locally apparently. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77112/new/ https://reviews.llvm.org/D77112 From cfe-commits at lists.llvm.org Thu Apr 2 00:30:39 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 07:30:39 +0000 (UTC) Subject: [PATCH] D77112: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` In-Reply-To: References: Message-ID: <293e5340cac06ee099e3eb9e9943b2d4@localhost.localdomain> This revision was not accepted when it landed; it landed in state "Needs Review". This revision was automatically updated to reflect the committed changes. Closed by commit rGc18d55998b33: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` (authored by jdoerfert). Changed prior to commit: https://reviews.llvm.org/D77112?vs=253765&id=254440#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77112/new/ https://reviews.llvm.org/D77112 Files: clang/include/clang/AST/ASTFwd.h clang/include/clang/AST/ASTTypeTraits.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/Basic/Attr.td clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Basic/OpenMPKinds.h clang/lib/AST/ASTTypeTraits.cpp clang/lib/AST/AttrImpl.cpp clang/lib/AST/OpenMPClause.cpp clang/lib/AST/StmtProfile.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/ASTMatchers/CMakeLists.txt clang/lib/ASTMatchers/Dynamic/Marshallers.h clang/lib/Analysis/CMakeLists.txt clang/lib/Basic/OpenMPKinds.cpp clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt clang/lib/StaticAnalyzer/Core/CMakeLists.txt clang/tools/libclang/CIndex.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp llvm/include/llvm/Frontend/OpenMP/OMPConstants.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPConstants.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77112.254440.patch Type: text/x-patch Size: 118730 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 00:33:13 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via cfe-commits) Date: Thu, 02 Apr 2020 00:33:13 -0700 (PDT) Subject: [clang-tools-extra] b420065 - [clangd] Fix an assertion crash in ReferenceFinder. Message-ID: <5e859539.1c69fb81.de2e0.f477@mx.google.com> Author: Haojian Wu Date: 2020-04-02T09:29:20+02:00 New Revision: b42006596905bea7bef54759ba3a5d1a7dd418fa URL: https://github.com/llvm/llvm-project/commit/b42006596905bea7bef54759ba3a5d1a7dd418fa DIFF: https://github.com/llvm/llvm-project/commit/b42006596905bea7bef54759ba3a5d1a7dd418fa.diff LOG: [clangd] Fix an assertion crash in ReferenceFinder. Summary: The assertion is almost correct, but it fails on refs from non-preamble Reviewers: sammccall Reviewed By: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77222 Added: Modified: clang-tools-extra/clangd/XRefs.cpp clang-tools-extra/clangd/unittests/XRefsTests.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp index 7e27be38bcc3..3bf8d0e818e8 100644 --- a/clang-tools-extra/clangd/XRefs.cpp +++ b/clang-tools-extra/clangd/XRefs.cpp @@ -583,13 +583,11 @@ class ReferenceFinder : public index::IndexDataConsumer { SourceLocation Loc, index::IndexDataConsumer::ASTNodeInfo ASTNode) override { assert(D->isCanonicalDecl() && "expect D to be a canonical declaration"); - if (!CanonicalTargets.count(D)) + const SourceManager &SM = AST.getSourceManager(); + if (!CanonicalTargets.count(D) || !isInsideMainFile(Loc, SM)) return true; const auto &TB = AST.getTokens(); - const SourceManager &SM = AST.getSourceManager(); Loc = SM.getFileLoc(Loc); - // We are only traversing decls *inside* the main file, so this should hold. - assert(isInsideMainFile(Loc, SM)); if (const auto *Tok = TB.spelledTokenAt(Loc)) References.push_back({*Tok, Roles}); return true; diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp index 6b568456ba02..ce7f76ccf4f4 100644 --- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -1121,6 +1121,30 @@ TEST(FindReferences, WithinAST) { } } +TEST(FindReferences, MainFileReferencesOnly) { + llvm::StringRef Test = + R"cpp( + void test() { + int [[fo^o]] = 1; + // refs not from main file should not be included. + #include "foo.inc" + })cpp"; + + Annotations Code(Test); + auto TU = TestTU::withCode(Code.code()); + TU.AdditionalFiles["foo.inc"] = R"cpp( + foo = 3; + )cpp"; + auto AST = TU.build(); + + std::vector> ExpectedLocations; + for (const auto &R : Code.ranges()) + ExpectedLocations.push_back(RangeIs(R)); + EXPECT_THAT(findReferences(AST, Code.point(), 0).References, + ElementsAreArray(ExpectedLocations)) + << Test; +} + TEST(FindReferences, ExplicitSymbols) { const char *Tests[] = { R"cpp( From cfe-commits at lists.llvm.org Thu Apr 2 01:03:12 2020 From: cfe-commits at lists.llvm.org (MyDeveloperDay via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 08:03:12 +0000 (UTC) Subject: [PATCH] D75791: [clang-format] Added new option IndentExternBlock In-Reply-To: References: Message-ID: <1f7bdfd0ff3c4715d597155c3d15586b@localhost.localdomain> MyDeveloperDay added a comment. I have no concerns with this patch other than the consideration of the defaults. My concern is whatever our choice we will generate churn on existing code where the .clang-format file has AfterExternBlock = true (or its true in inbuilt BasedOnStyle type) https://github.com/search?q=%22AfterExternBlock%3A+true%22&type=Code This is also true for all Mozilla and Allman styles, I'd be happy to give this a LGTM, but I feel like I'll end up saying "told you so on the choice of defaults" when the complaints come in, unless we are able to say `Style.IndentExternBlock = Style.BraceWrapping.AfterExternBlock` The problem is really that we need to detect the existence of IndentExternBlock missing from the config and a boolean isn't the best choice for this because we have 3 states (NotSpecified,Indent,DontIndent) I'm uncomfortable with the decision we've made that says IndentExternBlock is by default false when previously if we were putting a break we were following the normal indenting rules of all other control blocks parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/Style.IndentExternBlock); If we can't solve that, I'm not sure I'm happy to Accept, but code wise I'm fine with everything else. I'm not sure if I'm overly worrying. There is some code in the `void mapping(IO &IO, FormatStyle &Style)` that could show you a way to do this.. but I'm also constantly surprised by how many of the enumeration cases started out as booleans only later to have to be converted to enums. The more I think about this the more I think the problem can probably be dealt with better by making it an enumeration. (even if you support true and false to mean "indent" and "don't indent" template <> struct ScalarEnumerationTraits { static void enumeration(IO &IO, FormatStyle::BracketAlignmentStyle &Value) { IO.enumCase(Value, "Align", FormatStyle::BAS_Align); IO.enumCase(Value, "DontAlign", FormatStyle::BAS_DontAlign); IO.enumCase(Value, "AlwaysBreak", FormatStyle::BAS_AlwaysBreak); // For backward compatibility. IO.enumCase(Value, "true", FormatStyle::BAS_Align); IO.enumCase(Value, "false", FormatStyle::BAS_DontAlign); } }; CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75791/new/ https://reviews.llvm.org/D75791 From cfe-commits at lists.llvm.org Thu Apr 2 01:03:12 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 08:03:12 +0000 (UTC) Subject: [PATCH] D77063: [WIP][clangd] Dont block for preamble builds In-Reply-To: References: Message-ID: kadircet updated this revision to Diff 254442. kadircet added a comment. - Rebase Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77063/new/ https://reviews.llvm.org/D77063 Files: clang-tools-extra/clangd/TUScheduler.cpp clang-tools-extra/clangd/unittests/ClangdTests.cpp clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp clang-tools-extra/clangd/unittests/XRefsTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77063.254442.patch Type: text/x-patch Size: 12583 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 01:03:13 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 08:03:13 +0000 (UTC) Subject: [PATCH] D76725: [clangd] Build ASTs only with fresh preambles or after building a new preamble In-Reply-To: References: Message-ID: <3caa8b3562dcf4aa1c12144f00e93d39@localhost.localdomain> kadircet added a comment. preambleReady part is a little bit different than you've described, it looks more like: ASTWorker::preambleReady(): enqueue({ if(preamble!=lastPreamble) { lastPreamble = preamble cache.get(); // force next read to use this preamble } build ast publish ast.diagnostics if (inputs == currentInputs) cache.put(ast) }) also the last 3 steps are on a different function called `generateDiagnostics` since the code is a little bit long. it immediately follows the `preambleReady`(now named `updatePreamble`). ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:17 +// An update request changes latest inputs to ensure any subsequent read sees +// the version of the file they were requested. In addition to that it might +// result in publishing diagnostics. ---------------- sammccall wrote: > You need to mention "building an AST" here, as you reference it below. just saying "it will issue a build for new inputs", which is explained in details in the next paragraph. ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:29 +// modification to relevant part of the current file. Such a preamble is called +// usable. +// In the presence of stale(non-usable) preambles, ASTWorker won't publish ---------------- sammccall wrote: > I don't think "usable" is a good name for this, because we *use* preambles that are not "usable". > > I think "compatible" or "up-to-date" or "fresh" or so would have enough semantic distance to make this less confusing. using compatible. ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:341 SynchronizedTUStatus &Status; + ASTWorker &AW; }; ---------------- sammccall wrote: > Please don't use initialisms like this for members, they're hard to follow out of context. > I'd suggest ASTPeer (and PreamblePeer) or just Peer, to indicate these threads are tightly-coupled partners. PW was for PeerWorker :P ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:554 + LatestBuild->Version, Inputs.Version, FileName); + // We still notify the ASTWorker to make sure diagnostics are updated to + // the latest version of the file without requiring user update. ---------------- sammccall wrote: > This is going to trigger a rebuild of the fileindex - is it really necessary? astworker won't trigger that if inputs are the same. ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:630 + WantDiagnostics WantDiags) { + std::string TaskName = llvm::formatv("Preamble Update ({0})", PI.Version); + // Store preamble and build diagnostics with new preamble if requested. ---------------- sammccall wrote: > "Golden AST from preamble"? > Current text is not terribly descriptive... this is not necessarily a golden ast now. just changing it to "Build AST" ================ Comment at: clang-tools-extra/clangd/TUScheduler.cpp:675 + assert(LatestPreamble); + assert(isPreambleUsable(*LatestPreamble, Inputs, FileName, *Invocation)); + ---------------- sammccall wrote: > this isn't a safe assert - it does IO and could transiently become true/false right, thanks for catching it! the one above is also not true (`assert(LatestPreamble)`) as preamble build might've failed. I suppose we would still want to move forward so that we can surface diagnostics saying `why it failed`. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76725/new/ https://reviews.llvm.org/D76725 From cfe-commits at lists.llvm.org Thu Apr 2 01:03:33 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 08:03:33 +0000 (UTC) Subject: [PATCH] D77222: [clangd] Fix an assertion crash in ReferenceFinder. In-Reply-To: References: Message-ID: <770269820c312a3f1a5059798aecd881@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGb42006596905: [clangd] Fix an assertion crash in ReferenceFinder. (authored by hokein). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77222/new/ https://reviews.llvm.org/D77222 Files: clang-tools-extra/clangd/XRefs.cpp clang-tools-extra/clangd/unittests/XRefsTests.cpp Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -1121,6 +1121,30 @@ } } +TEST(FindReferences, MainFileReferencesOnly) { + llvm::StringRef Test = + R"cpp( + void test() { + int [[fo^o]] = 1; + // refs not from main file should not be included. + #include "foo.inc" + })cpp"; + + Annotations Code(Test); + auto TU = TestTU::withCode(Code.code()); + TU.AdditionalFiles["foo.inc"] = R"cpp( + foo = 3; + )cpp"; + auto AST = TU.build(); + + std::vector> ExpectedLocations; + for (const auto &R : Code.ranges()) + ExpectedLocations.push_back(RangeIs(R)); + EXPECT_THAT(findReferences(AST, Code.point(), 0).References, + ElementsAreArray(ExpectedLocations)) + << Test; +} + TEST(FindReferences, ExplicitSymbols) { const char *Tests[] = { R"cpp( Index: clang-tools-extra/clangd/XRefs.cpp =================================================================== --- clang-tools-extra/clangd/XRefs.cpp +++ clang-tools-extra/clangd/XRefs.cpp @@ -583,13 +583,11 @@ SourceLocation Loc, index::IndexDataConsumer::ASTNodeInfo ASTNode) override { assert(D->isCanonicalDecl() && "expect D to be a canonical declaration"); - if (!CanonicalTargets.count(D)) + const SourceManager &SM = AST.getSourceManager(); + if (!CanonicalTargets.count(D) || !isInsideMainFile(Loc, SM)) return true; const auto &TB = AST.getTokens(); - const SourceManager &SM = AST.getSourceManager(); Loc = SM.getFileLoc(Loc); - // We are only traversing decls *inside* the main file, so this should hold. - assert(isInsideMainFile(Loc, SM)); if (const auto *Tok = TB.spelledTokenAt(Loc)) References.push_back({*Tok, Roles}); return true; -------------- next part -------------- A non-text attachment was scrubbed... Name: D77222.254443.patch Type: text/x-patch Size: 1997 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 01:23:36 2020 From: cfe-commits at lists.llvm.org (Xiang1 Zhang via cfe-commits) Date: Thu, 02 Apr 2020 01:23:36 -0700 (PDT) Subject: [clang] d08fadd - [X86] Add SERIALIZE instruction. Message-ID: <5e85a108.1c69fb81.2743.e229@mx.google.com> Author: WangTianQing Date: 2020-04-02T16:19:23+08:00 New Revision: d08fadd6628a061bca66d37d6e0de2c51249ad22 URL: https://github.com/llvm/llvm-project/commit/d08fadd6628a061bca66d37d6e0de2c51249ad22 DIFF: https://github.com/llvm/llvm-project/commit/d08fadd6628a061bca66d37d6e0de2c51249ad22.diff LOG: [X86] Add SERIALIZE instruction. Summary: For more details about this instruction, please refer to the latest ISE document: https://software.intel.com/en-us/download/intel-architecture-instruction-set-extensions-programming-reference Reviewers: craig.topper, RKSimon, LuoYuanke Reviewed By: craig.topper Subscribers: mgorny, hiraditya, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77193 Added: clang/lib/Headers/serializeintrin.h clang/test/CodeGen/x86-serialize-intrin.c llvm/test/CodeGen/X86/serialize-intrinsic.ll Modified: clang/docs/ClangCommandLineReference.rst clang/include/clang/Basic/BuiltinsX86.def clang/include/clang/Driver/Options.td clang/lib/Basic/Targets/X86.cpp clang/lib/Basic/Targets/X86.h clang/lib/Headers/CMakeLists.txt clang/lib/Headers/cpuid.h clang/lib/Headers/immintrin.h clang/test/Driver/x86-target-features.c clang/test/Preprocessor/x86_target_features.c llvm/include/llvm/IR/IntrinsicsX86.td llvm/lib/Support/Host.cpp llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86InstrInfo.td llvm/lib/Target/X86/X86Subtarget.h llvm/test/MC/Disassembler/X86/x86-16.txt llvm/test/MC/Disassembler/X86/x86-32.txt llvm/test/MC/Disassembler/X86/x86-64.txt llvm/test/MC/X86/x86-16.s llvm/test/MC/X86/x86-32-coverage.s llvm/test/MC/X86/x86-64.s Removed: ################################################################################ diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst index 3f0e471e852a..51d4f32edec4 100644 --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -3145,6 +3145,8 @@ X86 .. option:: -msahf, -mno-sahf +.. option:: -mserialize, -mno-serialize + .. option:: -msgx, -mno-sgx .. option:: -msha, -mno-sha diff --git a/clang/include/clang/Basic/BuiltinsX86.def b/clang/include/clang/Basic/BuiltinsX86.def index d6aa46de02f9..ccb6f341d63d 100644 --- a/clang/include/clang/Basic/BuiltinsX86.def +++ b/clang/include/clang/Basic/BuiltinsX86.def @@ -1900,6 +1900,9 @@ TARGET_BUILTIN(__builtin_ia32_invpcid, "vUiv*", "nc", "invpcid") TARGET_BUILTIN(__builtin_ia32_enqcmd, "Ucv*vC*", "n", "enqcmd") TARGET_BUILTIN(__builtin_ia32_enqcmds, "Ucv*vC*", "n", "enqcmd") +// SERIALIZE +TARGET_BUILTIN(__builtin_ia32_serialize, "v", "n", "serialize") + // MSVC TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index becabcf21878..61e1d4128016 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3218,6 +3218,8 @@ def mrdseed : Flag<["-"], "mrdseed">, Group; def mno_rdseed : Flag<["-"], "mno-rdseed">, Group; def msahf : Flag<["-"], "msahf">, Group; def mno_sahf : Flag<["-"], "mno-sahf">, Group; +def mserialize : Flag<["-"], "mserialize">, Group; +def mno_serialize : Flag<["-"], "mno-serialize">, Group; def msgx : Flag<["-"], "msgx">, Group; def mno_sgx : Flag<["-"], "mno-sgx">, Group; def msha : Flag<["-"], "msha">, Group; diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index f06bf84cfd99..def23a65edde 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -857,6 +857,8 @@ bool X86TargetInfo::handleTargetFeatures(std::vector &Features, HasINVPCID = true; } else if (Feature == "+enqcmd") { HasENQCMD = true; + } else if (Feature == "+serialize") { + HasSERIALIZE = true; } X86SSEEnum Level = llvm::StringSwitch(Feature) @@ -1247,6 +1249,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__INVPCID__"); if (HasENQCMD) Builder.defineMacro("__ENQCMD__"); + if (HasSERIALIZE) + Builder.defineMacro("__SERIALIZE__"); // Each case falls through to the previous one here. switch (SSELevel) { @@ -1390,6 +1394,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const { .Case("rdseed", true) .Case("rtm", true) .Case("sahf", true) + .Case("serialize", true) .Case("sgx", true) .Case("sha", true) .Case("shstk", true) @@ -1474,6 +1479,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("retpoline-external-thunk", HasRetpolineExternalThunk) .Case("rtm", HasRTM) .Case("sahf", HasLAHFSAHF) + .Case("serialize", HasSERIALIZE) .Case("sgx", HasSGX) .Case("sha", HasSHA) .Case("shstk", HasSHSTK) diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index 0e0dae7db3ac..e14b101a3fa5 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -124,6 +124,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasPTWRITE = false; bool HasINVPCID = false; bool HasENQCMD = false; + bool HasSERIALIZE = false; protected: /// Enumeration of all of the X86 CPUs supported by Clang. diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index 5ca6f3cca1bc..6851957600e0 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -88,6 +88,7 @@ set(files ptwriteintrin.h rdseedintrin.h rtmintrin.h + serializeintrin.h sgxintrin.h s390intrin.h shaintrin.h diff --git a/clang/lib/Headers/cpuid.h b/clang/lib/Headers/cpuid.h index 4ddd64847c32..b06c37fa08cc 100644 --- a/clang/lib/Headers/cpuid.h +++ b/clang/lib/Headers/cpuid.h @@ -182,6 +182,7 @@ /* Features in %edx for leaf 7 sub-leaf 0 */ #define bit_AVX5124VNNIW 0x00000004 #define bit_AVX5124FMAPS 0x00000008 +#define bit_SERIALIZE 0x00004000 #define bit_PCONFIG 0x00040000 #define bit_IBT 0x00100000 diff --git a/clang/lib/Headers/immintrin.h b/clang/lib/Headers/immintrin.h index edf8c42ec491..164b1f40478d 100644 --- a/clang/lib/Headers/immintrin.h +++ b/clang/lib/Headers/immintrin.h @@ -434,6 +434,10 @@ _storebe_i64(void * __P, long long __D) { #include #endif +#if !defined(_MSC_VER) || __has_feature(modules) || defined(__SERIALIZE__) +#include +#endif + #if defined(_MSC_VER) && __has_extension(gnu_asm) /* Define the default attributes for these intrinsics */ #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) diff --git a/clang/lib/Headers/serializeintrin.h b/clang/lib/Headers/serializeintrin.h new file mode 100644 index 000000000000..b774e5a24a0b --- /dev/null +++ b/clang/lib/Headers/serializeintrin.h @@ -0,0 +1,30 @@ +/*===--------------- serializeintrin.h - serialize intrinsics --------------=== + * + * 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 __IMMINTRIN_H +#error "Never use directly; include instead." +#endif + +#ifndef __SERIALIZEINTRIN_H +#define __SERIALIZEINTRIN_H + +/// Serialize instruction fetch and execution. +/// +/// \headerfile +/// +/// This intrinsic corresponds to the SERIALIZE instruction. +/// +static __inline__ void +__attribute__((__always_inline__, __nodebug__, __target__("serialize"))) +_serialize (void) +{ + __builtin_ia32_serialize (); +} + +#endif /* __SERIALIZEINTRIN_H */ diff --git a/clang/test/CodeGen/x86-serialize-intrin.c b/clang/test/CodeGen/x86-serialize-intrin.c new file mode 100644 index 000000000000..a3587efc8883 --- /dev/null +++ b/clang/test/CodeGen/x86-serialize-intrin.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -ffreestanding -triple x86_64-unknown-unknown -target-feature +serialize -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -ffreestanding -triple i386-unknown-unknown -target-feature +serialize -emit-llvm -o - | FileCheck %s + +#include + +void test_serialize(void) +{ +// CHECK-LABEL: test_serialize +// CHECK: call void @llvm.x86.serialize() + _serialize(); +} diff --git a/clang/test/Driver/x86-target-features.c b/clang/test/Driver/x86-target-features.c index 9a406b504b24..58e7a45c0a83 100644 --- a/clang/test/Driver/x86-target-features.c +++ b/clang/test/Driver/x86-target-features.c @@ -198,3 +198,8 @@ // RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-vzeroupper %s -### -o %t.o 2>&1 | FileCheck --check-prefix=NO-VZEROUPPER %s // VZEROUPPER: "-target-feature" "+vzeroupper" // NO-VZEROUPPER: "-target-feature" "-vzeroupper" + +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mserialize %s -### -o %t.o 2>&1 | FileCheck -check-prefix=SERIALIZE %s +// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-serialize %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-SERIALIZE %s +// SERIALIZE: "-target-feature" "+serialize" +// NO-SERIALIZE: "-target-feature" "-serialize" diff --git a/clang/test/Preprocessor/x86_target_features.c b/clang/test/Preprocessor/x86_target_features.c index 8d55c5d29e12..e3bfdc527089 100644 --- a/clang/test/Preprocessor/x86_target_features.c +++ b/clang/test/Preprocessor/x86_target_features.c @@ -483,3 +483,11 @@ // RUN: %clang -target i386-unknown-unknown -march=atom -mno-enqcmd -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=NOENQCMD %s // NOENQCMD-NOT: #define __ENQCMD__ 1 + +// RUN: %clang -target i386-unknown-unknown -march=atom -mserialize -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=SERIALIZE %s + +// SERIALIZE: #define __SERIALIZE__ 1 + +// RUN: %clang -target i386-unknown-unknown -march=atom -mno-serialize -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=NOSERIALIZE %s + +// NOSERIALIZE-NOT: #define __SERIALIZE__ 1 diff --git a/llvm/include/llvm/IR/IntrinsicsX86.td b/llvm/include/llvm/IR/IntrinsicsX86.td index 4d353c7e93c2..8623be78478a 100644 --- a/llvm/include/llvm/IR/IntrinsicsX86.td +++ b/llvm/include/llvm/IR/IntrinsicsX86.td @@ -4930,3 +4930,11 @@ let TargetPrefix = "x86" in { def int_x86_enqcmds : GCCBuiltin<"__builtin_ia32_enqcmds">, Intrinsic<[llvm_i8_ty], [llvm_ptr_ty, llvm_ptr_ty], []>; } + +//===----------------------------------------------------------------------===// +// SERIALIZE - Serialize instruction fetch and execution + +let TargetPrefix = "x86" in { + def int_x86_serialize : GCCBuiltin<"__builtin_ia32_serialize">, + Intrinsic<[], [], []>; +} diff --git a/llvm/lib/Support/Host.cpp b/llvm/lib/Support/Host.cpp index d7558faed784..6b8f7ca2c45b 100644 --- a/llvm/lib/Support/Host.cpp +++ b/llvm/lib/Support/Host.cpp @@ -1477,6 +1477,7 @@ bool sys::getHostCPUFeatures(StringMap &Features) { Features["movdir64b"] = HasLeaf7 && ((ECX >> 28) & 1); Features["enqcmd"] = HasLeaf7 && ((ECX >> 29) & 1); + Features["serialize"] = HasLeaf7 && ((EDX >> 14) & 1); // There are two CPUID leafs which information associated with the pconfig // instruction: // EAX=0x7, ECX=0x0 indicates the availability of the instruction (via the 18th diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index 6c4ab8f5a6f3..94818796530c 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -273,6 +273,8 @@ def FeatureWAITPKG : SubtargetFeature<"waitpkg", "HasWAITPKG", "true", "Wait and pause enhancements">; def FeatureENQCMD : SubtargetFeature<"enqcmd", "HasENQCMD", "true", "Has ENQCMD instructions">; +def FeatureSERIALIZE : SubtargetFeature<"serialize", "HasSERIALIZE", "true", + "Has serialize instruction">; // On some processors, instructions that implicitly take two memory operands are // slow. In practice, this means that CALL, PUSH, and POP with memory operands // should be avoided in favor of a MOV + register CALL/PUSH/POP. diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 6940510609a8..a5293c2c2119 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -955,6 +955,7 @@ def HasCmpxchg8b : Predicate<"Subtarget->hasCmpxchg8b()">; def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">; def HasPCONFIG : Predicate<"Subtarget->hasPCONFIG()">; def HasENQCMD : Predicate<"Subtarget->hasENQCMD()">; +def HasSERIALIZE : Predicate<"Subtarget->hasSERIALIZE()">; def Not64BitMode : Predicate<"!Subtarget->is64Bit()">, AssemblerPredicate<(all_of (not Mode64Bit)), "Not 64-bit mode">; def In64BitMode : Predicate<"Subtarget->is64Bit()">, @@ -2861,6 +2862,13 @@ let SchedRW = [WriteLoad] in { def : InstAlias<"clzero\t{%eax|eax}", (CLZERO32r)>, Requires<[Not64BitMode]>; def : InstAlias<"clzero\t{%rax|rax}", (CLZERO64r)>, Requires<[In64BitMode]>; +//===----------------------------------------------------------------------===// +// SERIALIZE Instruction +// +def SERIALIZE : I<0x01, MRM_E8, (outs), (ins), "serialize", + [(int_x86_serialize)]>, PS, + Requires<[HasSERIALIZE]>; + //===----------------------------------------------------------------------===// // Pattern fragments to auto generate TBM instructions. //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index 93801455254c..cea8e1d83401 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -397,6 +397,9 @@ class X86Subtarget final : public X86GenSubtargetInfo { /// Processor supports PCONFIG instruction bool HasPCONFIG = false; + /// Processor supports SERIALIZE instruction + bool HasSERIALIZE = false; + /// Processor has a single uop BEXTR implementation. bool HasFastBEXTR = false; @@ -706,6 +709,7 @@ class X86Subtarget final : public X86GenSubtargetInfo { bool threewayBranchProfitable() const { return ThreewayBranchProfitable; } bool hasINVPCID() const { return HasINVPCID; } bool hasENQCMD() const { return HasENQCMD; } + bool hasSERIALIZE() const { return HasSERIALIZE; } bool useRetpolineIndirectCalls() const { return UseRetpolineIndirectCalls; } bool useRetpolineIndirectBranches() const { return UseRetpolineIndirectBranches; diff --git a/llvm/test/CodeGen/X86/serialize-intrinsic.ll b/llvm/test/CodeGen/X86/serialize-intrinsic.ll new file mode 100644 index 000000000000..629bb6dabd28 --- /dev/null +++ b/llvm/test/CodeGen/X86/serialize-intrinsic.ll @@ -0,0 +1,26 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+serialize | FileCheck %s --check-prefix=X86_64 +; RUN: llc < %s -mtriple=i386-unknown-unknown -mattr=+serialize | FileCheck %s --check-prefix=X86 +; RUN: llc < %s -mtriple=x86_64-linux-gnux32 -mattr=+serialize | FileCheck %s --check-prefix=X32 + +define void @test_serialize() { +; X86_64-LABEL: test_serialize: +; X86_64: # %bb.0: # %entry +; X86_64-NEXT: serialize +; X86_64-NEXT: retq +; +; X86-LABEL: test_serialize: +; X86: # %bb.0: # %entry +; X86-NEXT: serialize +; X86-NEXT: retl +; +; X32-LABEL: test_serialize: +; X32: # %bb.0: # %entry +; X32-NEXT: serialize +; X32-NEXT: retq +entry: + call void @llvm.x86.serialize() + ret void +} + +declare void @llvm.x86.serialize() diff --git a/llvm/test/MC/Disassembler/X86/x86-16.txt b/llvm/test/MC/Disassembler/X86/x86-16.txt index 5820b5e273a8..95948e33ac68 100644 --- a/llvm/test/MC/Disassembler/X86/x86-16.txt +++ b/llvm/test/MC/Disassembler/X86/x86-16.txt @@ -836,3 +836,6 @@ # CHECK: enqcmds (%edi), %edi 0x67,0xf3,0x0f,0x38,0xf8,0x3f + +# CHECK: serialize +0x0f 0x01 0xe8 diff --git a/llvm/test/MC/Disassembler/X86/x86-32.txt b/llvm/test/MC/Disassembler/X86/x86-32.txt index 86157d0e8f61..9e04cc27d879 100644 --- a/llvm/test/MC/Disassembler/X86/x86-32.txt +++ b/llvm/test/MC/Disassembler/X86/x86-32.txt @@ -943,3 +943,6 @@ # CHECK: enqcmds 8128(%bx,%di), %ax 0x67,0xf3,0x0f,0x38,0xf8,0x81,0xc0,0x1f + +# CHECK: serialize +0x0f 0x01 0xe8 diff --git a/llvm/test/MC/Disassembler/X86/x86-64.txt b/llvm/test/MC/Disassembler/X86/x86-64.txt index 9b4064c3f73a..8ef1363e4c48 100644 --- a/llvm/test/MC/Disassembler/X86/x86-64.txt +++ b/llvm/test/MC/Disassembler/X86/x86-64.txt @@ -691,3 +691,6 @@ # CHECK: enqcmds 485498096, %rax 0xf3,0x0f,0x38,0xf8,0x04,0x25,0xf0,0x1c,0xf0,0x1c + +# CHECK: serialize +0x0f 0x01 0xe8 diff --git a/llvm/test/MC/X86/x86-16.s b/llvm/test/MC/X86/x86-16.s index b849d0aacd2b..531a5302886c 100644 --- a/llvm/test/MC/X86/x86-16.s +++ b/llvm/test/MC/X86/x86-16.s @@ -1029,3 +1029,7 @@ enqcmd (%edi), %edi // CHECK: enqcmds (%edi), %edi // CHECK: encoding: [0x67,0xf3,0x0f,0x38,0xf8,0x3f] enqcmds (%edi), %edi + +// CHECK: serialize +// CHECK: encoding: [0x0f,0x01,0xe8] +serialize diff --git a/llvm/test/MC/X86/x86-32-coverage.s b/llvm/test/MC/X86/x86-32-coverage.s index 1403c7cbfc34..0e6d0afe63b1 100644 --- a/llvm/test/MC/X86/x86-32-coverage.s +++ b/llvm/test/MC/X86/x86-32-coverage.s @@ -10876,3 +10876,7 @@ enqcmds (%bx,%di), %di // CHECK: enqcmds 8128(%bx,%di), %ax // CHECK: encoding: [0x67,0xf3,0x0f,0x38,0xf8,0x81,0xc0,0x1f] enqcmds 8128(%bx,%di), %ax + +// CHECK: serialize +// CHECK: encoding: [0x0f,0x01,0xe8] +serialize diff --git a/llvm/test/MC/X86/x86-64.s b/llvm/test/MC/X86/x86-64.s index b2251ecb4473..8339e675be5b 100644 --- a/llvm/test/MC/X86/x86-64.s +++ b/llvm/test/MC/X86/x86-64.s @@ -1877,3 +1877,7 @@ enqcmds -8192(%rdx), %rbx // CHECK: enqcmds 485498096, %rax // CHECK: encoding: [0xf3,0x0f,0x38,0xf8,0x04,0x25,0xf0,0x1c,0xf0,0x1c] enqcmds 485498096, %rax + +// CHECK: serialize +// CHECK: encoding: [0x0f,0x01,0xe8] +serialize From cfe-commits at lists.llvm.org Thu Apr 2 01:32:00 2020 From: cfe-commits at lists.llvm.org (Daniel Kiss via cfe-commits) Date: Thu, 02 Apr 2020 01:32:00 -0700 (PDT) Subject: [clang] 7314aea - [clang] Move branch-protection from CodeGenOptions to LangOptions Message-ID: <5e85a300.1c69fb81.a07c7.f0c5@mx.google.com> Author: Daniel Kiss Date: 2020-04-02T10:31:52+02:00 New Revision: 7314aea5a42d33f9f5af5d158d8892e88072764e URL: https://github.com/llvm/llvm-project/commit/7314aea5a42d33f9f5af5d158d8892e88072764e DIFF: https://github.com/llvm/llvm-project/commit/7314aea5a42d33f9f5af5d158d8892e88072764e.diff LOG: [clang] Move branch-protection from CodeGenOptions to LangOptions Summary: Reason: the option has an effect on preprocessing. Also see thread: http://lists.llvm.org/pipermail/cfe-dev/2020-March/065014.html Reviewers: chill, efriedma Reviewed By: efriedma Subscribers: efriedma, danielkiss, cfe-commits, kristof.beyls Tags: #clang Differential Revision: https://reviews.llvm.org/D77131 Added: Modified: clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Basic/CodeGenOptions.h clang/include/clang/Basic/LangOptions.def clang/include/clang/Basic/LangOptions.h clang/include/clang/Basic/TargetInfo.h clang/lib/AST/PrintfFormatString.cpp clang/lib/Basic/Targets/AArch64.cpp clang/lib/CodeGen/CGDeclCXX.cpp clang/lib/CodeGen/TargetInfo.cpp clang/lib/Frontend/CompilerInvocation.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index a62cf5e729db..0faa013ac497 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -387,10 +387,6 @@ CODEGENOPT(ForceEmitVTables, 1, 0) /// Whether to emit an address-significance table into the object file. CODEGENOPT(Addrsig, 1, 0) -ENUM_CODEGENOPT(SignReturnAddress, SignReturnAddressScope, 2, SignReturnAddressScope::None) -ENUM_CODEGENOPT(SignReturnAddressKey, SignReturnAddressKeyValue, 1, SignReturnAddressKeyValue::AKey) -CODEGENOPT(BranchTargetEnforcement, 1, 0) - /// Whether to emit unused static constants. CODEGENOPT(KeepStaticConsts, 1, 0) @@ -400,4 +396,3 @@ CODEGENOPT(ForceAAPCSBitfieldLoad, 1, 0) #undef CODEGENOPT #undef ENUM_CODEGENOPT #undef VALUE_CODEGENOPT - diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index d435bebcdcf9..60d418688710 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -110,14 +110,6 @@ class CodeGenOptions : public CodeGenOptionsBase { Embed_Marker // Embed a marker as a placeholder for bitcode. }; - enum class SignReturnAddressScope { - None, // No signing for any function - NonLeaf, // Sign the return address of functions that spill LR - All // Sign the return address of all functions - }; - - enum class SignReturnAddressKeyValue { AKey, BKey }; - enum class FramePointerKind { None, // Omit all frame pointers. NonLeaf, // Keep non-leaf frame pointers. diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 6152e227d599..51dc87b0b671 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -353,6 +353,12 @@ LANGOPT(RegisterStaticDestructors, 1, 1, "Register C++ static destructors") COMPATIBLE_VALUE_LANGOPT(MaxTokens, 32, 0, "Max number of tokens per TU or 0") +ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, SignReturnAddressScopeKind::None, + "Scope of return address signing") +ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, SignReturnAddressKeyKind::AKey, + "Key used for return address signing") +LANGOPT(BranchTargetEnforcement, 1, 0, "Branch-target enforcement enabled") + #undef LANGOPT #undef COMPATIBLE_LANGOPT #undef BENIGN_LANGOPT diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 524ae9a822f4..090263342401 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -229,6 +229,22 @@ class LangOptions : public LangOptionsBase { All, }; + enum class SignReturnAddressScopeKind { + /// No signing for any function. + None, + /// Sign the return address of functions that spill LR. + NonLeaf, + /// Sign the return address of all functions, + All + }; + + enum class SignReturnAddressKeyKind { + /// Return address signing uses APIA key. + AKey, + /// Return address signing uses APIB key. + BKey + }; + public: /// Set of enabled sanitizers. SanitizerSet Sanitize; diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 5edfa0e4e0c7..ab4795404071 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -16,7 +16,7 @@ #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/LLVM.h" -#include "clang/Basic/CodeGenOptions.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/TargetCXXABI.h" #include "clang/Basic/TargetOptions.h" @@ -1138,10 +1138,10 @@ class TargetInfo : public virtual TransferrableTargetInfo, } struct BranchProtectionInfo { - CodeGenOptions::SignReturnAddressScope SignReturnAddr = - CodeGenOptions::SignReturnAddressScope::None; - CodeGenOptions::SignReturnAddressKeyValue SignKey = - CodeGenOptions::SignReturnAddressKeyValue::AKey; + LangOptions::SignReturnAddressScopeKind SignReturnAddr = + LangOptions::SignReturnAddressScopeKind::None; + LangOptions::SignReturnAddressKeyKind SignKey = + LangOptions::SignReturnAddressKeyKind::AKey; bool BranchTargetEnforcement = false; }; diff --git a/clang/lib/AST/PrintfFormatString.cpp b/clang/lib/AST/PrintfFormatString.cpp index bae60d464407..d13ff0a02d17 100644 --- a/clang/lib/AST/PrintfFormatString.cpp +++ b/clang/lib/AST/PrintfFormatString.cpp @@ -11,10 +11,11 @@ // //===----------------------------------------------------------------------===// +#include "FormatStringParsing.h" #include "clang/AST/FormatString.h" #include "clang/AST/OSLog.h" -#include "FormatStringParsing.h" #include "clang/Basic/TargetInfo.h" +#include "llvm/Support/Regex.h" using clang::analyze_format_string::ArgType; using clang::analyze_format_string::FormatStringHandler; diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index e7bfff504a7c..f70a53457613 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "AArch64.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/ArrayRef.h" @@ -121,15 +122,15 @@ bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, return false; BPI.SignReturnAddr = - llvm::StringSwitch(PBP.Scope) - .Case("non-leaf", CodeGenOptions::SignReturnAddressScope::NonLeaf) - .Case("all", CodeGenOptions::SignReturnAddressScope::All) - .Default(CodeGenOptions::SignReturnAddressScope::None); + llvm::StringSwitch(PBP.Scope) + .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf) + .Case("all", LangOptions::SignReturnAddressScopeKind::All) + .Default(LangOptions::SignReturnAddressScopeKind::None); if (PBP.Key == "a_key") - BPI.SignKey = CodeGenOptions::SignReturnAddressKeyValue::AKey; + BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey; else - BPI.SignKey = CodeGenOptions::SignReturnAddressKeyValue::BKey; + BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey; BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement; return true; diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index 3baa0a080f5d..2a01aff9f0f2 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -16,7 +16,7 @@ #include "CodeGenFunction.h" #include "TargetInfo.h" #include "clang/AST/Attr.h" -#include "clang/Basic/CodeGenOptions.h" +#include "clang/Basic/LangOptions.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/MDBuilder.h" @@ -392,20 +392,20 @@ llvm::Function *CodeGenModule::CreateGlobalInitOrDestructFunction( !isInSanitizerBlacklist(SanitizerKind::ShadowCallStack, Fn, Loc)) Fn->addFnAttr(llvm::Attribute::ShadowCallStack); - auto RASignKind = getCodeGenOpts().getSignReturnAddress(); - if (RASignKind != CodeGenOptions::SignReturnAddressScope::None) { + auto RASignKind = getLangOpts().getSignReturnAddressScope(); + if (RASignKind != LangOptions::SignReturnAddressScopeKind::None) { Fn->addFnAttr("sign-return-address", - RASignKind == CodeGenOptions::SignReturnAddressScope::All + RASignKind == LangOptions::SignReturnAddressScopeKind::All ? "all" : "non-leaf"); - auto RASignKey = getCodeGenOpts().getSignReturnAddressKey(); + auto RASignKey = getLangOpts().getSignReturnAddressKey(); Fn->addFnAttr("sign-return-address-key", - RASignKey == CodeGenOptions::SignReturnAddressKeyValue::AKey + RASignKey == LangOptions::SignReturnAddressKeyKind::AKey ? "a_key" : "b_key"); } - if (getCodeGenOpts().BranchTargetEnforcement) + if (getLangOpts().BranchTargetEnforcement) Fn->addFnAttr("branch-target-enforcement"); return Fn; diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index e64fe4f3943d..e2825a3752a1 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -5107,9 +5107,11 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { if (!FD) return; - CodeGenOptions::SignReturnAddressScope Scope = CGM.getCodeGenOpts().getSignReturnAddress(); - CodeGenOptions::SignReturnAddressKeyValue Key = CGM.getCodeGenOpts().getSignReturnAddressKey(); - bool BranchTargetEnforcement = CGM.getCodeGenOpts().BranchTargetEnforcement; + LangOptions::SignReturnAddressScopeKind Scope = + CGM.getLangOpts().getSignReturnAddressScope(); + LangOptions::SignReturnAddressKeyKind Key = + CGM.getLangOpts().getSignReturnAddressKey(); + bool BranchTargetEnforcement = CGM.getLangOpts().BranchTargetEnforcement; if (const auto *TA = FD->getAttr()) { ParsedTargetAttr Attr = TA->parse(); if (!Attr.BranchProtection.empty()) { @@ -5125,14 +5127,14 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { } auto *Fn = cast(GV); - if (Scope != CodeGenOptions::SignReturnAddressScope::None) { + if (Scope != LangOptions::SignReturnAddressScopeKind::None) { Fn->addFnAttr("sign-return-address", - Scope == CodeGenOptions::SignReturnAddressScope::All + Scope == LangOptions::SignReturnAddressScopeKind::All ? "all" : "non-leaf"); Fn->addFnAttr("sign-return-address-key", - Key == CodeGenOptions::SignReturnAddressKeyValue::AKey + Key == LangOptions::SignReturnAddressKeyKind::AKey ? "a_key" : "b_key"); } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 5d0be3c1f1b0..23638e16a5b7 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1387,38 +1387,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.Addrsig = Args.hasArg(OPT_faddrsig); - if (Arg *A = Args.getLastArg(OPT_msign_return_address_EQ)) { - StringRef SignScope = A->getValue(); - - if (SignScope.equals_lower("none")) - Opts.setSignReturnAddress(CodeGenOptions::SignReturnAddressScope::None); - else if (SignScope.equals_lower("all")) - Opts.setSignReturnAddress(CodeGenOptions::SignReturnAddressScope::All); - else if (SignScope.equals_lower("non-leaf")) - Opts.setSignReturnAddress( - CodeGenOptions::SignReturnAddressScope::NonLeaf); - else - Diags.Report(diag::err_drv_invalid_value) - << A->getAsString(Args) << SignScope; - - if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) { - StringRef SignKey = A->getValue(); - if (!SignScope.empty() && !SignKey.empty()) { - if (SignKey.equals_lower("a_key")) - Opts.setSignReturnAddressKey( - CodeGenOptions::SignReturnAddressKeyValue::AKey); - else if (SignKey.equals_lower("b_key")) - Opts.setSignReturnAddressKey( - CodeGenOptions::SignReturnAddressKeyValue::BKey); - else - Diags.Report(diag::err_drv_invalid_value) - << A->getAsString(Args) << SignKey; - } - } - } - - Opts.BranchTargetEnforcement = Args.hasArg(OPT_mbranch_target_enforce); - Opts.KeepStaticConsts = Args.hasArg(OPT_fkeep_static_consts); Opts.SpeculativeLoadHardening = Args.hasArg(OPT_mspeculative_load_hardening); @@ -3348,6 +3316,40 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.BuildingPCHWithObjectFile = Args.hasArg(OPT_building_pch_with_obj); Opts.MaxTokens = getLastArgIntValue(Args, OPT_fmax_tokens_EQ, 0, Diags); + + if (Arg *A = Args.getLastArg(OPT_msign_return_address_EQ)) { + StringRef SignScope = A->getValue(); + + if (SignScope.equals_lower("none")) + Opts.setSignReturnAddressScope( + LangOptions::SignReturnAddressScopeKind::None); + else if (SignScope.equals_lower("all")) + Opts.setSignReturnAddressScope( + LangOptions::SignReturnAddressScopeKind::All); + else if (SignScope.equals_lower("non-leaf")) + Opts.setSignReturnAddressScope( + LangOptions::SignReturnAddressScopeKind::NonLeaf); + else + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << SignScope; + + if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) { + StringRef SignKey = A->getValue(); + if (!SignScope.empty() && !SignKey.empty()) { + if (SignKey.equals_lower("a_key")) + Opts.setSignReturnAddressKey( + LangOptions::SignReturnAddressKeyKind::AKey); + else if (SignKey.equals_lower("b_key")) + Opts.setSignReturnAddressKey( + LangOptions::SignReturnAddressKeyKind::BKey); + else + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << SignKey; + } + } + } + + Opts.BranchTargetEnforcement = Args.hasArg(OPT_mbranch_target_enforce); } static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) { From cfe-commits at lists.llvm.org Thu Apr 2 01:36:01 2020 From: cfe-commits at lists.llvm.org (Maximilian Fickert via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 08:36:01 +0000 (UTC) Subject: [PATCH] D75034: [clang-format] use spaces for alignment with UT_ForContinuationAndIndentation In-Reply-To: References: Message-ID: <862922819a2ee936bd2665ce4e24715f@localhost.localdomain> fickert added a comment. Great, thank you! I do not have push access to the repository, so someone else would need to commit this for me: Maximilian Fickert Should I add the fix for the test cases missing the tab configuration (see my last inline comment: https://reviews.llvm.org/D75034#inline-703423)? Or submit it as a separate change set? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75034/new/ https://reviews.llvm.org/D75034 From cfe-commits at lists.llvm.org Thu Apr 2 01:36:01 2020 From: cfe-commits at lists.llvm.org (Momchil Velikov via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 08:36:01 +0000 (UTC) Subject: [PATCH] D71129: [ARM][CMSE] Implement CMSE attributes In-Reply-To: References: Message-ID: <04c43da2d008ec45471f560ae19947e5@localhost.localdomain> chill added a comment. In D71129#1956137 , @snidertm wrote: > Have you already committed support for CMSE attributes to the LLVM backend? Or is that on the way? The last two CMSE patches are under review: https://reviews.llvm.org/D76518 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71129/new/ https://reviews.llvm.org/D71129 From cfe-commits at lists.llvm.org Thu Apr 2 01:36:10 2020 From: cfe-commits at lists.llvm.org (Daniel Kiss via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 08:36:10 +0000 (UTC) Subject: [PATCH] D77131: [clang] Move branch-protection from CodeGenOptions to LangOptions In-Reply-To: References: Message-ID: <8496be42999b5c25bad5db48834d2707@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG7314aea5a42d: [clang] Move branch-protection from CodeGenOptions to LangOptions (authored by danielkiss). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77131/new/ https://reviews.llvm.org/D77131 Files: clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Basic/CodeGenOptions.h clang/include/clang/Basic/LangOptions.def clang/include/clang/Basic/LangOptions.h clang/include/clang/Basic/TargetInfo.h clang/lib/AST/PrintfFormatString.cpp clang/lib/Basic/Targets/AArch64.cpp clang/lib/CodeGen/CGDeclCXX.cpp clang/lib/CodeGen/TargetInfo.cpp clang/lib/Frontend/CompilerInvocation.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77131.254446.patch Type: text/x-patch Size: 12830 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 01:36:12 2020 From: cfe-commits at lists.llvm.org (Xiang Zhang via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 08:36:12 +0000 (UTC) Subject: [PATCH] D77193: [X86] Add SERIALIZE instruction. In-Reply-To: References: Message-ID: <67d55ea3017292e8dff77546286de95e@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGd08fadd6628a: [X86] Add SERIALIZE instruction. (authored by tianqing, committed by xiangzhangllvm). Changed prior to commit: https://reviews.llvm.org/D77193?vs=254114&id=254447#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77193/new/ https://reviews.llvm.org/D77193 Files: clang/docs/ClangCommandLineReference.rst clang/include/clang/Basic/BuiltinsX86.def clang/include/clang/Driver/Options.td clang/lib/Basic/Targets/X86.cpp clang/lib/Basic/Targets/X86.h clang/lib/Headers/CMakeLists.txt clang/lib/Headers/cpuid.h clang/lib/Headers/immintrin.h clang/lib/Headers/serializeintrin.h clang/test/CodeGen/x86-serialize-intrin.c clang/test/Driver/x86-target-features.c clang/test/Preprocessor/x86_target_features.c llvm/include/llvm/IR/IntrinsicsX86.td llvm/lib/Support/Host.cpp llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86InstrInfo.td llvm/lib/Target/X86/X86Subtarget.h llvm/test/CodeGen/X86/serialize-intrinsic.ll llvm/test/MC/Disassembler/X86/x86-16.txt llvm/test/MC/Disassembler/X86/x86-32.txt llvm/test/MC/Disassembler/X86/x86-64.txt llvm/test/MC/X86/x86-16.s llvm/test/MC/X86/x86-32-coverage.s llvm/test/MC/X86/x86-64.s -------------- next part -------------- A non-text attachment was scrubbed... Name: D77193.254447.patch Type: text/x-patch Size: 15290 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 02:08:46 2020 From: cfe-commits at lists.llvm.org (Momchil Velikov via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 09:08:46 +0000 (UTC) Subject: [PATCH] D71129: [ARM][CMSE] Implement CMSE attributes In-Reply-To: References: Message-ID: chill marked 4 inline comments as done. chill added inline comments. ================ Comment at: clang/lib/CodeGen/CGCall.cpp:1882 + if (FI.isCmseNSCall()) + FuncAttrs.addAttribute("cmse_nonsecure_call"); + ---------------- snidertm wrote: > Just curious … Does the LLVM backend have a way to extract a StringRef attribute from a CallInst? I know that you can do that with hasFnAttribute(), but I don't see anything for CallInst objects CallInst *CI = ... ; ... = CI->getAttributes().hasFnAttribute("cmse_nonsecure_call")) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71129/new/ https://reviews.llvm.org/D71129 From cfe-commits at lists.llvm.org Thu Apr 2 02:08:47 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 09:08:47 +0000 (UTC) Subject: [PATCH] D76818: [clang-tidy] Add check llvmlibc-implementation-in-namespace. In-Reply-To: References: Message-ID: njames93 added a comment. This check needs a store Options override method as it reading options from a configuration. Check other checks to see how this is done. ================ Comment at: clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.h:35 +private: + std::string RequiredNamespace; +}; ---------------- This can be made const Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76818/new/ https://reviews.llvm.org/D76818 From cfe-commits at lists.llvm.org Thu Apr 2 02:08:53 2020 From: cfe-commits at lists.llvm.org (Vlastimil Labsky via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 09:08:53 +0000 (UTC) Subject: [PATCH] D77221: [AVR] Rework MCU family detection to support more AVR MCUs In-Reply-To: References: Message-ID: <33838b99ac0261d630450d932850d39e@localhost.localdomain> vlastik updated this revision to Diff 254456. vlastik added a comment. Fix regression introduced by patch Failed unit tests: - Clang.Driver::avr-link-mcu-family-unimplemented.c - Clang.Misc::target-invalid-cpu-note.c CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77221/new/ https://reviews.llvm.org/D77221 Files: clang/lib/Basic/Targets/AVR.cpp clang/lib/Basic/Targets/AVR.h clang/lib/Driver/ToolChains/AVR.cpp llvm/include/llvm/Support/AVRTargetParser.h llvm/lib/Support/AVRTargetParser.cpp llvm/lib/Support/CMakeLists.txt -------------- next part -------------- A non-text attachment was scrubbed... Name: D77221.254456.patch Type: text/x-patch Size: 32121 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 02:41:00 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 09:41:00 +0000 (UTC) Subject: [PATCH] D77225: [clangd] Support textDocument/semanticTokens/edits In-Reply-To: References: Message-ID: <3f29c67e71bc53f6e1a88b6f56f9edb1@localhost.localdomain> hokein accepted this revision. hokein added a comment. This revision is now accepted and ready to land. this is neat, and the new semantic highlighting protocol is much nicer than the old one. ================ Comment at: clang-tools-extra/clangd/ClangdLSPServer.cpp:1245 +static void increment(std::string &S) { + for (char &C : llvm::reverse(S)) { + if (C != '9') { ---------------- nit: add assert(C >= '0' && C <= '9'). ================ Comment at: clang-tools-extra/clangd/SemanticHighlighting.cpp:605 +diffTokens(llvm::ArrayRef Old, + llvm::ArrayRef New) { + // For now, just replace everything from the first-last modification. ---------------- nit: assert Old and New are sorted. ================ Comment at: clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp:734 + Results.push_back({HighlightingKind::Variable, R}); + for (unsigned I = 0; I < static_cast(HighlightingKind::LastKind); ++I) { + HighlightingKind Kind = static_cast(I); ---------------- should be `<=`? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77225/new/ https://reviews.llvm.org/D77225 From cfe-commits at lists.llvm.org Thu Apr 2 02:41:02 2020 From: cfe-commits at lists.llvm.org (Pratyai Mazumder via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 09:41:02 +0000 (UTC) Subject: [PATCH] D77244: sancov/inline-bool-flag feature + tests + docs. In-Reply-To: References: Message-ID: pratyai updated this revision to Diff 254461. pratyai added a comment. Undid the `arc lint` on autocomplete.c. `arc lint` does not seem to have an option --style, but it's just one line diff anyway. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77244/new/ https://reviews.llvm.org/D77244 Files: clang/docs/SanitizerCoverage.rst clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/CC1Options.td clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/SanitizerArgs.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/Driver/autocomplete.c clang/test/Driver/fsanitize-coverage.c compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp llvm/include/llvm/Transforms/Instrumentation.h llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp llvm/test/Instrumentation/SanitizerCoverage/coff-pc-table-inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-inline-bool-flag.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D77244.254461.patch Type: text/x-patch Size: 29886 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 02:41:03 2020 From: cfe-commits at lists.llvm.org (Pratyai Mazumder via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 09:41:03 +0000 (UTC) Subject: [PATCH] D77244: sancov/inline-bool-flag feature + tests + docs. In-Reply-To: References: Message-ID: pratyai updated this revision to Diff 254462. pratyai added a comment. Did the same for fsanitize-coverage.c. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77244/new/ https://reviews.llvm.org/D77244 Files: clang/docs/SanitizerCoverage.rst clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/CC1Options.td clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/SanitizerArgs.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/Driver/autocomplete.c clang/test/Driver/fsanitize-coverage.c compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp llvm/include/llvm/Transforms/Instrumentation.h llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp llvm/test/Instrumentation/SanitizerCoverage/coff-pc-table-inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-inline-bool-flag.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D77244.254462.patch Type: text/x-patch Size: 29841 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 03:13:54 2020 From: cfe-commits at lists.llvm.org (Pratyai Mazumder via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 10:13:54 +0000 (UTC) Subject: [PATCH] D77244: sancov/inline-bool-flag feature + tests + docs. In-Reply-To: References: Message-ID: <8b6b37ccf9bb164123523e81bdbec0d0@localhost.localdomain> pratyai updated this revision to Diff 254470. pratyai added a comment. And missed a space. Sorry, I'm just not very familiar with this kind of test, and cannot spot the mistakes before going to the web UI. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77244/new/ https://reviews.llvm.org/D77244 Files: clang/docs/SanitizerCoverage.rst clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/CC1Options.td clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/SanitizerArgs.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/Driver/autocomplete.c clang/test/Driver/fsanitize-coverage.c compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp llvm/include/llvm/Transforms/Instrumentation.h llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp llvm/test/Instrumentation/SanitizerCoverage/coff-pc-table-inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-inline-bool-flag.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D77244.254470.patch Type: text/x-patch Size: 29854 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 03:13:54 2020 From: cfe-commits at lists.llvm.org (Pratyai Mazumder via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 10:13:54 +0000 (UTC) Subject: [PATCH] D77244: sancov/inline-bool-flag feature + tests + docs. In-Reply-To: References: Message-ID: <65a576599ca18cd3264f33a208cc96be@localhost.localdomain> pratyai updated this revision to Diff 254468. pratyai added a comment. fsanitize-coverage.c undo was incorrect the first time :( Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77244/new/ https://reviews.llvm.org/D77244 Files: clang/docs/SanitizerCoverage.rst clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/CC1Options.td clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/SanitizerArgs.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/Driver/autocomplete.c clang/test/Driver/fsanitize-coverage.c compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp llvm/include/llvm/Transforms/Instrumentation.h llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp llvm/test/Instrumentation/SanitizerCoverage/coff-pc-table-inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-inline-bool-flag.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D77244.254468.patch Type: text/x-patch Size: 29853 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 03:54:28 2020 From: cfe-commits at lists.llvm.org (Daniel Kiss via cfe-commits) Date: Thu, 02 Apr 2020 03:54:28 -0700 (PDT) Subject: [clang] 37ced5a - [clang][AARCH64] Add __ARM_FEATURE_{PAC, BTI}_DEFAULT defines Message-ID: <5e85c464.1c69fb81.97a0.ffd9@mx.google.com> Author: Daniel Kiss Date: 2020-04-02T12:54:21+02:00 New Revision: 37ced5a571066c11548c672f354c6091f5903991 URL: https://github.com/llvm/llvm-project/commit/37ced5a571066c11548c672f354c6091f5903991 DIFF: https://github.com/llvm/llvm-project/commit/37ced5a571066c11548c672f354c6091f5903991.diff LOG: [clang][AARCH64] Add __ARM_FEATURE_{PAC, BTI}_DEFAULT defines Summary: As defined by Arm C Language Extensions (ACLE) these macro defines should be set to specific values depending on -mbranch-protection. Reviewers: chill Reviewed By: chill Subscribers: danielkiss, cfe-commits, kristof.beyls Tags: #clang Differential Revision: https://reviews.llvm.org/D77134 Added: Modified: clang/include/clang/Basic/LangOptions.h clang/lib/Basic/Targets/AArch64.cpp clang/test/Preprocessor/aarch64-target-features.c Removed: ################################################################################ diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 090263342401..0a0cbaf80ae8 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -367,6 +367,21 @@ class LangOptions : public LangOptionsBase { /// Return the OpenCL C or C++ version as a VersionTuple. VersionTuple getOpenCLVersionTuple() const; + + /// Check if return address signing is enabled. + bool hasSignReturnAddress() const { + return getSignReturnAddressScope() != SignReturnAddressScopeKind::None; + } + + /// Check if return address signing uses AKey. + bool isSignReturnAddressWithAKey() const { + return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey; + } + + /// Check if leaf functions are also signed. + bool isSignReturnAddressScopeAll() const { + return getSignReturnAddressScope() == SignReturnAddressScopeKind::All; + } }; /// Floating point control options diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index f70a53457613..8ceb7f2b515e 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -283,6 +283,27 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, if ((FPU & NeonMode) && HasFP16FML) Builder.defineMacro("__ARM_FEATURE_FP16FML", "1"); + if (Opts.hasSignReturnAddress()) { + // Bitmask: + // 0: Protection using the A key + // 1: Protection using the B key + // 2: Protection including leaf functions + unsigned Value = 0; + + if (Opts.isSignReturnAddressWithAKey()) + Value |= (1 << 0); + else + Value |= (1 << 1); + + if (Opts.isSignReturnAddressScopeAll()) + Value |= (1 << 2); + + Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", std::to_string(Value)); + } + + if (Opts.BranchTargetEnforcement) + Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1"); + switch (ArchKind) { default: break; diff --git a/clang/test/Preprocessor/aarch64-target-features.c b/clang/test/Preprocessor/aarch64-target-features.c index c62c82a0c96a..9cb12f8afb32 100644 --- a/clang/test/Preprocessor/aarch64-target-features.c +++ b/clang/test/Preprocessor/aarch64-target-features.c @@ -39,6 +39,8 @@ // CHECK-NOT: __ARM_SIZEOF_WCHAR_T 2 // CHECK-NOT: __ARM_FEATURE_SVE // CHECK-NOT: __ARM_FEATURE_DOTPROD +// CHECK-NOT: __ARM_FEATURE_PAC_DEFAULT +// CHECK-NOT: __ARM_FEATURE_BTI_DEFAULT // RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+crypto -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-CRYPTO %s // RUN: %clang -target arm64-none-linux-gnu -march=armv8-a+crypto -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-CRYPTO %s @@ -334,3 +336,33 @@ // ================== Check Memory Tagging Extensions (MTE). // RUN: %clang -target arm64-none-linux-gnu -march=armv8.5-a+memtag -x c -E -dM %s -o - 2>&1 | FileCheck -check-prefix=CHECK-MEMTAG %s // CHECK-MEMTAG: __ARM_FEATURE_MEMORY_TAGGING 1 + +// ================== Check Pointer Authentication Extension (PAuth). +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8.5-a -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=none -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=bti -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=standard -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+b-key -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-BKEY %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+leaf -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-ALL %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+leaf+b-key -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-PAUTH-BKEY-ALL %s +// CHECK-PAUTH-OFF-NOT: __ARM_FEATURE_PAC_DEFAULT +// CHECK-PAUTH: #define __ARM_FEATURE_PAC_DEFAULT 1 +// CHECK-PAUTH-BKEY: #define __ARM_FEATURE_PAC_DEFAULT 2 +// CHECK-PAUTH-ALL: #define __ARM_FEATURE_PAC_DEFAULT 5 +// CHECK-PAUTH-BKEY-ALL: #define __ARM_FEATURE_PAC_DEFAULT 6 + +// ================== Check Branch Target Identification (BTI). +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8.5-a -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=none -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+leaf -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+b-key -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+leaf+b-key -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI-OFF %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=standard -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=bti -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI %s +// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a -mbranch-protection=pac-ret+bti -x c -E -dM %s -o - | FileCheck -check-prefix=CHECK-BTI %s +// CHECK-BTI-OFF-NOT: __ARM_FEATURE_BTI_DEFAULT +// CHECK-BTI: #define __ARM_FEATURE_BTI_DEFAULT 1 From cfe-commits at lists.llvm.org Thu Apr 2 03:55:27 2020 From: cfe-commits at lists.llvm.org (Lucas Prates via cfe-commits) Date: Thu, 02 Apr 2020 03:55:27 -0700 (PDT) Subject: [clang] e6cb4b6 - [Clang][CodeGen] Fixing mismatch between memory layout and const expressions for oversized bitfields Message-ID: <5e85c49f.1c69fb81.4d2eb.0484@mx.google.com> Author: Lucas Prates Date: 2020-04-02T11:55:20+01:00 New Revision: e6cb4b659af9f9c1a4c179093b187e7ad7cc5770 URL: https://github.com/llvm/llvm-project/commit/e6cb4b659af9f9c1a4c179093b187e7ad7cc5770 DIFF: https://github.com/llvm/llvm-project/commit/e6cb4b659af9f9c1a4c179093b187e7ad7cc5770.diff LOG: [Clang][CodeGen] Fixing mismatch between memory layout and const expressions for oversized bitfields Summary: The construction of constants for structs/unions was conflicting the expected memory layout for over-sized bit-fields. When building the necessary bits for those fields, clang was ignoring the size information computed for the struct/union memory layout and using the original data from the AST's FieldDecl information. This caused an issue in big-endian targets, where the field's contant was incorrectly misplaced due to endian calculations. This patch aims to separate the constant value from the necessary padding bits, using the proper size information for each one of them. With this, the layout of constants for over-sized bit-fields matches the ABI requirements. Reviewers: rsmith, eli.friedman, efriedma Reviewed By: efriedma Subscribers: efriedma, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77048 Added: Modified: clang/lib/CodeGen/CGExprConstant.cpp clang/test/CodeGenCXX/bitfield-layout.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index e17c1c5f7ac4..da5d778a4922 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -589,19 +589,21 @@ bool ConstStructBuilder::AppendBytes(CharUnits FieldOffsetInChars, bool ConstStructBuilder::AppendBitField( const FieldDecl *Field, uint64_t FieldOffset, llvm::ConstantInt *CI, bool AllowOverwrite) { - uint64_t FieldSize = Field->getBitWidthValue(CGM.getContext()); + const CGRecordLayout &RL = + CGM.getTypes().getCGRecordLayout(Field->getParent()); + const CGBitFieldInfo &Info = RL.getBitFieldInfo(Field); llvm::APInt FieldValue = CI->getValue(); // Promote the size of FieldValue if necessary // FIXME: This should never occur, but currently it can because initializer // constants are cast to bool, and because clang is not enforcing bitfield // width limits. - if (FieldSize > FieldValue.getBitWidth()) - FieldValue = FieldValue.zext(FieldSize); + if (Info.Size > FieldValue.getBitWidth()) + FieldValue = FieldValue.zext(Info.Size); // Truncate the size of FieldValue to the bit field size. - if (FieldSize < FieldValue.getBitWidth()) - FieldValue = FieldValue.trunc(FieldSize); + if (Info.Size < FieldValue.getBitWidth()) + FieldValue = FieldValue.trunc(Info.Size); return Builder.addBits(FieldValue, CGM.getContext().toBits(StartOffset) + FieldOffset, diff --git a/clang/test/CodeGenCXX/bitfield-layout.cpp b/clang/test/CodeGenCXX/bitfield-layout.cpp index 46f41111a1de..d8f8c87eb28b 100644 --- a/clang/test/CodeGenCXX/bitfield-layout.cpp +++ b/clang/test/CodeGenCXX/bitfield-layout.cpp @@ -1,11 +1,14 @@ -// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -O3 | FileCheck -check-prefix CHECK-LP64 %s -// RUN: %clang_cc1 %s -triple=i386-apple-darwin10 -emit-llvm -o - -O3 | FileCheck -check-prefix CHECK-LP32 %s +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -O3 | FileCheck -check-prefix=CHECK-LP64 -check-prefix=CHECK %s +// RUN: %clang_cc1 %s -triple=i386-apple-darwin10 -emit-llvm -o - -O3 | FileCheck -check-prefix CHECK-LP32 -check-prefix=CHECK %s +// RUN: %clang_cc1 %s -triple=aarch64_be-none-eabi -emit-llvm -o - -O3 | FileCheck -check-prefix CHECK-A64BE -check-prefix=CHECK %s +// RUN: %clang_cc1 %s -triple=thumbv7_be-none-eabi -emit-llvm -o - -O3 | FileCheck -check-prefix CHECK-A32BE -check-prefix=CHECK %s // CHECK-LP64: %union.Test1 = type { i32, [4 x i8] } union Test1 { int a; int b: 39; -} t1; +}; +Test1 t1; // CHECK-LP64: %union.Test2 = type { i8 } union Test2 { @@ -17,10 +20,16 @@ union Test3 { int : 9; } t3; +// CHECK: %union.Test4 = type { i8, i8 } +union Test4 { + char val : 16; +}; +Test4 t4; #define CHECK(x) if (!(x)) return __LINE__ -int f() { +// CHECK: define i32 @_Z11test_assignv() +int test_assign() { struct { int a; @@ -37,7 +46,41 @@ int f() { CHECK(c.b == (unsigned long long)-1); CHECK(c.c == 0); -// CHECK-LP64: ret i32 0 -// CHECK-LP32: ret i32 0 + Test1 u1; + Test4 u2; + + u1.b = 1; + u2.val = 42; + + CHECK(u1.b == 1); + CHECK(u2.val == 42); + + // CHECK: ret i32 0 + return 0; +} + +// CHECK: define i32 @_Z9test_initv() +int test_init() { + struct S { + int a; + + unsigned long long b : 65; + + int c; + }; + S s1 = {1, 42, 0}; + + CHECK(s1.a == 1); + CHECK(s1.b == (unsigned long long)42); + CHECK(s1.c == 0); + + Test1 u1 = {1}; + Test4 u2 = {42}; + + CHECK(u1.a == 1); + CHECK(u1.b == 1); + CHECK(u2.val == 42); + + // CHECK: ret i32 0 return 0; } From cfe-commits at lists.llvm.org Wed Apr 1 16:21:12 2020 From: cfe-commits at lists.llvm.org (Nemanja Ivanovic via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 23:21:12 +0000 (UTC) Subject: [PATCH] D77249: [MSan] Pass command line options to MSan with new pass manager Message-ID: nemanjai created this revision. nemanjai added reviewers: eugenis, vitalybuka, philip.pfaffe, leonardchan, PowerPC. Herald added projects: clang, Sanitizers. Herald added subscribers: Sanitizers, cfe-commits. There are a number of test cases that fail when clang is built to use NPM by default. This is due to a number of issues. One of those issues is that when we construct the memory sanitizer instrumentation pass with the NPM, we do not pass in the pertinent flags. This patch focuses on that issue. For testing, this patch simply duplicates the tests that fail due to this issue and adds `-fexperimental-new-pass-manager` to the compile step. Once the NPM is the default, we can presumably remove those test cases. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77249 Files: clang/lib/CodeGen/BackendUtil.cpp compiler-rt/test/msan/chained_origin_empty_stack_npm.cpp compiler-rt/test/msan/chained_origin_limits_npm.cpp compiler-rt/test/msan/chained_origin_memcpy_npm.cpp compiler-rt/test/msan/chained_origin_npm.cpp compiler-rt/test/msan/select_float_origin_npm.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77249.254329.patch Type: text/x-patch Size: 17882 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Wed Apr 1 16:54:32 2020 From: cfe-commits at lists.llvm.org (Hendrik Greving via Phabricator via cfe-commits) Date: Wed, 01 Apr 2020 23:54:32 +0000 (UTC) Subject: [PATCH] D74183: [IRGen] Add an alignment attribute to underaligned sret parameters In-Reply-To: References: Message-ID: <4130958e434babc1d791a8a826fdd162@localhost.localdomain> hgreving added a comment. In D74183#1942262 , @nikic wrote: > In D74183#1941741 , @efriedma wrote: > > > If it's just tramp3d-v4, I'm not that concerned... but that's a weird result. On x86 in particular, alignment markings have almost no effect on optimization, generally. > > > I've just looked at the IR diff for tramp3d-v4 and it turns out that the root cause is an old friend of mine: The insertion of alignment assumptions during inlining (https://github.com/llvm/llvm-project/blob/b58902bc72c2b479b5ed27ec0d3422ba9782edbb/llvm/lib/Transforms/Utils/InlineFunction.cpp#L1139-L1173). That is, the IR now contains many instances of this sequence: > > %ptrint = ptrtoint %class.GuardLayers* %guards_m to i64 > %maskedptr = and i64 %ptrint, 3 > %maskcond = icmp eq i64 %maskedptr, 0 > tail call void @llvm.assume(i1 %maskcond) > > > to preserve the alignment information. From a cursory look I cannot tell whether these additional assumes also regress optimization (due to multi-use), but given the size increase on the final binary it seems pretty likely that this is the case. > > This preservation of alignment during inlining is the reason why we used to not emit alignment information for pointer arguments in Rust for a long time: It caused serious regressions in optimization and increased compile-time. Nowadays we do emit alignment information, but set `-preserve-alignment-assumptions-during-inlining=false` to prevent this inlining behavior. > > I think for the purposes of this revision, this means that we should probably either a) default `preserve-alignment-assumptions-during-inlining` to false (I would prefer this) or b) not emit the alignment unless it is smaller than the ABI alignment (I guess this was what this patch originally did?) We are having a problem with this very issue on a target not supporting a stack, with sroa bailing due to above, in our case causing a crash. Our only workaround for this is currently `preserve-alignment-assumptions-during-inlining` to false. We were actually wondering if this is causing performance issues on targets that due support a stack. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D74183/new/ https://reviews.llvm.org/D74183 From cfe-commits at lists.llvm.org Wed Apr 1 18:32:33 2020 From: cfe-commits at lists.llvm.org (Vitaly Buka via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 01:32:33 +0000 (UTC) Subject: [PATCH] D77249: [MSan] Pass command line options to MSan with new pass manager In-Reply-To: References: Message-ID: <9e13e01aaaf2c0e9a951442c54af5dee@localhost.localdomain> vitalybuka added inline comments. ================ Comment at: compiler-rt/test/msan/chained_origin_empty_stack_npm.cpp:4 +// this test. +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 \ +// RUN: -fexperimental-new-pass-manager -O3 %s -o %t && \ ---------------- Why not to add RUN: section with -fexperimental-new-pass-manager into original tests? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77249/new/ https://reviews.llvm.org/D77249 From cfe-commits at lists.llvm.org Wed Apr 1 19:37:17 2020 From: cfe-commits at lists.llvm.org (Nemanja Ivanovic via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 02:37:17 +0000 (UTC) Subject: [PATCH] D77249: [MSan] Pass command line options to MSan with new pass manager In-Reply-To: References: Message-ID: nemanjai marked an inline comment as done. nemanjai added inline comments. ================ Comment at: compiler-rt/test/msan/chained_origin_empty_stack_npm.cpp:4 +// this test. +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 \ +// RUN: -fexperimental-new-pass-manager -O3 %s -o %t && \ ---------------- vitalybuka wrote: > Why not to add RUN: section with -fexperimental-new-pass-manager into original tests? I just felt that this is a simpler way forward for a couple of reasons: 1. Once the default switches, it is a very obvious change to just delete these files rather than digging through the code inside the existing ones 2. Many of the tests actually contain the testing that is split up into multiple steps so I would have to duplicate all the steps for the NPM vs. default builds: - compile/link - run with one option set and FileCheck - run with another option set and FileCheck - rinse/repeat (example: chained_origin_limits.cpp) But of course, if there are strong objections to this approach, I can certainly go the other way. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77249/new/ https://reviews.llvm.org/D77249 From cfe-commits at lists.llvm.org Wed Apr 1 22:50:48 2020 From: cfe-commits at lists.llvm.org (Nemanja Ivanovic via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 05:50:48 +0000 (UTC) Subject: [PATCH] D77249: [MSan] Pass command line options to MSan with new pass manager In-Reply-To: References: Message-ID: <8caff84535070c9b995236d82ac2932d@localhost.localdomain> nemanjai marked an inline comment as done. nemanjai added inline comments. ================ Comment at: compiler-rt/test/msan/chained_origin_empty_stack_npm.cpp:4 +// this test. +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 \ +// RUN: -fexperimental-new-pass-manager -O3 %s -o %t && \ ---------------- nemanjai wrote: > vitalybuka wrote: > > Why not to add RUN: section with -fexperimental-new-pass-manager into original tests? > I just felt that this is a simpler way forward for a couple of reasons: > 1. Once the default switches, it is a very obvious change to just delete these files rather than digging through the code inside the existing ones > 2. Many of the tests actually contain the testing that is split up into multiple steps so I would have to duplicate all the steps for the NPM vs. default builds: > - compile/link > - run with one option set and FileCheck > - run with another option set and FileCheck > - rinse/repeat > (example: chained_origin_limits.cpp) > > But of course, if there are strong objections to this approach, I can certainly go the other way. Seems Phabricator reformatted what I wrote here. Points 3, 4, 5, 6 were supposed to be sub-bullets for 2. Basically, I tried to describe that in the mentioned test case, I would have to replicate a number of subsequent steps for each `RUN` directive that invokes the compiler. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77249/new/ https://reviews.llvm.org/D77249 From cfe-commits at lists.llvm.org Thu Apr 2 04:18:48 2020 From: cfe-commits at lists.llvm.org (Andrzej Warzynski via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 11:18:48 +0000 (UTC) Subject: [PATCH] D76929: [AArch64][SVE] Add SVE intrinsic for LD1RQ In-Reply-To: References: Message-ID: <76210204292525d80d0decb1148b268d@localhost.localdomain> andwar added a comment. Cheers for working on this @kmclaughlin ! ================ Comment at: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp:1407 case AArch64ISD::PTRUE: return "AArch64ISD::PTRUE"; + case AArch64ISD::LD1RQ: return "AArch64ISD::LD1RQ"; case AArch64ISD::LDNF1: return "AArch64ISD::LDNF1"; ---------------- [nit] In AArch64ISelLowering.h you added `LD1RQ` as the last load instruction, here it's the first load instruction. ================ Comment at: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp:11592 +static SDValue performLD1RQCombine(SDNode *N, SelectionDAG &DAG) { + SDLoc DL(N); ---------------- [Nit] I think that this method could be simplified and made more explicit: ``` static SDValue performLD1RQCombine(SDNode *N, SelectionDAG &DAG) { SDLoc DL(N); EVT VT = N->getValueType(0); EVT LoadVT = VT; if (VT.isFloatingPoint()) LoadVT = VT.changeTypeToInteger(); SDValue Ops[] = {N->getOperand(0), N->getOperand(2), N->getOperand(3)}; SDValue Load = DAG.getNode(AArch64ISD::LD1RQ, DL, {LoadVT, MVT::Other}, Ops); if (VT.isFloatingPoint()) { SDValue LoadChain = SDValue(Load.getNode(), 1); Load = DAG.getMergeValues( {DAG.getNode(ISD::BITCAST, DL, VT, Load), LoadChain}, DL); } return Load; } ``` This way: * there's only 1 `return` statement * you are being explicit about preserving the chain when generating the bit cast * `Load` replaces a bit non-descriptive `L` This is a matter of style, so please use what feels best. ================ Comment at: llvm/lib/Target/AArch64/AArch64InstrFormats.td:495 +}]>; +def SImmS16XForm : SDNodeXFormgetTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64); ---------------- IIUC, only this definition is need for `LD1RQ`. Could you add a note in the commit message to highlight that `SImmS2XForm`, `SImmS3XForm` and `SImmS4XForm` are added for consistency? Alternatively, only keep that one that's needed. ================ Comment at: llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td:16 // Non-faulting loads - node definitions // ---------------- This comment should read `Non-faulting & first-faulting loads - node definitions`. That's my fault,, sorry! ================ Comment at: llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td:23 +def SDT_AArch64_LD1RQ : SDTypeProfile<1, 2, [ + SDTCisVec<0>, SDTCisVec<1>, SDTCisPtrTy<2>, ---------------- The (undocumented) style here is: ``` // - node definitions // // - node definitions // ``` Could you move `LD1RQ` to a dedicated block and add a comment? Ta! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76929/new/ https://reviews.llvm.org/D76929 From cfe-commits at lists.llvm.org Thu Apr 2 04:18:49 2020 From: cfe-commits at lists.llvm.org (Pratyai Mazumder via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 11:18:49 +0000 (UTC) Subject: [PATCH] D77244: sancov/inline-bool-flag feature + tests + docs. In-Reply-To: References: Message-ID: <4059e503b8f5be9f53a0dca2a47d89f4@localhost.localdomain> pratyai added a comment. It looks like I broke the tests after the `i8 `-> `i1` switch. I think it's because of an existing bug. From https://llvm.org/docs/LangRef.html > i1:8:8 - i1 is 8-bit (byte) aligned OTOH, in `SanitizerCoverage.cpp`, we have in `CreateFunctionLocalArrayInSection()`: Array->setAlignment(Align(Ty->isPointerTy() ? DL->getPointerSize() : Ty->getPrimitiveSizeInBits() / 8)); IIUC `getPrimitiveSizeInBits() / 8` would be `1 / 8 => 0` for `i1` type (it works for other `int` types which have multiple-of-8 bits. PLMK if my assessment is correct, and if so if I should fix it in a separate patch, or just keep that in here. I'll leave this patch "un-split" for now. Thanks! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77244/new/ https://reviews.llvm.org/D77244 From cfe-commits at lists.llvm.org Thu Apr 2 04:19:12 2020 From: cfe-commits at lists.llvm.org (Daniel Kiss via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 11:19:12 +0000 (UTC) Subject: [PATCH] D77134: [clang][AARCH64] Add __ARM_FEATURE_{PAC, BTI}_DEFAULT defines In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rG37ced5a57106: [clang][AARCH64] Add __ARM_FEATURE_{PAC, BTI}_DEFAULT defines (authored by danielkiss). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77134/new/ https://reviews.llvm.org/D77134 Files: clang/include/clang/Basic/LangOptions.h clang/lib/Basic/Targets/AArch64.cpp clang/test/Preprocessor/aarch64-target-features.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77134.254482.patch Type: text/x-patch Size: 6152 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 04:19:17 2020 From: cfe-commits at lists.llvm.org (Lucas Prates via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 11:19:17 +0000 (UTC) Subject: [PATCH] D77048: [Clang][CodeGen] Fixing mismatch between memory layout and const expressions for oversized bitfields In-Reply-To: References: Message-ID: <872b9552ee29cf3fc121b0373a22f338@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGe6cb4b659af9: [Clang][CodeGen] Fixing mismatch between memory layout and const expressions… (authored by pratlucas). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77048/new/ https://reviews.llvm.org/D77048 Files: clang/lib/CodeGen/CGExprConstant.cpp clang/test/CodeGenCXX/bitfield-layout.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77048.254483.patch Type: text/x-patch Size: 3511 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 04:51:25 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Thu, 02 Apr 2020 11:51:25 +0000 (UTC) Subject: [PATCH] D77150: [Analyzer] New Option for ContainerModeling: AggressiveEraseModeling In-Reply-To: References: Message-ID: <77622e92239c870069ea2db81a23be31@localhost.localdomain> Szelethus added a comment. Some tests would be appreciated, It really helps me understand whats going on. ================ Comment at: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td:620-624 + "AggressiveEraseModeling", + "Enables exploration of the past-the-end branch for the " + "return value of the erase() method of containers.", + "false", + Released> ---------------- Hmm. The description isn't really user-friendly, imo, but the option doesn't sound too user-facing either. I don't think this is an option to be tinkered with. I think we should make this hidden. Also, even for developers, I find this a bitconfusing at first. Do we not enable that by default? Why not? What do we have to gain/lose? ================ Comment at: clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp:692-699 + std::tie(StateEnd, StateNotEnd) = State->assume(*RetEnd); + if (StateEnd) { + C.addTransition(StateEnd); + } + if (StateNotEnd) { + C.addTransition(StateNotEnd); + } ---------------- Right, so the const is a state split. That doesn't sound like something regular users should fine-tune. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77150/new/ https://reviews.llvm.org/D77150 From cfe-commits at lists.llvm.org Thu Apr 2 04:51:25 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Thu, 02 Apr 2020 11:51:25 +0000 (UTC) Subject: [PATCH] D77150: [Analyzer] New Option for ContainerModeling: AggressiveEraseModeling In-Reply-To: References: Message-ID: <33892d76615c096e6328a076e500797b@localhost.localdomain> Szelethus added inline comments. ================ Comment at: clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp:692-699 + std::tie(StateEnd, StateNotEnd) = State->assume(*RetEnd); + if (StateEnd) { + C.addTransition(StateEnd); + } + if (StateNotEnd) { + C.addTransition(StateNotEnd); + } ---------------- Szelethus wrote: > Right, so the const is a state split. That doesn't sound like something regular users should fine-tune. cost* :^) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77150/new/ https://reviews.llvm.org/D77150 From cfe-commits at lists.llvm.org Thu Apr 2 04:51:28 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Thu, 02 Apr 2020 11:51:28 +0000 (UTC) Subject: [PATCH] D76510: [analyzer] Change the default output type to PD_TEXT_MINIMAL in the frontend, error if an output loc is missing for PathDiagConsumers that need it In-Reply-To: References: Message-ID: <9d69a4639c60f4e019fce69aaddb6b90@localhost.localdomain> Szelethus marked an inline comment as done. Szelethus added a comment. Lets highlight then that this change affects the analyzer in **frontend** mode, not in the **driver** configuration. I might make a patch for that too, btw. @NoQ, were you able to check whether **this** change could break anything? :) ================ Comment at: clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h:209 AnalysisConstraints AnalysisConstraintsOpt = RangeConstraintsModel; - AnalysisDiagClients AnalysisDiagOpt = PD_HTML; + AnalysisDiagClients AnalysisDiagOpt = PD_TEXT_MINIMAL; AnalysisPurgeMode AnalysisPurgeOpt = PurgeStmt; ---------------- NoQ wrote: > This patch most likely changes almost nothing because the default output mode of `clang --analyze` has always been Plist: > > ```lang=c++ > lib/Driver/ToolChains/Clang.cpp > 2938: // Set the output format. The default is plist, for (lame) historical reasons. > 2939- CmdArgs.push_back("-analyzer-output"); > 2940- if (Arg *A = Args.getLastArg(options::OPT__analyzer_output)) > 2941- CmdArgs.push_back(A->getValue()); > 2942- else > 2943- CmdArgs.push_back("plist"); > ``` > I'll double check on historical reasons; i suspect we should be able to transition out of it eventually because this is indeed the worst possible output mode for `--analyze`. > > That said, i wonder how/why do our tests currently work without flooding everything with html reports. Because the HTML report acts like the text if no output file is supplied. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76510/new/ https://reviews.llvm.org/D76510 From cfe-commits at lists.llvm.org Thu Apr 2 05:19:49 2020 From: cfe-commits at lists.llvm.org (Sven van Haastregt via cfe-commits) Date: Thu, 02 Apr 2020 05:19:49 -0700 (PDT) Subject: [clang] 9da6a40 - [OpenCL] Add sub-group builtin functions Message-ID: <5e85d865.1c69fb81.79a22.0fff@mx.google.com> Author: Sven van Haastregt Date: 2020-04-02T13:18:56+01:00 New Revision: 9da6a40e0999523f8bdabfdab875890770eb9b3a URL: https://github.com/llvm/llvm-project/commit/9da6a40e0999523f8bdabfdab875890770eb9b3a DIFF: https://github.com/llvm/llvm-project/commit/9da6a40e0999523f8bdabfdab875890770eb9b3a.diff LOG: [OpenCL] Add sub-group builtin functions Add the sub-group builtin functions from the OpenCL Extension specification. This patch excludes the sub_group_barrier builtins that take argument types not yet handled by the `-fdeclare-opencl-builtins` machinery. Co-authored-by: Pierre Gondois Added: Modified: clang/lib/Sema/OpenCLBuiltins.td clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl Removed: ################################################################################ diff --git a/clang/lib/Sema/OpenCLBuiltins.td b/clang/lib/Sema/OpenCLBuiltins.td index 40798b744ced..745363a6b43f 100644 --- a/clang/lib/Sema/OpenCLBuiltins.td +++ b/clang/lib/Sema/OpenCLBuiltins.td @@ -1273,15 +1273,6 @@ def : Builtin<"get_default_queue", [Queue]>; // TODO: ndrange functions -// OpenCL v2.0 s9.17.3: Additions to section 6.13.1: Work-Item Functions -let MinVersion = CL20 in { - let Extension = FuncExtKhrSubgroups in { - def get_sub_group_size : Builtin<"get_sub_group_size", [UInt]>; - def get_max_sub_group_size : Builtin<"get_max_sub_group_size", [UInt]>; - def get_num_sub_groups : Builtin<"get_num_sub_groups", [UInt]>; - } -} - //-------------------------------------------------------------------- // End of the builtin functions defined in the OpenCL C specification. // Builtin functions defined in the OpenCL C Extension are below. @@ -1456,6 +1447,41 @@ let Extension = FuncExtKhrGlMsaaSharing in { } } +//-------------------------------------------------------------------- +// OpenCL Extension v2.0 s28 - Subgroups +// --- Table 28.2.1 --- +let Extension = FuncExtKhrSubgroups in { + foreach name = ["get_sub_group_size", "get_max_sub_group_size", + "get_num_sub_groups", "get_sub_group_id", + "get_sub_group_local_id"] in { + def : Builtin; + } + let MinVersion = CL20 in { + foreach name = ["get_enqueued_num_sub_groups"] in { + def : Builtin; + } + } +} + +// --- Table 28.2.2 --- +// TODO: sub_group_barrier + +// --- Table 28.2.4 --- +let Extension = FuncExtKhrSubgroups in { + foreach name = ["sub_group_all", "sub_group_any"] in { + def : Builtin; + } + foreach name = ["sub_group_broadcast"] in { + def : Builtin; + } + foreach name = ["sub_group_reduce_", "sub_group_scan_exclusive_", + "sub_group_scan_inclusive_"] in { + foreach op = ["add", "min", "max"] in { + def : Builtin; + } + } +} + //-------------------------------------------------------------------- // Arm extensions. let Extension = ArmIntegerDotProductInt8 in { diff --git a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl index e593b21ec459..d1dcdfe8cb35 100644 --- a/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl +++ b/clang/test/SemaOpenCL/fdeclare-opencl-builtins.cl @@ -140,14 +140,11 @@ kernel void basic_image_writeonly(write_only image1d_buffer_t image_write_only_i kernel void basic_subgroup(global uint *out) { out[0] = get_sub_group_size(); -#if !defined(__OPENCL_CPP_VERSION__) && __OPENCL_C_VERSION__ < CL_VERSION_2_0 -// expected-error at -2{{implicit declaration of function 'get_sub_group_size' is invalid in OpenCL}} -// expected-error at -3{{implicit conversion changes signedness: 'int' to 'uint' (aka 'unsigned int')}} -#elif defined(__OPENCL_CPP_VERSION__) -// expected-error at -5{{no matching function for call to 'get_sub_group_size'}} -// expected-note at -6{{candidate unavailable as it requires OpenCL extension 'cl_khr_subgroups' to be enabled}} +#if defined(__OPENCL_CPP_VERSION__) + // expected-error at -2{{no matching function for call to 'get_sub_group_size'}} + // expected-note at -3{{candidate unavailable as it requires OpenCL extension 'cl_khr_subgroups' to be enabled}} #else -// expected-error at -8{{use of declaration 'get_sub_group_size' requires cl_khr_subgroups extension to be enabled}} + // expected-error at -5{{use of declaration 'get_sub_group_size' requires cl_khr_subgroups extension to be enabled}} #endif } From cfe-commits at lists.llvm.org Thu Apr 2 05:23:36 2020 From: cfe-commits at lists.llvm.org (Serge Pavlov via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 12:23:36 +0000 (UTC) Subject: [PATCH] D76384: Move FPFeatures from BinaryOperator bitfields to Trailing storage In-Reply-To: References: Message-ID: <86e34f93eb12178e450bcb0a6448c93d@localhost.localdomain> sepavloff added inline comments. ================ Comment at: clang/include/clang/Basic/LangOptions.h:394 + return true; + } + ---------------- erichkeane wrote: > rjmccall wrote: > > erichkeane wrote: > > > rjmccall wrote: > > > > rjmccall wrote: > > > > > erichkeane wrote: > > > > > > rjmccall wrote: > > > > > > > The problem with having both functions that take `ASTContext`s and functions that don't is that it's easy to mix them, so they either need to have the same behavior (in which case it's pointless to have an overload that takes the `ASTContext`) or you're making something really error-prone. > > > > > > > > > > > > > > I would feel a lot more confident that you were designing and using these APIs correctly if you actually took advantage of the ability to not store trailing FPOptions in some case, like when they match the global settings in the ASTContext. That way you'll actually be verifying that everything behaves correctly if nodes don't store FPOptions. If you do that, I think you'll see my point about not having all these easily-confusable functions that do or do not take `ASTContext`s.. > > > > > > I think I disagree with @rjmccall that these requiresTrailingStorage should be here at all. I think we should store in the AST ANY programmer opinion, even if they match the global setting. It seems to me that this would be more tolerant of any global-setting rewrites that modules/et-al introduce, as well as make the AST Print consistent. Always storing FPOptions when the user has explicitly overriding it also better captures the programmer's intent. > > > > > I covered this elsewhere in the review. If you want to have that tolerance — and I think you should — then expressions should store (and Sema should track) the active pragma state, which can be most easily expressed as a pair of an FPOptions and a mask to apply to the global FPOptions. When you enter a pragma, you clear the relevant bits from the global FPOptions mask. > > > > > > > > > > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. > > > > > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. > > > > > > > > I meant to say: for a million nodes that don't care in the slightest about FPOptions, as well as for a million more nodes that aren't using pragma overrides. > > > Right, I get the intent, and I completely agree with that. My point was EVERY Expr that is affected by a #pragma should store it. Though, after looking at your Macro concern above, I'm less compelled. > > > > > > I guess was suggesting that the logic for "requiresTrailingStorage" should just be "modified by a pragma" instead of "FPOptions != The global setting". > > Well, "modified by a pragma" still wouldn't make the AST agnostic to global settings, since the pragmas don't override everything in FPOptions at once. But I agree that would achieve the most important goal, which is to stop inflating the AST when pragmas *aren't* in effect, which is approximately 100% of the time. In order to do that, though, we'll need to start tracking pragmas, which we should do but which can wait for a follow-up patch. In the meantime, I don't think you're ever going to get the interfaces right for queries like `BinaryOperator::getFPOptions` unless you actually stop relying on the fact that you're unconditionally storing `FPOptions`. You need to passing around ASTContexts for that. That's why I'm suggesting using an exact match with the global settings as a simple thing you can easily check without modifying what data you collect in `FPOptions`. > That sounds like a good plan to me. Thanks for entertaining my conversation/questions. > we'll need to start tracking pragmas This is made in D76599 by representing floating point pragmas with a special statement node. These nodes allow an AST consumer like CodeGen or constant evaluator to maintain current set of floating options when it traverses AST. This approach looks simpler and more consistent as global state is represented as a variable in AST consumer and is not replicated to every relevant node. It makes easier to implement codegen for things like rounding mode, when change of the FP state requires specific instructions. A pragma statement can be used to generate required code. But if the state is spread by several nodes, it is more difficult for codegen to create necessary prolog/epilog code. Now compiler does not have support of properties that need synchronization with hardware, so these problems are not topical yet, but they eventually will arise. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76384/new/ https://reviews.llvm.org/D76384 From cfe-commits at lists.llvm.org Thu Apr 2 05:36:47 2020 From: cfe-commits at lists.llvm.org (Alexey Bataev via cfe-commits) Date: Thu, 02 Apr 2020 05:36:47 -0700 (PDT) Subject: [clang] 13a1504 - [OPENMP50]Add initial support for OpenMP 5.0 iterator. Message-ID: <5e85dc5f.1c69fb81.6fcfa.06f4@mx.google.com> Author: Alexey Bataev Date: 2020-04-02T08:28:15-04:00 New Revision: 13a1504ffb9a9a4f82dc1b60d9e8cbb173c7d030 URL: https://github.com/llvm/llvm-project/commit/13a1504ffb9a9a4f82dc1b60d9e8cbb173c7d030 DIFF: https://github.com/llvm/llvm-project/commit/13a1504ffb9a9a4f82dc1b60d9e8cbb173c7d030.diff LOG: [OPENMP50]Add initial support for OpenMP 5.0 iterator. Added basic parsing/semantic analysis/(de)serialization support for iterator expression introduced in OpenMP 5.0. Added: Modified: clang/include/clang-c/Index.h clang/include/clang/AST/ASTContext.h clang/include/clang/AST/BuiltinTypes.def clang/include/clang/AST/ComputeDependence.h clang/include/clang/AST/ExprOpenMP.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/AST/TextNodeDumper.h clang/include/clang/Basic/DiagnosticParseKinds.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Basic/StmtNodes.td clang/include/clang/Parse/Parser.h clang/include/clang/Sema/Sema.h clang/include/clang/Serialization/ASTBitCodes.h clang/lib/AST/ASTContext.cpp clang/lib/AST/ComputeDependence.cpp clang/lib/AST/Expr.cpp clang/lib/AST/ExprClassification.cpp clang/lib/AST/ExprConstant.cpp clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/NSAPI.cpp clang/lib/AST/OpenMPClause.cpp clang/lib/AST/StmtPrinter.cpp clang/lib/AST/StmtProfile.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/AST/Type.cpp clang/lib/AST/TypeLoc.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaExceptionSpec.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTCommon.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/Serialization/ASTWriterStmt.cpp clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp clang/lib/StaticAnalyzer/Core/ExprEngine.cpp clang/test/OpenMP/depobj_messages.cpp clang/test/OpenMP/task_ast_print.cpp clang/test/OpenMP/task_depend_messages.cpp clang/tools/libclang/CIndex.cpp clang/tools/libclang/CXCursor.cpp Removed: ################################################################################ diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 641f058dafaa..0acd50021ed8 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2180,7 +2180,12 @@ enum CXCursorKind { */ CXCursor_OMPArrayShapingExpr = 150, - CXCursor_LastExpr = CXCursor_OMPArrayShapingExpr, + /** + * OpenMP 5.0 [2.1.6 Iterators] + */ + CXCursor_OMPIteratorExpr = 151, + + CXCursor_LastExpr = CXCursor_OMPIteratorExpr, /* Statements */ CXCursor_FirstStmt = 200, diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index ebb5ca593843..6813ab58874e 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -970,7 +970,7 @@ class ASTContext : public RefCountedBase { #include "clang/Basic/OpenCLImageTypes.def" CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; CanQualType OCLQueueTy, OCLReserveIDTy; - CanQualType OMPArraySectionTy, OMPArrayShapingTy; + CanQualType OMPArraySectionTy, OMPArrayShapingTy, OMPIteratorTy; #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ CanQualType Id##Ty; #include "clang/Basic/OpenCLExtensionTypes.def" diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index f42503773945..f8eb4ec19c8f 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -316,8 +316,11 @@ PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy) // A placeholder type for OpenMP array shaping operation. PLACEHOLDER_TYPE(OMPArrayShaping, OMPArrayShapingTy) +// A placeholder type for OpenMP iterators. +PLACEHOLDER_TYPE(OMPIterator, OMPIteratorTy) + #ifdef LAST_BUILTIN_TYPE -LAST_BUILTIN_TYPE(OMPArrayShaping) +LAST_BUILTIN_TYPE(OMPIterator) #undef LAST_BUILTIN_TYPE #endif diff --git a/clang/include/clang/AST/ComputeDependence.h b/clang/include/clang/AST/ComputeDependence.h index 63947eaff73b..ab742c9b70dd 100644 --- a/clang/include/clang/AST/ComputeDependence.h +++ b/clang/include/clang/AST/ComputeDependence.h @@ -88,6 +88,7 @@ class PseudoObjectExpr; class AtomicExpr; class OMPArraySectionExpr; class OMPArrayShapingExpr; +class OMPIteratorExpr; class ObjCArrayLiteral; class ObjCDictionaryLiteral; class ObjCBoxedExpr; @@ -174,6 +175,7 @@ ExprDependence computeDependence(AtomicExpr *E); ExprDependence computeDependence(OMPArraySectionExpr *E); ExprDependence computeDependence(OMPArrayShapingExpr *E); +ExprDependence computeDependence(OMPIteratorExpr *E); ExprDependence computeDependence(ObjCArrayLiteral *E); ExprDependence computeDependence(ObjCDictionaryLiteral *E); diff --git a/clang/include/clang/AST/ExprOpenMP.h b/clang/include/clang/AST/ExprOpenMP.h index 4a0cd07f1dab..dc6e061604b3 100644 --- a/clang/include/clang/AST/ExprOpenMP.h +++ b/clang/include/clang/AST/ExprOpenMP.h @@ -205,6 +205,169 @@ class OMPArrayShapingExpr final return const_child_range(Begin, Begin + NumDims + 1); } }; + +/// OpenMP 5.0 [2.1.6 Iterators] +/// Iterators are identifiers that expand to multiple values in the clause on +/// which they appear. +/// The syntax of the iterator modifier is as follows: +/// \code +/// iterator(iterators-definition) +/// \endcode +/// where iterators-definition is one of the following: +/// \code +/// iterator-specifier [, iterators-definition ] +/// \endcode +/// where iterator-specifier is one of the following: +/// \code +/// [ iterator-type ] identifier = range-specification +/// \endcode +/// where identifier is a base language identifier. +/// iterator-type is a type name. +/// range-specification is of the form begin:end[:step], where begin and end are +/// expressions for which their types can be converted to iterator-type and step +/// is an integral expression. +/// In an iterator-specifier, if the iterator-type is not specified then the +/// type of that iterator is of int type. +/// The iterator-type must be an integral or pointer type. +/// The iterator-type must not be const qualified. +class OMPIteratorExpr final + : public Expr, + private llvm::TrailingObjects { +public: + /// Iterator range representation begin:end[:step]. + struct IteratorRange { + Expr *Begin = nullptr; + Expr *End = nullptr; + Expr *Step = nullptr; + }; + /// Iterator definition representation. + struct IteratorDefinition { + Decl *IteratorDecl = nullptr; + IteratorRange Range; + SourceLocation AssignmentLoc; + SourceLocation ColonLoc, SecondColonLoc; + }; + +private: + friend TrailingObjects; + friend class ASTStmtReader; + friend class ASTStmtWriter; + + /// Offset in the list of expressions for subelements of the ranges. + enum class RangeExprOffset { + Begin = 0, + End = 1, + Step = 2, + Total = 3, + }; + /// Offset in the list of locations for subelements of colon symbols + /// locations. + enum class RangeLocOffset { + AssignLoc = 0, + FirstColonLoc = 1, + SecondColonLoc = 2, + Total = 3, + }; + /// Location of 'iterator' keyword. + SourceLocation IteratorKwLoc; + /// Location of '('. + SourceLocation LPLoc; + /// Location of ')'. + SourceLocation RPLoc; + /// Number of iterator definitions. + unsigned NumIterators = 0; + + OMPIteratorExpr(QualType ExprTy, SourceLocation IteratorKwLoc, + SourceLocation L, SourceLocation R, + ArrayRef Data); + + /// Construct an empty expression. + explicit OMPIteratorExpr(EmptyShell Shell, unsigned NumIterators) + : Expr(OMPIteratorExprClass, Shell), NumIterators(NumIterators) {} + + /// Sets basic declaration for the specified iterator definition. + void setIteratorDeclaration(unsigned I, Decl *D); + + /// Sets the location of the assignment symbol for the specified iterator + /// definition. + void setAssignmentLoc(unsigned I, SourceLocation Loc); + + /// Sets begin, end and optional step expressions for specified iterator + /// definition. + void setIteratorRange(unsigned I, Expr *Begin, SourceLocation ColonLoc, + Expr *End, SourceLocation SecondColonLoc, Expr *Step); + + unsigned numTrailingObjects(OverloadToken) const { + return NumIterators; + } + + unsigned numTrailingObjects(OverloadToken) const { + return NumIterators * static_cast(RangeExprOffset::Total); + } + +public: + static OMPIteratorExpr *Create(const ASTContext &Context, QualType T, + SourceLocation IteratorKwLoc, SourceLocation L, + SourceLocation R, + ArrayRef Data); + + static OMPIteratorExpr *CreateEmpty(const ASTContext &Context, + unsigned NumIterators); + + SourceLocation getLParenLoc() const { return LPLoc; } + void setLParenLoc(SourceLocation L) { LPLoc = L; } + + SourceLocation getRParenLoc() const { return RPLoc; } + void setRParenLoc(SourceLocation L) { RPLoc = L; } + + SourceLocation getIteratorKwLoc() const { return IteratorKwLoc; } + void setIteratorKwLoc(SourceLocation L) { IteratorKwLoc = L; } + SourceLocation getBeginLoc() const LLVM_READONLY { return IteratorKwLoc; } + SourceLocation getEndLoc() const LLVM_READONLY { return RPLoc; } + + /// Gets the iterator declaration for the given iterator. + Decl *getIteratorDecl(unsigned I); + const Decl *getIteratorDecl(unsigned I) const { + return const_cast(this)->getIteratorDecl(I); + } + + /// Gets the iterator range for the given iterator. + IteratorRange getIteratorRange(unsigned I); + const IteratorRange getIteratorRange(unsigned I) const { + return const_cast(this)->getIteratorRange(I); + } + + /// Gets the location of '=' for the given iterator definition. + SourceLocation getAssignLoc(unsigned I) const; + /// Gets the location of the first ':' in the range for the given iterator + /// definition. + SourceLocation getColonLoc(unsigned I) const; + /// Gets the location of the second ':' (if any) in the range for the given + /// iteratori definition. + SourceLocation getSecondColonLoc(unsigned I) const; + + /// Returns number of iterator definitions. + unsigned numOfIterators() const { return NumIterators; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPIteratorExprClass; + } + + // Iterators + child_range children() { + Stmt **Begin = reinterpret_cast(getTrailingObjects()); + return child_range( + Begin, Begin + NumIterators * static_cast(RangeExprOffset::Total)); + } + const_child_range children() const { + Stmt *const *Begin = + reinterpret_cast(getTrailingObjects()); + return const_child_range( + Begin, Begin + NumIterators * static_cast(RangeExprOffset::Total)); + } +}; + } // end namespace clang #endif diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 0d4b69911f19..028af6ac9a72 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -4372,6 +4372,9 @@ class OMPDependClause final /// Set colon location. void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } + /// Sets optional dependency modifier. + void setModifier(Expr *DepModifier); + public: /// Creates clause with a list of variables \a VL. /// @@ -4387,7 +4390,7 @@ class OMPDependClause final /// clause. static OMPDependClause *Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, + SourceLocation EndLoc, Expr *DepModifier, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef VL, unsigned NumLoops); @@ -4404,6 +4407,12 @@ class OMPDependClause final /// Get dependency type. OpenMPDependClauseKind getDependencyKind() const { return DepKind; } + /// Return optional depend modifier. + Expr *getModifier(); + const Expr *getModifier() const { + return const_cast(this)->getModifier(); + } + /// Get dependency type location. SourceLocation getDependencyLoc() const { return DepLoc; } diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 46661e59f181..345333849659 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2552,6 +2552,7 @@ DEF_TRAVERSE_STMT(AddrLabelExpr, {}) DEF_TRAVERSE_STMT(ArraySubscriptExpr, {}) DEF_TRAVERSE_STMT(OMPArraySectionExpr, {}) DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {}) +DEF_TRAVERSE_STMT(OMPIteratorExpr, {}) DEF_TRAVERSE_STMT(BlockExpr, { TRY_TO(TraverseDecl(S->getBlockDecl())); diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h index b08d1e482be8..0fb4baf0ca4d 100644 --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -274,6 +274,7 @@ class TextNodeDumper void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node); void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node); void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node); + void VisitOMPIteratorExpr(const OMPIteratorExpr *Node); void VisitRValueReferenceType(const ReferenceType *T); void VisitArrayType(const ArrayType *T); diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 6eb320a85a30..f3741531c8b5 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1220,6 +1220,10 @@ def err_omp_expected_identifier_for_critical : Error< "expected identifier specifying the name of the 'omp critical' directive">; def err_omp_expected_reduction_identifier : Error< "expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'">; +def err_omp_expected_equal_in_iterator : Error< + "expected '=' in iterator specifier">; +def err_omp_expected_punc_after_iterator : Error< + "expected ',' or ')' after iterator specifier">; def err_omp_decl_in_declare_simd_variant : Error< "function declaration is expected after 'declare %select{simd|variant}0' directive">; def err_omp_unknown_map_type : Error< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 951a955984f6..901ac758b383 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9760,6 +9760,14 @@ def note_omp_conversion_here : Note< def err_omp_ambiguous_conversion : Error< "ambiguous conversion from type %0 to an integral or unscoped " "enumeration type">; +def err_omp_iterator_not_integral_or_pointer : Error< + "expected integral or pointer type as the iterator-type, not %0">; +def err_omp_iterator_constant : Error< + "expected non-constant type as the iterator-type, constant %0 is provided">; +def err_omp_iterator_step_not_integral : Error< + "iterator step expression %0 is not the integral expression">; +def err_omp_iterator_step_constant_zero : Error< + "iterator step expression %0 evaluates to 0">; def err_omp_required_access : Error< "%0 variable must be %1">; def err_omp_const_variable : Error< @@ -9953,6 +9961,7 @@ def err_omp_invalid_mapper: Error< "cannot find a valid user-defined mapper for type %0 with name %1">; def err_omp_array_section_use : Error<"OpenMP array section is not allowed here">; def err_omp_array_shaping_use : Error<"OpenMP array shaping operation is not allowed here">; +def err_omp_iterator_use : Error<"OpenMP iterator is not allowed here">; def err_omp_typecheck_section_value : Error< "subscripted value is not an array or pointer">; def err_omp_typecheck_section_not_integer : Error< @@ -10031,6 +10040,10 @@ def err_omp_depend_sink_source_not_allowed : Error< "'depend(%select{source|sink:vec}0)' clause%select{|s}0 cannot be mixed with 'depend(%select{sink:vec|source}0)' clause%select{s|}0">; def err_omp_depend_zero_length_array_section_not_allowed : Error< "zero-length array section is not allowed in 'depend' clause">; +def err_omp_depend_sink_source_with_modifier : Error< + "depend modifier cannot be used with 'sink' or 'source' depend type">; +def err_omp_depend_modifier_not_iterator : Error< + "expected iterator specification as depend modifier">; def err_omp_linear_ordered : Error< "'linear' clause cannot be specified along with 'ordered' clause with a parameter">; def err_omp_unexpected_schedule_modifier : Error< diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index ba1b5ebd6305..aecf24f89033 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -70,6 +70,7 @@ def OffsetOfExpr : StmtNode; def UnaryExprOrTypeTraitExpr : StmtNode; def ArraySubscriptExpr : StmtNode; def OMPArraySectionExpr : StmtNode; +def OMPIteratorExpr : StmtNode; def CallExpr : StmtNode; def MemberExpr : StmtNode; def CastExpr : StmtNode; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 290da0006116..ca0a5fd68994 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3086,6 +3086,11 @@ class Parser : public CodeCompletionHandler { OMPClause *ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, bool ParseOnly); + /// Parses and creates OpenMP 5.0 iterators expression: + /// = 'iterator' '(' { [ ] identifier = + /// }+ ')' + ExprResult ParseOpenMPIteratorsExpr(); + public: /// Parses simple expression in parens for single-expression clauses of OpenMP /// constructs. @@ -3095,7 +3100,7 @@ class Parser : public CodeCompletionHandler { /// Data used for parsing list of variables in OpenMP clauses. struct OpenMPVarListDataTy { - Expr *TailExpr = nullptr; + Expr *DepModOrTailExpr = nullptr; SourceLocation ColonLoc; SourceLocation RLoc; CXXScopeSpec ReductionOrMapperIdScopeSpec; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 9a41356ddb70..e1365e84a0b3 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -25,6 +25,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprObjC.h" +#include "clang/AST/ExprOpenMP.h" #include "clang/AST/ExternalASTSource.h" #include "clang/AST/LocInfoType.h" #include "clang/AST/MangleNumberingContext.h" @@ -4904,6 +4905,21 @@ class Sema final { ArrayRef Dims, ArrayRef Brackets); + /// Data structure for iterator expression. + struct OMPIteratorData { + IdentifierInfo *DeclIdent = nullptr; + SourceLocation DeclIdentLoc; + ParsedType Type; + OMPIteratorExpr::IteratorRange Range; + SourceLocation AssignLoc; + SourceLocation ColonLoc; + SourceLocation SecColonLoc; + }; + + ExprResult ActOnOMPIteratorExpr(Scope *S, SourceLocation IteratorKwLoc, + SourceLocation LLoc, SourceLocation RLoc, + ArrayRef Data); + // This struct is for use by ActOnMemberAccess to allow // BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after // changing the access operator from a '.' to a '->' (to see if that is the @@ -10572,7 +10588,7 @@ class Sema final { SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); OMPClause *ActOnOpenMPVarListClause( - OpenMPClauseKind Kind, ArrayRef Vars, Expr *TailExpr, + OpenMPClauseKind Kind, ArrayRef Vars, Expr *DepModOrTailExpr, const OMPVarListLocTy &Locs, SourceLocation ColonLoc, CXXScopeSpec &ReductionOrMapperIdScopeSpec, DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, @@ -10670,10 +10686,10 @@ class Sema final { SourceLocation EndLoc); /// Called on well-formed 'depend' clause. OMPClause * - ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, - SourceLocation ColonLoc, ArrayRef VarList, - SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc); + ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, + SourceLocation DepLoc, SourceLocation ColonLoc, + ArrayRef VarList, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc); /// Called on well-formed 'device' clause. OMPClause *ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *Device, SourceLocation StartLoc, diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 68bcb26b6df5..e6e9c8570cc8 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1019,6 +1019,9 @@ namespace serialization { /// The placeholder type for OpenMP array shaping operation. PREDEF_TYPE_OMP_ARRAY_SHAPING = 70, + /// The placeholder type for OpenMP iterator expression. + PREDEF_TYPE_OMP_ITERATOR = 71, + /// OpenCL image types with auto numeration #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ PREDEF_TYPE_##Id##_ID, @@ -1872,6 +1875,7 @@ namespace serialization { STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE, EXPR_OMP_ARRAY_SECTION, EXPR_OMP_ARRAY_SHAPING, + EXPR_OMP_ITERATOR, // ARC EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 8bee34e65754..1e81e0a67b4d 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1389,6 +1389,7 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target, if (LangOpts.OpenMP) { InitBuiltinType(OMPArraySectionTy, BuiltinType::OMPArraySection); InitBuiltinType(OMPArrayShapingTy, BuiltinType::OMPArrayShaping); + InitBuiltinType(OMPIteratorTy, BuiltinType::OMPIterator); } // C99 6.2.5p11. diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp index a023ed173184..3a326f62a2ec 100644 --- a/clang/lib/AST/ComputeDependence.cpp +++ b/clang/lib/AST/ComputeDependence.cpp @@ -372,6 +372,22 @@ ExprDependence clang::computeDependence(OMPArrayShapingExpr *E) { return D; } +ExprDependence clang::computeDependence(OMPIteratorExpr *E) { + auto D = toExprDependence(E->getType()->getDependence()); + for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) { + if (auto *VD = cast_or_null(E->getIteratorDecl(I))) + D |= toExprDependence(VD->getType()->getDependence()); + OMPIteratorExpr::IteratorRange IR = E->getIteratorRange(I); + if (Expr *BE = IR.Begin) + D |= BE->getDependence(); + if (Expr *EE = IR.End) + D |= EE->getDependence(); + if (Expr *SE = IR.Step) + D |= SE->getDependence(); + } + return D; +} + /// Compute the type-, value-, and instantiation-dependence of a /// declaration reference /// based on the declaration being referenced. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index fb63897d871f..d82381d611ef 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -3399,6 +3399,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, case ArraySubscriptExprClass: case OMPArraySectionExprClass: case OMPArrayShapingExprClass: + case OMPIteratorExprClass: case MemberExprClass: case ConditionalOperatorClass: case BinaryConditionalOperatorClass: @@ -4617,3 +4618,118 @@ OMPArrayShapingExpr *OMPArrayShapingExpr::CreateEmpty(const ASTContext &Context, alignof(OMPArrayShapingExpr)); return new (Mem) OMPArrayShapingExpr(EmptyShell(), NumDims); } + +void OMPIteratorExpr::setIteratorDeclaration(unsigned I, Decl *D) { + assert(I < NumIterators && + "Idx is greater or equal the number of iterators definitions."); + getTrailingObjects()[I] = D; +} + +void OMPIteratorExpr::setAssignmentLoc(unsigned I, SourceLocation Loc) { + assert(I < NumIterators && + "Idx is greater or equal the number of iterators definitions."); + getTrailingObjects< + SourceLocation>()[I * static_cast(RangeLocOffset::Total) + + static_cast(RangeLocOffset::AssignLoc)] = Loc; +} + +void OMPIteratorExpr::setIteratorRange(unsigned I, Expr *Begin, + SourceLocation ColonLoc, Expr *End, + SourceLocation SecondColonLoc, + Expr *Step) { + assert(I < NumIterators && + "Idx is greater or equal the number of iterators definitions."); + getTrailingObjects()[I * static_cast(RangeExprOffset::Total) + + static_cast(RangeExprOffset::Begin)] = + Begin; + getTrailingObjects()[I * static_cast(RangeExprOffset::Total) + + static_cast(RangeExprOffset::End)] = End; + getTrailingObjects()[I * static_cast(RangeExprOffset::Total) + + static_cast(RangeExprOffset::Step)] = Step; + getTrailingObjects< + SourceLocation>()[I * static_cast(RangeLocOffset::Total) + + static_cast(RangeLocOffset::FirstColonLoc)] = + ColonLoc; + getTrailingObjects< + SourceLocation>()[I * static_cast(RangeLocOffset::Total) + + static_cast(RangeLocOffset::SecondColonLoc)] = + SecondColonLoc; +} + +Decl *OMPIteratorExpr::getIteratorDecl(unsigned I) { + return getTrailingObjects()[I]; +} + +OMPIteratorExpr::IteratorRange OMPIteratorExpr::getIteratorRange(unsigned I) { + IteratorRange Res; + Res.Begin = + getTrailingObjects()[I * static_cast( + RangeExprOffset::Total) + + static_cast(RangeExprOffset::Begin)]; + Res.End = + getTrailingObjects()[I * static_cast( + RangeExprOffset::Total) + + static_cast(RangeExprOffset::End)]; + Res.Step = + getTrailingObjects()[I * static_cast( + RangeExprOffset::Total) + + static_cast(RangeExprOffset::Step)]; + return Res; +} + +SourceLocation OMPIteratorExpr::getAssignLoc(unsigned I) const { + return getTrailingObjects< + SourceLocation>()[I * static_cast(RangeLocOffset::Total) + + static_cast(RangeLocOffset::AssignLoc)]; +} + +SourceLocation OMPIteratorExpr::getColonLoc(unsigned I) const { + return getTrailingObjects< + SourceLocation>()[I * static_cast(RangeLocOffset::Total) + + static_cast(RangeLocOffset::FirstColonLoc)]; +} + +SourceLocation OMPIteratorExpr::getSecondColonLoc(unsigned I) const { + return getTrailingObjects< + SourceLocation>()[I * static_cast(RangeLocOffset::Total) + + static_cast(RangeLocOffset::SecondColonLoc)]; +} + +OMPIteratorExpr::OMPIteratorExpr( + QualType ExprTy, SourceLocation IteratorKwLoc, SourceLocation L, + SourceLocation R, ArrayRef Data) + : Expr(OMPIteratorExprClass, ExprTy, VK_LValue, OK_Ordinary), + IteratorKwLoc(IteratorKwLoc), LPLoc(L), RPLoc(R), + NumIterators(Data.size()) { + for (unsigned I = 0, E = Data.size(); I < E; ++I) { + const IteratorDefinition &D = Data[I]; + setIteratorDeclaration(I, D.IteratorDecl); + setAssignmentLoc(I, D.AssignmentLoc); + setIteratorRange(I, D.Range.Begin, D.ColonLoc, D.Range.End, + D.SecondColonLoc, D.Range.Step); + } + setDependence(computeDependence(this)); +} + +OMPIteratorExpr * +OMPIteratorExpr::Create(const ASTContext &Context, QualType T, + SourceLocation IteratorKwLoc, SourceLocation L, + SourceLocation R, + ArrayRef Data) { + void *Mem = Context.Allocate( + totalSizeToAlloc( + Data.size(), Data.size() * static_cast(RangeExprOffset::Total), + Data.size() * static_cast(RangeLocOffset::Total)), + alignof(OMPIteratorExpr)); + return new (Mem) OMPIteratorExpr(T, IteratorKwLoc, L, R, Data); +} + +OMPIteratorExpr *OMPIteratorExpr::CreateEmpty(const ASTContext &Context, + unsigned NumIterators) { + void *Mem = Context.Allocate( + totalSizeToAlloc( + NumIterators, NumIterators * static_cast(RangeExprOffset::Total), + NumIterators * static_cast(RangeLocOffset::Total)), + alignof(OMPIteratorExpr)); + return new (Mem) OMPIteratorExpr(EmptyShell(), NumIterators); +} diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 4505626bb61f..8587a476a5d9 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -141,6 +141,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::MSPropertySubscriptExprClass: case Expr::OMPArraySectionExprClass: case Expr::OMPArrayShapingExprClass: + case Expr::OMPIteratorExprClass: return Cl::CL_LValue; // C99 6.5.2.5p5 says that compound literals are lvalues. diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 4a11c846f4ab..c6e1cc7b67df 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -14181,6 +14181,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { case Expr::ArraySubscriptExprClass: case Expr::OMPArraySectionExprClass: case Expr::OMPArrayShapingExprClass: + case Expr::OMPIteratorExprClass: case Expr::MemberExprClass: case Expr::CompoundAssignOperatorClass: case Expr::CompoundLiteralExprClass: diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 4c05990ee410..cb7bd61574ef 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3715,6 +3715,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) { case Expr::RecoveryExprClass: case Expr::OMPArraySectionExprClass: case Expr::OMPArrayShapingExprClass: + case Expr::OMPIteratorExprClass: case Expr::CXXInheritedCtorInitExprClass: llvm_unreachable("unexpected statement kind"); diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp index 2bfe977a5ba5..3bb3605ea936 100644 --- a/clang/lib/AST/NSAPI.cpp +++ b/clang/lib/AST/NSAPI.cpp @@ -484,6 +484,7 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const { case BuiltinType::BuiltinFn: case BuiltinType::OMPArraySection: case BuiltinType::OMPArrayShaping: + case BuiltinType::OMPIterator: break; } diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 4b7ebbb3c26d..eeb690750fb7 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -900,16 +900,19 @@ OMPDepobjClause *OMPDepobjClause::CreateEmpty(const ASTContext &C) { OMPDependClause * OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, - OpenMPDependClauseKind DepKind, SourceLocation DepLoc, - SourceLocation ColonLoc, ArrayRef VL, - unsigned NumLoops) { - void *Mem = C.Allocate(totalSizeToAlloc(VL.size() + NumLoops)); + Expr *DepModifier, OpenMPDependClauseKind DepKind, + SourceLocation DepLoc, SourceLocation ColonLoc, + ArrayRef VL, unsigned NumLoops) { + void *Mem = C.Allocate( + totalSizeToAlloc(VL.size() + /*depend-modifier*/ 1 + NumLoops), + alignof(OMPDependClause)); OMPDependClause *Clause = new (Mem) OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops); Clause->setVarRefs(VL); Clause->setDependencyKind(DepKind); Clause->setDependencyLoc(DepLoc); Clause->setColonLoc(ColonLoc); + Clause->setModifier(DepModifier); for (unsigned I = 0 ; I < NumLoops; ++I) Clause->setLoopData(I, nullptr); return Clause; @@ -917,7 +920,9 @@ OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc, OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N, unsigned NumLoops) { - void *Mem = C.Allocate(totalSizeToAlloc(N + NumLoops)); + void *Mem = + C.Allocate(totalSizeToAlloc(N + /*depend-modifier*/ 1 + NumLoops), + alignof(OMPDependClause)); return new (Mem) OMPDependClause(N, NumLoops); } @@ -927,7 +932,7 @@ void OMPDependClause::setLoopData(unsigned NumLoop, Expr *Cnt) { NumLoop < NumLoops && "Expected sink or source depend + loop index must be less number of " "loops."); - auto It = std::next(getVarRefs().end(), NumLoop); + auto *It = std::next(getVarRefs().end(), NumLoop + 1); *It = Cnt; } @@ -937,7 +942,7 @@ Expr *OMPDependClause::getLoopData(unsigned NumLoop) { NumLoop < NumLoops && "Expected sink or source depend + loop index must be less number of " "loops."); - auto It = std::next(getVarRefs().end(), NumLoop); + auto *It = std::next(getVarRefs().end(), NumLoop + 1); return *It; } @@ -947,10 +952,15 @@ const Expr *OMPDependClause::getLoopData(unsigned NumLoop) const { NumLoop < NumLoops && "Expected sink or source depend + loop index must be less number of " "loops."); - auto It = std::next(getVarRefs().end(), NumLoop); + const auto *It = std::next(getVarRefs().end(), NumLoop + 1); return *It; } +void OMPDependClause::setModifier(Expr *DepModifier) { + *getVarRefs().end() = DepModifier; +} +Expr *OMPDependClause::getModifier() { return *getVarRefs().end(); } + unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber( MappableExprComponentListsRef ComponentLists) { unsigned TotalNum = 0u; @@ -1727,6 +1737,10 @@ void OMPClausePrinter::VisitOMPDepobjClause(OMPDepobjClause *Node) { void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) { OS << "depend("; + if (Expr *DepModifier = Node->getModifier()) { + DepModifier->printPretty(OS, nullptr, Policy); + OS << ", "; + } OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Node->getDependencyKind()); if (!Node->varlist_empty()) { diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 3d03f3902d61..6537ca98667e 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1361,6 +1361,26 @@ void StmtPrinter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *Node) { PrintExpr(Node->getBase()); } +void StmtPrinter::VisitOMPIteratorExpr(OMPIteratorExpr *Node) { + OS << "iterator("; + for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) { + auto *VD = cast(Node->getIteratorDecl(I)); + VD->getType().print(OS, Policy); + const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I); + OS << " " << VD->getName() << " = "; + PrintExpr(Range.Begin); + OS << ":"; + PrintExpr(Range.End); + if (Range.Step) { + OS << ":"; + PrintExpr(Range.Step); + } + if (I < E - 1) + OS << ", "; + } + OS << ")"; +} + void StmtPrinter::PrintCallArgs(CallExpr *Call) { for (unsigned i = 0, e = Call->getNumArgs(); i != e; ++i) { if (isa(Call->getArg(i))) { diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 054276a98424..fec12ac98b4e 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -1198,6 +1198,12 @@ void StmtProfiler::VisitOMPArrayShapingExpr(const OMPArrayShapingExpr *S) { VisitExpr(S); } +void StmtProfiler::VisitOMPIteratorExpr(const OMPIteratorExpr *S) { + VisitExpr(S); + for (unsigned I = 0, E = S->numOfIterators(); I < E; ++I) + VisitDecl(S->getIteratorDecl(I)); +} + void StmtProfiler::VisitCallExpr(const CallExpr *S) { VisitExpr(S); } diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 6a6d8692228a..dc0dd92f09df 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1086,6 +1086,23 @@ void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) { OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); } +void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) { + OS << " "; + for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) { + Visit(Node->getIteratorDecl(I)); + OS << " = "; + const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I); + OS << " begin "; + Visit(Range.Begin); + OS << " end "; + Visit(Range.End); + if (Range.Step) { + OS << " step "; + Visit(Range.Step); + } + } +} + void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) { if (T->isSpelledAsLValue()) OS << " written as lvalue reference"; diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index f90eb5cb9c92..3428437c3146 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2910,6 +2910,8 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { return ""; case OMPArrayShaping: return ""; + case OMPIterator: + return ""; #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ case Id: \ return #ExtType; @@ -3917,6 +3919,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const { case BuiltinType::NullPtr: case BuiltinType::OMPArraySection: case BuiltinType::OMPArrayShaping: + case BuiltinType::OMPIterator: return false; } llvm_unreachable("unknown builtin type"); diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index dd48ae3fc262..50391dba2a05 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -405,6 +405,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const { case BuiltinType::BuiltinFn: case BuiltinType::OMPArraySection: case BuiltinType::OMPArrayShaping: + case BuiltinType::OMPIterator: return TST_unspecified; } diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 147d1b271d0c..1f5ed3d9c999 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -755,7 +755,8 @@ static bool parseDeclareSimdClauses( getOpenMPClauseKind(ClauseName), *Vars, Data)) IsError = true; if (CKind == OMPC_aligned) { - Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr); + Alignments.append(Aligneds.size() - Alignments.size(), + Data.DepModOrTailExpr); } else if (CKind == OMPC_linear) { assert(0 <= Data.ExtraModifier && Data.ExtraModifier <= OMPC_LINEAR_unknown && @@ -766,7 +767,7 @@ static bool parseDeclareSimdClauses( Data.ExtraModifier = OMPC_LINEAR_val; LinModifiers.append(Linears.size() - LinModifiers.size(), Data.ExtraModifier); - Steps.append(Linears.size() - Steps.size(), Data.TailExpr); + Steps.append(Linears.size() - Steps.size(), Data.DepModOrTailExpr); } } else // TODO: add parsing of other clauses. @@ -3054,6 +3055,114 @@ static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) { P.ConsumeToken(); } +/// Parses simple expression in parens for single-expression clauses of OpenMP +/// constructs. +/// \param RLoc Returned location of right paren. +ExprResult Parser::ParseOpenMPIteratorsExpr() { + assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator" && + "Expected 'iterator' token."); + SourceLocation IteratorKwLoc = ConsumeToken(); + + BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); + if (T.expectAndConsume(diag::err_expected_lparen_after, "iterator")) + return ExprError(); + + SourceLocation LLoc = T.getOpenLocation(); + SmallVector Data; + while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) { + // Check if the type parsing is required. + ParsedType IteratorType; + if (Tok.isNot(tok::identifier) || NextToken().isNot(tok::equal)) { + // identifier '=' is not found - parse type. + TypeResult TR = ParseTypeName(); + if (TR.isInvalid()) { + T.skipToEnd(); + return ExprError(); + } + IteratorType = TR.get(); + } + + // Parse identifier. + IdentifierInfo *II = nullptr; + SourceLocation IdLoc; + if (Tok.is(tok::identifier)) { + II = Tok.getIdentifierInfo(); + IdLoc = ConsumeToken(); + } else { + Diag(Tok, diag::err_expected_unqualified_id) << 0; + } + + // Parse '='. + SourceLocation AssignLoc; + if (Tok.is(tok::equal)) + AssignLoc = ConsumeToken(); + else + Diag(Tok, diag::err_omp_expected_equal_in_iterator); + + // Parse range-specification - ':' [ ':' ] + ColonProtectionRAIIObject ColonRAII(*this); + // Parse + SourceLocation Loc = Tok.getLocation(); + ExprResult LHS = ParseCastExpression(AnyCastExpr); + ExprResult Begin = Actions.CorrectDelayedTyposInExpr( + ParseRHSOfBinaryExpression(LHS, prec::Conditional)); + Begin = Actions.ActOnFinishFullExpr(Begin.get(), Loc, + /*DiscardedValue=*/false); + // Parse ':'. + SourceLocation ColonLoc; + if (Tok.is(tok::colon)) + ColonLoc = ConsumeToken(); + + // Parse + Loc = Tok.getLocation(); + LHS = ParseCastExpression(AnyCastExpr); + ExprResult End = Actions.CorrectDelayedTyposInExpr( + ParseRHSOfBinaryExpression(LHS, prec::Conditional)); + End = Actions.ActOnFinishFullExpr(End.get(), Loc, + /*DiscardedValue=*/false); + + SourceLocation SecColonLoc; + ExprResult Step; + // Parse optional step. + if (Tok.is(tok::colon)) { + // Parse ':' + SecColonLoc = ConsumeToken(); + // Parse + Loc = Tok.getLocation(); + LHS = ParseCastExpression(AnyCastExpr); + Step = Actions.CorrectDelayedTyposInExpr( + ParseRHSOfBinaryExpression(LHS, prec::Conditional)); + Step = Actions.ActOnFinishFullExpr(Step.get(), Loc, + /*DiscardedValue=*/false); + } + + // Parse ',' or ')' + if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren)) + Diag(Tok, diag::err_omp_expected_punc_after_iterator); + if (Tok.is(tok::comma)) + ConsumeToken(); + + Sema::OMPIteratorData &D = Data.emplace_back(); + D.DeclIdent = II; + D.DeclIdentLoc = IdLoc; + D.Type = IteratorType; + D.AssignLoc = AssignLoc; + D.ColonLoc = ColonLoc; + D.SecColonLoc = SecColonLoc; + D.Range.Begin = Begin.get(); + D.Range.End = End.get(); + D.Range.Step = Step.get(); + } + + // Parse ')'. + SourceLocation RLoc = Tok.getLocation(); + if (!T.consumeClose()) + RLoc = T.getCloseLocation(); + + return Actions.ActOnOMPIteratorExpr(getCurScope(), IteratorKwLoc, LLoc, RLoc, + Data); +} + /// Parses clauses with list. bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, @@ -3069,6 +3178,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, getOpenMPClauseName(Kind))) return true; + bool DependWithIterator = false; bool NeedRParenForLinear = false; BalancedDelimiterTracker LinearT(*this, tok::l_paren, tok::annot_pragma_openmp_end); @@ -3106,6 +3216,22 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Data.ReductionOrMapperId = Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId); } else if (Kind == OMPC_depend) { + if (getLangOpts().OpenMP >= 50) { + if (Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator") { + // Handle optional dependence modifier. + // iterator(iterators-definition) + // where iterators-definition is iterator-specifier [, + // iterators-definition ] + // where iterator-specifier is [ iterator-type ] identifier = + // range-specification + DependWithIterator = true; + EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope); + ExprResult IteratorRes = ParseOpenMPIteratorsExpr(); + Data.DepModOrTailExpr = IteratorRes.get(); + // Parse ',' + ExpectAndConsume(tok::comma); + } + } // Handle dependency type for depend clause. ColonProtectionRAIIObject ColonRAII(*this); Data.ExtraModifier = getOpenMPSimpleClauseType( @@ -3227,7 +3353,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, /*DiscardedValue=*/false); if (Tail.isUsable()) { if (Tok.is(tok::colon)) { - Data.TailExpr = Tail.get(); + Data.DepModOrTailExpr = Tail.get(); Data.ColonLoc = ConsumeToken(); TPA.Commit(); } else { @@ -3253,6 +3379,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned); while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) && Tok.isNot(tok::annot_pragma_openmp_end))) { + ParseScope OMPListScope(this, Scope::OpenMPDirectiveScope); ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail); // Parse variable ExprResult VarExpr = @@ -3289,7 +3416,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false); if (Tail.isUsable()) - Data.TailExpr = Tail.get(); + Data.DepModOrTailExpr = Tail.get(); else SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); @@ -3299,8 +3426,11 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Data.RLoc = Tok.getLocation(); if (!T.consumeClose()) Data.RLoc = T.getCloseLocation(); + // Exit from scope when the iterator is used in depend clause. + if (DependWithIterator) + ExitScope(); return (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) || - (MustHaveTail && !Data.TailExpr) || InvalidReductionId || + (MustHaveTail && !Data.DepModOrTailExpr) || InvalidReductionId || IsInvalidMapperModifier; } @@ -3372,7 +3502,7 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, return nullptr; OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc); return Actions.ActOnOpenMPVarListClause( - Kind, Vars, Data.TailExpr, Locs, Data.ColonLoc, + Kind, Vars, Data.DepModOrTailExpr, Locs, Data.ColonLoc, Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, Data.ExtraModifier, Data.MapTypeModifiers, Data.MapTypeModifiersLoc, Data.IsMapTypeImplicit, Data.ExtraModifierLoc); diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index fad2ae1cc066..0dc0c68205fb 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1300,6 +1300,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Expr::ArraySubscriptExprClass: case Expr::OMPArraySectionExprClass: case Expr::OMPArrayShapingExprClass: + case Expr::OMPIteratorExprClass: case Expr::BinaryOperatorClass: case Expr::DependentCoawaitExprClass: case Expr::CompoundAssignOperatorClass: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c0f8600aa0cc..8d0e97c85771 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4873,6 +4873,131 @@ ExprResult Sema::ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, LParenLoc, RParenLoc, NewDims, Brackets); } +ExprResult Sema::ActOnOMPIteratorExpr(Scope *S, SourceLocation IteratorKwLoc, + SourceLocation LLoc, SourceLocation RLoc, + ArrayRef Data) { + SmallVector ID; + bool IsCorrect = true; + for (const OMPIteratorData &D : Data) { + TypeSourceInfo *TInfo = nullptr; + SourceLocation StartLoc; + QualType DeclTy; + if (!D.Type.getAsOpaquePtr()) { + // OpenMP 5.0, 2.1.6 Iterators + // In an iterator-specifier, if the iterator-type is not specified then + // the type of that iterator is of int type. + DeclTy = Context.IntTy; + StartLoc = D.DeclIdentLoc; + } else { + DeclTy = GetTypeFromParser(D.Type, &TInfo); + StartLoc = TInfo->getTypeLoc().getBeginLoc(); + } + + bool IsDeclTyDependent = DeclTy->isDependentType() || + DeclTy->containsUnexpandedParameterPack() || + DeclTy->isInstantiationDependentType(); + if (!IsDeclTyDependent) { + if (!DeclTy->isIntegralType(Context) && !DeclTy->isAnyPointerType()) { + // OpenMP 5.0, 2.1.6 Iterators, Restrictions, C/C++ + // The iterator-type must be an integral or pointer type. + Diag(StartLoc, diag::err_omp_iterator_not_integral_or_pointer) + << DeclTy; + IsCorrect = false; + continue; + } + if (DeclTy.isConstant(Context)) { + // OpenMP 5.0, 2.1.6 Iterators, Restrictions, C/C++ + // The iterator-type must not be const qualified. + Diag(StartLoc, diag::err_omp_iterator_not_integral_or_pointer) + << DeclTy; + IsCorrect = false; + continue; + } + } + + // Iterator declaration. + assert(D.DeclIdent && "Identifier expected."); + // Always try to create iterator declarator to avoid extra error messages + // about unknown declarations use. + auto *VD = VarDecl::Create(Context, CurContext, StartLoc, D.DeclIdentLoc, + D.DeclIdent, DeclTy, TInfo, SC_None); + VD->setImplicit(); + if (S) { + // Check for conflicting previous declaration. + DeclarationNameInfo NameInfo(VD->getDeclName(), D.DeclIdentLoc); + LookupResult Previous(*this, NameInfo, LookupOrdinaryName, + ForVisibleRedeclaration); + Previous.suppressDiagnostics(); + LookupName(Previous, S); + + FilterLookupForScope(Previous, CurContext, S, /*ConsiderLinkage=*/false, + /*AllowInlineNamespace=*/false); + if (!Previous.empty()) { + NamedDecl *Old = Previous.getRepresentativeDecl(); + Diag(D.DeclIdentLoc, diag::err_redefinition) << VD->getDeclName(); + Diag(Old->getLocation(), diag::note_previous_definition); + } else { + PushOnScopeChains(VD, S); + } + } else { + CurContext->addDecl(VD); + } + Expr *Begin = D.Range.Begin; + if (!IsDeclTyDependent && Begin && !Begin->isTypeDependent()) { + ExprResult BeginRes = + PerformImplicitConversion(Begin, DeclTy, AA_Converting); + Begin = BeginRes.get(); + } + Expr *End = D.Range.End; + if (!IsDeclTyDependent && End && !End->isTypeDependent()) { + ExprResult EndRes = PerformImplicitConversion(End, DeclTy, AA_Converting); + End = EndRes.get(); + } + Expr *Step = D.Range.Step; + if (!IsDeclTyDependent && Step && !Step->isTypeDependent()) { + if (!Step->getType()->isIntegralType(Context)) { + Diag(Step->getExprLoc(), diag::err_omp_iterator_step_not_integral) + << Step << Step->getSourceRange(); + IsCorrect = false; + continue; + } + llvm::APSInt Result; + bool IsConstant = Step->isIntegerConstantExpr(Result, Context); + // OpenMP 5.0, 2.1.6 Iterators, Restrictions + // If the step expression of a range-specification equals zero, the + // behavior is unspecified. + if (IsConstant && Result.isNullValue()) { + Diag(Step->getExprLoc(), diag::err_omp_iterator_step_constant_zero) + << Step << Step->getSourceRange(); + IsCorrect = false; + continue; + } + } + if (!Begin || !End || !IsCorrect) { + IsCorrect = false; + continue; + } + OMPIteratorExpr::IteratorDefinition &IDElem = ID.emplace_back(); + IDElem.IteratorDecl = VD; + IDElem.AssignmentLoc = D.AssignLoc; + IDElem.Range.Begin = Begin; + IDElem.Range.End = End; + IDElem.Range.Step = Step; + IDElem.ColonLoc = D.ColonLoc; + IDElem.SecondColonLoc = D.SecColonLoc; + } + if (!IsCorrect) { + // Invalidate all created iterator declarations if error is found. + for (const OMPIteratorExpr::IteratorDefinition &D : ID) { + if (Decl *ID = D.IteratorDecl) + ID->setInvalidDecl(); + } + return ExprError(); + } + return OMPIteratorExpr::Create(Context, Context.OMPIteratorTy, IteratorKwLoc, + LLoc, RLoc, ID); +} + ExprResult Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc) { @@ -5634,6 +5759,7 @@ static bool isPlaceholderToRemoveAsArg(QualType type) { case BuiltinType::BuiltinFn: case BuiltinType::OMPArraySection: case BuiltinType::OMPArrayShaping: + case BuiltinType::OMPIterator: return true; } @@ -18513,6 +18639,9 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { case BuiltinType::OMPArrayShaping: return ExprError(Diag(E->getBeginLoc(), diag::err_omp_array_shaping_use)); + case BuiltinType::OMPIterator: + return ExprError(Diag(E->getBeginLoc(), diag::err_omp_iterator_use)); + // Everything else should be impossible. #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ case BuiltinType::Id: diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 7d2ae172fe4d..df56c3be43fc 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -13053,7 +13053,7 @@ OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, } OMPClause *Sema::ActOnOpenMPVarListClause( - OpenMPClauseKind Kind, ArrayRef VarList, Expr *TailExpr, + OpenMPClauseKind Kind, ArrayRef VarList, Expr *DepModOrTailExpr, const OMPVarListLocTy &Locs, SourceLocation ColonLoc, CXXScopeSpec &ReductionOrMapperIdScopeSpec, DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, @@ -13103,13 +13103,13 @@ OMPClause *Sema::ActOnOpenMPVarListClause( assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && "Unexpected linear modifier."); Res = ActOnOpenMPLinearClause( - VarList, TailExpr, StartLoc, LParenLoc, + VarList, DepModOrTailExpr, StartLoc, LParenLoc, static_cast(ExtraModifier), ExtraModifierLoc, ColonLoc, EndLoc); break; case OMPC_aligned: - Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, - ColonLoc, EndLoc); + Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, + LParenLoc, ColonLoc, EndLoc); break; case OMPC_copyin: Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); @@ -13124,8 +13124,8 @@ OMPClause *Sema::ActOnOpenMPVarListClause( assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && "Unexpected depend modifier."); Res = ActOnOpenMPDependClause( - static_cast(ExtraModifier), ExtraModifierLoc, - ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); + DepModOrTailExpr, static_cast(ExtraModifier), + ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); break; case OMPC_map: assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && @@ -13150,8 +13150,8 @@ OMPClause *Sema::ActOnOpenMPVarListClause( Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); break; case OMPC_allocate: - Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, - ColonLoc, EndLoc); + Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, + LParenLoc, ColonLoc, EndLoc); break; case OMPC_nontemporal: Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); @@ -15642,7 +15642,7 @@ OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, } OMPClause * -Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, +Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { @@ -15664,12 +15664,26 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, Except.push_back(OMPC_DEPEND_sink); if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) Except.push_back(OMPC_DEPEND_depobj); + std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) + ? "depend modifier(iterator) or " + : ""; Diag(DepLoc, diag::err_omp_unexpected_clause_value) - << getListOfPossibleValues(OMPC_depend, /*First=*/0, - /*Last=*/OMPC_DEPEND_unknown, Except) + << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, + /*Last=*/OMPC_DEPEND_unknown, + Except) << getOpenMPClauseName(OMPC_depend); return nullptr; } + if (DepModifier && + (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { + Diag(DepModifier->getExprLoc(), + diag::err_omp_depend_sink_source_with_modifier); + return nullptr; + } + if (DepModifier && + !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) + Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); + SmallVector Vars; DSAStackTy::OperatorOffsetTy OpsOffs; llvm::APSInt DepCounter(/*BitWidth=*/32); @@ -15878,8 +15892,8 @@ Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, return nullptr; auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, - DepKind, DepLoc, ColonLoc, Vars, - TotalDepCount.getZExtValue()); + DepModifier, DepKind, DepLoc, ColonLoc, + Vars, TotalDepCount.getZExtValue()); if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && DSAStack->isParentOrderedRegion()) DSAStack->addDoacrossDependClause(C, OpsOffs); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 82cfa246e3f7..de05d436d3b9 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1842,12 +1842,13 @@ class TreeTransform { /// By default, performs semantic analysis to build the new OpenMP clause. /// Subclasses may override this routine to provide diff erent behavior. OMPClause * - RebuildOMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, - SourceLocation ColonLoc, ArrayRef VarList, - SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPDependClause(DepKind, DepLoc, ColonLoc, VarList, - StartLoc, LParenLoc, EndLoc); + RebuildOMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, + SourceLocation DepLoc, SourceLocation ColonLoc, + ArrayRef VarList, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc) { + return getSema().ActOnOpenMPDependClause(DepModifier, DepKind, DepLoc, + ColonLoc, VarList, StartLoc, + LParenLoc, EndLoc); } /// Build a new OpenMP 'device' clause. @@ -2391,6 +2392,17 @@ class TreeTransform { BracketsRanges); } + /// Build a new iterator expression. + /// + /// By default, performs semantic analysis to build the new expression. + /// Subclasses may override this routine to provide diff erent behavior. + ExprResult RebuildOMPIteratorExpr( + SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc, + ArrayRef Data) { + return getSema().ActOnOMPIteratorExpr(/*Scope=*/nullptr, IteratorKwLoc, + LLoc, RLoc, Data); + } + /// Build a new call expression. /// /// By default, performs semantic analysis to build the new expression. @@ -9291,6 +9303,13 @@ template OMPClause * TreeTransform::TransformOMPDependClause(OMPDependClause *C) { llvm::SmallVector Vars; + Expr *DepModifier = C->getModifier(); + if (DepModifier) { + ExprResult DepModRes = getDerived().TransformExpr(DepModifier); + if (DepModRes.isInvalid()) + return nullptr; + DepModifier = DepModRes.get(); + } Vars.reserve(C->varlist_size()); for (auto *VE : C->varlists()) { ExprResult EVar = getDerived().TransformExpr(cast(VE)); @@ -9299,8 +9318,9 @@ TreeTransform::TransformOMPDependClause(OMPDependClause *C) { Vars.push_back(EVar.get()); } return getDerived().RebuildOMPDependClause( - C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(), Vars, - C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); + DepModifier, C->getDependencyKind(), C->getDependencyLoc(), + C->getColonLoc(), Vars, C->getBeginLoc(), C->getLParenLoc(), + C->getEndLoc()); } template @@ -10054,6 +10074,65 @@ TreeTransform::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) { E->getBracketsRanges()); } +template +ExprResult +TreeTransform::TransformOMPIteratorExpr(OMPIteratorExpr *E) { + unsigned NumIterators = E->numOfIterators(); + SmallVector Data(NumIterators); + + bool ErrorFound = false; + bool NeedToRebuild = getDerived().AlwaysRebuild(); + for (unsigned I = 0; I < NumIterators; ++I) { + auto *D = cast(E->getIteratorDecl(I)); + Data[I].DeclIdent = D->getIdentifier(); + Data[I].DeclIdentLoc = D->getLocation(); + if (D->getLocation() == D->getBeginLoc()) { + assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) && + "Implicit type must be int."); + } else { + TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo()); + QualType DeclTy = getDerived().TransformType(D->getType()); + Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI); + } + OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I); + ExprResult Begin = getDerived().TransformExpr(Range.Begin); + ExprResult End = getDerived().TransformExpr(Range.End); + ExprResult Step = getDerived().TransformExpr(Range.Step); + ErrorFound = ErrorFound || + !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() && + !Data[I].Type.get().isNull())) || + Begin.isInvalid() || End.isInvalid() || Step.isInvalid(); + if (ErrorFound) + continue; + Data[I].Range.Begin = Begin.get(); + Data[I].Range.End = End.get(); + Data[I].Range.Step = Step.get(); + Data[I].AssignLoc = E->getAssignLoc(I); + Data[I].ColonLoc = E->getColonLoc(I); + Data[I].SecColonLoc = E->getSecondColonLoc(I); + NeedToRebuild = + NeedToRebuild || + (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() != + D->getType().getTypePtrOrNull()) || + Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End || + Range.Step != Data[I].Range.Step; + } + if (ErrorFound) + return ExprError(); + if (!NeedToRebuild) + return E; + + ExprResult Res = getDerived().RebuildOMPIteratorExpr( + E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data); + if (!Res.isUsable()) + return Res; + auto *IE = cast(Res.get()); + for (unsigned I = 0; I < NumIterators; ++I) + getDerived().transformedLocalDecl(E->getIteratorDecl(I), + IE->getIteratorDecl(I)); + return Res; +} + template ExprResult TreeTransform::TransformCallExpr(CallExpr *E) { diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp index 158a12f0329d..566bda2d71f7 100644 --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -246,6 +246,9 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) { case BuiltinType::OMPArrayShaping: ID = PREDEF_TYPE_OMP_ARRAY_SHAPING; break; + case BuiltinType::OMPIterator: + ID = PREDEF_TYPE_OMP_ITERATOR; + break; } return TypeIdx(ID); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index bea9bdd22bab..74bb1c7f87dc 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -6960,6 +6960,9 @@ QualType ASTReader::GetType(TypeID ID) { case PREDEF_TYPE_OMP_ARRAY_SHAPING: T = Context.OMPArraySectionTy; break; + case PREDEF_TYPE_OMP_ITERATOR: + T = Context.OMPIteratorTy; + break; #define SVE_TYPE(Name, Id, SingletonId) \ case PREDEF_TYPE_##Id##_ID: \ T = Context.SingletonId; \ @@ -12307,6 +12310,7 @@ void OMPClauseReader::VisitOMPDepobjClause(OMPDepobjClause *C) { void OMPClauseReader::VisitOMPDependClause(OMPDependClause *C) { C->setLParenLoc(Record.readSourceLocation()); + C->setModifier(Record.readSubExpr()); C->setDependencyKind( static_cast(Record.readInt())); C->setDependencyLoc(Record.readSourceLocation()); diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index bc8c231731e8..2c915659ad7c 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -927,6 +927,26 @@ void ASTStmtReader::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { E->setRParenLoc(readSourceLocation()); } +void ASTStmtReader::VisitOMPIteratorExpr(OMPIteratorExpr *E) { + VisitExpr(E); + unsigned NumIters = Record.readInt(); + E->setIteratorKwLoc(readSourceLocation()); + E->setLParenLoc(readSourceLocation()); + E->setRParenLoc(readSourceLocation()); + for (unsigned I = 0; I < NumIters; ++I) { + E->setIteratorDeclaration(I, Record.readDeclRef()); + E->setAssignmentLoc(I, readSourceLocation()); + Expr *Begin = Record.readSubExpr(); + Expr *End = Record.readSubExpr(); + Expr *Step = Record.readSubExpr(); + SourceLocation ColonLoc = readSourceLocation(); + SourceLocation SecColonLoc; + if (Step) + SecColonLoc = readSourceLocation(); + E->setIteratorRange(I, Begin, ColonLoc, End, SecColonLoc, Step); + } +} + void ASTStmtReader::VisitCallExpr(CallExpr *E) { VisitExpr(E); unsigned NumArgs = Record.readInt(); @@ -2887,6 +2907,11 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { Context, Record[ASTStmtReader::NumExprFields]); break; + case EXPR_OMP_ITERATOR: + S = OMPIteratorExpr::CreateEmpty(Context, + Record[ASTStmtReader::NumExprFields]); + break; + case EXPR_CALL: S = CallExpr::CreateEmpty( Context, /*NumArgs=*/Record[ASTStmtReader::NumExprFields], Empty); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index f7c58ed11d9f..27f44a706f9f 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6379,6 +6379,7 @@ void OMPClauseWriter::VisitOMPDependClause(OMPDependClause *C) { Record.push_back(C->varlist_size()); Record.push_back(C->getNumLoops()); Record.AddSourceLocation(C->getLParenLoc()); + Record.AddStmt(C->getModifier()); Record.push_back(C->getDependencyKind()); Record.AddSourceLocation(C->getDependencyLoc()); Record.AddSourceLocation(C->getColonLoc()); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 840823298be7..ee8bb3e1d462 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -787,6 +787,26 @@ void ASTStmtWriter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { Code = serialization::EXPR_OMP_ARRAY_SHAPING; } +void ASTStmtWriter::VisitOMPIteratorExpr(OMPIteratorExpr *E) { + VisitExpr(E); + Record.push_back(E->numOfIterators()); + Record.AddSourceLocation(E->getIteratorKwLoc()); + Record.AddSourceLocation(E->getLParenLoc()); + Record.AddSourceLocation(E->getRParenLoc()); + for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) { + Record.AddDeclRef(E->getIteratorDecl(I)); + Record.AddSourceLocation(E->getAssignLoc(I)); + OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I); + Record.AddStmt(Range.Begin); + Record.AddStmt(Range.End); + Record.AddStmt(Range.Step); + Record.AddSourceLocation(E->getColonLoc(I)); + if (Range.Step) + Record.AddSourceLocation(E->getSecondColonLoc(I)); + } + Code = serialization::EXPR_OMP_ITERATOR; +} + void ASTStmtWriter::VisitCallExpr(CallExpr *E) { VisitExpr(E); Record.push_back(E->getNumArgs()); diff --git a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp index d16410a19b97..1cf81b54e77d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp @@ -352,6 +352,7 @@ static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1, case Stmt::ArraySubscriptExprClass: case Stmt::OMPArraySectionExprClass: case Stmt::OMPArrayShapingExprClass: + case Stmt::OMPIteratorExprClass: case Stmt::ImplicitCastExprClass: case Stmt::ParenExprClass: case Stmt::BreakStmtClass: diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 4c0914628a0d..1f0d89d59120 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1414,6 +1414,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::CXXNullPtrLiteralExprClass: case Stmt::OMPArraySectionExprClass: case Stmt::OMPArrayShapingExprClass: + case Stmt::OMPIteratorExprClass: case Stmt::TypeTraitExprClass: { Bldr.takeNodes(Pred); ExplodedNodeSet preVisit; diff --git a/clang/test/OpenMP/depobj_messages.cpp b/clang/test/OpenMP/depobj_messages.cpp index a33b16f985a0..1b20b1c525e7 100644 --- a/clang/test/OpenMP/depobj_messages.cpp +++ b/clang/test/OpenMP/depobj_messages.cpp @@ -142,7 +142,7 @@ label1 : { #pragma omp parallel depobj(argc) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}} ; #pragma omp depobj(x) seq_cst // expected-error {{unexpected OpenMP clause 'seq_cst' in directive '#pragma omp depobj'}} -#pragma omp depobj(x) depend(source: x) // expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp depobj(x) depend(source: x) // expected-error {{expected depend modifier(iterator) or 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} #pragma omp depobj(x) update // expected-error {{expected '(' after 'update'}} #pragma omp depobj(x) update( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'update'}} #pragma omp depobj(x) update(sink // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'update'}} diff --git a/clang/test/OpenMP/task_ast_print.cpp b/clang/test/OpenMP/task_ast_print.cpp index 1da6c5045934..cc569a6aab84 100644 --- a/clang/test/OpenMP/task_ast_print.cpp +++ b/clang/test/OpenMP/task_ast_print.cpp @@ -26,7 +26,7 @@ struct S1 { template class S7 : public T { protected: - T a, b; + T a, b, c[10], d[10]; S7() : a(0) {} public: @@ -34,7 +34,7 @@ class S7 : public T { omp_depend_t x; omp_event_handle_t evt; #pragma omp taskgroup allocate(b) task_reduction(+:b) -#pragma omp task private(a) private(this->a) private(T::a) in_reduction(+:this->b) allocate(b) depend(depobj:x) detach(evt) +#pragma omp task private(a) private(this->a) private(T::a) in_reduction(+:this->b) allocate(b) depend(depobj:x) detach(evt) depend(iterator(i=0:10:1, T *k = &a:&b), in: c[i], d[(int)(k-&a)]) for (int k = 0; k < a.a; ++k) ++this->a.a; } @@ -47,9 +47,9 @@ class S7 : public T { }; // CHECK: #pragma omp taskgroup allocate(this->b) task_reduction(+: this->b) -// CHECK: #pragma omp task private(this->a) private(this->a) private(T::a) in_reduction(+: this->b) allocate(this->b) depend(depobj : x) detach(evt){{$}} +// CHECK: #pragma omp task private(this->a) private(this->a) private(T::a) in_reduction(+: this->b) allocate(this->b) depend(depobj : x) detach(evt) depend(iterator(int i = 0:10:1, T * k = &this->a:&this->b), in : this->c[i],this->d[(int)(k - &this->a)]){{$}} // CHECK: #pragma omp task private(this->a) private(this->a) -// CHECK: #pragma omp task private(this->a) private(this->a) private(this->S1::a) +// CHECK: #pragma omp task private(this->a) private(this->a) private(this->S1::a) in_reduction(+: this->b) allocate(this->b) depend(depobj : x) detach(evt) depend(iterator(int i = 0:10:1, S1 * k = &this->a:&this->b), in : this->c[i],this->d[(int)(k - &this->a)]) class S8 : public S7 { S8() {} @@ -176,10 +176,10 @@ int main(int argc, char **argv) { // CHECK-NEXT: foo(); #pragma omp taskgroup task_reduction(min: arr1) #pragma omp parallel reduction(+:arr1) -#pragma omp task in_reduction(min: arr1) +#pragma omp task in_reduction(min: arr1) depend(iterator(i=0:argc, unsigned j=argc:0:a), out: argv[i][j]) // CHECK-NEXT: #pragma omp taskgroup task_reduction(min: arr1) // CHECK-NEXT: #pragma omp parallel reduction(+: arr1) - // CHECK-NEXT: #pragma omp task in_reduction(min: arr1) + // CHECK-NEXT: #pragma omp task in_reduction(min: arr1) depend(iterator(int i = 0:argc, unsigned int j = argc:0:a), out : argv[i][j]) foo(); // CHECK-NEXT: foo(); // CHECK-NEXT: #pragma omp task in_reduction(+: arr1) diff --git a/clang/test/OpenMP/task_depend_messages.cpp b/clang/test/OpenMP/task_depend_messages.cpp index f04c167cbdcc..bfb0e771b2ca 100644 --- a/clang/test/OpenMP/task_depend_messages.cpp +++ b/clang/test/OpenMP/task_depend_messages.cpp @@ -28,11 +28,11 @@ int main(int argc, char **argv, char *env[]) { #pragma omp task depend(in : arr[0]) #pragma omp task depend // expected-error {{expected '(' after 'depend'}} - #pragma omp task depend ( // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} - #pragma omp task depend () // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} - #pragma omp task depend (argc // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} - #pragma omp task depend (source : argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} - #pragma omp task depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend ( // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-warning {{missing ':' after dependency type - ignoring}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend () // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend (argc // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend (source : argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend (source) // expected-error {{expected expression}} expected-warning {{missing ':' after dependency type - ignoring}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} #pragma omp task depend (in : argc)) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}} #pragma omp task depend (out: ) // expected-error {{expected expression}} #pragma omp task depend (inout : foobool(argc)), depend (in, argc) // omp50-error {{expected addressable lvalue expression, array element, array section or array shaping expression}} omp45-error {{expected addressable lvalue expression, array element or array section}} expected-warning {{missing ':' after dependency type - ignoring}} expected-error {{expected expression}} @@ -70,7 +70,19 @@ int main(int argc, char **argv, char *env[]) { #pragma omp task depend(in : ([a])a) // omp45-error {{expected body of lambda expression}} omp50-error {{expected expression with a pointer to a complete type as a base of an array shaping operation}} #pragma omp task depend(in : ([a])argc) // omp45-error {{expected body of lambda expression}} omp50-error {{expected expression with a pointer to a complete type as a base of an array shaping operation}} #pragma omp task depend(in : ([-1][0])argv) // omp45-error {{expected variable name or 'this' in lambda capture list}} omp45-error {{expected ')'}} omp45-note {{to match this '('}} omp50-error {{array shaping dimension is evaluated to a non-positive value -1}} omp50-error {{array shaping dimension is evaluated to a non-positive value 0}} + #pragma omp task depend(iterator // expected-error {{expected ')'}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-note {{to match this '('}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} omp50-error {{expected '(' after 'iterator'}} omp50-error {{expected ','}} + #pragma omp task depend(iterator():argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected ','}} omp50-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} + #pragma omp task depend(iterator(argc // expected-error {{expected ')'}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-note {{to match this '('}} omp50-error {{unknown type name 'argc'}} omp50-error {{expected ')'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} omp50-error {{expected ','}} omp50-note {{to match this '('}} + #pragma omp task depend(iterator(unsigned argc: // expected-error {{expected ')'}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-note {{to match this '('}} omp50-error {{expected '=' in iterator specifier}} omp50-error 2 {{expected expression}} omp50-error {{expected ',' or ')' after iterator specifier}} omp50-error {{expected ')'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} omp50-error {{expected ','}} omp50-note {{to match this '('}} + #pragma omp task depend(iterator(unsigned argc = // expected-error {{expected ')'}} omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} expected-warning {{missing ':' after dependency type - ignoring}} expected-note {{to match this '('}} omp50-error 2 {{expected expression}} omp50-error {{expected ',' or ')' after iterator specifier}} omp50-error {{expected ')'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} omp50-error {{expected ','}} omp50-note {{to match this '('}} + #pragma omp task depend(iterator(vector argc = 0:2):argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{expected integral or pointer type as the iterator-type, not 'vector'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'depobj' in OpenMP clause 'depend'}} omp50-error {{expected ','}} + #pragma omp task depend(iterator(vector *argc = nullptr:nullptr+2:0), in:argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{invalid operands to binary expression ('nullptr_t' and 'int')}} omp50-error {{iterator step expression 0 evaluates to 0}} + #pragma omp task depend(iterator(vector *argc = 0:vector():argc), in:argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp50-error {{converting 'vector' to incompatible type 'vector *'}} foo(); +#pragma omp task depend(iterator(unsigned argc = 0:10), in : argc) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} + argc = 0; +#pragma omp task depend(iterator(i = 0:10, i = 0:10), in : argv[i]) // omp45-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} omp45-error {{use of undeclared identifier 'i'}} omp50-error {{redefinition of 'i'}} omp50-note {{previous definition is here}} + i = 0; // expected-error {{use of undeclared identifier 'i'}} return 0; } diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index bb9fed165679..14814f89d97d 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -5185,6 +5185,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return cxstring::createRef("OMPArraySectionExpr"); case CXCursor_OMPArrayShapingExpr: return cxstring::createRef("OMPArrayShapingExpr"); + case CXCursor_OMPIteratorExpr: + return cxstring::createRef("OMPIteratorExpr"); case CXCursor_BinaryOperator: return cxstring::createRef("BinaryOperator"); case CXCursor_CompoundAssignOperator: diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index 4f4e0c4ea1d5..3bcc7cc7af05 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -427,6 +427,10 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent, K = CXCursor_OMPArrayShapingExpr; break; + case Stmt::OMPIteratorExprClass: + K = CXCursor_OMPIteratorExpr; + break; + case Stmt::BinaryOperatorClass: K = CXCursor_BinaryOperator; break; From cfe-commits at lists.llvm.org Thu Apr 2 06:28:22 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 13:28:22 +0000 (UTC) Subject: [PATCH] D77125: [Analyzer] Model return values of container insert and delete operations In-Reply-To: References: Message-ID: martong added a comment. In D77125#1955245 , @baloghadamsoftware wrote: > In D77125#1952769 , @martong wrote: > > > It seems like we could model here `emplace` and `emplace_after` exactly the same way we do with `insert` and `insert_after`, couldn't we? Perhaps that could go into this patch too. > > > They are already in this patch (see the tests and the `CallDescriptionMap`), but they share their handing function with `insert` and `insert_after`. Ok, I missed that. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77125/new/ https://reviews.llvm.org/D77125 From cfe-commits at lists.llvm.org Thu Apr 2 06:28:23 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Thu, 02 Apr 2020 13:28:23 +0000 (UTC) Subject: [PATCH] D76790: [analyzer] StdLibraryFunctionsChecker: fix bug with arg constraints In-Reply-To: References: Message-ID: <7ce690f9326de314631581fed032c292@localhost.localdomain> Szelethus accepted this revision. Szelethus added a comment. This revision is now accepted and ready to land. Yup, looks great, sorry for the slack! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76790/new/ https://reviews.llvm.org/D76790 From cfe-commits at lists.llvm.org Thu Apr 2 07:01:22 2020 From: cfe-commits at lists.llvm.org (Florian Hahn via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 14:01:22 +0000 (UTC) Subject: [PATCH] D76612: [Matrix] Add draft specification for matrix support in Clang. In-Reply-To: References: Message-ID: <8faa7a2f85c2ad30d1fb54a3f09545ed@localhost.localdomain> fhahn updated this revision to Diff 254505. fhahn added a comment. Update arithmetic conversion rules after recent discussion on cfe-dev. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76612/new/ https://reviews.llvm.org/D76612 Files: clang/docs/LanguageExtensions.rst clang/docs/MatrixSupport.rst -------------- next part -------------- A non-text attachment was scrubbed... Name: D76612.254505.patch Type: text/x-patch Size: 12792 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 07:01:22 2020 From: cfe-commits at lists.llvm.org (Kevin P. Neal via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 14:01:22 +0000 (UTC) Subject: [PATCH] D77074: [FPEnv][AArch64] Platform-specific builtin constrained FP enablement In-Reply-To: References: Message-ID: kpn marked an inline comment as done. kpn added inline comments. ================ Comment at: clang/lib/CodeGen/CGBuiltin.cpp:8486-8492 + return Builder.CreateConstrainedFPCall( + F, + {EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2)), Ops[0]}); + } else { + Function *F = CGM.getIntrinsic(Intrinsic::fma, HalfTy); + // NEON intrinsic puts accumulator first, unlike the LLVM fma. + return Builder.CreateCall(F, {EmitScalarExpr(E->getArg(1)), ---------------- dnsampaio wrote: > It seems that `Builder.CreateCall` and `Builder.CreateConstrainedFPCall` usually have the same arguments, except for the function F being or not part of "experimental_constrained_". > Would it make sense to teach the `Builder` to select between creating a constrained or not call, depending if the function passed is constrained? > > I was thinking in something like this: > ``` > Function *F = CGM.getIntrinsic( Builder.getIsFPConstrained()? > Intrinsic::experimental_constrained_fma : > Intrinsic::fma, HalfTy); > return Builder.CreateCallConstrainedFPIfRequired(F, .... > ``` > In CGBuiltins.cpp we already have emitUnaryMaybeConstrainedFPBuiltin() plus Binary and Ternary. They work well for the pattern seen on other hosts. But they won't easily work for this ticket. How about a new function just below those three that will work well here? A emitCallMaybeConstrainedFPBuiltin() that takes two intrinsic IDs and chooses which one based on constrained FP would make for an even more compact use. The block of example code you put above would just turn into a single function call. Does that work for you? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77074/new/ https://reviews.llvm.org/D77074 From cfe-commits at lists.llvm.org Thu Apr 2 07:01:23 2020 From: cfe-commits at lists.llvm.org (Pratyai Mazumder via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 14:01:23 +0000 (UTC) Subject: [PATCH] D77244: sancov/inline-bool-flag feature + tests + docs. In-Reply-To: References: Message-ID: <78e5238bf4ceece9c1b746b0a2fd9d9e@localhost.localdomain> pratyai updated this revision to Diff 254508. pratyai added a comment. Added the alignment for i1 as a special case. Also the inline-bool-flag.ll test had to be changed with it. PTAL if I am missing something; I did not expect it to be much diffrerent than inline-8bit-counters.ll, but evidently it is now. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77244/new/ https://reviews.llvm.org/D77244 Files: clang/docs/SanitizerCoverage.rst clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/CC1Options.td clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/SanitizerArgs.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/Driver/autocomplete.c clang/test/Driver/fsanitize-coverage.c compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp llvm/include/llvm/Transforms/Instrumentation.h llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp llvm/test/Instrumentation/SanitizerCoverage/coff-pc-table-inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-inline-bool-flag.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D77244.254508.patch Type: text/x-patch Size: 30531 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 07:01:24 2020 From: cfe-commits at lists.llvm.org (Pratyai Mazumder via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 14:01:24 +0000 (UTC) Subject: [PATCH] D77244: sancov/inline-bool-flag feature + tests + docs. In-Reply-To: References: Message-ID: <390fb7b751199d01c53ac19c57d0e6a5@localhost.localdomain> pratyai updated this revision to Diff 254509. pratyai added a comment. Added the alignment for i1 as a special case. Also the inline-bool-flag.ll test had to be changed with it. PTAL if I am missing something; I did not expect it to be much diffrerent than inline-8bit-counters.ll, but evidently it is now. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77244/new/ https://reviews.llvm.org/D77244 Files: clang/docs/SanitizerCoverage.rst clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/CC1Options.td clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/SanitizerArgs.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/Driver/autocomplete.c clang/test/Driver/fsanitize-coverage.c compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp llvm/include/llvm/Transforms/Instrumentation.h llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp llvm/test/Instrumentation/SanitizerCoverage/coff-pc-table-inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-inline-bool-flag.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D77244.254509.patch Type: text/x-patch Size: 30531 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 07:01:25 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Bal=C3=A1zs_K=C3=A9ri_via_Phabricator?= via cfe-commits) Date: Thu, 02 Apr 2020 14:01:25 +0000 (UTC) Subject: [PATCH] D77305: [Analyzer][VLASize] Support multi-dimensional arrays. Message-ID: balazske created this revision. Herald added subscribers: cfe-commits, ASDenysPetrov, martong, Charusso, gamesh411, dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, baloghadamsoftware, xazax.hun. Herald added a reviewer: Szelethus. Herald added a project: clang. Check the size constraints for every (variable) dimension of the array. Try to compute array size by multiplying size for every dimension. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77305 Files: clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp clang/test/Analysis/vla.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77305.254511.patch Type: text/x-patch Size: 8153 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 07:01:25 2020 From: cfe-commits at lists.llvm.org (Daniel Kiss via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 14:01:25 +0000 (UTC) Subject: [PATCH] D75181: [AArch64] Handle BTI/PAC in case of generated functions. In-Reply-To: References: Message-ID: <9361b47493efd7754a9ab2a4c57a7868@localhost.localdomain> danielkiss marked an inline comment as done. danielkiss added inline comments. ================ Comment at: clang/lib/CodeGen/TargetInfo.cpp:5149-5152 + if (BPI.BranchTargetEnforcement) + Fn->addFnAttr("branch-target-enforcement", "true"); + else + Fn->addFnAttr("branch-target-enforcement", "false"); ---------------- I'm going to rebase the patch. I add there a new attribute here "ignore-branch-target-enforcement" so then the "branch-target-enforcement"="true"/"false" could be just "branch-target-enforcement". CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75181/new/ https://reviews.llvm.org/D75181 From cfe-commits at lists.llvm.org Thu Apr 2 07:32:06 2020 From: cfe-commits at lists.llvm.org (Aaron Ballman via cfe-commits) Date: Thu, 02 Apr 2020 07:32:06 -0700 (PDT) Subject: [clang] 54d0a55 - Fix several typos in the attribute documentation. Message-ID: <5e85f766.1c69fb81.9afdb.221c@mx.google.com> Author: Aaron Ballman Date: 2020-04-02T10:31:39-04:00 New Revision: 54d0a55d7fb9b5269c637a41f73be7bf385570d6 URL: https://github.com/llvm/llvm-project/commit/54d0a55d7fb9b5269c637a41f73be7bf385570d6 DIFF: https://github.com/llvm/llvm-project/commit/54d0a55d7fb9b5269c637a41f73be7bf385570d6.diff LOG: Fix several typos in the attribute documentation. Added: Modified: clang/include/clang/Basic/AttrDocs.td Removed: ################################################################################ diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index bdc47b43c34b..fb1c82a80115 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -140,7 +140,7 @@ def NoEscapeDocs : Documentation { the compiler that the pointer cannot escape: that is, no reference to the object the pointer points to that is derived from the parameter value will survive after the function returns. Users are responsible for making sure parameters -annotated with ``noescape`` do not actuallly escape. Calling ``free()`` on such +annotated with ``noescape`` do not actually escape. Calling ``free()`` on such a parameter does not constitute an escape. For example: @@ -485,7 +485,7 @@ parameter. Note that this attribute merely informs the compiler that a function always returns a sufficiently aligned pointer. It does not cause the compiler to emit code to enforce that alignment. The behavior is undefined if the returned -poitner is not sufficiently aligned. +pointer is not sufficiently aligned. }]; } @@ -943,11 +943,11 @@ The behavior of a function with respect to reference counting for Foundation convention (e.g. functions starting with "get" are assumed to return at ``+0``). -It can be overriden using a family of the following attributes. In +It can be overridden using a family of the following attributes. In Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to a function communicates that the object is returned at ``+1``, and the caller is responsible for freeing it. -Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +Similarly, the annotation ``__attribute__((ns_returns_not_retained))`` specifies that the object is returned at ``+0`` and the ownership remains with the callee. The annotation ``__attribute__((ns_consumes_self))`` specifies that @@ -1291,7 +1291,7 @@ correspond to diff erent platforms. For most platforms, the availability attribute with the platform corresponding to the target platform will be used; any others will be ignored. However, the availability for ``watchOS`` and ``tvOS`` can be implicitly inferred from an ``iOS`` availability attribute. -Any explicit availability attributes for those platforms are still prefered over +Any explicit availability attributes for those platforms are still preferred over the implicitly inferred availability attributes. If no availability attribute specifies availability for the current target platform, the availability attributes are ignored. Supported platforms are: @@ -1399,7 +1399,7 @@ pragma rather than using the inferred ``iOS`` availability from the declaration: void getsThePragmaTVOSAvailabilityAttribute(void) __attribute__((availability(iOS,introduced=11.0))); #pragma clang attribute pop -The compiler is also able to apply implicly inferred attributes from a pragma +The compiler is also able to apply implicitly inferred attributes from a pragma as well. For example, when targeting ``tvOS``, the function below will receive a ``tvOS`` availability attribute that is implicitly inferred from the ``iOS`` availability attribute applied by the pragma: @@ -1717,7 +1717,7 @@ def BPFPreserveAccessIndexDocs : Documentation { Clang supports the ``__attribute__((preserve_access_index))`` attribute for the BPF target. This attribute may be attached to a struct or union declaration, where if -g is specified, it enables -preserving struct or union member access debuginfo indicies of this +preserving struct or union member access debuginfo indices of this struct or union, similar to clang ``__builtin_preserve_acceess_index()``. }]; } @@ -1733,7 +1733,7 @@ directly as an interrupt service routine. By default, the compiler will produce a function prologue and epilogue suitable for an interrupt service routine that handles an External Interrupt Controller (eic) -generated interrupt. This behaviour can be explicitly requested with the "eic" +generated interrupt. This behavior can be explicitly requested with the "eic" argument. Otherwise, for use with vectored interrupt mode, the argument passed should be @@ -3680,7 +3680,7 @@ using the Swift calling convention for a function or function pointer. The lowering for the Swift calling convention, as described by the Swift ABI documentation, occurs in multiple phases. The first, "high-level" phase breaks down the formal parameters and results into innately direct -and indirect components, adds implicit paraameters for the generic +and indirect components, adds implicit parameters for the generic signature, and assigns the context and error ABI treatments to parameters where applicable. The second phase breaks down the direct parameters and results from the first phase and assigns them to registers or the @@ -3722,7 +3722,7 @@ of the first phase, as follows: ``swiftcall`` does not support variadic arguments or unprototyped functions. The parameter ABI treatment attributes are aspects of the function type. -A function type which which applies an ABI treatment attribute to a +A function type which applies an ABI treatment attribute to a parameter is a diff erent type from an otherwise-identical function type that does not. A single parameter may not have multiple ABI treatment attributes. @@ -3851,7 +3851,7 @@ with diff erent ABI versions supported. For example, a newer version of a class could have a diff erent set of data members and thus have a diff erent size. Using the ``abi_tag`` attribute, it is possible to have diff erent mangled names for a global variable of the class type. Therefore, the old code could keep using -the old manged name and the new code will use the new mangled name with tags. +the old mangled name and the new code will use the new mangled name with tags. }]; } @@ -4005,9 +4005,9 @@ takes precedence over the command line option ``-fpatchable-function-entry=N,M`` def TransparentUnionDocs : Documentation { let Category = DocCatDecl; let Content = [{ -This attribute can be applied to a union to change the behaviour of calls to +This attribute can be applied to a union to change the behavior of calls to functions that have an argument with a transparent union type. The compiler -behaviour is changed in the following manner: +behavior is changed in the following manner: - A value whose type is any member of the transparent union can be passed as an argument without the need to cast that value. @@ -4539,7 +4539,7 @@ When applied to the definition of a function, method, or block, every parameter of the function with implicit strong retainable object pointer type is considered externally-retained, and becomes ``const``. By explicitly annotating a parameter with ``__strong``, you can opt back into the default -non-externally-retained behaviour for that parameter. For instance, +non-externally-retained behavior for that parameter. For instance, ``first_param`` is externally-retained below, but not ``second_param``: .. code-block:: objc @@ -4561,7 +4561,7 @@ def MIGConventionDocs : Documentation { The Mach Interface Generator release-on-success convention dictates functions that follow it to only release arguments passed to them when they return "success" (a ``kern_return_t`` error code that indicates that -no errors have occured). Otherwise the release is performed by the MIG client +no errors have occurred). Otherwise the release is performed by the MIG client that called the function. The annotation ``__attribute__((mig_server_routine))`` is applied in order to specify which functions are expected to follow the convention. This allows the Static Analyzer to find bugs caused by violations of From cfe-commits at lists.llvm.org Thu Apr 2 07:33:44 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 14:33:44 +0000 (UTC) Subject: [PATCH] D76125: [clangd] Decouple preambleworker from astworker, NFCI In-Reply-To: References: Message-ID: <8bce0105a8e0aff52dd228c29ab33c85@localhost.localdomain> kadircet updated this revision to Diff 254516. kadircet added a comment. - Start preambleworker in sync mode instead of blocking Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76125/new/ https://reviews.llvm.org/D76125 Files: clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Preamble.h clang-tools-extra/clangd/TUScheduler.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76125.254516.patch Type: text/x-patch Size: 15295 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 07:33:44 2020 From: cfe-commits at lists.llvm.org (Jason Liu via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 14:33:44 +0000 (UTC) Subject: [PATCH] D76932: [AIX] emit .extern and .weak directive linkage In-Reply-To: References: Message-ID: <83e3c05f92872695ab8bad196843a6ad@localhost.localdomain> jasonliu added inline comments. ================ Comment at: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:1486 // Emit visibility info for declarations for (const Function &F : M) { ---------------- Comment should change to something similar to: `Emit linkage(XCOFF) and visibility info for declarations.` ================ Comment at: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:1510 + continue; + } + ---------------- What if we have ``` void foo(); void (*foo_ptr)() = foo; int bar() { foo(); } ``` We would need both `.extern .foo` and `.extern foo[DS]`. Also, please have a similar case into the lit test. ================ Comment at: llvm/lib/MC/MCXCOFFStreamer.cpp:38 case MCSA_Global: + case llvm::MCSA_Extern: Symbol->setStorageClass(XCOFF::C_EXT); ---------------- Please remove `llvm::` for MCSA_Extern and MCSA_Weak to make the style consistent. ================ Comment at: llvm/lib/MC/MCXCOFFStreamer.cpp:48 + Symbol->setStorageClass(XCOFF::C_WEAKEXT); + Symbol->setExternal(true); + break; ---------------- Maybe we should just move `Symbol->setExternal(true);` outside of the switch, as it is set for every attribute that we are going to emit. ================ Comment at: llvm/lib/MC/XCOFFObjectWriter.cpp:351 + if (nameShouldBeInStringTable(ContainingCsect->getSectionName())) + Strings.add(ContainingCsect->getSectionName()); + } ---------------- We should `continue` here if the rest of the logic does not matter. ================ Comment at: llvm/lib/MC/XCOFFObjectWriter.cpp:352 + Strings.add(ContainingCsect->getSectionName()); + } // If the symbol is the csect itself, we don't need to put the symbol ---------------- A new line after '}'. ================ Comment at: llvm/lib/MC/XCOFFObjectWriter.cpp:353 + } // If the symbol is the csect itself, we don't need to put the symbol // into csect's Syms. ---------------- line 353 to 365 did not align properly. ================ Comment at: llvm/test/CodeGen/PowerPC/aix-extern-weak.ll:17 + +define weak void @foo_weak() #0 { +entry: ---------------- Nit: Please remove #0, #1 from the test case. ================ Comment at: llvm/test/CodeGen/PowerPC/aix-extern-weak.ll:55 + +; COMMON: .weak foo_weak[DS] # -- Begin function foo_weak +; COMMON-NEXT: .weak .foo_weak ---------------- A proper space alignment would make the expected result more readable. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76932/new/ https://reviews.llvm.org/D76932 From cfe-commits at lists.llvm.org Thu Apr 2 07:33:45 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 14:33:45 +0000 (UTC) Subject: [PATCH] D76304: [clangd] Update TUStatus api to accommodate preamble thread In-Reply-To: References: Message-ID: kadircet updated this revision to Diff 254519. kadircet added a comment. - Rebase Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76304/new/ https://reviews.llvm.org/D76304 Files: clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/TUScheduler.cpp clang-tools-extra/clangd/TUScheduler.h clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76304.254519.patch Type: text/x-patch Size: 22021 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 07:33:46 2020 From: cfe-commits at lists.llvm.org (Michael Liao via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 14:33:46 +0000 (UTC) Subject: [PATCH] D59321: AMDGPU: Teach toolchain to link rocm device libs In-Reply-To: References: Message-ID: <0fcf6c099910b3aab9a7fee2b4a53c2d@localhost.localdomain> hliao added a comment. In D59321#1955646 , @arsenm wrote: > In D59321#1955405 , @hliao wrote: > > > Do we have a better way to avoid adding those empty bitcode files? > > > No, we need the files to exist for tests. This is what existing bitcode link tests do could you update this patch? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D59321/new/ https://reviews.llvm.org/D59321 From cfe-commits at lists.llvm.org Thu Apr 2 07:33:46 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 14:33:46 +0000 (UTC) Subject: [PATCH] D76725: [clangd] Build ASTs only with fresh preambles or after building a new preamble In-Reply-To: References: Message-ID: <2ae11a08409ffe1bbc424d13060fe813@localhost.localdomain> kadircet updated this revision to Diff 254520. kadircet added a comment. - Rebase Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76725/new/ https://reviews.llvm.org/D76725 Files: clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Preamble.h clang-tools-extra/clangd/TUScheduler.cpp clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp clang-tools-extra/clangd/unittests/FileIndexTests.cpp clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp clang-tools-extra/clangd/unittests/TestTU.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76725.254520.patch Type: text/x-patch Size: 49289 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 07:52:55 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via cfe-commits) Date: Thu, 02 Apr 2020 07:52:55 -0700 (PDT) Subject: [clang-tools-extra] da8eda1 - [clangd] Get rid of redundant make_uniques Message-ID: <5e85fc47.1c69fb81.5fdea.21cc@mx.google.com> Author: Kadir Cetinkaya Date: 2020-04-02T16:52:13+02:00 New Revision: da8eda1ab1ae97115f9ed170216ed89b69662578 URL: https://github.com/llvm/llvm-project/commit/da8eda1ab1ae97115f9ed170216ed89b69662578 DIFF: https://github.com/llvm/llvm-project/commit/da8eda1ab1ae97115f9ed170216ed89b69662578.diff LOG: [clangd] Get rid of redundant make_uniques Added: Modified: clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/TUScheduler.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp index 2c7cb5d2b85d..f6205879aa29 100644 --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -551,8 +551,7 @@ buildAST(PathRef FileName, std::unique_ptr Invocation, } return ParsedAST::build( - Inputs.Version, std::make_unique(*Invocation), - CompilerInvocationDiags, Preamble, + Inputs.Version, std::move(Invocation), CompilerInvocationDiags, Preamble, llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents, FileName), std::move(VFS), Inputs.Index, Inputs.Opts); } diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp index e5a001997ecc..a2df2c3ff62f 100644 --- a/clang-tools-extra/clangd/TUScheduler.cpp +++ b/clang-tools-extra/clangd/TUScheduler.cpp @@ -569,12 +569,10 @@ void ASTWorker::runWithAST( vlog("ASTWorker rebuilding evicted AST to run {0}: {1} version {2}", Name, FileName, CurrentInputs->Version); llvm::Optional NewAST = - Invocation - ? buildAST(FileName, - std::make_unique(*Invocation), - CompilerInvocationDiagConsumer.take(), *CurrentInputs, - getPossiblyStalePreamble()) - : None; + Invocation ? buildAST(FileName, std::move(Invocation), + CompilerInvocationDiagConsumer.take(), + *CurrentInputs, getPossiblyStalePreamble()) + : None; AST = NewAST ? std::make_unique(std::move(*NewAST)) : nullptr; } // Make sure we put the AST back into the LRU cache. From cfe-commits at lists.llvm.org Thu Apr 2 08:00:28 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via cfe-commits) Date: Thu, 02 Apr 2020 08:00:28 -0700 (PDT) Subject: [clang] 1525232 - [analyzer] StdLibraryFunctionsChecker: fix bug with arg constraints Message-ID: <5e85fe0c.1c69fb81.202d2.2854@mx.google.com> Author: Gabor Marton Date: 2020-04-02T17:00:11+02:00 New Revision: 1525232e276153e325a49372894ae52ed07351a5 URL: https://github.com/llvm/llvm-project/commit/1525232e276153e325a49372894ae52ed07351a5 DIFF: https://github.com/llvm/llvm-project/commit/1525232e276153e325a49372894ae52ed07351a5.diff LOG: [analyzer] StdLibraryFunctionsChecker: fix bug with arg constraints Summary: Previously we induced a state split if there were multiple argument constraints given for a function. This was because we called `addTransition` inside the for loop. The fix is to is to store the state and apply the next argument constraint on that. And once the loop is finished we call `addTransition`. Reviewers: NoQ, Szelethus, baloghadamsoftware Subscribers: whisperity, xazax.hun, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, C Tags: #clang Differential Revision: https://reviews.llvm.org/D76790 Added: Modified: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp clang/test/Analysis/std-c-library-functions-arg-constraints.c Removed: ################################################################################ diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 136a0fb6a374..6a577940e313 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -1422,6 +1422,12 @@ def DebugIteratorModeling : Checker<"DebugIteratorModeling">, Dependencies<[DebugContainerModeling, IteratorModeling]>, Documentation; +def StdCLibraryFunctionsTesterChecker : Checker<"StdCLibraryFunctionsTester">, + HelpText<"Add test functions to the summary map, so testing of individual " + "summary constituents becomes possible.">, + Dependencies<[StdCLibraryFunctionsChecker]>, + Documentation; + } // end "debug" diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp index 6e5f5f8b5874..f03696daab0b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -306,7 +306,11 @@ class StdLibraryFunctionsChecker void checkPostCall(const CallEvent &Call, CheckerContext &C) const; bool evalCall(const CallEvent &Call, CheckerContext &C) const; - enum CheckKind { CK_StdCLibraryFunctionArgsChecker, CK_NumCheckKinds }; + enum CheckKind { + CK_StdCLibraryFunctionArgsChecker, + CK_StdCLibraryFunctionsTesterChecker, + CK_NumCheckKinds + }; DefaultBool ChecksEnabled[CK_NumCheckKinds]; CheckerNameRef CheckNames[CK_NumCheckKinds]; @@ -455,23 +459,26 @@ void StdLibraryFunctionsChecker::checkPreCall(const CallEvent &Call, const Summary &Summary = *FoundSummary; ProgramStateRef State = C.getState(); + ProgramStateRef NewState = State; for (const ValueConstraintPtr& VC : Summary.ArgConstraints) { - ProgramStateRef SuccessSt = VC->apply(State, Call, Summary); - ProgramStateRef FailureSt = VC->negate()->apply(State, Call, Summary); + ProgramStateRef SuccessSt = VC->apply(NewState, Call, Summary); + ProgramStateRef FailureSt = VC->negate()->apply(NewState, Call, Summary); // The argument constraint is not satisfied. if (FailureSt && !SuccessSt) { - if (ExplodedNode *N = C.generateErrorNode(State)) + if (ExplodedNode *N = C.generateErrorNode(NewState)) reportBug(Call, N, C); break; } else { - // Apply the constraint even if we cannot reason about the argument. This - // means both SuccessSt and FailureSt can be true. If we weren't applying - // the constraint that would mean that symbolic execution continues on a - // code whose behaviour is undefined. + // We will apply the constraint even if we cannot reason about the + // argument. This means both SuccessSt and FailureSt can be true. If we + // weren't applying the constraint that would mean that symbolic + // execution continues on a code whose behaviour is undefined. assert(SuccessSt); - C.addTransition(SuccessSt); + NewState = SuccessSt; } } + if (NewState && NewState != State) + C.addTransition(NewState); } void StdLibraryFunctionsChecker::checkPostCall(const CallEvent &Call, @@ -936,6 +943,32 @@ void StdLibraryFunctionsChecker::initFunctionSummaries( {"getdelim", Summaries{Getline(IntTy, IntMax), Getline(LongTy, LongMax), Getline(LongLongTy, LongLongMax)}}, }; + + // Functions for testing. + if (ChecksEnabled[CK_StdCLibraryFunctionsTesterChecker]) { + llvm::StringMap TestFunctionSummaryMap = { + {"__two_constrained_args", + Summaries{ + Summary(ArgTypes{IntTy, IntTy}, RetType{IntTy}, EvalCallAsPure) + .ArgConstraint( + ArgumentCondition(0U, WithinRange, SingleValue(1))) + .ArgConstraint( + ArgumentCondition(1U, WithinRange, SingleValue(1)))}}, + {"__arg_constrained_twice", + Summaries{Summary(ArgTypes{IntTy}, RetType{IntTy}, EvalCallAsPure) + .ArgConstraint( + ArgumentCondition(0U, OutOfRange, SingleValue(1))) + .ArgConstraint( + ArgumentCondition(0U, OutOfRange, SingleValue(2)))}}, + }; + for (auto &E : TestFunctionSummaryMap) { + auto InsertRes = + FunctionSummaryMap.insert({std::string(E.getKey()), E.getValue()}); + assert(InsertRes.second && + "Test functions must not clash with modeled functions"); + (void)InsertRes; + } + } } void ento::registerStdCLibraryFunctionsChecker(CheckerManager &mgr) { @@ -958,3 +991,4 @@ bool ento::shouldRegisterStdCLibraryFunctionsChecker(const CheckerManager &mgr) bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; } REGISTER_CHECKER(StdCLibraryFunctionArgsChecker) +REGISTER_CHECKER(StdCLibraryFunctionsTesterChecker) diff --git a/clang/test/Analysis/std-c-library-functions-arg-constraints.c b/clang/test/Analysis/std-c-library-functions-arg-constraints.c index a20b90ad1ccb..9753f9eb00cc 100644 --- a/clang/test/Analysis/std-c-library-functions-arg-constraints.c +++ b/clang/test/Analysis/std-c-library-functions-arg-constraints.c @@ -3,6 +3,7 @@ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \ // RUN: -analyzer-checker=apiModeling.StdCLibraryFunctionArgs \ +// RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \ // RUN: -analyzer-checker=debug.ExprInspection \ // RUN: -triple x86_64-unknown-linux-gnu \ // RUN: -verify=report @@ -12,6 +13,7 @@ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \ // RUN: -analyzer-checker=apiModeling.StdCLibraryFunctionArgs \ +// RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \ // RUN: -analyzer-checker=debug.ExprInspection \ // RUN: -triple x86_64-unknown-linux-gnu \ // RUN: -analyzer-output=text \ @@ -85,3 +87,30 @@ void test_notnull_symbolic2(FILE *fp, int *buf) { // bugpath-warning{{Function argument constraint is not satisfied}} \ // bugpath-note{{Function argument constraint is not satisfied}} } + +int __two_constrained_args(int, int); +void test_constraints_on_multiple_args(int x, int y) { + // State split should not happen here. I.e. x == 1 should not be evaluated + // FALSE. + __two_constrained_args(x, y); + clang_analyzer_eval(x == 1); // \ + // report-warning{{TRUE}} \ + // bugpath-warning{{TRUE}} \ + // bugpath-note{{TRUE}} + clang_analyzer_eval(y == 1); // \ + // report-warning{{TRUE}} \ + // bugpath-warning{{TRUE}} \ + // bugpath-note{{TRUE}} +} + +int __arg_constrained_twice(int); +void test_multiple_constraints_on_same_arg(int x) { + __arg_constrained_twice(x); + // Check that both constraints are applied and only one branch is there. + clang_analyzer_eval(x < 1 || x > 2); // \ + // report-warning{{TRUE}} \ + // bugpath-warning{{TRUE}} \ + // bugpath-note{{TRUE}} \ + // bugpath-note{{Assuming 'x' is < 1}} \ + // bugpath-note{{Left side of '||' is true}} +} From cfe-commits at lists.llvm.org Thu Apr 2 08:06:27 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 15:06:27 +0000 (UTC) Subject: [PATCH] D77309: [clangd] Get rid of ASTWorker::getCurrentFileInputs Message-ID: kadircet created this revision. kadircet added a reviewer: sammccall. Herald added subscribers: cfe-commits, usaxena95, arphaman, jkorous, MaskRay, javed.absar, ilya-biryukov. Herald added a project: clang. kadircet added a parent revision: D76725: [clangd] Build ASTs only with fresh preambles or after building a new preamble. FileInputs are only written by ASTWorker thread, therefore it is safe to read them without the lock inside that thread. It can still be read by other threads through ASTWorker::getCurrentCompileCommand though. This patch also gets rid of the smart pointer wrapping FileInputs as there is never mutliple owners. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77309 Files: clang-tools-extra/clangd/TUScheduler.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77309.254526.patch Type: text/x-patch Size: 5381 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 08:06:29 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 15:06:29 +0000 (UTC) Subject: [PATCH] D77041: [AST] Fix a crash on invalid constexpr Ctorinitializer when building RecoveryExpr. In-Reply-To: References: Message-ID: hokein updated this revision to Diff 254525. hokein added a comment. remove accident change. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77041/new/ https://reviews.llvm.org/D77041 Files: clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/invalid-constructor-init.cpp Index: clang/test/SemaCXX/invalid-constructor-init.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/invalid-constructor-init.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -frecovery-ast -verify %s + +struct X { + int Y; + constexpr X() // expected-error {{constexpr constructor never produces}} + : Y(foo()) {} // expected-error {{use of undeclared identifier 'foo'}} +}; +// no crash on evaluating the constexpr ctor. +constexpr int Z = X().Y; // expected-error {{constexpr variable 'Z' must be initialized by a constant expression}} + +struct X2 { + int Y = foo(); // expected-error {{use of undeclared identifier 'foo'}} \ + // expected-note {{subexpression not valid in a constant expression}} + constexpr X2() {} // expected-error {{constexpr constructor never produces a constant expression}} +}; + +struct CycleDelegate { + int Y; + CycleDelegate(int) + : Y(foo()) {} // expected-error {{use of undeclared identifier 'foo'}} + // no bogus "delegation cycle" diagnostic + CycleDelegate(float) : CycleDelegate(1) {} +}; Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -4975,6 +4975,13 @@ return false; } + if (const auto *CtorDecl = dyn_cast_or_null(Definition)) { + for (const auto *InitExpr : CtorDecl->inits()) { + if (InitExpr->getInit() && InitExpr->getInit()->containsErrors()) + return false; + } + } + // Can we evaluate this function call? if (Definition && Definition->isConstexpr() && Body) return true; @@ -14736,6 +14743,15 @@ if (FD->isDependentContext()) return true; + // Bail out if a constexpr constructor has an initializer that contains an + // error. We deliberately don't produce a diagnostic, as we have produced a + // relevant diagnostic when parsing the error initializer. + if (const auto *Ctor = dyn_cast(FD)) { + for (const auto *InitExpr : Ctor->inits()) { + if (InitExpr->getInit() && InitExpr->getInit()->containsErrors()) + return false; + } + } Expr::EvalStatus Status; Status.Diag = &Diags; -------------- next part -------------- A non-text attachment was scrubbed... Name: D77041.254525.patch Type: text/x-patch Size: 2276 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 08:06:31 2020 From: cfe-commits at lists.llvm.org (Martin Probst via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 15:06:31 +0000 (UTC) Subject: [PATCH] D77311: clang-format: [JS] detect C++ keywords. Message-ID: mprobst created this revision. mprobst added a reviewer: krasimir. Herald added subscribers: cfe-commits, jfb. Herald added a project: clang. C++ defines a number of keywords that are regular identifiers in JavaScript, e.g. `concept`: const concept = 1; // legit JS This change expands the existing `IsJavaScriptIdentifier(Tok)` function to return false for C++ keywords that aren't keywords in JS. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77311 Files: clang/lib/Format/FormatToken.h clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTestJS.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77311.254528.patch Type: text/x-patch Size: 5960 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 08:06:32 2020 From: cfe-commits at lists.llvm.org (Jason Liu via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 15:06:32 +0000 (UTC) Subject: [PATCH] D76932: [AIX] emit .extern and .weak directive linkage In-Reply-To: References: Message-ID: jasonliu added inline comments. ================ Comment at: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:407 case GlobalValue::WeakAnyLinkage: case GlobalValue::WeakODRLinkage: if (MAI->hasWeakDefDirective()) { ---------------- Could we verify if these Linkage should also always emit .weak? We do have one test case that tests LinkOnceODRLinkage in llvm/test/CodeGen/PowerPC/aix-LinkOnceODRLinkage.ll, but no other linkages here is tested and confirmed the behavior is right for AIX. Also LinkOnceODRLinkage.ll test needs to get update as well, since we will emit `.weak _Z3fooIiEvT_[DS]` now. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76932/new/ https://reviews.llvm.org/D76932 From cfe-commits at lists.llvm.org Thu Apr 2 08:06:56 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 15:06:56 +0000 (UTC) Subject: [PATCH] D76790: [analyzer] StdLibraryFunctionsChecker: fix bug with arg constraints In-Reply-To: References: Message-ID: <7f5db07b692be5e62aafad8aa65a9680@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG1525232e2761: [analyzer] StdLibraryFunctionsChecker: fix bug with arg constraints (authored by martong). Changed prior to commit: https://reviews.llvm.org/D76790?vs=253595&id=254530#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76790/new/ https://reviews.llvm.org/D76790 Files: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp clang/test/Analysis/std-c-library-functions-arg-constraints.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D76790.254530.patch Type: text/x-patch Size: 6732 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 08:37:47 2020 From: cfe-commits at lists.llvm.org (Sam McCall via cfe-commits) Date: Thu, 02 Apr 2020 08:37:47 -0700 (PDT) Subject: [clang-tools-extra] 24bb2d1 - [clangd] Add a tweak for adding "using" statement. Message-ID: <5e8606cb.1c69fb81.9592d.30b8@mx.google.com> Author: Adam Czachorowski Date: 2020-04-02T17:37:38+02:00 New Revision: 24bb2d1e776897c3a93856d2ca76decb4cfd0562 URL: https://github.com/llvm/llvm-project/commit/24bb2d1e776897c3a93856d2ca76decb4cfd0562 DIFF: https://github.com/llvm/llvm-project/commit/24bb2d1e776897c3a93856d2ca76decb4cfd0562.diff LOG: [clangd] Add a tweak for adding "using" statement. Summary: This triggers on types and function calls with namespace qualifiers. The action is to remove the qualifier and instead add a "using" statement at appropriate place. It is not always clear where to add the "using" line. Right now we find the nearest "using" line and add it there, thus keeping with local convention. If there are no usings, we put it at the deepest relevant namespace level. This is an initial version only. There are several improvements that can be made: * Support for qualifiers that are not purely namespace (e.g. record types, etc). * Removing qualifier from other instances of the same type/call. * Smarter placement of the "using" line. Reviewers: sammccall Reviewed By: sammccall Subscribers: nridge, mgorny, ilya-biryukov, MaskRay, jkorous, mgrang, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D76432 Added: clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp Modified: clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt clang-tools-extra/clangd/unittests/TweakTests.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp new file mode 100644 index 000000000000..1ecec6674b02 --- /dev/null +++ b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp @@ -0,0 +1,286 @@ +//===--- AddUsing.cpp --------------------------------------------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "AST.h" +#include "FindTarget.h" +#include "Logger.h" +#include "refactor/Tweak.h" +#include "clang/AST/Decl.h" +#include "clang/AST/RecursiveASTVisitor.h" + +namespace clang { +namespace clangd { +namespace { + +// Tweak for removing full namespace qualifier under cursor on DeclRefExpr and +// types and adding "using" statement instead. +// +// Only qualifiers that refer exclusively to namespaces (no record types) are +// supported. There is some guessing of appropriate place to insert the using +// declaration. If we find any existing usings, we insert it there. If not, we +// insert right after the inner-most relevant namespace declaration. If there is +// none, or there is, but it was declared via macro, we insert above the first +// top level decl. +// +// Currently this only removes qualifier from under the cursor. In the future, +// we should improve this to remove qualifier from all occurences of this +// symbol. +class AddUsing : public Tweak { +public: + const char *id() const override; + + bool prepare(const Selection &Inputs) override; + Expected apply(const Selection &Inputs) override; + std::string title() const override; + Intent intent() const override { return Refactor; } + +private: + // The qualifier to remove. Set by prepare(). + NestedNameSpecifierLoc QualifierToRemove; + // The name following QualifierToRemove. Set by prepare(). + llvm::StringRef Name; +}; +REGISTER_TWEAK(AddUsing) + +std::string AddUsing::title() const { + return std::string(llvm::formatv( + "Add using-declaration for {0} and remove qualifier.", Name)); +} + +// Locates all "using" statements relevant to SelectionDeclContext. +class UsingFinder : public RecursiveASTVisitor { +public: + UsingFinder(std::vector &Results, + const DeclContext *SelectionDeclContext, const SourceManager &SM) + : Results(Results), SelectionDeclContext(SelectionDeclContext), SM(SM) {} + + bool VisitUsingDecl(UsingDecl *D) { + auto Loc = D->getUsingLoc(); + if (SM.getFileID(Loc) != SM.getMainFileID()) { + return true; + } + if (D->getDeclContext()->Encloses(SelectionDeclContext)) { + Results.push_back(D); + } + return true; + } + + bool TraverseDecl(Decl *Node) { + // There is no need to go deeper into nodes that do not enclose selection, + // since "using" there will not affect selection, nor would it make a good + // insertion point. + if (Node->getDeclContext()->Encloses(SelectionDeclContext)) { + return RecursiveASTVisitor::TraverseDecl(Node); + } + return true; + } + +private: + std::vector &Results; + const DeclContext *SelectionDeclContext; + const SourceManager &SM; +}; + +struct InsertionPointData { + // Location to insert the "using" statement. If invalid then the statement + // should not be inserted at all (it already exists). + SourceLocation Loc; + // Extra suffix to place after the "using" statement. Depending on what the + // insertion point is anchored to, we may need one or more \n to ensure + // proper formatting. + std::string Suffix; +}; + +// Finds the best place to insert the "using" statement. Returns invalid +// SourceLocation if the "using" statement already exists. +// +// The insertion point might be a little awkward if the decl we're anchoring to +// has a comment in an unfortunate place (e.g. directly above function or using +// decl, or immediately following "namespace {". We should add some helpers for +// dealing with that and use them in other code modifications as well. +llvm::Expected +findInsertionPoint(const Tweak::Selection &Inputs, + const NestedNameSpecifierLoc &QualifierToRemove, + const llvm::StringRef Name) { + auto &SM = Inputs.AST->getSourceManager(); + + // Search for all using decls that affect this point in file. We need this for + // two reasons: to skip adding "using" if one already exists and to find best + // place to add it, if it doesn't exist. + SourceLocation LastUsingLoc; + std::vector Usings; + UsingFinder(Usings, &Inputs.ASTSelection.commonAncestor()->getDeclContext(), + SM) + .TraverseAST(Inputs.AST->getASTContext()); + + for (auto &U : Usings) { + if (SM.isBeforeInTranslationUnit(Inputs.Cursor, U->getUsingLoc())) + // "Usings" is sorted, so we're done. + break; + if (U->getQualifier()->getAsNamespace()->getCanonicalDecl() == + QualifierToRemove.getNestedNameSpecifier() + ->getAsNamespace() + ->getCanonicalDecl() && + U->getName() == Name) { + return InsertionPointData(); + } + // Insertion point will be before last UsingDecl that affects cursor + // position. For most cases this should stick with the local convention of + // add using inside or outside namespace. + LastUsingLoc = U->getUsingLoc(); + } + if (LastUsingLoc.isValid()) { + InsertionPointData Out; + Out.Loc = LastUsingLoc; + return Out; + } + + // No relevant "using" statements. Try the nearest namespace level. + const auto *NS = Inputs.ASTSelection.commonAncestor() + ->getDeclContext() + .getEnclosingNamespaceContext(); + if (auto *ND = dyn_cast(NS)) { + auto Toks = Inputs.AST->getTokens().expandedTokens(ND->getSourceRange()); + const auto *Tok = llvm::find_if(Toks, [](const syntax::Token &Tok) { + return Tok.kind() == tok::l_brace; + }); + if (Tok == Toks.end() || Tok->endLocation().isInvalid()) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Namespace with no {"); + } + if (!Tok->endLocation().isMacroID()) { + InsertionPointData Out; + Out.Loc = Tok->endLocation(); + Out.Suffix = "\n"; + return Out; + } + } + // No using, no namespace, no idea where to insert. Try above the first + // top level decl. + auto TLDs = Inputs.AST->getLocalTopLevelDecls(); + if (TLDs.empty()) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Cannot find place to insert \"using\""); + } + InsertionPointData Out; + Out.Loc = SM.getExpansionLoc(TLDs[0]->getBeginLoc()); + Out.Suffix = "\n\n"; + return Out; +} + +bool AddUsing::prepare(const Selection &Inputs) { + auto &SM = Inputs.AST->getSourceManager(); + auto *Node = Inputs.ASTSelection.commonAncestor(); + if (Node == nullptr) + return false; + + // If we're looking at a type or NestedNameSpecifier, walk up the tree until + // we find the "main" node we care about, which would be ElaboratedTypeLoc or + // DeclRefExpr. + for (; Node->Parent; Node = Node->Parent) { + if (Node->ASTNode.get()) { + continue; + } else if (auto *T = Node->ASTNode.get()) { + if (T->getAs()) { + break; + } else if (Node->Parent->ASTNode.get() || + Node->Parent->ASTNode.get()) { + // Node is TypeLoc, but it's parent is either TypeLoc or + // NestedNameSpecifier. In both cases, we want to go up, to find + // the outermost TypeLoc. + continue; + } + } + break; + } + if (Node == nullptr) + return false; + + if (auto *D = Node->ASTNode.get()) { + QualifierToRemove = D->getQualifierLoc(); + Name = D->getDecl()->getName(); + } else if (auto *T = Node->ASTNode.get()) { + if (auto E = T->getAs()) { + QualifierToRemove = E.getQualifierLoc(); + Name = + E.getType().getUnqualifiedType().getBaseTypeIdentifier()->getName(); + } + } + + // FIXME: This only supports removing qualifiers that are made up of just + // namespace names. If qualifier contains a type, we could take the longest + // namespace prefix and remove that. + if (!QualifierToRemove.hasQualifier() || + !QualifierToRemove.getNestedNameSpecifier()->getAsNamespace() || + Name.empty()) { + return false; + } + + // Macros are diff icult. We only want to offer code action when what's spelled + // under the cursor is a namespace qualifier. If it's a macro that expands to + // a qualifier, user would not know what code action will actually change. + // On the other hand, if the qualifier is part of the macro argument, we + // should still support that. + if (SM.isMacroBodyExpansion(QualifierToRemove.getBeginLoc()) || + !SM.isWrittenInSameFile(QualifierToRemove.getBeginLoc(), + QualifierToRemove.getEndLoc())) { + return false; + } + + return true; +} + +Expected AddUsing::apply(const Selection &Inputs) { + auto &SM = Inputs.AST->getSourceManager(); + auto &TB = Inputs.AST->getTokens(); + + // Determine the length of the qualifier under the cursor, then remove it. + auto SpelledTokens = TB.spelledForExpanded( + TB.expandedTokens(QualifierToRemove.getSourceRange())); + if (!SpelledTokens) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Could not determine length of the qualifier"); + } + unsigned Length = + syntax::Token::range(SM, SpelledTokens->front(), SpelledTokens->back()) + .length(); + tooling::Replacements R; + if (auto Err = R.add(tooling::Replacement( + SM, SpelledTokens->front().location(), Length, ""))) { + return std::move(Err); + } + + auto InsertionPoint = findInsertionPoint(Inputs, QualifierToRemove, Name); + if (!InsertionPoint) { + return InsertionPoint.takeError(); + } + + if (InsertionPoint->Loc.isValid()) { + // Add the using statement at appropriate location. + std::string UsingText; + llvm::raw_string_ostream UsingTextStream(UsingText); + UsingTextStream << "using "; + QualifierToRemove.getNestedNameSpecifier()->print( + UsingTextStream, Inputs.AST->getASTContext().getPrintingPolicy()); + UsingTextStream << Name << ";" << InsertionPoint->Suffix; + + assert(SM.getFileID(InsertionPoint->Loc) == SM.getMainFileID()); + if (auto Err = R.add(tooling::Replacement(SM, InsertionPoint->Loc, 0, + UsingTextStream.str()))) { + return std::move(Err); + } + } + + return Effect::mainFileEdit(Inputs.AST->getASTContext().getSourceManager(), + std::move(R)); +} + +} // namespace +} // namespace clangd +} // namespace clang diff --git a/clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt b/clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt index 5817830b7ea3..995288bca2cf 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt +++ b/clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt @@ -12,6 +12,7 @@ set(LLVM_LINK_COMPONENTS # $ to a list of sources, see # clangd/tool/CMakeLists.txt for an example. add_clang_library(clangDaemonTweaks OBJECT + AddUsing.cpp AnnotateHighlightings.cpp DumpAST.cpp DefineInline.cpp diff --git a/clang-tools-extra/clangd/unittests/TweakTests.cpp b/clang-tools-extra/clangd/unittests/TweakTests.cpp index cae922ffcb95..b5d6117217b6 100644 --- a/clang-tools-extra/clangd/unittests/TweakTests.cpp +++ b/clang-tools-extra/clangd/unittests/TweakTests.cpp @@ -2390,6 +2390,250 @@ TEST_F(DefineOutlineTest, FailsMacroSpecifier) { EXPECT_EQ(apply(Case.first), Case.second); } } + +TWEAK_TEST(AddUsing); +TEST_F(AddUsingTest, Prepare) { + const std::string Header = R"cpp( +#define NS(name) one::two::name +namespace one { +void oo() {} +namespace two { +enum ee {}; +void ff() {} +class cc { +public: + struct st {}; + static void mm() {} +}; +} +})cpp"; + + EXPECT_AVAILABLE(Header + "void fun() { o^n^e^:^:^t^w^o^:^:^f^f(); }"); + EXPECT_AVAILABLE(Header + "void fun() { o^n^e^::^o^o(); }"); + EXPECT_AVAILABLE(Header + "void fun() { o^n^e^:^:^t^w^o^:^:^e^e E; }"); + EXPECT_AVAILABLE(Header + "void fun() { o^n^e^:^:^t^w^o:^:^c^c C; }"); + EXPECT_UNAVAILABLE(Header + + "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^m^m(); }"); + EXPECT_UNAVAILABLE(Header + + "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^s^t inst; }"); + EXPECT_UNAVAILABLE(Header + + "void fun() { o^n^e^:^:^t^w^o^:^:^c^c^:^:^s^t inst; }"); + EXPECT_UNAVAILABLE(Header + "void fun() { N^S(c^c) inst; }"); +} + +TEST_F(AddUsingTest, Apply) { + FileName = "test.cpp"; + struct { + llvm::StringRef TestSource; + llvm::StringRef ExpectedSource; + } Cases[]{{ + // Function, no other using, namespace. + R"cpp( +#include "test.hpp" +namespace { +void fun() { + ^o^n^e^:^:^t^w^o^:^:^f^f(); +} +})cpp", + R"cpp( +#include "test.hpp" +namespace {using one::two::ff; + +void fun() { + ff(); +} +})cpp", + }, + // Type, no other using, namespace. + { + R"cpp( +#include "test.hpp" +namespace { +void fun() { + ::on^e::t^wo::c^c inst; +} +})cpp", + R"cpp( +#include "test.hpp" +namespace {using ::one::two::cc; + +void fun() { + cc inst; +} +})cpp", + }, + // Type, no other using, no namespace. + { + R"cpp( +#include "test.hpp" + +void fun() { + on^e::t^wo::e^e inst; +})cpp", + R"cpp( +#include "test.hpp" + +using one::two::ee; + +void fun() { + ee inst; +})cpp"}, + // Function, other usings. + { + R"cpp( +#include "test.hpp" + +using one::two::cc; +using one::two::ee; + +namespace { +void fun() { + one::two::f^f(); +} +})cpp", + R"cpp( +#include "test.hpp" + +using one::two::cc; +using one::two::ff;using one::two::ee; + +namespace { +void fun() { + ff(); +} +})cpp", + }, + // Function, other usings inside namespace. + { + R"cpp( +#include "test.hpp" + +using one::two::cc; + +namespace { + +using one::two::ff; + +void fun() { + o^ne::o^o(); +} +})cpp", + R"cpp( +#include "test.hpp" + +using one::two::cc; + +namespace { + +using one::oo;using one::two::ff; + +void fun() { + oo(); +} +})cpp"}, + // Using comes after cursor. + { + R"cpp( +#include "test.hpp" + +namespace { + +void fun() { + one::t^wo::ff(); +} + +using one::two::cc; + +})cpp", + R"cpp( +#include "test.hpp" + +namespace {using one::two::ff; + + +void fun() { + ff(); +} + +using one::two::cc; + +})cpp"}, + // Pointer type. + {R"cpp( +#include "test.hpp" + +void fun() { + one::two::c^c *p; +})cpp", + R"cpp( +#include "test.hpp" + +using one::two::cc; + +void fun() { + cc *p; +})cpp"}, + // Namespace declared via macro. + {R"cpp( +#include "test.hpp" +#define NS_BEGIN(name) namespace name { + +NS_BEGIN(foo) + +void fun() { + one::two::f^f(); +} +})cpp", + R"cpp( +#include "test.hpp" +#define NS_BEGIN(name) namespace name { + +using one::two::ff; + +NS_BEGIN(foo) + +void fun() { + ff(); +} +})cpp"}, + // Inside macro argument. + {R"cpp( +#include "test.hpp" +#define CALL(name) name() + +void fun() { + CALL(one::t^wo::ff); +})cpp", + R"cpp( +#include "test.hpp" +#define CALL(name) name() + +using one::two::ff; + +void fun() { + CALL(ff); +})cpp"}}; + llvm::StringMap EditedFiles; + for (const auto &Case : Cases) { + for (const auto &SubCase : expandCases(Case.TestSource)) { + ExtraFiles["test.hpp"] = R"cpp( +namespace one { +void oo() {} +namespace two { +enum ee {}; +void ff() {} +class cc { +public: + struct st { struct nested {}; }; + static void mm() {} +}; +} +})cpp"; + EXPECT_EQ(apply(SubCase, &EditedFiles), Case.ExpectedSource); + } + } +} + } // namespace } // namespace clangd } // namespace clang From cfe-commits at lists.llvm.org Thu Apr 2 08:38:12 2020 From: cfe-commits at lists.llvm.org (Sam McCall via cfe-commits) Date: Thu, 02 Apr 2020 08:38:12 -0700 (PDT) Subject: [clang-tools-extra] fc83010 - [clangd] Don't send semanticHighlights to clients that support semanticTokens. Message-ID: <5e8606e4.1c69fb81.e343.feaf@mx.google.com> Author: Sam McCall Date: 2020-04-02T17:38:02+02:00 New Revision: fc830106e15553fcca3fc80066fe5a988e16dfec URL: https://github.com/llvm/llvm-project/commit/fc830106e15553fcca3fc80066fe5a988e16dfec DIFF: https://github.com/llvm/llvm-project/commit/fc830106e15553fcca3fc80066fe5a988e16dfec.diff LOG: [clangd] Don't send semanticHighlights to clients that support semanticTokens. Summary: This allows the standard mechanism to gracefully displace the old one. Reviewers: hokein Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77206 Added: Modified: clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/ClangdServer.h clang-tools-extra/clangd/Protocol.cpp clang-tools-extra/clangd/Protocol.h clang-tools-extra/clangd/test/semantic-tokens.test Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index 310c1fec17dd..8906e6f68f2f 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -480,6 +480,13 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, ClangdServerOpts.TheiaSemanticHighlighting = Params.capabilities.TheiaSemanticHighlighting; + if (Params.capabilities.TheiaSemanticHighlighting && + Params.capabilities.SemanticTokens) { + log("Client supports legacy semanticHighlights notification and standard " + "semanticTokens request, choosing the latter (no notifications)."); + ClangdServerOpts.TheiaSemanticHighlighting = false; + } + if (Params.rootUri && *Params.rootUri) ClangdServerOpts.WorkspaceRoot = std::string(Params.rootUri->file()); else if (Params.rootPath && !Params.rootPath->empty()) @@ -612,7 +619,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, }}}}; if (NegotiatedOffsetEncoding) Result["offsetEncoding"] = *NegotiatedOffsetEncoding; - if (Params.capabilities.TheiaSemanticHighlighting) + if (ClangdServerOpts.TheiaSemanticHighlighting) Result.getObject("capabilities") ->insert( {"semanticHighlighting", diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index f1e981e6c14f..ae3da84c42c8 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -145,7 +145,7 @@ class ClangdServer { /// fetch system include path. std::vector QueryDriverGlobs; - /// Enable semantic highlighting features. + /// Enable notification-based semantic highlighting. bool TheiaSemanticHighlighting = false; /// Returns true if the tweak should be enabled. diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp index 9d7c96df02c0..019c6c038467 100644 --- a/clang-tools-extra/clangd/Protocol.cpp +++ b/clang-tools-extra/clangd/Protocol.cpp @@ -297,6 +297,8 @@ bool fromJSON(const llvm::json::Value &Params, ClientCapabilities &R) { SemanticHighlighting->getBoolean("semanticHighlighting")) R.TheiaSemanticHighlighting = *SemanticHighlightingSupport; } + if (auto *SemanticHighlighting = TextDocument->getObject("semanticTokens")) + R.SemanticTokens = true; if (auto *Diagnostics = TextDocument->getObject("publishDiagnostics")) { if (auto CategorySupport = Diagnostics->getBoolean("categorySupport")) R.DiagnosticCategory = *CategorySupport; diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h index 5d0b60d7fe9f..a713d47862b1 100644 --- a/clang-tools-extra/clangd/Protocol.h +++ b/clang-tools-extra/clangd/Protocol.h @@ -433,8 +433,13 @@ struct ClientCapabilities { /// textDocument.codeAction.codeActionLiteralSupport. bool CodeActionStructure = false; + /// Client advertises support for the semanticTokens feature. + /// We support the textDocument/semanticTokens request in any case. + /// textDocument.semanticTokens + bool SemanticTokens = false; /// Client supports Theia semantic highlighting extension. /// https://github.com/microsoft/vscode-languageserver-node/pull/367 + /// This will be ignored if the client also supports semanticTokens. /// textDocument.semanticHighlightingCapabilities.semanticHighlighting /// FIXME: drop this support once clients support LSP 3.16 Semantic Tokens. bool TheiaSemanticHighlighting = false; diff --git a/clang-tools-extra/clangd/test/semantic-tokens.test b/clang-tools-extra/clangd/test/semantic-tokens.test index 1f6b51af84dd..679766995d52 100644 --- a/clang-tools-extra/clangd/test/semantic-tokens.test +++ b/clang-tools-extra/clangd/test/semantic-tokens.test @@ -1,5 +1,10 @@ -# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s -{"jsonrpc":"2.0","id":0,"method":"initialize","params":{}} +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s -implicit-check-not=semanticHighlight +# Send capabilities for both Theia semanticHighlight & standard semanticTokens. +# clangd should not use/acknowledge the Theia protocol in this case. +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"capabilities":{"textDocument":{ + "semanticHighlightingCapabilities":{"semanticHighlighting":true}, + "semanticTokens":{"dynamicRegistration":true} +}}}} --- {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.cpp","languageId":"cpp","text":"int x = 2;"}}} --- From cfe-commits at lists.llvm.org Thu Apr 2 08:39:05 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 15:39:05 +0000 (UTC) Subject: [PATCH] D77313: [AST] Allow VectorTypes of 1-256 elements, and powers of two up to 2**31. Message-ID: sammccall created this revision. sammccall added reviewers: hokein, rjmccall, erichkeane. Herald added a project: clang. Herald added a subscriber: cfe-commits. This used to be 1-2043 elements, and recently regressed to a limit of 1023. The new behavior is an almost-superset of GCC, which accepts powers of two up to 2**62. This change frees one further bit in VectorType in case Type grows again. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77313 Files: clang/include/clang/AST/Type.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/AST/Type.cpp clang/lib/Sema/SemaType.cpp clang/test/Sema/types.c clang/test/SemaCXX/vector.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77313.254532.patch Type: text/x-patch Size: 10422 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 08:39:06 2020 From: cfe-commits at lists.llvm.org (Ayke via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 15:39:06 +0000 (UTC) Subject: [PATCH] D66324: clang-misexpect: Profile Guided Validation of Performance Annotations in LLVM In-Reply-To: References: Message-ID: aykevl added a comment. I have the same issue as @wenju. The second time I call `ExecuteCompilerInvocation` it will give the error above, leading me to believe some memory isn't properly cleared. Note: the `--pgo-warn-misexpect` option is not passed in the compiler invocation. Repository: rL LLVM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D66324/new/ https://reviews.llvm.org/D66324 From cfe-commits at lists.llvm.org Thu Apr 2 08:39:09 2020 From: cfe-commits at lists.llvm.org (JF Bastien via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 15:39:09 +0000 (UTC) Subject: [PATCH] D77311: clang-format: [JS] detect C++ keywords. In-Reply-To: References: Message-ID: jfb added a comment. Some of these are technically "future reserved keywords": https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords Wouldn't it be better to list all of JS's keywords at this point? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77311/new/ https://reviews.llvm.org/D77311 From cfe-commits at lists.llvm.org Thu Apr 2 08:39:36 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 15:39:36 +0000 (UTC) Subject: [PATCH] D76432: [clangd] Add a tweak for adding "using" statement. In-Reply-To: References: Message-ID: <61351eea5c3ef8841d1f70630bbf9201@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG24bb2d1e7768: [clangd] Add a tweak for adding "using" statement. (authored by adamcz, committed by sammccall). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76432/new/ https://reviews.llvm.org/D76432 Files: clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt clang-tools-extra/clangd/unittests/TweakTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76432.254534.patch Type: text/x-patch Size: 16470 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 08:39:48 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 15:39:48 +0000 (UTC) Subject: [PATCH] D77206: [clangd] Don't send semanticHighlights to clients that support semanticTokens. In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rGfc830106e155: [clangd] Don't send semanticHighlights to clients that support semanticTokens. (authored by sammccall). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77206/new/ https://reviews.llvm.org/D77206 Files: clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/ClangdServer.h clang-tools-extra/clangd/Protocol.cpp clang-tools-extra/clangd/Protocol.h clang-tools-extra/clangd/test/semantic-tokens.test Index: clang-tools-extra/clangd/test/semantic-tokens.test =================================================================== --- clang-tools-extra/clangd/test/semantic-tokens.test +++ clang-tools-extra/clangd/test/semantic-tokens.test @@ -1,5 +1,10 @@ -# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s -{"jsonrpc":"2.0","id":0,"method":"initialize","params":{}} +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s -implicit-check-not=semanticHighlight +# Send capabilities for both Theia semanticHighlight & standard semanticTokens. +# clangd should not use/acknowledge the Theia protocol in this case. +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"capabilities":{"textDocument":{ + "semanticHighlightingCapabilities":{"semanticHighlighting":true}, + "semanticTokens":{"dynamicRegistration":true} +}}}} --- {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.cpp","languageId":"cpp","text":"int x = 2;"}}} --- Index: clang-tools-extra/clangd/Protocol.h =================================================================== --- clang-tools-extra/clangd/Protocol.h +++ clang-tools-extra/clangd/Protocol.h @@ -433,8 +433,13 @@ /// textDocument.codeAction.codeActionLiteralSupport. bool CodeActionStructure = false; + /// Client advertises support for the semanticTokens feature. + /// We support the textDocument/semanticTokens request in any case. + /// textDocument.semanticTokens + bool SemanticTokens = false; /// Client supports Theia semantic highlighting extension. /// https://github.com/microsoft/vscode-languageserver-node/pull/367 + /// This will be ignored if the client also supports semanticTokens. /// textDocument.semanticHighlightingCapabilities.semanticHighlighting /// FIXME: drop this support once clients support LSP 3.16 Semantic Tokens. bool TheiaSemanticHighlighting = false; Index: clang-tools-extra/clangd/Protocol.cpp =================================================================== --- clang-tools-extra/clangd/Protocol.cpp +++ clang-tools-extra/clangd/Protocol.cpp @@ -297,6 +297,8 @@ SemanticHighlighting->getBoolean("semanticHighlighting")) R.TheiaSemanticHighlighting = *SemanticHighlightingSupport; } + if (auto *SemanticHighlighting = TextDocument->getObject("semanticTokens")) + R.SemanticTokens = true; if (auto *Diagnostics = TextDocument->getObject("publishDiagnostics")) { if (auto CategorySupport = Diagnostics->getBoolean("categorySupport")) R.DiagnosticCategory = *CategorySupport; Index: clang-tools-extra/clangd/ClangdServer.h =================================================================== --- clang-tools-extra/clangd/ClangdServer.h +++ clang-tools-extra/clangd/ClangdServer.h @@ -145,7 +145,7 @@ /// fetch system include path. std::vector QueryDriverGlobs; - /// Enable semantic highlighting features. + /// Enable notification-based semantic highlighting. bool TheiaSemanticHighlighting = false; /// Returns true if the tweak should be enabled. Index: clang-tools-extra/clangd/ClangdLSPServer.cpp =================================================================== --- clang-tools-extra/clangd/ClangdLSPServer.cpp +++ clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -480,6 +480,13 @@ ClangdServerOpts.TheiaSemanticHighlighting = Params.capabilities.TheiaSemanticHighlighting; + if (Params.capabilities.TheiaSemanticHighlighting && + Params.capabilities.SemanticTokens) { + log("Client supports legacy semanticHighlights notification and standard " + "semanticTokens request, choosing the latter (no notifications)."); + ClangdServerOpts.TheiaSemanticHighlighting = false; + } + if (Params.rootUri && *Params.rootUri) ClangdServerOpts.WorkspaceRoot = std::string(Params.rootUri->file()); else if (Params.rootPath && !Params.rootPath->empty()) @@ -612,7 +619,7 @@ }}}}; if (NegotiatedOffsetEncoding) Result["offsetEncoding"] = *NegotiatedOffsetEncoding; - if (Params.capabilities.TheiaSemanticHighlighting) + if (ClangdServerOpts.TheiaSemanticHighlighting) Result.getObject("capabilities") ->insert( {"semanticHighlighting", -------------- next part -------------- A non-text attachment was scrubbed... Name: D77206.254535.patch Type: text/x-patch Size: 4277 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 08:40:12 2020 From: cfe-commits at lists.llvm.org (Sam McCall via cfe-commits) Date: Thu, 02 Apr 2020 08:40:12 -0700 (PDT) Subject: [clang-tools-extra] 9e3063e - [clangd] Support textDocument/semanticTokens/edits Message-ID: <5e86075c.1c69fb81.8155d.258b@mx.google.com> Author: Sam McCall Date: 2020-04-02T17:38:29+02:00 New Revision: 9e3063eaceec5054684a77acf5281772df2a7f73 URL: https://github.com/llvm/llvm-project/commit/9e3063eaceec5054684a77acf5281772df2a7f73 DIFF: https://github.com/llvm/llvm-project/commit/9e3063eaceec5054684a77acf5281772df2a7f73.diff LOG: [clangd] Support textDocument/semanticTokens/edits Summary: This returns incremental highlights as a set of edits against the previous highlights. Server-side, we compute the full set of highlights, this just saves wire-format size. For now, the diff used is trivial: everything from the first change to the last change is sent as a single edit. The wire format is grungy - the replacement offset/length refer to positions in the encoded array instead of the logical list of tokens. We use token-oriented structs and translating to LSP forms when serializing. This departs from LSP (but is consistent with semanticTokens today). Tested in VSCode insiders (with a patched client to enable experimental features). Reviewers: hokein Subscribers: ilya-biryukov, MaskRay, jkorous, mgrang, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77225 Added: Modified: clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/ClangdLSPServer.h clang-tools-extra/clangd/Protocol.cpp clang-tools-extra/clangd/Protocol.h clang-tools-extra/clangd/SemanticHighlighting.cpp clang-tools-extra/clangd/SemanticHighlighting.h clang-tools-extra/clangd/test/initialize-params.test clang-tools-extra/clangd/test/semantic-tokens.test clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp index 8906e6f68f2f..19476d7fa052 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -586,7 +586,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, }}, {"semanticTokensProvider", llvm::json::Object{ - {"documentProvider", true}, + {"documentProvider", llvm::json::Object{{"edits", true}}}, {"rangeProvider", false}, {"legend", llvm::json::Object{{"tokenTypes", semanticTokenTypes()}, @@ -833,6 +833,10 @@ void ClangdLSPServer::onDocumentDidClose( std::lock_guard HLock(HighlightingsMutex); FileToHighlightings.erase(File); } + { + std::lock_guard HLock(SemanticTokensMutex); + LastSemanticTokens.erase(File); + } // clangd will not send updates for this file anymore, so we empty out the // list of diagnostics shown on the client (e.g. in the "Problems" pane of // VSCode). Note that this cannot race with actual diagnostics responses @@ -1243,16 +1247,71 @@ void ClangdLSPServer::onDocumentLink( }); } +// Increment a numeric string: "" -> 1 -> 2 -> ... -> 9 -> 10 -> 11 ... +static void increment(std::string &S) { + for (char &C : llvm::reverse(S)) { + if (C != '9') { + ++C; + return; + } + C = '0'; + } + S.insert(S.begin(), '1'); +} + void ClangdLSPServer::onSemanticTokens(const SemanticTokensParams &Params, Callback CB) { Server->semanticHighlights( Params.textDocument.uri.file(), - [CB(std::move(CB))]( - llvm::Expected> Toks) mutable { - if (!Toks) - return CB(Toks.takeError()); + [this, File(Params.textDocument.uri.file().str()), CB(std::move(CB))]( + llvm::Expected> HT) mutable { + if (!HT) + return CB(HT.takeError()); SemanticTokens Result; - Result.data = toSemanticTokens(*Toks); + Result.tokens = toSemanticTokens(*HT); + { + std::lock_guard Lock(SemanticTokensMutex); + auto& Last = LastSemanticTokens[File]; + + Last.tokens = Result.tokens; + increment(Last.resultId); + Result.resultId = Last.resultId; + } + CB(std::move(Result)); + }); +} + +void ClangdLSPServer::onSemanticTokensEdits( + const SemanticTokensEditsParams &Params, + Callback CB) { + Server->semanticHighlights( + Params.textDocument.uri.file(), + [this, PrevResultID(Params.previousResultId), + File(Params.textDocument.uri.file().str()), CB(std::move(CB))]( + llvm::Expected> HT) mutable { + if (!HT) + return CB(HT.takeError()); + std::vector Toks = toSemanticTokens(*HT); + + SemanticTokensOrEdits Result; + { + std::lock_guard Lock(SemanticTokensMutex); + auto& Last = LastSemanticTokens[File]; + + if (PrevResultID == Last.resultId) { + Result.edits = diff Tokens(Last.tokens, Toks); + } else { + vlog("semanticTokens/edits: wanted edits vs {0} but last result " + "had ID {1}. Returning full token list.", + PrevResultID, Last.resultId); + Result.tokens = Toks; + } + + Last.tokens = std::move(Toks); + increment(Last.resultId); + Result.resultId = Last.resultId; + } + CB(std::move(Result)); }); } @@ -1305,6 +1364,7 @@ ClangdLSPServer::ClangdLSPServer( MsgHandler->bind("textDocument/selectionRange", &ClangdLSPServer::onSelectionRange); MsgHandler->bind("textDocument/documentLink", &ClangdLSPServer::onDocumentLink); MsgHandler->bind("textDocument/semanticTokens", &ClangdLSPServer::onSemanticTokens); + MsgHandler->bind("textDocument/semanticTokens/edits", &ClangdLSPServer::onSemanticTokensEdits); // clang-format on } diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h index ff67bf772b7f..e259ad04a8e9 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.h @@ -120,6 +120,8 @@ class ClangdLSPServer : private ClangdServer::Callbacks { void onDocumentLink(const DocumentLinkParams &, Callback>); void onSemanticTokens(const SemanticTokensParams &, Callback); + void onSemanticTokensEdits(const SemanticTokensEditsParams &, + Callback); std::vector getFixes(StringRef File, const clangd::Diagnostic &D); @@ -162,6 +164,9 @@ class ClangdLSPServer : private ClangdServer::Callbacks { llvm::StringMap FixItsMap; std::mutex HighlightingsMutex; llvm::StringMap> FileToHighlightings; + // Last semantic-tokens response, for incremental requests. + std::mutex SemanticTokensMutex; + llvm::StringMap LastSemanticTokens; // Most code should not deal with Transport directly. // MessageHandler deals with incoming messages, use call() etc for outgoing. diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp index 019c6c038467..cd8e6bc10dce 100644 --- a/clang-tools-extra/clangd/Protocol.cpp +++ b/clang-tools-extra/clangd/Protocol.cpp @@ -986,21 +986,45 @@ llvm::json::Value toJSON(const FileStatus &FStatus) { }; } -void SemanticToken::encode(std::vector &Out) const { - Out.push_back(deltaLine); - Out.push_back(deltaStart); - Out.push_back(length); - Out.push_back(tokenType); - Out.push_back(tokenModifiers); +constexpr unsigned SemanticTokenEncodingSize = 5; +static llvm::json::Value encodeTokens(llvm::ArrayRef Toks) { + llvm::json::Array Result; + for (const auto &Tok : Toks) { + Result.push_back(Tok.deltaLine); + Result.push_back(Tok.deltaStart); + Result.push_back(Tok.length); + Result.push_back(Tok.tokenType); + Result.push_back(Tok.tokenModifiers); + } + assert(Result.size() == SemanticTokenEncodingSize * Toks.size()); + return Result; +} + +bool operator==(const SemanticToken &L, const SemanticToken &R) { + return std::tie(L.deltaLine, L.deltaStart, L.length, L.tokenType, + L.tokenModifiers) == std::tie(R.deltaLine, R.deltaStart, + R.length, R.tokenType, + R.tokenModifiers); } llvm::json::Value toJSON(const SemanticTokens &Tokens) { - std::vector Data; - for (const auto &Tok : Tokens.data) - Tok.encode(Data); - llvm::json::Object Result{{"data", std::move(Data)}}; - if (Tokens.resultId) - Result["resultId"] = *Tokens.resultId; + return llvm::json::Object{{"resultId", Tokens.resultId}, + {"data", encodeTokens(Tokens.tokens)}}; +} + +llvm::json::Value toJSON(const SemanticTokensEdit &Edit) { + return llvm::json::Object{ + {"start", SemanticTokenEncodingSize * Edit.startToken}, + {"deleteCount", SemanticTokenEncodingSize * Edit.deleteTokens}, + {"data", encodeTokens(Edit.tokens)}}; +} + +llvm::json::Value toJSON(const SemanticTokensOrEdits &TE) { + llvm::json::Object Result{{"resultId", TE.resultId}}; + if (TE.edits) + Result["edits"] = *TE.edits; + if (TE.tokens) + Result["data"] = encodeTokens(*TE.tokens); return Result; } @@ -1009,6 +1033,12 @@ bool fromJSON(const llvm::json::Value &Params, SemanticTokensParams &R) { return O && O.map("textDocument", R.textDocument); } +bool fromJSON(const llvm::json::Value &Params, SemanticTokensEditsParams &R) { + llvm::json::ObjectMapper O(Params); + return O && O.map("textDocument", R.textDocument) && + O.map("previousResultId", R.previousResultId); +} + llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const DocumentHighlight &V) { O << V.range; diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h index a713d47862b1..968b039c62cc 100644 --- a/clang-tools-extra/clangd/Protocol.h +++ b/clang-tools-extra/clangd/Protocol.h @@ -1362,9 +1362,8 @@ struct SemanticToken { unsigned tokenType = 0; /// each set bit will be looked up in `SemanticTokensLegend.tokenModifiers` unsigned tokenModifiers = 0; - - void encode(std::vector &Out) const; }; +bool operator==(const SemanticToken &, const SemanticToken &); /// A versioned set of tokens. struct SemanticTokens { @@ -1372,12 +1371,12 @@ struct SemanticTokens { // the client will include the result id in the next semantic token request. // A server can then instead of computing all semantic tokens again simply // send a delta. - llvm::Optional resultId; + std::string resultId; /// The actual tokens. For a detailed description about how the data is /// structured pls see /// https://github.com/microsoft/vscode-extension-samples/blob/5ae1f7787122812dcc84e37427ca90af5ee09f14/semantic-tokens-sample/vscode.proposed.d.ts#L71 - std::vector data; + std::vector tokens; }; llvm::json::Value toJSON(const SemanticTokens &); @@ -1387,6 +1386,37 @@ struct SemanticTokensParams { }; bool fromJSON(const llvm::json::Value &, SemanticTokensParams &); +/// Requests the changes in semantic tokens since a previous response. +struct SemanticTokensEditsParams { + /// The text document. + TextDocumentIdentifier textDocument; + /// The previous result id. + std::string previousResultId; +}; +bool fromJSON(const llvm::json::Value &Params, SemanticTokensEditsParams &R); + +/// Describes a a replacement of a contiguous range of semanticTokens. +struct SemanticTokensEdit { + // LSP specifies `start` and `deleteCount` which are relative to the array + // encoding of the previous tokens. + // We use token counts instead, and translate when serializing this struct. + unsigned startToken = 0; + unsigned deleteTokens = 0; + std::vector tokens; +}; +llvm::json::Value toJSON(const SemanticTokensEdit &); + +/// This models LSP SemanticTokensEdits | SemanticTokens, which is the result of +/// textDocument/semanticTokens/edits. +struct SemanticTokensOrEdits { + std::string resultId; + /// Set if we computed edits relative to a previous set of tokens. + llvm::Optional> edits; + /// Set if we computed a fresh set of tokens. + llvm::Optional> tokens; +}; +llvm::json::Value toJSON(const SemanticTokensOrEdits &); + /// Represents a semantic highlighting information that has to be applied on a /// specific line of the text document. struct TheiaSemanticHighlightingInformation { diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp index 59af922d4005..35eabfe00dd2 100644 --- a/clang-tools-extra/clangd/SemanticHighlighting.cpp +++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp @@ -600,5 +600,31 @@ llvm::StringRef toTextMateScope(HighlightingKind Kind) { llvm_unreachable("unhandled HighlightingKind"); } +std::vector + diff Tokens(llvm::ArrayRef Old, + llvm::ArrayRef New) { + // For now, just replace everything from the first-last modification. + // FIXME: use a real diff instead, this is bad with include-insertion. + + unsigned Offset = 0; + while (!Old.empty() && !New.empty() && Old.front() == New.front()) { + ++Offset; + Old = Old.drop_front(); + New = New.drop_front(); + } + while (!Old.empty() && !New.empty() && Old.back() == New.back()) { + Old = Old.drop_back(); + New = New.drop_back(); + } + + if (Old.empty() && New.empty()) + return {}; + SemanticTokensEdit Edit; + Edit.startToken = Offset; + Edit.deleteTokens = Old.size(); + Edit.tokens = New; + return {std::move(Edit)}; +} + } // namespace clangd } // namespace clang diff --git a/clang-tools-extra/clangd/SemanticHighlighting.h b/clang-tools-extra/clangd/SemanticHighlighting.h index d3b9ddc23a47..9a96cc28c4f5 100644 --- a/clang-tools-extra/clangd/SemanticHighlighting.h +++ b/clang-tools-extra/clangd/SemanticHighlighting.h @@ -90,6 +90,8 @@ std::vector getSemanticHighlightings(ParsedAST &AST); std::vector toSemanticTokens(llvm::ArrayRef); llvm::StringRef toSemanticTokenType(HighlightingKind Kind); +std::vector diff Tokens(llvm::ArrayRef Before, + llvm::ArrayRef After); /// Converts a HighlightingKind to a corresponding TextMate scope /// (https://manual.macromates.com/en/language_grammars). diff --git a/clang-tools-extra/clangd/test/initialize-params.test b/clang-tools-extra/clangd/test/initialize-params.test index 9eef5fa68dc9..6c4b847a07ef 100644 --- a/clang-tools-extra/clangd/test/initialize-params.test +++ b/clang-tools-extra/clangd/test/initialize-params.test @@ -39,7 +39,9 @@ # CHECK-NEXT: "renameProvider": true, # CHECK-NEXT: "selectionRangeProvider": true, # CHECK-NEXT: "semanticTokensProvider": { -# CHECK-NEXT: "documentProvider": true, +# CHECK-NEXT: "documentProvider": { +# CHECK-NEXT: "edits": true +# CHECK-NEXT: }, # CHECK-NEXT: "legend": { # CHECK-NEXT: "tokenModifiers": [], # CHECK-NEXT: "tokenTypes": [ diff --git a/clang-tools-extra/clangd/test/semantic-tokens.test b/clang-tools-extra/clangd/test/semantic-tokens.test index 679766995d52..6fab10362b28 100644 --- a/clang-tools-extra/clangd/test/semantic-tokens.test +++ b/clang-tools-extra/clangd/test/semantic-tokens.test @@ -6,8 +6,13 @@ "semanticTokens":{"dynamicRegistration":true} }}}} --- -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///foo.cpp","languageId":"cpp","text":"int x = 2;"}}} +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{ + "uri": "test:///foo.cpp", + "languageId": "cpp", + "text": "int x = 2;" +}}} --- +# Non-incremental token request. {"jsonrpc":"2.0","id":1,"method":"textDocument/semanticTokens","params":{"textDocument":{"uri":"test:///foo.cpp"}}} # CHECK: "id": 1, # CHECK-NEXT: "jsonrpc": "2.0", @@ -19,9 +24,64 @@ # CHECK-NEXT: 1, # CHECK-NEXT: 0, # CHECK-NEXT: 0 -# CHECK-NEXT: ] +# CHECK-NEXT: ], +# CHECK-NEXT: "resultId": "1" # CHECK-NEXT: } --- -{"jsonrpc":"2.0","id":2,"method":"shutdown"} +{"jsonrpc":"2.0","method":"textDocument/didChange","params":{ + "textDocument": {"uri":"test:///foo.cpp","version":2}, + "contentChanges":[{"text":"int x = 2;\nint y = 3;"}] +}} +--- +# Incremental token request, based on previous response. +{"jsonrpc":"2.0","id":2,"method":"textDocument/semanticTokens/edits","params":{ + "textDocument": {"uri":"test:///foo.cpp"}, + "previousResultId": "1" +}} +# CHECK: "id": 2, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": { +# CHECK-NEXT: "edits": [ +# CHECK-NEXT: { +# CHECK-NEXT: "data": [ +# Next line, char 5, variable, no modifiers +# CHECK-NEXT: 1, +# CHECK-NEXT: 4, +# CHECK-NEXT: 1, +# CHECK-NEXT: 0, +# CHECK-NEXT: 0 +# CHECK-NEXT: ], +# Inserted at position 1 +# CHECK-NEXT: "deleteCount": 0, +# CHECK-NEXT: "start": 5 +# CHECK-NEXT: } +# CHECK-NEXT: ], +# CHECK-NEXT: "resultId": "2" +# CHECK-NEXT: } +--- +# Incremental token request with incorrect baseline => full tokens list. +{"jsonrpc":"2.0","id":2,"method":"textDocument/semanticTokens/edits","params":{ + "textDocument": {"uri":"test:///foo.cpp"}, + "previousResultId": "bogus" +}} +# CHECK: "id": 2, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": { +# CHECK-NEXT: "data": [ +# CHECK-NEXT: 0, +# CHECK-NEXT: 4, +# CHECK-NEXT: 1, +# CHECK-NEXT: 0, +# CHECK-NEXT: 0, +# CHECK-NEXT: 1, +# CHECK-NEXT: 4, +# CHECK-NEXT: 1, +# CHECK-NEXT: 0, +# CHECK-NEXT: 0 +# CHECK-NEXT: ], +# CHECK-NEXT: "resultId": "3" +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","id":3,"method":"shutdown"} --- {"jsonrpc":"2.0","method":"exit"} diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp index 6c4a4590ab2a..1cca429a4ea6 100644 --- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -14,8 +14,10 @@ #include "TestFS.h" #include "TestTU.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" +#include "llvm/Support/ScopedPrinter.h" #include "gmock/gmock.h" #include @@ -23,6 +25,9 @@ namespace clang { namespace clangd { namespace { +using testing::IsEmpty; +using testing::SizeIs; + MATCHER_P(LineNumber, L, "") { return arg.Line == L; } MATCHER(EmptyHighlightings, "") { return arg.Tokens.empty(); } @@ -720,25 +725,29 @@ TEST(SemanticHighlighting, GeneratesHighlightsWhenFileChange) { ASSERT_EQ(Counter.Count, 1); } +// Ranges are highlighted as variables, unless highlighted as $Function etc. +std::vector tokens(llvm::StringRef MarkedText) { + Annotations A(MarkedText); + std::vector Results; + for (const Range& R : A.ranges()) + Results.push_back({HighlightingKind::Variable, R}); + for (unsigned I = 0; I < static_cast(HighlightingKind::LastKind); ++I) { + HighlightingKind Kind = static_cast(I); + for (const Range& R : A.ranges(llvm::to_string(Kind))) + Results.push_back({Kind, R}); + } + llvm::sort(Results); + return Results; +} + TEST(SemanticHighlighting, toSemanticTokens) { - auto CreatePosition = [](int Line, int Character) -> Position { - Position Pos; - Pos.line = Line; - Pos.character = Character; - return Pos; - }; + auto Results = toSemanticTokens(tokens(R"( + [[blah]] - std::vector Tokens = { - {HighlightingKind::Variable, - Range{CreatePosition(1, 1), CreatePosition(1, 5)}}, - {HighlightingKind::Function, - Range{CreatePosition(3, 4), CreatePosition(3, 7)}}, - {HighlightingKind::Variable, - Range{CreatePosition(3, 8), CreatePosition(3, 12)}}, - }; + $Function[[big]] [[bang]] + )")); - std::vector Results = toSemanticTokens(Tokens); - EXPECT_EQ(Tokens.size(), Results.size()); + ASSERT_THAT(Results, SizeIs(3)); EXPECT_EQ(Results[0].tokenType, unsigned(HighlightingKind::Variable)); EXPECT_EQ(Results[0].deltaLine, 1u); EXPECT_EQ(Results[0].deltaStart, 1u); @@ -755,6 +764,38 @@ TEST(SemanticHighlighting, toSemanticTokens) { EXPECT_EQ(Results[2].length, 4u); } +TEST(SemanticHighlighting, diff SemanticTokens) { + auto Before = toSemanticTokens(tokens(R"( + [[foo]] [[bar]] [[baz]] + [[one]] [[two]] [[three]] + )")); + EXPECT_THAT( diff Tokens(Before, Before), IsEmpty()); + + auto After = toSemanticTokens(tokens(R"( + [[foo]] [[hello]] [[world]] [[baz]] + [[one]] [[two]] [[three]] + )")); + + // Replace [bar, baz] with [hello, world, baz] + auto Diff = diff Tokens(Before, After); + ASSERT_THAT(Diff, SizeIs(1)); + EXPECT_EQ(1u, Diff.front().startToken); + EXPECT_EQ(2u, Diff.front().deleteTokens); + ASSERT_THAT(Diff.front().tokens, SizeIs(3)); + // hello + EXPECT_EQ(0u, Diff.front().tokens[0].deltaLine); + EXPECT_EQ(4u, Diff.front().tokens[0].deltaStart); + EXPECT_EQ(5u, Diff.front().tokens[0].length); + // world + EXPECT_EQ(0u, Diff.front().tokens[1].deltaLine); + EXPECT_EQ(6u, Diff.front().tokens[1].deltaStart); + EXPECT_EQ(5u, Diff.front().tokens[1].length); + // baz + EXPECT_EQ(0u, Diff.front().tokens[2].deltaLine); + EXPECT_EQ(6u, Diff.front().tokens[2].deltaStart); + EXPECT_EQ(3u, Diff.front().tokens[2].length); +} + TEST(SemanticHighlighting, toTheiaSemanticHighlightingInformation) { auto CreatePosition = [](int Line, int Character) -> Position { Position Pos; From cfe-commits at lists.llvm.org Thu Apr 2 08:40:27 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 15:40:27 +0000 (UTC) Subject: [PATCH] D77225: [clangd] Support textDocument/semanticTokens/edits In-Reply-To: References: Message-ID: <7a5bbd0341202e80b5ca96afcf7aa757@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG9e3063eaceec: [clangd] Support textDocument/semanticTokens/edits (authored by sammccall). Changed prior to commit: https://reviews.llvm.org/D77225?vs=254226&id=254536#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77225/new/ https://reviews.llvm.org/D77225 Files: clang-tools-extra/clangd/ClangdLSPServer.cpp clang-tools-extra/clangd/ClangdLSPServer.h clang-tools-extra/clangd/Protocol.cpp clang-tools-extra/clangd/Protocol.h clang-tools-extra/clangd/SemanticHighlighting.cpp clang-tools-extra/clangd/SemanticHighlighting.h clang-tools-extra/clangd/test/initialize-params.test clang-tools-extra/clangd/test/semantic-tokens.test clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77225.254536.patch Type: text/x-patch Size: 19584 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 09:12:17 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 16:12:17 +0000 (UTC) Subject: [PATCH] D77240: [CUDA] Add missing cmath overloads In-Reply-To: References: Message-ID: <27a204bb7e62c303243db604254bbd1b@localhost.localdomain> jdoerfert added a comment. I just noticed those as well. I forgot to put the new definitions into the forward declare header. Will do it in a second. The OpenMP math overlay doesn't have one so I forgot :( Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77240/new/ https://reviews.llvm.org/D77240 From cfe-commits at lists.llvm.org Thu Apr 2 09:12:19 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 16:12:19 +0000 (UTC) Subject: [PATCH] D77028: [NFC] Refactor DeferredDiagsEmitter and skip redundant visit In-Reply-To: References: Message-ID: yaxunl updated this revision to Diff 254537. yaxunl marked 2 inline comments as done. yaxunl added a comment. Herald added a reviewer: jdoerfert. added comments CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77028/new/ https://reviews.llvm.org/D77028 Files: clang/include/clang/Sema/Sema.h clang/lib/Sema/Sema.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77028.254537.patch Type: text/x-patch Size: 8140 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 09:12:20 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 16:12:20 +0000 (UTC) Subject: [PATCH] D77028: [NFC] Refactor DeferredDiagsEmitter and skip redundant visit In-Reply-To: References: Message-ID: <183b3c03f86a32dcab5a93dbcfb8d17c@localhost.localdomain> yaxunl added inline comments. ================ Comment at: clang/lib/Sema/Sema.cpp:1508 void checkFunc(SourceLocation Loc, FunctionDecl *FD) { + auto DiagsCountIt = DiagsCount.find(FD); FunctionDecl *Caller = UseStack.empty() ? nullptr : UseStack.back(); ---------------- rjmccall wrote: > It makes me a little uncomfortable to be holding an iterator this long while calling a fair amount of other stuff in the meantime. > > Your use of DiagsCount is subtle enough that it really needs to be explained in some comments. You're doing stuff conditionally based on both whether the entry exists but also whether it's non-zero. added comments CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77028/new/ https://reviews.llvm.org/D77028 From cfe-commits at lists.llvm.org Thu Apr 2 09:12:20 2020 From: cfe-commits at lists.llvm.org (Sjoerd Meijer via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 16:12:20 +0000 (UTC) Subject: [PATCH] D76679: [SveEmitter] Add more immediate operand checks. In-Reply-To: References: Message-ID: SjoerdMeijer accepted this revision. SjoerdMeijer added a comment. This revision is now accepted and ready to land. I think the float16 discussion is an interesting one, but doesn't necessarily need to be done here. I am asking some questions offline, but if we ever come to a different opinion on it, then we can follow up so it's somewhat orthogonal to this change, and so this looks fine to me. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76679/new/ https://reviews.llvm.org/D76679 From cfe-commits at lists.llvm.org Thu Apr 2 09:12:23 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 16:12:23 +0000 (UTC) Subject: [PATCH] D76384: Move FPFeatures from BinaryOperator bitfields to Trailing storage In-Reply-To: References: Message-ID: rjmccall added inline comments. ================ Comment at: clang/include/clang/Basic/LangOptions.h:394 + return true; + } + ---------------- sepavloff wrote: > erichkeane wrote: > > rjmccall wrote: > > > erichkeane wrote: > > > > rjmccall wrote: > > > > > rjmccall wrote: > > > > > > erichkeane wrote: > > > > > > > rjmccall wrote: > > > > > > > > The problem with having both functions that take `ASTContext`s and functions that don't is that it's easy to mix them, so they either need to have the same behavior (in which case it's pointless to have an overload that takes the `ASTContext`) or you're making something really error-prone. > > > > > > > > > > > > > > > > I would feel a lot more confident that you were designing and using these APIs correctly if you actually took advantage of the ability to not store trailing FPOptions in some case, like when they match the global settings in the ASTContext. That way you'll actually be verifying that everything behaves correctly if nodes don't store FPOptions. If you do that, I think you'll see my point about not having all these easily-confusable functions that do or do not take `ASTContext`s.. > > > > > > > I think I disagree with @rjmccall that these requiresTrailingStorage should be here at all. I think we should store in the AST ANY programmer opinion, even if they match the global setting. It seems to me that this would be more tolerant of any global-setting rewrites that modules/et-al introduce, as well as make the AST Print consistent. Always storing FPOptions when the user has explicitly overriding it also better captures the programmer's intent. > > > > > > I covered this elsewhere in the review. If you want to have that tolerance — and I think you should — then expressions should store (and Sema should track) the active pragma state, which can be most easily expressed as a pair of an FPOptions and a mask to apply to the global FPOptions. When you enter a pragma, you clear the relevant bits from the global FPOptions mask. > > > > > > > > > > > > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. > > > > > > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. > > > > > > > > > > I meant to say: for a million nodes that don't care in the slightest about FPOptions, as well as for a million more nodes that aren't using pragma overrides. > > > > Right, I get the intent, and I completely agree with that. My point was EVERY Expr that is affected by a #pragma should store it. Though, after looking at your Macro concern above, I'm less compelled. > > > > > > > > I guess was suggesting that the logic for "requiresTrailingStorage" should just be "modified by a pragma" instead of "FPOptions != The global setting". > > > Well, "modified by a pragma" still wouldn't make the AST agnostic to global settings, since the pragmas don't override everything in FPOptions at once. But I agree that would achieve the most important goal, which is to stop inflating the AST when pragmas *aren't* in effect, which is approximately 100% of the time. In order to do that, though, we'll need to start tracking pragmas, which we should do but which can wait for a follow-up patch. In the meantime, I don't think you're ever going to get the interfaces right for queries like `BinaryOperator::getFPOptions` unless you actually stop relying on the fact that you're unconditionally storing `FPOptions`. You need to passing around ASTContexts for that. That's why I'm suggesting using an exact match with the global settings as a simple thing you can easily check without modifying what data you collect in `FPOptions`. > > That sounds like a good plan to me. Thanks for entertaining my conversation/questions. > > we'll need to start tracking pragmas > > This is made in D76599 by representing floating point pragmas with a special statement node. These nodes allow an AST consumer like CodeGen or constant evaluator to maintain current set of floating options when it traverses AST. This approach looks simpler and more consistent as global state is represented as a variable in AST consumer and is not replicated to every relevant node. It makes easier to implement codegen for things like rounding mode, when change of the FP state requires specific instructions. A pragma statement can be used to generate required code. But if the state is spread by several nodes, it is more difficult for codegen to create necessary prolog/epilog code. Now compiler does not have support of properties that need synchronization with hardware, so these problems are not topical yet, but they eventually will arise. Constant evaluation does not normally traverse the AST in the way you mean. It does this when evaluating a constexpr function, but that's not the dominant case of constant evaluation. At the LLVM level, I think inlining, reordering, and ABI requirements on calls argue against a simple implementation model based on setting hardware flags when a pragma is entered and resetting them on exit. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76384/new/ https://reviews.llvm.org/D76384 From cfe-commits at lists.llvm.org Thu Apr 2 09:12:23 2020 From: cfe-commits at lists.llvm.org (Philip Reames via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 16:12:23 +0000 (UTC) Subject: [PATCH] D76140: [InlineFunction] update attributes during inlining In-Reply-To: References: Message-ID: reames accepted this revision. reames added a comment. This revision is now accepted and ready to land. LGTM again, with minor change. p.s. Sorry for missing the functional issue the first time. All of the test changes should have made the issue obvious, but despite reading the LangRef description of signext, I somehow managed to miss the separation between ABI and optimization attributes. ================ Comment at: llvm/lib/Transforms/Utils/InlineFunction.cpp:1177 + Valid.addDereferenceableOrNullAttr(DerefOrNullBytes); + auto AddAttrWithoutValues = + [&](SmallVectorImpl &Kinds) -> void { ---------------- I'm not sure that pulling out the helper for two cases actually helps readability. Can you drop this and just do the two cases directly please? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76140/new/ https://reviews.llvm.org/D76140 From cfe-commits at lists.llvm.org Thu Apr 2 09:12:27 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?D=C3=A1vid_Bolvansk=C3=BD_via_Phabricator?= via cfe-commits) Date: Thu, 02 Apr 2020 16:12:27 +0000 (UTC) Subject: [PATCH] D66324: clang-misexpect: Profile Guided Validation of Performance Annotations in LLVM In-Reply-To: References: Message-ID: <78b7624461bce7afc07f1218bb829441@localhost.localdomain> xbolva00 added a comment. Fix is easy, can you commit it as obvious? Repository: rL LLVM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D66324/new/ https://reviews.llvm.org/D66324 From cfe-commits at lists.llvm.org Thu Apr 2 09:12:28 2020 From: cfe-commits at lists.llvm.org (Brian Sumner via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 16:12:28 +0000 (UTC) Subject: [PATCH] D75917: Expose llvm fence instruction as clang intrinsic In-Reply-To: References: Message-ID: <2b6138bc364028d68b84b2627d704608@localhost.localdomain> b-sumner added a comment. Please go ahead and update to a string for the scope. Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75917/new/ https://reviews.llvm.org/D75917 From cfe-commits at lists.llvm.org Thu Apr 2 09:12:29 2020 From: cfe-commits at lists.llvm.org (Dmitry Polukhin via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 16:12:29 +0000 (UTC) Subject: [PATCH] D75184: [clang-tidy] Optional inheritance of file configs from parent =?UTF-8?Q?directories=C2=A0?= In-Reply-To: References: Message-ID: DmitryPolukhin added a comment. @alexfh friendly ping I implemented solution with priorities to resolve your concerns about `get()` vs `getLocalOrGlobal()` Could you please take another look to this diff? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75184/new/ https://reviews.llvm.org/D75184 From cfe-commits at lists.llvm.org Thu Apr 2 09:12:30 2020 From: cfe-commits at lists.llvm.org (Ye Luo via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 16:12:30 +0000 (UTC) Subject: [PATCH] D75788: [OpenMP] Provide math functions in OpenMP device code via OpenMP variants In-Reply-To: References: Message-ID: ye-luo accepted this revision. ye-luo added a comment. This revision is now accepted and ready to land. Good work. I verified that PR42798 and PR42799 are fixed by this. Tests are completed on Ubuntu 18.04. Clang now becomes usable for application developers. There are still issues on RHEL that openmp_wrappers is not added before the system math searching path. Option -isystem openmp_wrappers can be used as a workaround. This remaining issue should not be a blocker of accepting this patch. It can be dealt separately later without complicating the review of the current patch. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75788/new/ https://reviews.llvm.org/D75788 From cfe-commits at lists.llvm.org Thu Apr 2 09:44:20 2020 From: cfe-commits at lists.llvm.org (Dmitry Polukhin via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 16:44:20 +0000 (UTC) Subject: [PATCH] D76594: [clang][AST] Support AST files larger than 512M In-Reply-To: References: Message-ID: DmitryPolukhin added a comment. @rsmith, @dexonsmith, @jdoerfert could you please take a look to this diff? If you think that there are other reviewers who might have more context AST persistence, please add them. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76594/new/ https://reviews.llvm.org/D76594 From cfe-commits at lists.llvm.org Thu Apr 2 09:44:21 2020 From: cfe-commits at lists.llvm.org (Artem Belevich via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 16:44:21 +0000 (UTC) Subject: [PATCH] D77240: [CUDA] Add missing cmath overloads In-Reply-To: References: Message-ID: tra added a comment. In D77240#1957386 , @jdoerfert wrote: > I just noticed those as well. I forgot to put the new definitions into the forward declare header. Will do it in a second. The OpenMP math overlay doesn't have one so I forgot :( I'm not sure how it's going to help. The problem is that the functions are already defined by CUDA headers. Moving the duplicate definition to a different header does not change that. Bottom line is that the already-existing definitions are not needed for CUDA. If OpenMP needs them, then they should probably go into an OpenMP-specific header. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77240/new/ https://reviews.llvm.org/D77240 From cfe-commits at lists.llvm.org Thu Apr 2 09:44:24 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 16:44:24 +0000 (UTC) Subject: [PATCH] D77028: [NFC] Refactor DeferredDiagsEmitter and skip redundant visit In-Reply-To: References: Message-ID: rjmccall added inline comments. ================ Comment at: clang/lib/Sema/Sema.cpp:1508 void checkFunc(SourceLocation Loc, FunctionDecl *FD) { + auto DiagsCountIt = DiagsCount.find(FD); FunctionDecl *Caller = UseStack.empty() ? nullptr : UseStack.back(); ---------------- yaxunl wrote: > rjmccall wrote: > > It makes me a little uncomfortable to be holding an iterator this long while calling a fair amount of other stuff in the meantime. > > > > Your use of DiagsCount is subtle enough that it really needs to be explained in some comments. You're doing stuff conditionally based on both whether the entry exists but also whether it's non-zero. > added comments Okay, thanks for that. Two points, then. First, it looks like the count is really just a boolean for whether the function recursively triggers any diagnostics. And second, can't it just be as simple as whether we've visited that function at all in a context that's forcing diagnostics to be emitted? The logic seems to be to try to emit the diagnostics for each use-path, but why would we want that? ================ Comment at: clang/lib/Sema/Sema.cpp:1553 if (!Caller) ShouldEmit = IsKnownEmitted; if ((!ShouldEmit && !S.getLangOpts().OpenMP && !Caller) || ---------------- This becomes global state for the visitor; that doesn't seem like it can be right. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77028/new/ https://reviews.llvm.org/D77028 From cfe-commits at lists.llvm.org Thu Apr 2 09:44:25 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 16:44:25 +0000 (UTC) Subject: [PATCH] D77240: [CUDA] Add missing cmath overloads In-Reply-To: References: Message-ID: <32afb3fa2e19c7dc35e101014bb39deb@localhost.localdomain> jdoerfert abandoned this revision. jdoerfert added a comment. In D77240#1957468 , @tra wrote: > In D77240#1957386 , @jdoerfert wrote: > > > I just noticed those as well. I forgot to put the new definitions into the forward declare header. Will do it in a second. The OpenMP math overlay doesn't have one so I forgot :( > > > I'm not sure how it's going to help. The problem is that the functions are already defined by CUDA headers. Moving the duplicate definition to a different header does not change that. > Bottom line is that the already-existing definitions are not needed for CUDA. If OpenMP needs them, then they should probably go into an OpenMP-specific header. I see. In my CUDA headers `float acos(float)` is conditionally defined as well but as a `__cudart_builtin__`. So it seems we can redefine those but not the `float acosh(float)` which is a `__MATH_FUNCTIONS_DECL__` for some configurations. I'll move the new functions into an OpenMP only header. I thought they might be needed here too but that was wrong. Thanks for spending the time on this! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77240/new/ https://reviews.llvm.org/D77240 From cfe-commits at lists.llvm.org Thu Apr 2 09:44:30 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 16:44:30 +0000 (UTC) Subject: [PATCH] D77112: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` In-Reply-To: References: Message-ID: <8c59d07879f6e6185403fe2bb0d783e0@localhost.localdomain> jdoerfert updated this revision to Diff 254550. jdoerfert added a comment. Update with clang-tidy and documentation adjustments Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77112/new/ https://reviews.llvm.org/D77112 Files: clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cpp clang/include/clang/AST/ASTFwd.h clang/include/clang/AST/ASTTypeTraits.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/Basic/Attr.td clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Basic/OpenMPKinds.h clang/lib/AST/ASTTypeTraits.cpp clang/lib/AST/AttrImpl.cpp clang/lib/AST/OpenMPClause.cpp clang/lib/AST/StmtProfile.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/ASTMatchers/CMakeLists.txt clang/lib/ASTMatchers/Dynamic/Marshallers.h clang/lib/Analysis/CMakeLists.txt clang/lib/Basic/OpenMPKinds.cpp clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt clang/lib/StaticAnalyzer/Core/CMakeLists.txt clang/tools/libclang/CIndex.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp llvm/include/llvm/Frontend/OpenMP/OMPConstants.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPConstants.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77112.254550.patch Type: text/x-patch Size: 120426 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 10:17:36 2020 From: cfe-commits at lists.llvm.org (Anna Thomas via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 17:17:36 +0000 (UTC) Subject: [PATCH] D76140: [InlineFunction] update attributes during inlining In-Reply-To: References: Message-ID: anna added a comment. In D76140#1957416 , @reames wrote: > LGTM again, with minor change. will update it. > p.s. Sorry for missing the functional issue the first time. All of the test changes should have made the issue obvious, but despite reading the LangRef description of signext, I somehow managed to miss the separation between ABI and optimization attributes. thanks for the review Philip and pointing out the problem. All of us had missed the functional issue the first time around. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76140/new/ https://reviews.llvm.org/D76140 From cfe-commits at lists.llvm.org Thu Apr 2 10:17:38 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 17:17:38 +0000 (UTC) Subject: [PATCH] D77085: [clang-tidy] Added support for validating configuration options In-Reply-To: References: Message-ID: njames93 updated this revision to Diff 254552. njames93 added a comment. - Small refactor Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77085/new/ https://reviews.llvm.org/D77085 Files: clang-tools-extra/clang-tidy/ClangTidyCheck.cpp clang-tools-extra/clang-tidy/ClangTidyCheck.h clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77085.254552.patch Type: text/x-patch Size: 26583 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 10:17:41 2020 From: cfe-commits at lists.llvm.org (Krasimir Georgiev via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 17:17:41 +0000 (UTC) Subject: [PATCH] D77311: clang-format: [JS] detect C++ keywords. In-Reply-To: References: Message-ID: <7dc274b26ec8520c16e4c72ad50bade7@localhost.localdomain> krasimir added a comment. In D77311#1957367 , @jfb wrote: > Some of these are technically "future reserved keywords": https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords > > Wouldn't it be better to list all of JS's keywords at this point? +1 to consider listing all of JS's keywords instead of listing all C++ keywords that are not JS keywords. With the current approach, any time a new C++ keyword token gets introduced, the switch in `IsJavaScriptIdentifier` would have to be updated. But turning the implementation into something that lists JS keywords seems a bit tricky. Just a suggestion: maybe we can use the trick to #include TokenKinds.def used in TokenKinds.h : bool IsJavaScriptIdentifier(const FormatToken &Tok) const { switch (Tok.Tok.getKind()) { // list all JS keywords defined as KEYWORD in TokenKinds.def case tok::kw_break: case tok::kw_case: ... case tok::kw_return: return false; // All of the remaining C keywords are JS identifiers. #define KEYWORD(X,Y) case tok::kw_ ## X: #include "clang/Basic/TokenKinds.def" // #undef KEYWORD is not needed -- it's #undef-ed at the end of TokenKinds.def return true; // handle identifiers and everything else as in the patch. case tok::identifier: default: return false; } Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77311/new/ https://reviews.llvm.org/D77311 From cfe-commits at lists.llvm.org Thu Apr 2 10:50:07 2020 From: cfe-commits at lists.llvm.org (Kerry McLaughlin via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 17:50:07 +0000 (UTC) Subject: [PATCH] D77054: [AArch64][SVE] Add SVE intrinsics for saturating add & subtract In-Reply-To: References: Message-ID: <2b11909fe9a6a3eb44fbeae292eddafd@localhost.localdomain> kmclaughlin updated this revision to Diff 254558. kmclaughlin added a comment. Added patterns to AArch64SVEInstrInfo.td to support llvm.[s|u]add & llvm.[s|u]sub again, which was removed by my previous patch CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77054/new/ https://reviews.llvm.org/D77054 Files: llvm/include/llvm/IR/IntrinsicsAArch64.td llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td llvm/test/CodeGen/AArch64/sve-intrinsics-int-arith-imm.ll llvm/test/CodeGen/AArch64/sve-intrinsics-int-arith.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D77054.254558.patch Type: text/x-patch Size: 32935 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 10:50:09 2020 From: cfe-commits at lists.llvm.org (Brian Gesiak via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 17:50:09 +0000 (UTC) Subject: [PATCH] D70555: [coroutines] Don't build promise init with no args In-Reply-To: References: Message-ID: <570b5a9282056d175665566013d1fb15@localhost.localdomain> modocache added a comment. Of course, your approval is very welcome! 😄 I'll go ahead and land this today, thanks for the review! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70555/new/ https://reviews.llvm.org/D70555 From cfe-commits at lists.llvm.org Thu Apr 2 10:50:11 2020 From: cfe-commits at lists.llvm.org (Ye Luo via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 17:50:11 +0000 (UTC) Subject: [PATCH] D75788: [OpenMP] Provide math functions in OpenMP device code via OpenMP variants In-Reply-To: References: Message-ID: <98c2135a0aed3833b3c694fd36b459eb@localhost.localdomain> ye-luo added a comment. My RHEL issue was caused by a CPLUS_INCLUDE_PATH environment variable. So this is feature not a bug. After removing it, everything works smoothly for me. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75788/new/ https://reviews.llvm.org/D75788 From cfe-commits at lists.llvm.org Thu Apr 2 10:52:46 2020 From: cfe-commits at lists.llvm.org (Sterling Augustine via cfe-commits) Date: Thu, 02 Apr 2020 10:52:46 -0700 (PDT) Subject: [libunwind] 71fbd6e - Exit unwinding early when at the top of the stack and additional info won't be found. Message-ID: <5e86266e.1c69fb81.bd4d8.38e2@mx.google.com> Author: Sterling Augustine Date: 2020-04-02T10:52:25-07:00 New Revision: 71fbd6e40632f437049215904c28ad9d63cff4bc URL: https://github.com/llvm/llvm-project/commit/71fbd6e40632f437049215904c28ad9d63cff4bc DIFF: https://github.com/llvm/llvm-project/commit/71fbd6e40632f437049215904c28ad9d63cff4bc.diff LOG: Exit unwinding early when at the top of the stack and additional info won't be found. Summary: This patch follows libgcc's lead: When the return-address register is zero, there won't be additional stack frames to examine, or gather information about. Exit before spending time looking for something known not to be found. Subscribers: llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D77099 Added: Modified: libunwind/src/UnwindCursor.hpp Removed: ################################################################################ diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp index e7fb70cc5718..32d71c2c1ed3 100644 --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -1848,6 +1848,12 @@ void UnwindCursor::setInfoBasedOnIPRegister(bool isReturnAddress) { pc &= (pint_t)~0x1; #endif + // Exit early if at the top of the stack. + if (pc == 0) { + _unwindInfoMissing = true; + return; + } + // If the last line of a function is a "throw" the compiler sometimes // emits no instructions after the call to __cxa_throw. This means // the return address is actually the start of the next function. From cfe-commits at lists.llvm.org Thu Apr 2 10:53:23 2020 From: cfe-commits at lists.llvm.org (Nico Weber via cfe-commits) Date: Thu, 02 Apr 2020 10:53:23 -0700 (PDT) Subject: [clang] fb80b6b - Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang Message-ID: <5e862693.1c69fb81.cfcda.314e@mx.google.com> Author: Nico Weber Date: 2020-04-02T13:53:16-04:00 New Revision: fb80b6b2d58c476747a3206bd4371b787108591b URL: https://github.com/llvm/llvm-project/commit/fb80b6b2d58c476747a3206bd4371b787108591b DIFF: https://github.com/llvm/llvm-project/commit/fb80b6b2d58c476747a3206bd4371b787108591b.diff LOG: Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang Currently, all generated lit.site.cfg files contain absolute paths. This makes it impossible to build on one machine, and then transfer the build output to another machine for test execution. Being able to do this is useful for several use cases: 1. When running tests on an ARM machine, it would be possible to build on a fast x86 machine and then copy build artifacts over after building. 2. It allows running several test suites (clang, llvm, lld) on 3 different machines, reducing test time from sum(each test suite time) to max(each test suite time). This patch makes it possible to pass a list of variables that should be relative in the generated lit.site.cfg.py file to configure_lit_site_cfg(). The lit.site.cfg.py.in file needs to call `path()` on these variables, so that the paths are converted to absolute form at lit start time. The testers would have to have an LLVM checkout at the same revision, and the build dir would have to be at the same relative path as on the builder. This does not yet cover how to figure out which files to copy from the builder machine to the tester machines. (One idea is to look at the `--graphviz=test.dot` output and copy all inputs of the `check-llvm` target.) Differential Revision: https://reviews.llvm.org/D77184 Added: Modified: clang/test/CMakeLists.txt clang/test/Unit/lit.site.cfg.py.in clang/test/lit.site.cfg.py.in llvm/cmake/modules/AddLLVM.cmake llvm/test/CMakeLists.txt llvm/test/Unit/lit.site.cfg.py.in llvm/test/lit.site.cfg.py.in llvm/utils/gn/secondary/clang/test/BUILD.gn llvm/utils/gn/secondary/llvm/test/BUILD.gn Removed: ################################################################################ diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt index d453074d7926..ca326fea8066 100644 --- a/clang/test/CMakeLists.txt +++ b/clang/test/CMakeLists.txt @@ -35,6 +35,16 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py MAIN_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py + PATHS + "LLVM_SOURCE_DIR" + "LLVM_BINARY_DIR" + "LLVM_TOOLS_DIR" + "LLVM_LIBS_DIR" + "SHLIBDIR" + "LLVM_LIT_TOOLS_DIR" + "CLANG_BINARY_DIR" + "CLANG_SOURCE_DIR" + "CLANG_TOOLS_DIR" ) configure_lit_site_cfg( @@ -42,6 +52,13 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py MAIN_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py + PATHS + "LLVM_SOURCE_DIR" + "LLVM_BINARY_DIR" + "LLVM_TOOLS_DIR" + "LLVM_LIBS_DIR" + "CLANG_BINARY_DIR" + "SHLIBDIR" ) option(CLANG_TEST_USE_VG "Run Clang tests under Valgrind" OFF) diff --git a/clang/test/Unit/lit.site.cfg.py.in b/clang/test/Unit/lit.site.cfg.py.in index 715b4d93f58f..400a9c05e58c 100644 --- a/clang/test/Unit/lit.site.cfg.py.in +++ b/clang/test/Unit/lit.site.cfg.py.in @@ -2,14 +2,14 @@ import sys -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" -config.llvm_libs_dir = "@LLVM_LIBS_DIR@" +config.llvm_src_root = path("@LLVM_SOURCE_DIR@") +config.llvm_obj_root = path("@LLVM_BINARY_DIR@") +config.llvm_tools_dir = path("@LLVM_TOOLS_DIR@") +config.llvm_libs_dir = path("@LLVM_LIBS_DIR@") config.llvm_build_mode = "@LLVM_BUILD_MODE@" -config.clang_obj_root = "@CLANG_BINARY_DIR@" +config.clang_obj_root = path("@CLANG_BINARY_DIR@") config.enable_shared = @ENABLE_SHARED@ -config.shlibdir = "@SHLIBDIR@" +config.shlibdir = path("@SHLIBDIR@") config.target_triple = "@TARGET_TRIPLE@" # Support substitution of the tools_dir, libs_dirs, and build_mode with user @@ -25,4 +25,5 @@ except KeyError: lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) # Let the main config do the real work. -lit_config.load_config(config, "@CLANG_SOURCE_DIR@/test/Unit/lit.cfg.py") +lit_config.load_config( + config, os.path.join(path("@CLANG_SOURCE_DIR@"), "test/Unit/lit.cfg.py")) diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in index 62616d9a2b95..84dd0f8846cf 100644 --- a/clang/test/lit.site.cfg.py.in +++ b/clang/test/lit.site.cfg.py.in @@ -2,16 +2,16 @@ import sys -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" -config.llvm_libs_dir = "@LLVM_LIBS_DIR@" -config.llvm_shlib_dir = "@SHLIBDIR@" +config.llvm_src_root = path("@LLVM_SOURCE_DIR@") +config.llvm_obj_root = path("@LLVM_BINARY_DIR@") +config.llvm_tools_dir = path("@LLVM_TOOLS_DIR@") +config.llvm_libs_dir = path("@LLVM_LIBS_DIR@") +config.llvm_shlib_dir = path("@SHLIBDIR@") config.llvm_plugin_ext = "@LLVM_PLUGIN_EXT@" -config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" -config.clang_obj_root = "@CLANG_BINARY_DIR@" -config.clang_src_dir = "@CLANG_SOURCE_DIR@" -config.clang_tools_dir = "@CLANG_TOOLS_DIR@" +config.lit_tools_dir = path("@LLVM_LIT_TOOLS_DIR@") +config.clang_obj_root = path("@CLANG_BINARY_DIR@") +config.clang_src_dir = path("@CLANG_SOURCE_DIR@") +config.clang_tools_dir = path("@CLANG_TOOLS_DIR@") config.host_triple = "@LLVM_HOST_TRIPLE@" config.target_triple = "@TARGET_TRIPLE@" config.host_cxx = "@CMAKE_CXX_COMPILER@" @@ -50,4 +50,5 @@ if not "@CLANG_DEFAULT_LINKER@": config.available_features.add('platform-linker') # Let the main config do the real work. -lit_config.load_config(config, "@CLANG_SOURCE_DIR@/test/lit.cfg.py") +lit_config.load_config( + config, os.path.join(config.clang_src_dir, "test/lit.cfg.py")) diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index 238aa3eab9f4..74450b36523e 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -1396,8 +1396,14 @@ endmacro() # variables needed for the 'lit.site.cfg' files. This function bundles the # common variables that any Lit instance is likely to need, and custom # variables can be passed in. +# The keyword PATHS is followed by a list of cmake variable names that are +# mentioned as `path("@varname@")` in the lit.cfg.py.in file. Variables in that +# list are treated as paths that are relative to the directory the generated +# lit.cfg.py file is in, and the `path()` function converts the relative +# path back to absolute form. This makes it possible to move a build directory +# containing lit.cfg.py files from one machine to another. function(configure_lit_site_cfg site_in site_out) - cmake_parse_arguments(ARG "" "" "MAIN_CONFIG;OUTPUT_MAPPING" ${ARGN}) + cmake_parse_arguments(ARG "" "" "MAIN_CONFIG;OUTPUT_MAPPING;PATHS" ${ARGN}) if ("${ARG_MAIN_CONFIG}" STREQUAL "") get_filename_component(INPUT_DIR ${site_in} DIRECTORY) @@ -1447,12 +1453,17 @@ function(configure_lit_site_cfg site_in site_out) set(HOST_CXX "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}") set(HOST_LDFLAGS "${CMAKE_EXE_LINKER_FLAGS}") - set(LIT_SITE_CFG_IN_HEADER "## Autogenerated from ${site_in}\n## Do not edit!") + set(LIT_SITE_CFG_IN_HEADER "# Autogenerated from ${site_in}\n# Do not edit!") + + string(CONCAT LIT_SITE_CFG_IN_HEADER "${LIT_SITE_CFG_IN_HEADER}\n\n" + "# Allow generated lit.site.cfg.py to be relocatable.\n" + "def path(p): return os.path.join(os.path.dirname(__file__), p) if p else ''\n" + ) # Override config_target_triple (and the env) if(LLVM_TARGET_TRIPLE_ENV) # This is expanded into the heading. - string(CONCAT LIT_SITE_CFG_IN_HEADER "${LIT_SITE_CFG_IN_HEADER}\n\n" + string(CONCAT LIT_SITE_CFG_IN_HEADER "${LIT_SITE_CFG_IN_HEADER}" "import os\n" "target_env = \"${LLVM_TARGET_TRIPLE_ENV}\"\n" "config.target_triple = config.environment[target_env] = os.environ.get(target_env, \"${TARGET_TRIPLE}\")\n" @@ -1462,7 +1473,45 @@ function(configure_lit_site_cfg site_in site_out) set(TARGET_TRIPLE "\"+config.target_triple+\"") endif() + if (ARG_PATH_VALUES) + # Walk ARG_PATHS and collect the current value of the variables in there. + foreach(path ${ARG_PATHS}) + list(APPEND ARG_PATH_VALUES "${${path}}") + endforeach() + + # Compute paths relative to the directory containing output lit.site.cfg.py. + # Passing ARG_PATH_VALUES as-is to execute_process() makes cmake strip + # empty list entries. So escape the ;s in the list and do the splitting + # outselves. cmake has no relpath function, so use Python for that. + string(REPLACE ";" "\\;" ARG_PATH_VALUES_ESCAPED "${ARG_PATH_VALUES}") + get_filename_component(OUTPUT_DIR ${site_out} DIRECTORY) + execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" + "import os, sys; sys.stdout.write(';'.join(os.path.relpath(p, sys.argv[1]) if p else '' for p in sys.argv[2].split(';')))" + ${OUTPUT_DIR} + ${ARG_PATH_VALUES_ESCAPED} + OUTPUT_VARIABLE ARG_PATH_VALUES_RELATIVE) + + list(LENGTH ARG_PATHS len_paths) + list(LENGTH ARG_PATH_VALUES len_path_values) + list(LENGTH ARG_PATH_VALUES_RELATIVE len_path_value_rels) + if ((NOT ${len_paths} EQUAL ${len_path_values}) OR + (NOT ${len_paths} EQUAL ${path_value_len_rels})) + message(SEND_ERROR "PATHS lengths got confused") + endif() + + # Transform variables mentioned in ARG_PATHS to relative paths for + # the configure_file() call. Variables are copied to subscopeds by cmake, + # so this only modifies the local copy of the variables. + math(EXPR arg_path_limit "${len_paths} - 1") + foreach(i RANGE ${arg_path_limit}) + list(GET ARG_PATHS ${i} val1) + list(GET ARG_PATH_VALUES_RELATIVE ${i} val2) + set(${val1} ${val2}) + endforeach() + endif() + configure_file(${site_in} ${site_out} @ONLY) + if (EXISTS "${ARG_MAIN_CONFIG}") set(PYTHON_STATEMENT "map_config('${ARG_MAIN_CONFIG}', '${site_out}')") get_property(LLVM_LIT_CONFIG_MAP GLOBAL PROPERTY LLVM_LIT_CONFIG_MAP) diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt index d1bc970f3643..330a35212883 100644 --- a/llvm/test/CMakeLists.txt +++ b/llvm/test/CMakeLists.txt @@ -22,12 +22,23 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py MAIN_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py + PATHS + "LLVM_SOURCE_DIR" + "LLVM_BINARY_DIR" + "LLVM_TOOLS_DIR" + "LLVM_LIBRARY_DIR" + "SHLIBDIR" ) configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py MAIN_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py + PATHS + "LLVM_SOURCE_DIR" + "LLVM_BINARY_DIR" + "LLVM_TOOLS_DIR" + "SHLIBDIR" ) # Set the depends list as a variable so that it can grow conditionally. diff --git a/llvm/test/Unit/lit.site.cfg.py.in b/llvm/test/Unit/lit.site.cfg.py.in index 1fef001be627..3358ccf89eed 100644 --- a/llvm/test/Unit/lit.site.cfg.py.in +++ b/llvm/test/Unit/lit.site.cfg.py.in @@ -2,12 +2,12 @@ import sys -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" +config.llvm_src_root = path("@LLVM_SOURCE_DIR@") +config.llvm_obj_root = path("@LLVM_BINARY_DIR@") +config.llvm_tools_dir = path("@LLVM_TOOLS_DIR@") config.llvm_build_mode = "@LLVM_BUILD_MODE@" config.enable_shared = @ENABLE_SHARED@ -config.shlibdir = "@SHLIBDIR@" +config.shlibdir = path("@SHLIBDIR@") # Support substitution of the tools_dir and build_mode with user parameters. # This is used when we can't determine the tool dir at configuration time. @@ -20,4 +20,5 @@ except KeyError: lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) # Let the main config do the real work. -lit_config.load_config(config, "@LLVM_SOURCE_DIR@/test/Unit/lit.cfg.py") +lit_config.load_config( + config, os.path.join(config.llvm_src_root, "test/Unit/lit.cfg.py")) diff --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in index 6f4d5f790828..2af0ec336089 100644 --- a/llvm/test/lit.site.cfg.py.in +++ b/llvm/test/lit.site.cfg.py.in @@ -4,14 +4,14 @@ import sys config.host_triple = "@LLVM_HOST_TRIPLE@" config.target_triple = "@TARGET_TRIPLE@" -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" -config.llvm_lib_dir = "@LLVM_LIBRARY_DIR@" -config.llvm_shlib_dir = "@SHLIBDIR@" +config.llvm_src_root = path("@LLVM_SOURCE_DIR@") +config.llvm_obj_root = path("@LLVM_BINARY_DIR@") +config.llvm_tools_dir = path("@LLVM_TOOLS_DIR@") +config.llvm_lib_dir = path("@LLVM_LIBRARY_DIR@") +config.llvm_shlib_dir = path("@SHLIBDIR@") config.llvm_shlib_ext = "@SHLIBEXT@" config.llvm_exe_ext = "@EXEEXT@" -config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" +config.lit_tools_dir = path("@LLVM_LIT_TOOLS_DIR@") config.python_executable = "@PYTHON_EXECUTABLE@" config.gold_executable = "@GOLD_EXECUTABLE@" config.ld64_executable = "@LD64_EXECUTABLE@" @@ -63,4 +63,5 @@ import lit.llvm lit.llvm.initialize(lit_config, config) # Let the main config do the real work. -lit_config.load_config(config, "@LLVM_SOURCE_DIR@/test/lit.cfg.py") +lit_config.load_config( + config, os.path.join(config.llvm_src_root, "test/lit.cfg.py")) diff --git a/llvm/utils/gn/secondary/clang/test/BUILD.gn b/llvm/utils/gn/secondary/clang/test/BUILD.gn index 874891e89c81..84ac2e893cdf 100644 --- a/llvm/utils/gn/secondary/clang/test/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/test/BUILD.gn @@ -12,7 +12,10 @@ template("write_lit_config") { input = invoker.input output = invoker.output values = [ - "LIT_SITE_CFG_IN_HEADER=## Autogenerated from $input, do not edit", + # FIXME: Write relative paths for path()s. + "LIT_SITE_CFG_IN_HEADER=" + + "## Autogenerated from $input, do not edit\n\n" + + "def path(p): return p if p else \"\"", "CLANG_BINARY_DIR=" + rebase_path(get_label_info("//clang", "target_out_dir")), "CLANG_SOURCE_DIR=" + rebase_path("//clang"), diff --git a/llvm/utils/gn/secondary/llvm/test/BUILD.gn b/llvm/utils/gn/secondary/llvm/test/BUILD.gn index 0f7d90d1ab60..c7740ac4cc99 100644 --- a/llvm/utils/gn/secondary/llvm/test/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/test/BUILD.gn @@ -14,7 +14,10 @@ template("write_lit_config") { input = invoker.input output = invoker.output values = [ - "LIT_SITE_CFG_IN_HEADER=## Autogenerated from $input, do not edit", + # FIXME: Write relative paths for path()s. + "LIT_SITE_CFG_IN_HEADER=" + + "## Autogenerated from $input, do not edit\n\n" + + "def path(p): return p if p else \"\"", "ENABLE_SHARED=0", "LLVM_BINARY_DIR=" + rebase_path(get_label_info("//llvm", "target_out_dir")), From cfe-commits at lists.llvm.org Thu Apr 2 11:22:54 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 18:22:54 +0000 (UTC) Subject: [PATCH] D77313: [AST] Allow VectorTypes of 1-256 elements, and powers of two up to 2**31. In-Reply-To: References: Message-ID: efriedma added a comment. I think I would rather just pay the extra 8 bytes per VectorType, and expand this to support all vector types supported by LLVM. It's not like we allocate enough VectorTypes for it to matter, anyway. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77313/new/ https://reviews.llvm.org/D77313 From cfe-commits at lists.llvm.org Thu Apr 2 11:22:55 2020 From: cfe-commits at lists.llvm.org (Christopher Tetreault via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 18:22:55 +0000 (UTC) Subject: [PATCH] D77257: Clean up usages of asserting vector getters in Type In-Reply-To: References: Message-ID: <9b20c4fd4bbba05a35525c4e91c97c53@localhost.localdomain> ctetreau updated this revision to Diff 254570. ctetreau added a comment. Note that this is NFC Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77257/new/ https://reviews.llvm.org/D77257 Files: clang/lib/CodeGen/CGAtomic.cpp clang/lib/CodeGen/CGBuiltin.cpp clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprScalar.cpp clang/lib/CodeGen/PatternInit.cpp clang/lib/CodeGen/TargetInfo.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77257.254570.patch Type: text/x-patch Size: 29730 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 11:23:41 2020 From: cfe-commits at lists.llvm.org (Nico Weber via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 18:23:41 +0000 (UTC) Subject: [PATCH] D77184: Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang In-Reply-To: References: Message-ID: <5d7f50e3367016c13d6ce4fe53d50184@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGfb80b6b2d58c: Make it possible for lit.site.cfg to contain relative paths, and use it for… (authored by thakis). Herald added a project: clang. Herald added a subscriber: cfe-commits. Changed prior to commit: https://reviews.llvm.org/D77184?vs=254033&id=254572#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77184/new/ https://reviews.llvm.org/D77184 Files: clang/test/CMakeLists.txt clang/test/Unit/lit.site.cfg.py.in clang/test/lit.site.cfg.py.in llvm/cmake/modules/AddLLVM.cmake llvm/test/CMakeLists.txt llvm/test/Unit/lit.site.cfg.py.in llvm/test/lit.site.cfg.py.in llvm/utils/gn/secondary/clang/test/BUILD.gn llvm/utils/gn/secondary/llvm/test/BUILD.gn -------------- next part -------------- A non-text attachment was scrubbed... Name: D77184.254572.patch Type: text/x-patch Size: 12458 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 11:23:45 2020 From: cfe-commits at lists.llvm.org (Anna Thomas via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 18:23:45 +0000 (UTC) Subject: [PATCH] D76140: [InlineFunction] update attributes during inlining In-Reply-To: References: Message-ID: <05496ed9a42120a9c123c797e412fcc4@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGbf7a16a76871: [InlineFunction] Update valid return attributes at callsite within callee body (authored by anna). Changed prior to commit: https://reviews.llvm.org/D76140?vs=254222&id=254573#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76140/new/ https://reviews.llvm.org/D76140 Files: llvm/lib/Transforms/Utils/InlineFunction.cpp llvm/test/Transforms/Inline/ret_attr_update.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D76140.254573.patch Type: text/x-patch Size: 13318 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 11:56:02 2020 From: cfe-commits at lists.llvm.org (Roland McGrath via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 18:56:02 +0000 (UTC) Subject: [PATCH] D72959: Relative VTables ABI on Fuchsia In-Reply-To: References: Message-ID: mcgrathr added inline comments. ================ Comment at: libcxxabi/src/private_typeinfo.cpp:617 // Get (dynamic_ptr, dynamic_type) from static_ptr +#ifndef __Fuchsia__ void **vtable = *static_cast(static_ptr); ---------------- ldionne wrote: > Please introduce a macro that generically expresses that relative vtables are enabled, and explain what it is. You can then enable that macro only on `__Fuchsia__`. I'd like to avoid freely adding platform-specific `#ifdef`s in the code when it's easy to avoid. I think the libcxxabi change should be separated from the compiler change entirely. It will need more configuration issues resolved before it usefully lands. Let's keep this change just for the pure compiler feature. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72959/new/ https://reviews.llvm.org/D72959 From cfe-commits at lists.llvm.org Thu Apr 2 11:56:04 2020 From: cfe-commits at lists.llvm.org (Erik Pilkington via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 18:56:04 +0000 (UTC) Subject: [PATCH] D72872: [ObjC generics] Fix not inheriting type bounds in categories/extensions. In-Reply-To: References: Message-ID: <7d9f29e2ed8da3d0a5437b1ffbb6aef8@localhost.localdomain> erik.pilkington accepted this revision. erik.pilkington added a comment. This revision is now accepted and ready to land. LGTM, sorry for the delay in reviewing this. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72872/new/ https://reviews.llvm.org/D72872 From cfe-commits at lists.llvm.org Thu Apr 2 11:56:04 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 18:56:04 +0000 (UTC) Subject: [PATCH] D77054: [AArch64][SVE] Add SVE intrinsics for saturating add & subtract In-Reply-To: References: Message-ID: efriedma added a comment. You should be able to refactor the patterns into the definitions of the multiclasses sve_int_bin_cons_arit_0 and sve_int_arith_imm0, to avoid repeating them four times. (You might want to look at other places using null_frag in SVEInstrFormats.td for inspiration.) CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77054/new/ https://reviews.llvm.org/D77054 From cfe-commits at lists.llvm.org Thu Apr 2 12:00:22 2020 From: cfe-commits at lists.llvm.org (Nico Weber via cfe-commits) Date: Thu, 02 Apr 2020 12:00:22 -0700 (PDT) Subject: [clang] ab11b9e - Revert "Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang" Message-ID: <5e863646.1c69fb81.87e6a.26a5@mx.google.com> Author: Nico Weber Date: 2020-04-02T15:00:09-04:00 New Revision: ab11b9eefa16661017c2c7b3b34c46b069f43fb7 URL: https://github.com/llvm/llvm-project/commit/ab11b9eefa16661017c2c7b3b34c46b069f43fb7 DIFF: https://github.com/llvm/llvm-project/commit/ab11b9eefa16661017c2c7b3b34c46b069f43fb7.diff LOG: Revert "Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang" This reverts commit fb80b6b2d58c476747a3206bd4371b787108591b and follow-up 631ee8b24adf36359b61ecb47484e8e82de35be8. Seems to not work on Windows: http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/31684 http://lab.llvm.org:8011/builders/llvm-clang-win-x-aarch64/builds/6512 Let's revert while I investigate. Added: Modified: clang/test/CMakeLists.txt clang/test/Unit/lit.site.cfg.py.in clang/test/lit.site.cfg.py.in llvm/cmake/modules/AddLLVM.cmake llvm/test/CMakeLists.txt llvm/test/Unit/lit.site.cfg.py.in llvm/test/lit.site.cfg.py.in llvm/utils/gn/secondary/clang/test/BUILD.gn llvm/utils/gn/secondary/llvm/test/BUILD.gn Removed: ################################################################################ diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt index ca326fea8066..d453074d7926 100644 --- a/clang/test/CMakeLists.txt +++ b/clang/test/CMakeLists.txt @@ -35,16 +35,6 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py MAIN_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py - PATHS - "LLVM_SOURCE_DIR" - "LLVM_BINARY_DIR" - "LLVM_TOOLS_DIR" - "LLVM_LIBS_DIR" - "SHLIBDIR" - "LLVM_LIT_TOOLS_DIR" - "CLANG_BINARY_DIR" - "CLANG_SOURCE_DIR" - "CLANG_TOOLS_DIR" ) configure_lit_site_cfg( @@ -52,13 +42,6 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py MAIN_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py - PATHS - "LLVM_SOURCE_DIR" - "LLVM_BINARY_DIR" - "LLVM_TOOLS_DIR" - "LLVM_LIBS_DIR" - "CLANG_BINARY_DIR" - "SHLIBDIR" ) option(CLANG_TEST_USE_VG "Run Clang tests under Valgrind" OFF) diff --git a/clang/test/Unit/lit.site.cfg.py.in b/clang/test/Unit/lit.site.cfg.py.in index 400a9c05e58c..715b4d93f58f 100644 --- a/clang/test/Unit/lit.site.cfg.py.in +++ b/clang/test/Unit/lit.site.cfg.py.in @@ -2,14 +2,14 @@ import sys -config.llvm_src_root = path("@LLVM_SOURCE_DIR@") -config.llvm_obj_root = path("@LLVM_BINARY_DIR@") -config.llvm_tools_dir = path("@LLVM_TOOLS_DIR@") -config.llvm_libs_dir = path("@LLVM_LIBS_DIR@") +config.llvm_src_root = "@LLVM_SOURCE_DIR@" +config.llvm_obj_root = "@LLVM_BINARY_DIR@" +config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" +config.llvm_libs_dir = "@LLVM_LIBS_DIR@" config.llvm_build_mode = "@LLVM_BUILD_MODE@" -config.clang_obj_root = path("@CLANG_BINARY_DIR@") +config.clang_obj_root = "@CLANG_BINARY_DIR@" config.enable_shared = @ENABLE_SHARED@ -config.shlibdir = path("@SHLIBDIR@") +config.shlibdir = "@SHLIBDIR@" config.target_triple = "@TARGET_TRIPLE@" # Support substitution of the tools_dir, libs_dirs, and build_mode with user @@ -25,5 +25,4 @@ except KeyError: lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) # Let the main config do the real work. -lit_config.load_config( - config, os.path.join(path("@CLANG_SOURCE_DIR@"), "test/Unit/lit.cfg.py")) +lit_config.load_config(config, "@CLANG_SOURCE_DIR@/test/Unit/lit.cfg.py") diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in index 84dd0f8846cf..62616d9a2b95 100644 --- a/clang/test/lit.site.cfg.py.in +++ b/clang/test/lit.site.cfg.py.in @@ -2,16 +2,16 @@ import sys -config.llvm_src_root = path("@LLVM_SOURCE_DIR@") -config.llvm_obj_root = path("@LLVM_BINARY_DIR@") -config.llvm_tools_dir = path("@LLVM_TOOLS_DIR@") -config.llvm_libs_dir = path("@LLVM_LIBS_DIR@") -config.llvm_shlib_dir = path("@SHLIBDIR@") +config.llvm_src_root = "@LLVM_SOURCE_DIR@" +config.llvm_obj_root = "@LLVM_BINARY_DIR@" +config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" +config.llvm_libs_dir = "@LLVM_LIBS_DIR@" +config.llvm_shlib_dir = "@SHLIBDIR@" config.llvm_plugin_ext = "@LLVM_PLUGIN_EXT@" -config.lit_tools_dir = path("@LLVM_LIT_TOOLS_DIR@") -config.clang_obj_root = path("@CLANG_BINARY_DIR@") -config.clang_src_dir = path("@CLANG_SOURCE_DIR@") -config.clang_tools_dir = path("@CLANG_TOOLS_DIR@") +config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" +config.clang_obj_root = "@CLANG_BINARY_DIR@" +config.clang_src_dir = "@CLANG_SOURCE_DIR@" +config.clang_tools_dir = "@CLANG_TOOLS_DIR@" config.host_triple = "@LLVM_HOST_TRIPLE@" config.target_triple = "@TARGET_TRIPLE@" config.host_cxx = "@CMAKE_CXX_COMPILER@" @@ -50,5 +50,4 @@ if not "@CLANG_DEFAULT_LINKER@": config.available_features.add('platform-linker') # Let the main config do the real work. -lit_config.load_config( - config, os.path.join(config.clang_src_dir, "test/lit.cfg.py")) +lit_config.load_config(config, "@CLANG_SOURCE_DIR@/test/lit.cfg.py") diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index 0732ca6ed0d0..238aa3eab9f4 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -1396,14 +1396,8 @@ endmacro() # variables needed for the 'lit.site.cfg' files. This function bundles the # common variables that any Lit instance is likely to need, and custom # variables can be passed in. -# The keyword PATHS is followed by a list of cmake variable names that are -# mentioned as `path("@varname@")` in the lit.cfg.py.in file. Variables in that -# list are treated as paths that are relative to the directory the generated -# lit.cfg.py file is in, and the `path()` function converts the relative -# path back to absolute form. This makes it possible to move a build directory -# containing lit.cfg.py files from one machine to another. function(configure_lit_site_cfg site_in site_out) - cmake_parse_arguments(ARG "" "" "MAIN_CONFIG;OUTPUT_MAPPING;PATHS" ${ARGN}) + cmake_parse_arguments(ARG "" "" "MAIN_CONFIG;OUTPUT_MAPPING" ${ARGN}) if ("${ARG_MAIN_CONFIG}" STREQUAL "") get_filename_component(INPUT_DIR ${site_in} DIRECTORY) @@ -1453,17 +1447,12 @@ function(configure_lit_site_cfg site_in site_out) set(HOST_CXX "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}") set(HOST_LDFLAGS "${CMAKE_EXE_LINKER_FLAGS}") - set(LIT_SITE_CFG_IN_HEADER "# Autogenerated from ${site_in}\n# Do not edit!") - - string(CONCAT LIT_SITE_CFG_IN_HEADER "${LIT_SITE_CFG_IN_HEADER}\n\n" - "# Allow generated lit.site.cfg.py to be relocatable.\n" - "def path(p): return os.path.join(os.path.dirname(__file__), p) if p else ''\n" - ) + set(LIT_SITE_CFG_IN_HEADER "## Autogenerated from ${site_in}\n## Do not edit!") # Override config_target_triple (and the env) if(LLVM_TARGET_TRIPLE_ENV) # This is expanded into the heading. - string(CONCAT LIT_SITE_CFG_IN_HEADER "${LIT_SITE_CFG_IN_HEADER}" + string(CONCAT LIT_SITE_CFG_IN_HEADER "${LIT_SITE_CFG_IN_HEADER}\n\n" "import os\n" "target_env = \"${LLVM_TARGET_TRIPLE_ENV}\"\n" "config.target_triple = config.environment[target_env] = os.environ.get(target_env, \"${TARGET_TRIPLE}\")\n" @@ -1473,45 +1462,7 @@ function(configure_lit_site_cfg site_in site_out) set(TARGET_TRIPLE "\"+config.target_triple+\"") endif() - if (ARG_PATHS) - # Walk ARG_PATHS and collect the current value of the variables in there. - foreach(path ${ARG_PATHS}) - list(APPEND ARG_PATH_VALUES "${${path}}") - endforeach() - - # Compute paths relative to the directory containing output lit.site.cfg.py. - # Passing ARG_PATH_VALUES as-is to execute_process() makes cmake strip - # empty list entries. So escape the ;s in the list and do the splitting - # outselves. cmake has no relpath function, so use Python for that. - string(REPLACE ";" "\\;" ARG_PATH_VALUES_ESCAPED "${ARG_PATH_VALUES}") - get_filename_component(OUTPUT_DIR ${site_out} DIRECTORY) - execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" - "import os, sys; sys.stdout.write(';'.join(os.path.relpath(p, sys.argv[1]) if p else '' for p in sys.argv[2].split(';')))" - ${OUTPUT_DIR} - ${ARG_PATH_VALUES_ESCAPED} - OUTPUT_VARIABLE ARG_PATH_VALUES_RELATIVE) - - list(LENGTH ARG_PATHS len_paths) - list(LENGTH ARG_PATH_VALUES len_path_values) - list(LENGTH ARG_PATH_VALUES_RELATIVE len_path_value_rels) - if ((NOT ${len_paths} EQUAL ${len_path_values}) OR - (NOT ${len_paths} EQUAL ${len_path_value_rels})) - message(SEND_ERROR "PATHS lengths got confused") - endif() - - # Transform variables mentioned in ARG_PATHS to relative paths for - # the configure_file() call. Variables are copied to subscopeds by cmake, - # so this only modifies the local copy of the variables. - math(EXPR arg_path_limit "${len_paths} - 1") - foreach(i RANGE ${arg_path_limit}) - list(GET ARG_PATHS ${i} val1) - list(GET ARG_PATH_VALUES_RELATIVE ${i} val2) - set(${val1} ${val2}) - endforeach() - endif() - configure_file(${site_in} ${site_out} @ONLY) - if (EXISTS "${ARG_MAIN_CONFIG}") set(PYTHON_STATEMENT "map_config('${ARG_MAIN_CONFIG}', '${site_out}')") get_property(LLVM_LIT_CONFIG_MAP GLOBAL PROPERTY LLVM_LIT_CONFIG_MAP) diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt index 330a35212883..d1bc970f3643 100644 --- a/llvm/test/CMakeLists.txt +++ b/llvm/test/CMakeLists.txt @@ -22,23 +22,12 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py MAIN_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py - PATHS - "LLVM_SOURCE_DIR" - "LLVM_BINARY_DIR" - "LLVM_TOOLS_DIR" - "LLVM_LIBRARY_DIR" - "SHLIBDIR" ) configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py MAIN_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py - PATHS - "LLVM_SOURCE_DIR" - "LLVM_BINARY_DIR" - "LLVM_TOOLS_DIR" - "SHLIBDIR" ) # Set the depends list as a variable so that it can grow conditionally. diff --git a/llvm/test/Unit/lit.site.cfg.py.in b/llvm/test/Unit/lit.site.cfg.py.in index 3358ccf89eed..1fef001be627 100644 --- a/llvm/test/Unit/lit.site.cfg.py.in +++ b/llvm/test/Unit/lit.site.cfg.py.in @@ -2,12 +2,12 @@ import sys -config.llvm_src_root = path("@LLVM_SOURCE_DIR@") -config.llvm_obj_root = path("@LLVM_BINARY_DIR@") -config.llvm_tools_dir = path("@LLVM_TOOLS_DIR@") +config.llvm_src_root = "@LLVM_SOURCE_DIR@" +config.llvm_obj_root = "@LLVM_BINARY_DIR@" +config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" config.llvm_build_mode = "@LLVM_BUILD_MODE@" config.enable_shared = @ENABLE_SHARED@ -config.shlibdir = path("@SHLIBDIR@") +config.shlibdir = "@SHLIBDIR@" # Support substitution of the tools_dir and build_mode with user parameters. # This is used when we can't determine the tool dir at configuration time. @@ -20,5 +20,4 @@ except KeyError: lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) # Let the main config do the real work. -lit_config.load_config( - config, os.path.join(config.llvm_src_root, "test/Unit/lit.cfg.py")) +lit_config.load_config(config, "@LLVM_SOURCE_DIR@/test/Unit/lit.cfg.py") diff --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in index 2af0ec336089..6f4d5f790828 100644 --- a/llvm/test/lit.site.cfg.py.in +++ b/llvm/test/lit.site.cfg.py.in @@ -4,14 +4,14 @@ import sys config.host_triple = "@LLVM_HOST_TRIPLE@" config.target_triple = "@TARGET_TRIPLE@" -config.llvm_src_root = path("@LLVM_SOURCE_DIR@") -config.llvm_obj_root = path("@LLVM_BINARY_DIR@") -config.llvm_tools_dir = path("@LLVM_TOOLS_DIR@") -config.llvm_lib_dir = path("@LLVM_LIBRARY_DIR@") -config.llvm_shlib_dir = path("@SHLIBDIR@") +config.llvm_src_root = "@LLVM_SOURCE_DIR@" +config.llvm_obj_root = "@LLVM_BINARY_DIR@" +config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" +config.llvm_lib_dir = "@LLVM_LIBRARY_DIR@" +config.llvm_shlib_dir = "@SHLIBDIR@" config.llvm_shlib_ext = "@SHLIBEXT@" config.llvm_exe_ext = "@EXEEXT@" -config.lit_tools_dir = path("@LLVM_LIT_TOOLS_DIR@") +config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" config.python_executable = "@PYTHON_EXECUTABLE@" config.gold_executable = "@GOLD_EXECUTABLE@" config.ld64_executable = "@LD64_EXECUTABLE@" @@ -63,5 +63,4 @@ import lit.llvm lit.llvm.initialize(lit_config, config) # Let the main config do the real work. -lit_config.load_config( - config, os.path.join(config.llvm_src_root, "test/lit.cfg.py")) +lit_config.load_config(config, "@LLVM_SOURCE_DIR@/test/lit.cfg.py") diff --git a/llvm/utils/gn/secondary/clang/test/BUILD.gn b/llvm/utils/gn/secondary/clang/test/BUILD.gn index 84ac2e893cdf..874891e89c81 100644 --- a/llvm/utils/gn/secondary/clang/test/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/test/BUILD.gn @@ -12,10 +12,7 @@ template("write_lit_config") { input = invoker.input output = invoker.output values = [ - # FIXME: Write relative paths for path()s. - "LIT_SITE_CFG_IN_HEADER=" + - "## Autogenerated from $input, do not edit\n\n" + - "def path(p): return p if p else \"\"", + "LIT_SITE_CFG_IN_HEADER=## Autogenerated from $input, do not edit", "CLANG_BINARY_DIR=" + rebase_path(get_label_info("//clang", "target_out_dir")), "CLANG_SOURCE_DIR=" + rebase_path("//clang"), diff --git a/llvm/utils/gn/secondary/llvm/test/BUILD.gn b/llvm/utils/gn/secondary/llvm/test/BUILD.gn index c7740ac4cc99..0f7d90d1ab60 100644 --- a/llvm/utils/gn/secondary/llvm/test/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/test/BUILD.gn @@ -14,10 +14,7 @@ template("write_lit_config") { input = invoker.input output = invoker.output values = [ - # FIXME: Write relative paths for path()s. - "LIT_SITE_CFG_IN_HEADER=" + - "## Autogenerated from $input, do not edit\n\n" + - "def path(p): return p if p else \"\"", + "LIT_SITE_CFG_IN_HEADER=## Autogenerated from $input, do not edit", "ENABLE_SHARED=0", "LLVM_BINARY_DIR=" + rebase_path(get_label_info("//llvm", "target_out_dir")), From cfe-commits at lists.llvm.org Thu Apr 2 12:28:34 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 19:28:34 +0000 (UTC) Subject: [PATCH] D59321: AMDGPU: Teach toolchain to link rocm device libs In-Reply-To: References: Message-ID: arsenm updated this revision to Diff 254584. arsenm added a comment. Rebase CHANGES SINCE LAST ACTION https://reviews.llvm.org/D59321/new/ https://reviews.llvm.org/D59321 Files: clang/include/clang/Basic/DiagnosticDriverKinds.td clang/include/clang/Driver/Options.td clang/lib/Driver/Driver.cpp clang/lib/Driver/ToolChains/AMDGPU.cpp clang/lib/Driver/ToolChains/AMDGPU.h clang/lib/Driver/ToolChains/HIP.cpp clang/lib/Driver/ToolChains/HIP.h clang/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl clang/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl clang/test/Driver/Inputs/rocm-device-libs/lib/hip.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/ockl.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_correctly_rounded_sqrt_off.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_correctly_rounded_sqrt_on.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_daz_opt_off.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_daz_opt_on.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_finite_only_off.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_finite_only_on.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_isa_version_1010.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_isa_version_1011.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_isa_version_1012.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_isa_version_803.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_isa_version_900.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_unsafe_math_off.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_unsafe_math_on.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_wavefrontsize64_off.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_wavefrontsize64_on.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/ocml.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/opencl.amdgcn.bc clang/test/Driver/amdgpu-visibility.cl clang/test/Driver/rocm-detect.cl clang/test/Driver/rocm-device-libs.cl clang/test/Driver/rocm-not-found.cl llvm/include/llvm/Support/TargetParser.h llvm/lib/Support/TargetParser.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D59321.254584.patch Type: text/x-patch Size: 33723 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 12:28:36 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 19:28:36 +0000 (UTC) Subject: [PATCH] D77329: [AMDGPU] Allow AGPR in inline asm Message-ID: yaxunl created this revision. yaxunl added reviewers: rampitec, arsenm. Herald added subscribers: kerbowa, t-tye, tpr, dstuttard, nhaehnle, wdng, jvesely, kzhuravl. rampitec accepted this revision. rampitec added a comment. This revision is now accepted and ready to land. Thanks. Could you also update AMDGPUTargetInfo::GCCRegNames[] (in a separate change)? It is used in clobber constraints. JBTW, it does not support register tuples even for V and S now. ================ Comment at: clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl:11-14 + float acc_c; + float reg_a; + float reg_b; + float reg_c; ---------------- These mostly aren't the right types? https://reviews.llvm.org/D77329 Files: clang/lib/Basic/Targets/AMDGPU.h clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl Index: clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl =================================================================== --- clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl +++ clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl @@ -1,8 +1,21 @@ // REQUIRES: amdgpu-registered-target -// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -O0 -o - -triple amdgcn %s | FileCheck %s kernel void test_long(int arg0) { long v15_16; - // CHECK: tail call i64 asm sideeffect "v_lshlrev_b64 v[15:16], 0, $0", "={v[15:16]},v"(i32 %arg0) + // CHECK: call i64 asm sideeffect "v_lshlrev_b64 v[15:16], 0, $0", "={v[15:16]},v" __asm volatile("v_lshlrev_b64 v[15:16], 0, %0" : "={v[15:16]}"(v15_16) : "v"(arg0)); } + +kernel void test_agpr() { + float acc_c; + float reg_a; + float reg_b; + float reg_c; + // CHECK: call float asm "v_mfma_f32_32x32x1f32 $0, $1, $2, $3", "=a,v,v,a" + __asm ("v_mfma_f32_32x32x1f32 %0, %1, %2, %3" : "=a"(acc_c) : "v"(reg_a), "v"(reg_b), "a"(acc_c)); + // CHECK: call float asm sideeffect "v_mfma_f32_32x32x1f32 a[0:31], $0, $1, a[0:31]", "={a[0:31]},v,v,{a[0:31]}" + __asm volatile("v_mfma_f32_32x32x1f32 a[0:31], %0, %1, a[0:31]" : "={a[0:31]}"(acc_c) : "v"(reg_a),"v"(reg_b), "{a[0:31]}"(acc_c)); + // CHECK: call float asm "v_accvgpr_read_b32 $0, $1", "={a1},{a1}" + __asm ("v_accvgpr_read_b32 %0, %1" : "={a1}"(reg_c) : "{a1}"(acc_c)); +} \ No newline at end of file Index: clang/lib/Basic/Targets/AMDGPU.h =================================================================== --- clang/lib/Basic/Targets/AMDGPU.h +++ clang/lib/Basic/Targets/AMDGPU.h @@ -114,11 +114,14 @@ /// Accepted register names: (n, m is unsigned integer, n < m) /// v /// s + /// a /// {vn}, {v[n]} /// {sn}, {s[n]} + /// {an}, {a[n]} /// {S} , where S is a special register name ////{v[n:m]} /// {s[n:m]} + /// {a[n:m]} bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override { static const ::llvm::StringSet<> SpecialRegs({ @@ -135,7 +138,7 @@ } if (S.empty()) return false; - if (S.front() != 'v' && S.front() != 's') { + if (S.front() != 'v' && S.front() != 's' && S.front() != 'a') { if (!HasLeftParen) return false; auto E = S.find('}'); @@ -153,7 +156,7 @@ if (!HasLeftParen) { if (!S.empty()) return false; - // Found s or v. + // Found s, v or a. Info.setAllowsRegister(); Name = S.data() - 1; return true; @@ -184,7 +187,8 @@ S = S.drop_front(); if (!S.empty()) return false; - // Found {vn}, {sn}, {v[n]}, {s[n]}, {v[n:m]}, or {s[n:m]}. + // Found {vn}, {sn}, {an}, {v[n]}, {s[n]}, {a[n]}, {v[n:m]}, {s[n:m]} + // or {a[n:m]}. Info.setAllowsRegister(); Name = S.data() - 1; return true; -------------- next part -------------- A non-text attachment was scrubbed... Name: D77329.254587.patch Type: text/x-patch Size: 2896 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 12:28:38 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 19:28:38 +0000 (UTC) Subject: [PATCH] D77329: [AMDGPU] Allow AGPR in inline asm In-Reply-To: References: Message-ID: <5418ea674eb37ab2aa14ae173113833b@localhost.localdomain> arsenm added inline comments. ================ Comment at: clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl:11-14 + float acc_c; + float reg_a; + float reg_b; + float reg_c; ---------------- These mostly aren't the right types? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77329/new/ https://reviews.llvm.org/D77329 From cfe-commits at lists.llvm.org Thu Apr 2 12:28:39 2020 From: cfe-commits at lists.llvm.org (Stanislav Mekhanoshin via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 19:28:39 +0000 (UTC) Subject: [PATCH] D77329: [AMDGPU] Allow AGPR in inline asm In-Reply-To: References: Message-ID: <89eb0a759e4860702b4f6db6d01e067f@localhost.localdomain> rampitec accepted this revision. rampitec added a comment. This revision is now accepted and ready to land. Thanks. Could you also update AMDGPUTargetInfo::GCCRegNames[] (in a separate change)? It is used in clobber constraints. JBTW, it does not support register tuples even for V and S now. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77329/new/ https://reviews.llvm.org/D77329 From cfe-commits at lists.llvm.org Thu Apr 2 12:28:40 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 19:28:40 +0000 (UTC) Subject: [PATCH] D59321: AMDGPU: Teach toolchain to link rocm device libs In-Reply-To: References: Message-ID: arsenm updated this revision to Diff 254591. arsenm added a comment. Correct group CHANGES SINCE LAST ACTION https://reviews.llvm.org/D59321/new/ https://reviews.llvm.org/D59321 Files: clang/include/clang/Basic/DiagnosticDriverKinds.td clang/include/clang/Driver/Options.td clang/lib/Driver/Driver.cpp clang/lib/Driver/ToolChains/AMDGPU.cpp clang/lib/Driver/ToolChains/AMDGPU.h clang/lib/Driver/ToolChains/HIP.cpp clang/lib/Driver/ToolChains/HIP.h clang/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl clang/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl clang/test/Driver/Inputs/rocm-device-libs/lib/hip.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/ockl.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_correctly_rounded_sqrt_off.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_correctly_rounded_sqrt_on.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_daz_opt_off.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_daz_opt_on.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_finite_only_off.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_finite_only_on.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_isa_version_1010.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_isa_version_1011.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_isa_version_1012.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_isa_version_803.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_isa_version_900.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_unsafe_math_off.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_unsafe_math_on.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_wavefrontsize64_off.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/oclc_wavefrontsize64_on.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/ocml.amdgcn.bc clang/test/Driver/Inputs/rocm-device-libs/lib/opencl.amdgcn.bc clang/test/Driver/amdgpu-visibility.cl clang/test/Driver/rocm-detect.cl clang/test/Driver/rocm-device-libs.cl clang/test/Driver/rocm-not-found.cl llvm/include/llvm/Support/TargetParser.h llvm/lib/Support/TargetParser.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D59321.254591.patch Type: text/x-patch Size: 33720 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 13:00:49 2020 From: cfe-commits at lists.llvm.org (Florian Hahn via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 20:00:49 +0000 (UTC) Subject: [PATCH] D76793: [Matrix] Implement + and - operators for MatrixType. In-Reply-To: References: Message-ID: <6208b6d768c682c42d0fe051d7b26c0f@localhost.localdomain> fhahn updated this revision to Diff 254598. fhahn added a comment. Implement conversions for matrix/scalar variants. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76793/new/ https://reviews.llvm.org/D76793 Files: clang/include/clang/Sema/Sema.h clang/lib/CodeGen/CGExprScalar.cpp clang/lib/Sema/SemaExpr.cpp clang/test/CodeGen/matrix-type-operators.c clang/test/CodeGenCXX/matrix-type-operators.cpp clang/test/Sema/matrix-type-operators.c clang/test/SemaCXX/matrix-type-operators.cpp llvm/include/llvm/IR/MatrixBuilder.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D76793.254598.patch Type: text/x-patch Size: 39922 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 13:00:51 2020 From: cfe-commits at lists.llvm.org (Florian Hahn via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 20:00:51 +0000 (UTC) Subject: [PATCH] D76794: [Matrix] Implement * binary operator for MatrixType. In-Reply-To: References: Message-ID: fhahn updated this revision to Diff 254601. fhahn added a comment. Implement conversion for matrix/scalar variants. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76794/new/ https://reviews.llvm.org/D76794 Files: clang/include/clang/Sema/Sema.h clang/lib/CodeGen/CGExprScalar.cpp clang/lib/Sema/SemaExpr.cpp clang/test/CodeGen/matrix-type-operators.c clang/test/CodeGenCXX/matrix-type-operators.cpp clang/test/Sema/matrix-type-operators.c clang/test/SemaCXX/matrix-type-operators.cpp llvm/include/llvm/IR/MatrixBuilder.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D76794.254601.patch Type: text/x-patch Size: 30003 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 13:00:52 2020 From: cfe-commits at lists.llvm.org (Florian Hahn via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 20:00:52 +0000 (UTC) Subject: [PATCH] D76794: [Matrix] Implement * binary operator for MatrixType. In-Reply-To: References: Message-ID: <97f74ebc7d5f5947136285bc0462253c@localhost.localdomain> fhahn updated this revision to Diff 254602. fhahn added a comment. clang-format Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76794/new/ https://reviews.llvm.org/D76794 Files: clang/include/clang/Sema/Sema.h clang/lib/CodeGen/CGExprScalar.cpp clang/lib/Sema/SemaExpr.cpp clang/test/CodeGen/matrix-type-operators.c clang/test/CodeGenCXX/matrix-type-operators.cpp clang/test/Sema/matrix-type-operators.c clang/test/SemaCXX/matrix-type-operators.cpp llvm/include/llvm/IR/MatrixBuilder.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D76794.254602.patch Type: text/x-patch Size: 30075 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 13:00:55 2020 From: cfe-commits at lists.llvm.org (Denys Petrov via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 20:00:55 +0000 (UTC) Subject: [PATCH] D77062: [analyzer] Added check for unaccaptable equality operation between Loc and NonLoc types In-Reply-To: References: Message-ID: <5ec75d6add534d4e5d595c13b05031cb@localhost.localdomain> ASDenysPetrov updated this revision to Diff 254605. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77062/new/ https://reviews.llvm.org/D77062 Files: clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp clang/test/Analysis/string.c Index: clang/test/Analysis/string.c =================================================================== --- clang/test/Analysis/string.c +++ clang/test/Analysis/string.c @@ -363,6 +363,14 @@ strcpy(x, y); // no-warning } +void *func_strcpy_no_assertion(); +char ***ptr_strcpy_no_assertion; +void strcpy_no_assertion() { + *(unsigned char **)ptr_strcpy_no_assertion = (unsigned char *)(func_strcpy_no_assertion()); + char c; + strcpy(**ptr_strcpy_no_assertion, &c); // no-assertion +} + //===----------------------------------------------------------------------=== // stpcpy() //===----------------------------------------------------------------------=== Index: clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -266,13 +266,16 @@ std::pair CStringChecker::assumeZero(CheckerContext &C, ProgramStateRef state, SVal V, QualType Ty) { + auto states = std::make_pair(state, state); + + // LazyCompoundVal cannot be handled by assume Optional val = V.getAs(); - if (!val) - return std::pair(state, state); + if (val && !V.getAs()) { + // return pair shall be {null, non-null} so reorder states + std::tie(states.second, states.first) = state->assume(*val); + } - SValBuilder &svalBuilder = C.getSValBuilder(); - DefinedOrUnknownSVal zero = svalBuilder.makeZeroVal(Ty); - return state->assume(svalBuilder.evalEQ(state, *val, zero)); + return states; } ProgramStateRef CStringChecker::checkNonNull(CheckerContext &C, -------------- next part -------------- A non-text attachment was scrubbed... Name: D77062.254605.patch Type: text/x-patch Size: 1796 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 13:12:37 2020 From: cfe-commits at lists.llvm.org (Nico Weber via cfe-commits) Date: Thu, 02 Apr 2020 13:12:37 -0700 (PDT) Subject: [clang] a16ba6f - Reland "Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang" Message-ID: <5e864735.1c69fb81.b3aa5.2e80@mx.google.com> Author: Nico Weber Date: 2020-04-02T16:12:03-04:00 New Revision: a16ba6fea2e554fae465dcaaca1d687d8e83a62e URL: https://github.com/llvm/llvm-project/commit/a16ba6fea2e554fae465dcaaca1d687d8e83a62e DIFF: https://github.com/llvm/llvm-project/commit/a16ba6fea2e554fae465dcaaca1d687d8e83a62e.diff LOG: Reland "Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang" The problem on Windows was that the \b in "..\bin" was interpreted as an escape sequence. Use r"" strings to prevent that. This reverts commit ab11b9eefa16661017c2c7b3b34c46b069f43fb7, with raw strings in the lit.site.cfg.py.in files. Differential Revision: https://reviews.llvm.org/D77184 Added: Modified: clang/test/CMakeLists.txt clang/test/Unit/lit.site.cfg.py.in clang/test/lit.site.cfg.py.in llvm/cmake/modules/AddLLVM.cmake llvm/test/CMakeLists.txt llvm/test/Unit/lit.site.cfg.py.in llvm/test/lit.site.cfg.py.in llvm/utils/gn/secondary/clang/test/BUILD.gn llvm/utils/gn/secondary/llvm/test/BUILD.gn Removed: ################################################################################ diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt index d453074d7926..ca326fea8066 100644 --- a/clang/test/CMakeLists.txt +++ b/clang/test/CMakeLists.txt @@ -35,6 +35,16 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py MAIN_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py + PATHS + "LLVM_SOURCE_DIR" + "LLVM_BINARY_DIR" + "LLVM_TOOLS_DIR" + "LLVM_LIBS_DIR" + "SHLIBDIR" + "LLVM_LIT_TOOLS_DIR" + "CLANG_BINARY_DIR" + "CLANG_SOURCE_DIR" + "CLANG_TOOLS_DIR" ) configure_lit_site_cfg( @@ -42,6 +52,13 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py MAIN_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py + PATHS + "LLVM_SOURCE_DIR" + "LLVM_BINARY_DIR" + "LLVM_TOOLS_DIR" + "LLVM_LIBS_DIR" + "CLANG_BINARY_DIR" + "SHLIBDIR" ) option(CLANG_TEST_USE_VG "Run Clang tests under Valgrind" OFF) diff --git a/clang/test/Unit/lit.site.cfg.py.in b/clang/test/Unit/lit.site.cfg.py.in index 715b4d93f58f..ad5e6d0c8b2a 100644 --- a/clang/test/Unit/lit.site.cfg.py.in +++ b/clang/test/Unit/lit.site.cfg.py.in @@ -2,14 +2,14 @@ import sys -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" -config.llvm_libs_dir = "@LLVM_LIBS_DIR@" +config.llvm_src_root = path(r"@LLVM_SOURCE_DIR@") +config.llvm_obj_root = path(r"@LLVM_BINARY_DIR@") +config.llvm_tools_dir = path(r"@LLVM_TOOLS_DIR@") +config.llvm_libs_dir = path(r"@LLVM_LIBS_DIR@") config.llvm_build_mode = "@LLVM_BUILD_MODE@" -config.clang_obj_root = "@CLANG_BINARY_DIR@" +config.clang_obj_root = path(r"@CLANG_BINARY_DIR@") config.enable_shared = @ENABLE_SHARED@ -config.shlibdir = "@SHLIBDIR@" +config.shlibdir = path(r"@SHLIBDIR@") config.target_triple = "@TARGET_TRIPLE@" # Support substitution of the tools_dir, libs_dirs, and build_mode with user @@ -25,4 +25,5 @@ except KeyError: lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) # Let the main config do the real work. -lit_config.load_config(config, "@CLANG_SOURCE_DIR@/test/Unit/lit.cfg.py") +lit_config.load_config( + config, os.path.join(path(r"@CLANG_SOURCE_DIR@"), "test/Unit/lit.cfg.py")) diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in index 62616d9a2b95..daec694bd128 100644 --- a/clang/test/lit.site.cfg.py.in +++ b/clang/test/lit.site.cfg.py.in @@ -2,16 +2,16 @@ import sys -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" -config.llvm_libs_dir = "@LLVM_LIBS_DIR@" -config.llvm_shlib_dir = "@SHLIBDIR@" +config.llvm_src_root = path(r"@LLVM_SOURCE_DIR@") +config.llvm_obj_root = path(r"@LLVM_BINARY_DIR@") +config.llvm_tools_dir = path(r"@LLVM_TOOLS_DIR@") +config.llvm_libs_dir = path(r"@LLVM_LIBS_DIR@") +config.llvm_shlib_dir = path(r"@SHLIBDIR@") config.llvm_plugin_ext = "@LLVM_PLUGIN_EXT@" -config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" -config.clang_obj_root = "@CLANG_BINARY_DIR@" -config.clang_src_dir = "@CLANG_SOURCE_DIR@" -config.clang_tools_dir = "@CLANG_TOOLS_DIR@" +config.lit_tools_dir = path(r"@LLVM_LIT_TOOLS_DIR@") +config.clang_obj_root = path(r"@CLANG_BINARY_DIR@") +config.clang_src_dir = path(r"@CLANG_SOURCE_DIR@") +config.clang_tools_dir = path(r"@CLANG_TOOLS_DIR@") config.host_triple = "@LLVM_HOST_TRIPLE@" config.target_triple = "@TARGET_TRIPLE@" config.host_cxx = "@CMAKE_CXX_COMPILER@" @@ -50,4 +50,5 @@ if not "@CLANG_DEFAULT_LINKER@": config.available_features.add('platform-linker') # Let the main config do the real work. -lit_config.load_config(config, "@CLANG_SOURCE_DIR@/test/lit.cfg.py") +lit_config.load_config( + config, os.path.join(config.clang_src_dir, "test/lit.cfg.py")) diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index 238aa3eab9f4..0732ca6ed0d0 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -1396,8 +1396,14 @@ endmacro() # variables needed for the 'lit.site.cfg' files. This function bundles the # common variables that any Lit instance is likely to need, and custom # variables can be passed in. +# The keyword PATHS is followed by a list of cmake variable names that are +# mentioned as `path("@varname@")` in the lit.cfg.py.in file. Variables in that +# list are treated as paths that are relative to the directory the generated +# lit.cfg.py file is in, and the `path()` function converts the relative +# path back to absolute form. This makes it possible to move a build directory +# containing lit.cfg.py files from one machine to another. function(configure_lit_site_cfg site_in site_out) - cmake_parse_arguments(ARG "" "" "MAIN_CONFIG;OUTPUT_MAPPING" ${ARGN}) + cmake_parse_arguments(ARG "" "" "MAIN_CONFIG;OUTPUT_MAPPING;PATHS" ${ARGN}) if ("${ARG_MAIN_CONFIG}" STREQUAL "") get_filename_component(INPUT_DIR ${site_in} DIRECTORY) @@ -1447,12 +1453,17 @@ function(configure_lit_site_cfg site_in site_out) set(HOST_CXX "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}") set(HOST_LDFLAGS "${CMAKE_EXE_LINKER_FLAGS}") - set(LIT_SITE_CFG_IN_HEADER "## Autogenerated from ${site_in}\n## Do not edit!") + set(LIT_SITE_CFG_IN_HEADER "# Autogenerated from ${site_in}\n# Do not edit!") + + string(CONCAT LIT_SITE_CFG_IN_HEADER "${LIT_SITE_CFG_IN_HEADER}\n\n" + "# Allow generated lit.site.cfg.py to be relocatable.\n" + "def path(p): return os.path.join(os.path.dirname(__file__), p) if p else ''\n" + ) # Override config_target_triple (and the env) if(LLVM_TARGET_TRIPLE_ENV) # This is expanded into the heading. - string(CONCAT LIT_SITE_CFG_IN_HEADER "${LIT_SITE_CFG_IN_HEADER}\n\n" + string(CONCAT LIT_SITE_CFG_IN_HEADER "${LIT_SITE_CFG_IN_HEADER}" "import os\n" "target_env = \"${LLVM_TARGET_TRIPLE_ENV}\"\n" "config.target_triple = config.environment[target_env] = os.environ.get(target_env, \"${TARGET_TRIPLE}\")\n" @@ -1462,7 +1473,45 @@ function(configure_lit_site_cfg site_in site_out) set(TARGET_TRIPLE "\"+config.target_triple+\"") endif() + if (ARG_PATHS) + # Walk ARG_PATHS and collect the current value of the variables in there. + foreach(path ${ARG_PATHS}) + list(APPEND ARG_PATH_VALUES "${${path}}") + endforeach() + + # Compute paths relative to the directory containing output lit.site.cfg.py. + # Passing ARG_PATH_VALUES as-is to execute_process() makes cmake strip + # empty list entries. So escape the ;s in the list and do the splitting + # outselves. cmake has no relpath function, so use Python for that. + string(REPLACE ";" "\\;" ARG_PATH_VALUES_ESCAPED "${ARG_PATH_VALUES}") + get_filename_component(OUTPUT_DIR ${site_out} DIRECTORY) + execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" + "import os, sys; sys.stdout.write(';'.join(os.path.relpath(p, sys.argv[1]) if p else '' for p in sys.argv[2].split(';')))" + ${OUTPUT_DIR} + ${ARG_PATH_VALUES_ESCAPED} + OUTPUT_VARIABLE ARG_PATH_VALUES_RELATIVE) + + list(LENGTH ARG_PATHS len_paths) + list(LENGTH ARG_PATH_VALUES len_path_values) + list(LENGTH ARG_PATH_VALUES_RELATIVE len_path_value_rels) + if ((NOT ${len_paths} EQUAL ${len_path_values}) OR + (NOT ${len_paths} EQUAL ${len_path_value_rels})) + message(SEND_ERROR "PATHS lengths got confused") + endif() + + # Transform variables mentioned in ARG_PATHS to relative paths for + # the configure_file() call. Variables are copied to subscopeds by cmake, + # so this only modifies the local copy of the variables. + math(EXPR arg_path_limit "${len_paths} - 1") + foreach(i RANGE ${arg_path_limit}) + list(GET ARG_PATHS ${i} val1) + list(GET ARG_PATH_VALUES_RELATIVE ${i} val2) + set(${val1} ${val2}) + endforeach() + endif() + configure_file(${site_in} ${site_out} @ONLY) + if (EXISTS "${ARG_MAIN_CONFIG}") set(PYTHON_STATEMENT "map_config('${ARG_MAIN_CONFIG}', '${site_out}')") get_property(LLVM_LIT_CONFIG_MAP GLOBAL PROPERTY LLVM_LIT_CONFIG_MAP) diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt index d1bc970f3643..330a35212883 100644 --- a/llvm/test/CMakeLists.txt +++ b/llvm/test/CMakeLists.txt @@ -22,12 +22,23 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py MAIN_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py + PATHS + "LLVM_SOURCE_DIR" + "LLVM_BINARY_DIR" + "LLVM_TOOLS_DIR" + "LLVM_LIBRARY_DIR" + "SHLIBDIR" ) configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.py.in ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg.py MAIN_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.cfg.py + PATHS + "LLVM_SOURCE_DIR" + "LLVM_BINARY_DIR" + "LLVM_TOOLS_DIR" + "SHLIBDIR" ) # Set the depends list as a variable so that it can grow conditionally. diff --git a/llvm/test/Unit/lit.site.cfg.py.in b/llvm/test/Unit/lit.site.cfg.py.in index 1fef001be627..f9fe421e2aa4 100644 --- a/llvm/test/Unit/lit.site.cfg.py.in +++ b/llvm/test/Unit/lit.site.cfg.py.in @@ -2,12 +2,12 @@ import sys -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" +config.llvm_src_root = path(r"@LLVM_SOURCE_DIR@") +config.llvm_obj_root = path(r"@LLVM_BINARY_DIR@") +config.llvm_tools_dir = path(r"@LLVM_TOOLS_DIR@") config.llvm_build_mode = "@LLVM_BUILD_MODE@" config.enable_shared = @ENABLE_SHARED@ -config.shlibdir = "@SHLIBDIR@" +config.shlibdir = path(r"@SHLIBDIR@") # Support substitution of the tools_dir and build_mode with user parameters. # This is used when we can't determine the tool dir at configuration time. @@ -20,4 +20,5 @@ except KeyError: lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key)) # Let the main config do the real work. -lit_config.load_config(config, "@LLVM_SOURCE_DIR@/test/Unit/lit.cfg.py") +lit_config.load_config( + config, os.path.join(config.llvm_src_root, "test/Unit/lit.cfg.py")) diff --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in index 6f4d5f790828..ee9e5941a39e 100644 --- a/llvm/test/lit.site.cfg.py.in +++ b/llvm/test/lit.site.cfg.py.in @@ -4,14 +4,14 @@ import sys config.host_triple = "@LLVM_HOST_TRIPLE@" config.target_triple = "@TARGET_TRIPLE@" -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" -config.llvm_lib_dir = "@LLVM_LIBRARY_DIR@" -config.llvm_shlib_dir = "@SHLIBDIR@" +config.llvm_src_root = path(r"@LLVM_SOURCE_DIR@") +config.llvm_obj_root = path(r"@LLVM_BINARY_DIR@") +config.llvm_tools_dir = path(r"@LLVM_TOOLS_DIR@") +config.llvm_lib_dir = path(r"@LLVM_LIBRARY_DIR@") +config.llvm_shlib_dir = path(r"@SHLIBDIR@") config.llvm_shlib_ext = "@SHLIBEXT@" config.llvm_exe_ext = "@EXEEXT@" -config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" +config.lit_tools_dir = path(r"@LLVM_LIT_TOOLS_DIR@") config.python_executable = "@PYTHON_EXECUTABLE@" config.gold_executable = "@GOLD_EXECUTABLE@" config.ld64_executable = "@LD64_EXECUTABLE@" @@ -63,4 +63,5 @@ import lit.llvm lit.llvm.initialize(lit_config, config) # Let the main config do the real work. -lit_config.load_config(config, "@LLVM_SOURCE_DIR@/test/lit.cfg.py") +lit_config.load_config( + config, os.path.join(config.llvm_src_root, "test/lit.cfg.py")) diff --git a/llvm/utils/gn/secondary/clang/test/BUILD.gn b/llvm/utils/gn/secondary/clang/test/BUILD.gn index 874891e89c81..84ac2e893cdf 100644 --- a/llvm/utils/gn/secondary/clang/test/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/test/BUILD.gn @@ -12,7 +12,10 @@ template("write_lit_config") { input = invoker.input output = invoker.output values = [ - "LIT_SITE_CFG_IN_HEADER=## Autogenerated from $input, do not edit", + # FIXME: Write relative paths for path()s. + "LIT_SITE_CFG_IN_HEADER=" + + "## Autogenerated from $input, do not edit\n\n" + + "def path(p): return p if p else \"\"", "CLANG_BINARY_DIR=" + rebase_path(get_label_info("//clang", "target_out_dir")), "CLANG_SOURCE_DIR=" + rebase_path("//clang"), diff --git a/llvm/utils/gn/secondary/llvm/test/BUILD.gn b/llvm/utils/gn/secondary/llvm/test/BUILD.gn index 0f7d90d1ab60..c7740ac4cc99 100644 --- a/llvm/utils/gn/secondary/llvm/test/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/test/BUILD.gn @@ -14,7 +14,10 @@ template("write_lit_config") { input = invoker.input output = invoker.output values = [ - "LIT_SITE_CFG_IN_HEADER=## Autogenerated from $input, do not edit", + # FIXME: Write relative paths for path()s. + "LIT_SITE_CFG_IN_HEADER=" + + "## Autogenerated from $input, do not edit\n\n" + + "def path(p): return p if p else \"\"", "ENABLE_SHARED=0", "LLVM_BINARY_DIR=" + rebase_path(get_label_info("//llvm", "target_out_dir")), From cfe-commits at lists.llvm.org Thu Apr 2 13:33:54 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 20:33:54 +0000 (UTC) Subject: [PATCH] D76184: [OpenMP][NFC] Remove the need to include `OpenMPClause.h` In-Reply-To: References: Message-ID: <75ab800065ceae61eeb07ed452777b2c@localhost.localdomain> rnk added a comment. In D76184#1956352 , @jdoerfert wrote: > @rnk What is the plan for this one now? Should I abandon it? Sorry, I got distracted. I tried reapplying it but it didn't apply cleanly. It's possible I hadn't locally applied your patch series correctly when I said it wasn't compiling. If you can get clang (and clangd and clang-tools-extra) to compile with your change, feel free to push. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76184/new/ https://reviews.llvm.org/D76184 From cfe-commits at lists.llvm.org Thu Apr 2 13:33:55 2020 From: cfe-commits at lists.llvm.org (Duncan P. N. Exon Smith via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 20:33:55 +0000 (UTC) Subject: [PATCH] D76594: [clang][AST] Support AST files larger than 512M In-Reply-To: References: Message-ID: dexonsmith resigned from this revision. dexonsmith added a reviewer: Bigcheese. dexonsmith added a subscriber: Bigcheese. dexonsmith added a comment. Herald added a subscriber: dexonsmith. In D76594#1957452 , @DmitryPolukhin wrote: > @rsmith, @dexonsmith, @jdoerfert could you please take a look to this diff? > If you think that there are other reviewers who might have more context AST persistence, please add them. @Bigcheese, can you take a look? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76594/new/ https://reviews.llvm.org/D76594 From cfe-commits at lists.llvm.org Thu Apr 2 13:33:55 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 20:33:55 +0000 (UTC) Subject: [PATCH] D77313: [AST] Allow VectorTypes of 1-256 elements, and powers of two up to 2**31. In-Reply-To: References: Message-ID: sammccall added a comment. In D77313#1957690 , @efriedma wrote: > I think I would rather just pay the extra 8 bytes per VectorType, and expand this to support all vector types supported by LLVM. It's not like we allocate enough VectorTypes for it to matter, anyway. llvm::VectorType seems to accept arbitrary `unsigned` size, so IIUC you'd suggest putting just putting `unsigned NumElements` in `VectorType`, which would cost 4 bytes and another 4 in padding. Sounds reasonable to me, I'll try that. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77313/new/ https://reviews.llvm.org/D77313 From cfe-commits at lists.llvm.org Thu Apr 2 13:33:59 2020 From: cfe-commits at lists.llvm.org (Andrew J Wock via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 20:33:59 +0000 (UTC) Subject: [PATCH] D76949: Replace subtract-from-zero float in version with fneg in PowerPC special fma compiler builtins In-Reply-To: References: Message-ID: ajwock updated this revision to Diff 254609. ajwock added a comment. Rebased for harbormaster. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76949/new/ https://reviews.llvm.org/D76949 Files: clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/builtins-ppc-fma.c Index: clang/test/CodeGen/builtins-ppc-fma.c =================================================================== --- /dev/null +++ clang/test/CodeGen/builtins-ppc-fma.c @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -triple powerpc64le-gnu-linux \ +// RUN: -target-feature +altivec -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck \ +// RUN: %s + +typedef __attribute__((vector_size(4 * sizeof(float)))) float vec_float; +typedef __attribute__((vector_size(2 * sizeof(double)))) double vec_double; + +volatile vec_double vd; +volatile vec_float vf; + +void test_fma(void) { + vf = __builtin_vsx_xvmaddasp(vf, vf, vf); + // CHECK: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) + + vd = __builtin_vsx_xvmaddadp(vd, vd, vd); + // CHECK: @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + + vf = __builtin_vsx_xvnmaddasp(vf, vf, vf); + // CHECK: [[RESULT:%[^ ]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK: fneg <4 x float> [[RESULT]] + + vd = __builtin_vsx_xvnmaddadp(vd, vd, vd); + // CHECK: [[RESULT:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK: fneg <2 x double> [[RESULT]] + + vf = __builtin_vsx_xvmsubasp(vf, vf, vf); + // CHECK: [[RESULT:%[^ ]+]] fneg <4 x float> %{{.*}} + // CHECK: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]]) + + vd = __builtin_vsx_xvmsubadp(vd, vd, vd); + // CHECK: fneg <2 x double> [[RESULT]] + // CHECK: [[RESULT:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + + vf = __builtin_vsx_xvnmsubasp(vf, vf, vf); + // CHECK: [[RESULT:%[^ ]+]] = fneg <4 x float> %{{.*}} + // CHECK: [[RESULT2:%[^ ]+]] = call <4 x float> @llvm.fma.v2f64(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]]) + // CHECK: fneg <4 x float> [[RESULT2]] + + vd = __builtin_vsx_xvnmsubadp(vd, vd, vd); + // CHECK: [[RESULT:%[^ ]+]] = fneg <2 x double> %{{.*}} + // CHECK: [[RESULT2:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT]]) + // CHECK: fneg <2 x double> [[RESULT2]] +} Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -13214,25 +13214,24 @@ Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *Z = EmitScalarExpr(E->getArg(2)); - Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); switch (BuiltinID) { case PPC::BI__builtin_vsx_xvmaddadp: case PPC::BI__builtin_vsx_xvmaddasp: return Builder.CreateCall(F, {X, Y, Z}); + case PPC::BI__builtin_vsx_xvnmaddadp: case PPC::BI__builtin_vsx_xvnmaddasp: - return Builder.CreateFSub(Zero, - Builder.CreateCall(F, {X, Y, Z}), "sub"); + return Builder.CreateFNeg(Builder.CreateCall(F, {X, Y, Z}), "neg"); + case PPC::BI__builtin_vsx_xvmsubadp: case PPC::BI__builtin_vsx_xvmsubasp: - return Builder.CreateCall(F, - {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); + return Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}); + case PPC::BI__builtin_vsx_xvnmsubadp: case PPC::BI__builtin_vsx_xvnmsubasp: - Value *FsubRes = - Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); - return Builder.CreateFSub(Zero, FsubRes, "sub"); + return Builder.CreateFNeg( + Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}), "neg"); } llvm_unreachable("Unknown FMA operation"); return nullptr; // Suppress no-return warning -------------- next part -------------- A non-text attachment was scrubbed... Name: D76949.254609.patch Type: text/x-patch Size: 3990 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 14:06:38 2020 From: cfe-commits at lists.llvm.org (Dennis van der Schagt via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 21:06:38 +0000 (UTC) Subject: [PATCH] D77334: [AVR] Remove duplicate specification of lib directory Message-ID: dennisschagt created this revision. dennisschagt added a reviewer: dylanmckay. Herald added subscribers: cfe-commits, Jim. Herald added a project: clang. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77334 Files: clang/lib/Driver/ToolChains/AVR.cpp Index: clang/lib/Driver/ToolChains/AVR.cpp =================================================================== --- clang/lib/Driver/ToolChains/AVR.cpp +++ clang/lib/Driver/ToolChains/AVR.cpp @@ -77,8 +77,6 @@ std::string GCCRoot = std::string(GCCInstallation.getInstallPath()); std::string LibcRoot = AVRLibcRoot.getValue(); - getFilePaths().push_back(LibcRoot + std::string("/lib/") + - std::string(*FamilyName)); getFilePaths().push_back(LibcRoot + std::string("/lib/") + std::string(*FamilyName)); getFilePaths().push_back(GCCRoot + std::string("/") + -------------- next part -------------- A non-text attachment was scrubbed... Name: D77334.254606.patch Type: text/x-patch Size: 666 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 14:06:40 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 21:06:40 +0000 (UTC) Subject: [PATCH] D77335: [AST] clang::VectorType supports any size (that fits in unsigned) Message-ID: sammccall created this revision. sammccall added reviewers: efriedma, hokein. Herald added a project: clang. Herald added a subscriber: cfe-commits. This matches llvm::VectorType. It moves the size from the type bitfield into VectorType, increasing size by 8 bytes (including padding of 4). This is OK as we don't expect to create terribly many of these types. c.f. D77313 which enables large power-of-two sizes without growing VectorType. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77335 Files: clang/include/clang/AST/Type.h clang/lib/AST/Type.cpp clang/lib/Sema/SemaType.cpp clang/test/Sema/types.c clang/test/SemaCXX/vector.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77335.254615.patch Type: text/x-patch Size: 8183 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 14:06:41 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 21:06:41 +0000 (UTC) Subject: [PATCH] D77313: [AST] Allow VectorTypes of 1-256 elements, and powers of two up to 2**31. In-Reply-To: References: Message-ID: sammccall added a comment. In D77313#1957970 , @sammccall wrote: > In D77313#1957690 , @efriedma wrote: > > > I think I would rather just pay the extra 8 bytes per VectorType, and expand this to support all vector types supported by LLVM. It's not like we allocate enough VectorTypes for it to matter, anyway. > > > Sounds reasonable to me, I'll try that. This alternative is in D77335 , which is much simpler. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77313/new/ https://reviews.llvm.org/D77313 From cfe-commits at lists.llvm.org Thu Apr 2 14:06:42 2020 From: cfe-commits at lists.llvm.org (Diogo N. Sampaio via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 21:06:42 +0000 (UTC) Subject: [PATCH] D77074: [FPEnv][AArch64] Platform-specific builtin constrained FP enablement In-Reply-To: References: Message-ID: dnsampaio added inline comments. ================ Comment at: clang/lib/CodeGen/CGBuiltin.cpp:8486-8492 + return Builder.CreateConstrainedFPCall( + F, + {EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2)), Ops[0]}); + } else { + Function *F = CGM.getIntrinsic(Intrinsic::fma, HalfTy); + // NEON intrinsic puts accumulator first, unlike the LLVM fma. + return Builder.CreateCall(F, {EmitScalarExpr(E->getArg(1)), ---------------- kpn wrote: > dnsampaio wrote: > > It seems that `Builder.CreateCall` and `Builder.CreateConstrainedFPCall` usually have the same arguments, except for the function F being or not part of "experimental_constrained_". > > Would it make sense to teach the `Builder` to select between creating a constrained or not call, depending if the function passed is constrained? > > > > I was thinking in something like this: > > ``` > > Function *F = CGM.getIntrinsic( Builder.getIsFPConstrained()? > > Intrinsic::experimental_constrained_fma : > > Intrinsic::fma, HalfTy); > > return Builder.CreateCallConstrainedFPIfRequired(F, .... > > ``` > > > In CGBuiltins.cpp we already have emitUnaryMaybeConstrainedFPBuiltin() plus Binary and Ternary. They work well for the pattern seen on other hosts. But they won't easily work for this ticket. > > How about a new function just below those three that will work well here? A emitCallMaybeConstrainedFPBuiltin() that takes two intrinsic IDs and chooses which one based on constrained FP would make for an even more compact use. The block of example code you put above would just turn into a single function call. Does that work for you? Sounds good to me. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77074/new/ https://reviews.llvm.org/D77074 From cfe-commits at lists.llvm.org Thu Apr 2 14:17:22 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via cfe-commits) Date: Thu, 02 Apr 2020 14:17:22 -0700 (PDT) Subject: [clang] ce2258c - clang/AMDGPU: Stop setting old denormal subtarget features Message-ID: <5e865662.1c69fb81.fa4d3.421a@mx.google.com> Author: Matt Arsenault Date: 2020-04-02T17:17:12-04:00 New Revision: ce2258c1cd5dc9cf20040d1b1e540d80250c1435 URL: https://github.com/llvm/llvm-project/commit/ce2258c1cd5dc9cf20040d1b1e540d80250c1435 DIFF: https://github.com/llvm/llvm-project/commit/ce2258c1cd5dc9cf20040d1b1e540d80250c1435.diff LOG: clang/AMDGPU: Stop setting old denormal subtarget features Added: Modified: clang/lib/Basic/Targets/AMDGPU.cpp clang/lib/Basic/Targets/AMDGPU.h clang/test/CodeGenCUDA/flush-denormals.cu clang/test/CodeGenOpenCL/amdgpu-features.cl Removed: ################################################################################ diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp index a34d3d8b4353..55d7c081ceac 100644 --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -233,28 +233,6 @@ bool AMDGPUTargetInfo::initFeatureMap( return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec); } -void AMDGPUTargetInfo::adjustTargetOptions(const CodeGenOptions &CGOpts, - TargetOptions &TargetOpts) const { - bool hasFP32Denormals = false; - bool hasFP64Denormals = false; - - for (auto &I : TargetOpts.FeaturesAsWritten) { - if (I == "+fp32-denormals" || I == "-fp32-denormals") - hasFP32Denormals = true; - if (I == "+fp64-fp16-denormals" || I == "-fp64-fp16-denormals") - hasFP64Denormals = true; - } - if (!hasFP32Denormals) - TargetOpts.Features.push_back( - (Twine(hasFastFMAF() && hasFullRateDenormalsF32() && - CGOpts.FP32DenormalMode.Output == llvm::DenormalMode::IEEE - ? '+' : '-') + Twine("fp32-denormals")) - .str()); - // Always do not flush fp64 or fp16 denorms. - if (!hasFP64Denormals && hasFP64()) - TargetOpts.Features.push_back("+fp64-fp16-denormals"); -} - void AMDGPUTargetInfo::fillValidCPUList( SmallVectorImpl &Values) const { if (isAMDGCN(getTriple())) diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h index ed6929214f6e..46ddc401fb6f 100644 --- a/clang/lib/Basic/Targets/AMDGPU.h +++ b/clang/lib/Basic/Targets/AMDGPU.h @@ -208,9 +208,6 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { StringRef CPU, const std::vector &FeatureVec) const override; - void adjustTargetOptions(const CodeGenOptions &CGOpts, - TargetOptions &TargetOpts) const override; - ArrayRef getTargetBuiltins() const override; void getTargetDefines(const LangOptions &Opts, diff --git a/clang/test/CodeGenCUDA/flush-denormals.cu b/clang/test/CodeGenCUDA/flush-denormals.cu index 8577fca92866..e5adb2aa6d25 100644 --- a/clang/test/CodeGenCUDA/flush-denormals.cu +++ b/clang/test/CodeGenCUDA/flush-denormals.cu @@ -1,26 +1,26 @@ // RUN: %clang_cc1 -fcuda-is-device \ // RUN: -triple nvptx-nvidia-cuda -emit-llvm -o - %s | \ -// RUN: FileCheck -check-prefix=NOFTZ %s +// RUN: FileCheck -check-prefixes=NOFTZ,PTXNOFTZ %s // RUN: %clang_cc1 -fcuda-is-device -fdenormal-fp-math-f32=ieee \ // RUN: -triple nvptx-nvidia-cuda -emit-llvm -o - %s | \ -// RUN: FileCheck -check-prefix=NOFTZ %s +// RUN: FileCheck -check-prefixes=NOFTZ,PTXNOFTZ %s // RUN: %clang_cc1 -fcuda-is-device -fdenormal-fp-math-f32=preserve-sign \ // RUN: -triple nvptx-nvidia-cuda -emit-llvm -o - %s | \ -// RUN: FileCheck -check-prefix=FTZ %s +// RUN: FileCheck -check-prefixes=FTZ,PTXFTZ %s // RUN: %clang_cc1 -fcuda-is-device -x hip \ // RUN: -triple amdgcn-amd-amdhsa -target-cpu gfx900 -emit-llvm -o - %s | \ -// RUN: FileCheck -check-prefix=AMDNOFTZ %s +// RUN: FileCheck -check-prefix=NOFTZ %s // RUN: %clang_cc1 -fcuda-is-device -x hip \ // RUN: -triple amdgcn-amd-amdhsa -target-cpu gfx900 -fdenormal-fp-math-f32=ieee -emit-llvm -o - %s | \ -// RUN: FileCheck -check-prefix=AMDNOFTZ %s +// RUN: FileCheck -check-prefix=NOFTZ %s // RUN: %clang_cc1 -fcuda-is-device -x hip -fdenormal-fp-math-f32=preserve-sign \ // RUN: -triple amdgcn-amd-amdhsa -target-cpu gfx900 -emit-llvm -o - %s | \ -// RUN: FileCheck -check-prefix=AMDFTZ %s +// RUN: FileCheck -check-prefix=FTZ %s #include "Inputs/cuda.h" @@ -29,10 +29,13 @@ // -fdenormal-fp-math-f32. Further, check that we reflect the presence or // absence of -fcuda-flush-denormals-to-zero in a module flag. -// AMDGCN targets always have +fp64-fp16-denormals. -// AMDGCN targets without fast FMAF (e.g. gfx803) always have +fp32-denormals. -// For AMDGCN target with fast FMAF (e.g. gfx900), it has +fp32-denormals -// by default and -fp32-denormals when there is option +// AMDGCN targets always have f64/f16 denormals enabled. +// +// AMDGCN targets without fast FMAF (e.g. gfx803) always have f32 denormal +// flushing by default. +// +// For AMDGCN target with fast FMAF (e.g. gfx900), it has ieee denormals by +// default and preserve-sign when there with the option // -fcuda-flush-denormals-to-zero. // CHECK-LABEL: define void @foo() #0 @@ -41,11 +44,8 @@ extern "C" __device__ void foo() {} // FTZ: attributes #0 = {{.*}} "denormal-fp-math-f32"="preserve-sign,preserve-sign" // NOFTZ-NOT: "denormal-fp-math-f32" -// AMDNOFTZ: attributes #0 = {{.*}}+fp32-denormals{{.*}}+fp64-fp16-denormals -// AMDFTZ: attributes #0 = {{.*}}+fp64-fp16-denormals{{.*}}-fp32-denormals - -// FTZ:!llvm.module.flags = !{{{.*}}[[MODFLAG:![0-9]+]]} -// FTZ:[[MODFLAG]] = !{i32 4, !"nvvm-reflect-ftz", i32 1} +// PTXFTZ:!llvm.module.flags = !{{{.*}}[[MODFLAG:![0-9]+]]} +// PTXFTZ:[[MODFLAG]] = !{i32 4, !"nvvm-reflect-ftz", i32 1} -// NOFTZ:!llvm.module.flags = !{{{.*}}[[MODFLAG:![0-9]+]]} -// NOFTZ:[[MODFLAG]] = !{i32 4, !"nvvm-reflect-ftz", i32 0} +// PTXNOFTZ:!llvm.module.flags = !{{{.*}}[[MODFLAG:![0-9]+]]} +// PTXNOFTZ:[[MODFLAG]] = !{i32 4, !"nvvm-reflect-ftz", i32 0} diff --git a/clang/test/CodeGenOpenCL/amdgpu-features.cl b/clang/test/CodeGenOpenCL/amdgpu-features.cl index b4ee2edc5443..7529a4d4abb1 100644 --- a/clang/test/CodeGenOpenCL/amdgpu-features.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-features.cl @@ -14,15 +14,15 @@ // RUN: %clang_cc1 -triple amdgcn -target-cpu gfx600 -S -emit-llvm -o - %s | FileCheck --check-prefix=GFX600 %s // RUN: %clang_cc1 -triple amdgcn -target-cpu gfx601 -S -emit-llvm -o - %s | FileCheck --check-prefix=GFX601 %s -// GFX904: "target-features"="+16-bit-insts,+ci-insts,+dpp,+flat-address-space,+fp32-denormals,+fp64-fp16-denormals,+gfx8-insts,+gfx9-insts,+s-memrealtime" -// GFX906: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dpp,+flat-address-space,+fp32-denormals,+fp64-fp16-denormals,+gfx8-insts,+gfx9-insts,+s-memrealtime" -// GFX908: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot3-insts,+dot4-insts,+dot5-insts,+dot6-insts,+dpp,+flat-address-space,+fp32-denormals,+fp64-fp16-denormals,+gfx8-insts,+gfx9-insts,+mai-insts,+s-memrealtime" -// GFX1010: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dpp,+flat-address-space,+fp32-denormals,+fp64-fp16-denormals,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime" -// GFX1011: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dpp,+flat-address-space,+fp32-denormals,+fp64-fp16-denormals,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime" -// GFX1012: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dpp,+flat-address-space,+fp32-denormals,+fp64-fp16-denormals,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime" -// GFX801: "target-features"="+16-bit-insts,+ci-insts,+dpp,+flat-address-space,+fp32-denormals,+fp64-fp16-denormals,+gfx8-insts,+s-memrealtime" -// GFX700: "target-features"="+ci-insts,+flat-address-space,+fp64-fp16-denormals,-fp32-denormals" -// GFX600: "target-features"="+fp64-fp16-denormals,-fp32-denormals" -// GFX601: "target-features"="+fp64-fp16-denormals,-fp32-denormals" +// GFX904: "target-features"="+16-bit-insts,+ci-insts,+dpp,+flat-address-space,+gfx8-insts,+gfx9-insts,+s-memrealtime" +// GFX906: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dpp,+flat-address-space,+gfx8-insts,+gfx9-insts,+s-memrealtime" +// GFX908: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot3-insts,+dot4-insts,+dot5-insts,+dot6-insts,+dpp,+flat-address-space,+gfx8-insts,+gfx9-insts,+mai-insts,+s-memrealtime" +// GFX1010: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dpp,+flat-address-space,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime" +// GFX1011: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dpp,+flat-address-space,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime" +// GFX1012: "target-features"="+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot2-insts,+dot5-insts,+dot6-insts,+dpp,+flat-address-space,+gfx10-insts,+gfx8-insts,+gfx9-insts,+s-memrealtime" +// GFX801: "target-features"="+16-bit-insts,+ci-insts,+dpp,+flat-address-space,+gfx8-insts,+s-memrealtime" +// GFX700: "target-features"="+ci-insts,+flat-address-space" +// GFX600-NOT: "target-features" +// GFX601-NOT: "target-features" kernel void test() {} From cfe-commits at lists.llvm.org Thu Apr 2 14:39:06 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 21:39:06 +0000 (UTC) Subject: [PATCH] D77234: clang/AMDGPU: Stop setting old denormal subtarget features In-Reply-To: References: Message-ID: <732fe19a12f38be9ede2478f4f1764b6@localhost.localdomain> arsenm closed this revision. arsenm added a comment. ce2258c1cd5dc9cf20040d1b1e540d80250c1435 CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77234/new/ https://reviews.llvm.org/D77234 From cfe-commits at lists.llvm.org Thu Apr 2 14:39:08 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 21:39:08 +0000 (UTC) Subject: [PATCH] D77329: [AMDGPU] Allow AGPR in inline asm In-Reply-To: References: Message-ID: <4f26eb00dad49fd9073476c5aa62db8a@localhost.localdomain> yaxunl updated this revision to Diff 254619. yaxunl added a comment. added agprs to GCCRegNames and fixed types in test CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77329/new/ https://reviews.llvm.org/D77329 Files: clang/lib/Basic/Targets/AMDGPU.cpp clang/lib/Basic/Targets/AMDGPU.h clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl -------------- next part -------------- A non-text attachment was scrubbed... Name: D77329.254619.patch Type: text/x-patch Size: 6135 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 14:39:09 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 21:39:09 +0000 (UTC) Subject: [PATCH] D77335: [AST] clang::VectorType supports any size (that fits in unsigned) In-Reply-To: References: Message-ID: <5e0869e41c39ef92515197e0f2d037fc@localhost.localdomain> efriedma added a comment. If you're going to add code to check for it, we might as well add testcases for ridiculous sizes, like `(__int128_t)1 << 100`. I think this makes sense. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77335/new/ https://reviews.llvm.org/D77335 From cfe-commits at lists.llvm.org Thu Apr 2 15:11:46 2020 From: cfe-commits at lists.llvm.org (Stanislav Mekhanoshin via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 22:11:46 +0000 (UTC) Subject: [PATCH] D77329: [AMDGPU] Allow AGPR in inline asm In-Reply-To: References: Message-ID: <375d22b446d84861981330421a188f40@localhost.localdomain> rampitec added inline comments. ================ Comment at: clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl:16 + float reg_b; + float reg_c; + // CHECK: call <32 x float> asm "v_mfma_f32_32x32x1f32 $0, $1, $2, $3", "=a,v,v,a,~{a0},~{a1},~{a2},~{a3},~{a4},~{a5},~{a6},~{a7},~{a8},~{a9},~{a10},~{a11},~{a12},~{a13},~{a14},~{a15},~{a16},~{a17},~{a18},~{a19},~{a20},~{a21},~{a22},~{a23},~{a24},~{a25},~{a26},~{a27},~{a28},~{a29},~{a30},~{a31}" ---------------- reg_c is also float32. ================ Comment at: clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl:36 +} \ No newline at end of file ---------------- New line. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77329/new/ https://reviews.llvm.org/D77329 From cfe-commits at lists.llvm.org Thu Apr 2 15:11:58 2020 From: cfe-commits at lists.llvm.org (Fady Ghanim via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 22:11:58 +0000 (UTC) Subject: [PATCH] D77112: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` In-Reply-To: References: Message-ID: <3eac03337aa721224fcb1e6ae1c6de8a@localhost.localdomain> fghanim accepted this revision. fghanim added a comment. This revision is now accepted and ready to land. OK, As I said a few days ago, I went over the patch, and I didn't see any functional changes. I am accepting this patch. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77112/new/ https://reviews.llvm.org/D77112 From cfe-commits at lists.llvm.org Thu Apr 2 16:17:50 2020 From: cfe-commits at lists.llvm.org (Alina Sbirlea via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 23:17:50 +0000 (UTC) Subject: [PATCH] D77341: [DomTree] Replace ChildrenGetter with GraphTraits over GraphDiff. Message-ID: asbirlea created this revision. asbirlea added reviewers: kuhar, dblaikie, NutshellySima. Herald added subscribers: cfe-commits, hiraditya. Herald added a project: clang. asbirlea added a comment. asbirlea added a parent revision: D77167: [GraphDiff] Extend GraphDiff to track a list of updates.. I sent this out to get some general feedback, but I'd like to be able to simplify the fact that this is replacing a `for` over `ChildrenGetter` with a `for` over `children(pair)`, plus 5 lines to set up the type and pair; one simplification is around getting the type inside `children` (`GraphDiffBBPair`) and another around having the BUI or not; for the latter I'm considering updating a few places such that BUI is never nullptr. This replaces the ChildrenGetter inside the DominatorTree with GraphTraits over a GraphDiff object, an object which encapsulated the view of the previous CFG. This also simplifies the extentions in clang which use DominatorTree, as GraphDiff also filters nullptrs. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77341 Files: clang/include/clang/Analysis/Analyses/Dominators.h llvm/include/llvm/IR/CFGDiff.h llvm/include/llvm/IR/Dominators.h llvm/include/llvm/Support/GenericDomTree.h llvm/include/llvm/Support/GenericDomTreeConstruction.h llvm/lib/IR/Dominators.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77341.254638.patch Type: text/x-patch Size: 24726 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 16:17:52 2020 From: cfe-commits at lists.llvm.org (Alina Sbirlea via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 23:17:52 +0000 (UTC) Subject: [PATCH] D77341: [DomTree] Replace ChildrenGetter with GraphTraits over GraphDiff. In-Reply-To: References: Message-ID: <2d7a8dfbfbf028a805421ada0e9f562e@localhost.localdomain> asbirlea added a comment. I sent this out to get some general feedback, but I'd like to be able to simplify the fact that this is replacing a `for` over `ChildrenGetter` with a `for` over `children(pair)`, plus 5 lines to set up the type and pair; one simplification is around getting the type inside `children` (`GraphDiffBBPair`) and another around having the BUI or not; for the latter I'm considering updating a few places such that BUI is never nullptr. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77341/new/ https://reviews.llvm.org/D77341 From cfe-commits at lists.llvm.org Thu Apr 2 16:17:55 2020 From: cfe-commits at lists.llvm.org (Luke Zarko via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 23:17:55 +0000 (UTC) Subject: [PATCH] D77342: Sema: check for null TInfo in ActOnBaseSpecifier Message-ID: zarko created this revision. zarko added a project: clang. Herald added a subscriber: cfe-commits. zarko added a reviewer: rsmith. In certain cases (particularly when some input files are missing), GetTypeFromParser will set TInfo to nullptr in ActOnBaseSpecifier. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77342 Files: clang/lib/Sema/SemaDeclCXX.cpp Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -2581,6 +2581,8 @@ TypeSourceInfo *TInfo = nullptr; GetTypeFromParser(basetype, &TInfo); + if (TInfo == nullptr) + return true; if (EllipsisLoc.isInvalid() && DiagnoseUnexpandedParameterPack(SpecifierRange.getBegin(), TInfo, -------------- next part -------------- A non-text attachment was scrubbed... Name: D77342.254637.patch Type: text/x-patch Size: 428 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 16:50:18 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 23:50:18 +0000 (UTC) Subject: [PATCH] D76083: [clang-tidy] Expand the list of functions in bugprone-unused-return-value In-Reply-To: References: Message-ID: sammccall added inline comments. ================ Comment at: clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp:98 + "::access;" + "::bind;" + "::connect;" ---------------- aaron.ballman wrote: > jranieri-grammatech wrote: > > alexfh wrote: > > > bind has a side effect and returns a success status. Thus, the result being unused isn't necessarily a bug. Same for `connect`. And probably for `setjmp` as well. > > In terms of bind, connect, and setjmp: while I personally would say that code not using the return value is bugprone, the data suggests that the vast majority of developers are using these functions in the intended manner and the false-positive rate should be low. > I think we have sufficient statistical data to suggest that these APIs should be on the list because the majority of programmers *do not* use them solely for side effects without using the return value, so my preference is to keep them in the list. I stumbled upon this review as we're considering turning this check on by default in clangd. There's a significant difference between unused std::async() (programmer misunderstood contract) and unused ::connect() (ignoring error conditions). The former is ~never noise, and the latter may be (e.g. in experimental or incomplete code). So there's some value in separating these two lists out either as an option or a separate named check (bugprone-unhandled-error?) I think we probably wouldn't enable this check by default if it includes the error-code functions. > the majority of programmers *do not* use them solely for side effects ...in popular, distributed software :-) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76083/new/ https://reviews.llvm.org/D76083 From cfe-commits at lists.llvm.org Thu Apr 2 16:50:20 2020 From: cfe-commits at lists.llvm.org (David Blaikie via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 23:50:20 +0000 (UTC) Subject: [PATCH] D77341: [DomTree] Replace ChildrenGetter with GraphTraits over GraphDiff. In-Reply-To: References: Message-ID: dblaikie added a comment. Couple of small nits, but I'll leave most of the review to someoen else here - I /think/ it's beyond my context/experience (but if necessary, poke me and I can look more/ask more questions/etc) ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:324-325 + const GraphDiffT *GDTmp = BUI ? BUI->PreViewOfCFG : &EmptyGD; + std::pair GDNodePair = + std::make_pair(GDTmp, N); + for (auto &Pair : children(GDNodePair)) { ---------------- No need for make_pair if you're going to specify the types on the LHS, could write this as: ``` std::pair<...> GDNodePair(GDTmp, N); ``` (similarly two instances further down in this patch - make_pair or explicit type, not both) Or you could use auto on the LHS given the types of the two parameters seem close enough that it's not too surprising what make_pair produces, maybe even just roll it all in together: ``` return !empty(children(std::make_pair(GDTmp, N))); ``` ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:326-330 + for (auto &Pair : children(GDNodePair)) { + (void)Pair; + return true; + } + return false; ---------------- Probably write this as (if I'm understanding the code/intent correctly): ``` return !empty(children(GDNodePair)); ``` Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77341/new/ https://reviews.llvm.org/D77341 From cfe-commits at lists.llvm.org Thu Apr 2 16:50:22 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 23:50:22 +0000 (UTC) Subject: [PATCH] D77348: [clangd] Enable some nice clang-tidy checks by default. Message-ID: sammccall created this revision. sammccall added a reviewer: hokein. Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay, ilya-biryukov. Herald added a project: clang. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77348 Files: clang-tools-extra/clang-tidy/ClangTidyOptions.cpp clang-tools-extra/clangd/tool/ClangdMain.cpp Index: clang-tools-extra/clangd/tool/ClangdMain.cpp =================================================================== --- clang-tools-extra/clangd/tool/ClangdMain.cpp +++ clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -691,18 +691,42 @@ std::unique_ptr ClangTidyOptProvider; /*GUARDED_BY(ClangTidyOptMu)*/ if (EnableClangTidy) { - auto OverrideClangTidyOptions = tidy::ClangTidyOptions::getDefaults(); - OverrideClangTidyOptions.Checks = ClangTidyChecks; + auto EmptyDefaults = tidy::ClangTidyOptions::getDefaults(); + EmptyDefaults.Checks.reset(); // So we can tell if checks were ever set. + tidy::ClangTidyOptions OverrideClangTidyOptions; + if (!ClangTidyChecks.empty()) + OverrideClangTidyOptions.Checks = ClangTidyChecks; ClangTidyOptProvider = std::make_unique( tidy::ClangTidyGlobalOptions(), - /* Default */ tidy::ClangTidyOptions::getDefaults(), + /* Default */ EmptyDefaults, /* Override */ OverrideClangTidyOptions, FSProvider.getFileSystem()); Opts.GetClangTidyOptions = [&](llvm::vfs::FileSystem &, llvm::StringRef File) { // This function must be thread-safe and tidy option providers are not. - std::lock_guard Lock(ClangTidyOptMu); - // FIXME: use the FS provided to the function. - return ClangTidyOptProvider->getOptions(File); + tidy::ClangTidyOptions Opts; + { + std::lock_guard Lock(ClangTidyOptMu); + // FIXME: use the FS provided to the function. + Opts = ClangTidyOptProvider->getOptions(File); + } + if (!Opts.Checks) { + // If the user hasn't configured clang-tidy checks at all, including + // via .clang-tidy, give them a nice set of checks. + // (This should be what the "default" options does, but it isn't...) + // + // These default checks are chosen for: + // - low false-positive rate + // - providing a lot of value + // - being reasonably efficient + Opts.Checks = llvm::join_items( + ",", "readability-misleading-indentation", + "readability-deleted-default", "bugprone-integer-division", + "bugprone-sizeof-expression", "bugprone-suspicious-include", + "bugprone-suspicious-missing-comma", "bugprone-unused-raii", + "bugprone-unused-return-value", "misc-unused-using-decls", + "misc-unused-alias-decls", "misc-definitions-in-headers"); + } + return Opts; }; } Opts.SuggestMissingIncludes = SuggestMissingIncludes; Index: clang-tools-extra/clang-tidy/ClangTidyOptions.cpp =================================================================== --- clang-tools-extra/clang-tidy/ClangTidyOptions.cpp +++ clang-tools-extra/clang-tidy/ClangTidyOptions.cpp @@ -142,6 +142,9 @@ ClangTidyOptions::mergeWith(const ClangTidyOptions &Other) const { ClangTidyOptions Result = *this; + llvm::errs() << "merging " << bool(Other.Checks) << "\n"; + if (Other.Checks) + llvm::errs() << "value: " << *Other.Checks << "\n"; mergeCommaSeparatedLists(Result.Checks, Other.Checks); mergeCommaSeparatedLists(Result.WarningsAsErrors, Other.WarningsAsErrors); overrideValue(Result.HeaderFilterRegex, Other.HeaderFilterRegex); @@ -168,8 +171,10 @@ ClangTidyOptions ClangTidyOptionsProvider::getOptions(llvm::StringRef FileName) { ClangTidyOptions Result; - for (const auto &Source : getRawOptions(FileName)) + for (const auto &Source : getRawOptions(FileName)) { + llvm::errs() << Source.second << "\n"; Result = Result.mergeWith(Source.first); + } return Result; } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77348.254644.patch Type: text/x-patch Size: 3733 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 16:50:26 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Thu, 02 Apr 2020 23:50:26 +0000 (UTC) Subject: [PATCH] D77335: [AST] clang::VectorType supports any size (that fits in unsigned) In-Reply-To: References: Message-ID: sammccall updated this revision to Diff 254646. sammccall added a comment. Add 1<<100 testcase, and clang-format Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77335/new/ https://reviews.llvm.org/D77335 Files: clang/include/clang/AST/Type.h clang/lib/AST/Type.cpp clang/lib/Sema/SemaType.cpp clang/test/Sema/types.c clang/test/SemaCXX/vector.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77335.254646.patch Type: text/x-patch Size: 8442 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 17:01:30 2020 From: cfe-commits at lists.llvm.org (Nico Weber via cfe-commits) Date: Thu, 02 Apr 2020 17:01:30 -0700 (PDT) Subject: [clang] e875ba1 - Try again to get tests passing again on Windows. Message-ID: <5e867cda.1c69fb81.60a83.4e66@mx.google.com> Author: Nico Weber Date: 2020-04-02T20:00:38-04:00 New Revision: e875ba1509955dc4b3512d820edecc0da26fa38d URL: https://github.com/llvm/llvm-project/commit/e875ba1509955dc4b3512d820edecc0da26fa38d DIFF: https://github.com/llvm/llvm-project/commit/e875ba1509955dc4b3512d820edecc0da26fa38d.diff LOG: Try again to get tests passing again on Windows. Things pass locally, but some tests on some bots are still unhappy. I'm not sure why. See if using forward slashes as before helps. Added: Modified: clang/test/Unit/lit.site.cfg.py.in clang/test/lit.site.cfg.py.in llvm/cmake/modules/AddLLVM.cmake llvm/test/Unit/lit.site.cfg.py.in llvm/test/lit.site.cfg.py.in Removed: ################################################################################ diff --git a/clang/test/Unit/lit.site.cfg.py.in b/clang/test/Unit/lit.site.cfg.py.in index ad5e6d0c8b2a..400a9c05e58c 100644 --- a/clang/test/Unit/lit.site.cfg.py.in +++ b/clang/test/Unit/lit.site.cfg.py.in @@ -2,14 +2,14 @@ import sys -config.llvm_src_root = path(r"@LLVM_SOURCE_DIR@") -config.llvm_obj_root = path(r"@LLVM_BINARY_DIR@") -config.llvm_tools_dir = path(r"@LLVM_TOOLS_DIR@") -config.llvm_libs_dir = path(r"@LLVM_LIBS_DIR@") +config.llvm_src_root = path("@LLVM_SOURCE_DIR@") +config.llvm_obj_root = path("@LLVM_BINARY_DIR@") +config.llvm_tools_dir = path("@LLVM_TOOLS_DIR@") +config.llvm_libs_dir = path("@LLVM_LIBS_DIR@") config.llvm_build_mode = "@LLVM_BUILD_MODE@" -config.clang_obj_root = path(r"@CLANG_BINARY_DIR@") +config.clang_obj_root = path("@CLANG_BINARY_DIR@") config.enable_shared = @ENABLE_SHARED@ -config.shlibdir = path(r"@SHLIBDIR@") +config.shlibdir = path("@SHLIBDIR@") config.target_triple = "@TARGET_TRIPLE@" # Support substitution of the tools_dir, libs_dirs, and build_mode with user @@ -26,4 +26,4 @@ except KeyError: # Let the main config do the real work. lit_config.load_config( - config, os.path.join(path(r"@CLANG_SOURCE_DIR@"), "test/Unit/lit.cfg.py")) + config, os.path.join(path("@CLANG_SOURCE_DIR@"), "test/Unit/lit.cfg.py")) diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in index daec694bd128..84dd0f8846cf 100644 --- a/clang/test/lit.site.cfg.py.in +++ b/clang/test/lit.site.cfg.py.in @@ -2,16 +2,16 @@ import sys -config.llvm_src_root = path(r"@LLVM_SOURCE_DIR@") -config.llvm_obj_root = path(r"@LLVM_BINARY_DIR@") -config.llvm_tools_dir = path(r"@LLVM_TOOLS_DIR@") -config.llvm_libs_dir = path(r"@LLVM_LIBS_DIR@") -config.llvm_shlib_dir = path(r"@SHLIBDIR@") +config.llvm_src_root = path("@LLVM_SOURCE_DIR@") +config.llvm_obj_root = path("@LLVM_BINARY_DIR@") +config.llvm_tools_dir = path("@LLVM_TOOLS_DIR@") +config.llvm_libs_dir = path("@LLVM_LIBS_DIR@") +config.llvm_shlib_dir = path("@SHLIBDIR@") config.llvm_plugin_ext = "@LLVM_PLUGIN_EXT@" -config.lit_tools_dir = path(r"@LLVM_LIT_TOOLS_DIR@") -config.clang_obj_root = path(r"@CLANG_BINARY_DIR@") -config.clang_src_dir = path(r"@CLANG_SOURCE_DIR@") -config.clang_tools_dir = path(r"@CLANG_TOOLS_DIR@") +config.lit_tools_dir = path("@LLVM_LIT_TOOLS_DIR@") +config.clang_obj_root = path("@CLANG_BINARY_DIR@") +config.clang_src_dir = path("@CLANG_SOURCE_DIR@") +config.clang_tools_dir = path("@CLANG_TOOLS_DIR@") config.host_triple = "@LLVM_HOST_TRIPLE@" config.target_triple = "@TARGET_TRIPLE@" config.host_cxx = "@CMAKE_CXX_COMPILER@" diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index 0732ca6ed0d0..a474071e9edb 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -1486,7 +1486,7 @@ function(configure_lit_site_cfg site_in site_out) string(REPLACE ";" "\\;" ARG_PATH_VALUES_ESCAPED "${ARG_PATH_VALUES}") get_filename_component(OUTPUT_DIR ${site_out} DIRECTORY) execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" - "import os, sys; sys.stdout.write(';'.join(os.path.relpath(p, sys.argv[1]) if p else '' for p in sys.argv[2].split(';')))" + "import os, sys; sys.stdout.write(';'.join(os.path.relpath(p, sys.argv[1]).replace('\\\\', '/') if p else '' for p in sys.argv[2].split(';')))" ${OUTPUT_DIR} ${ARG_PATH_VALUES_ESCAPED} OUTPUT_VARIABLE ARG_PATH_VALUES_RELATIVE) diff --git a/llvm/test/Unit/lit.site.cfg.py.in b/llvm/test/Unit/lit.site.cfg.py.in index f9fe421e2aa4..3358ccf89eed 100644 --- a/llvm/test/Unit/lit.site.cfg.py.in +++ b/llvm/test/Unit/lit.site.cfg.py.in @@ -2,12 +2,12 @@ import sys -config.llvm_src_root = path(r"@LLVM_SOURCE_DIR@") -config.llvm_obj_root = path(r"@LLVM_BINARY_DIR@") -config.llvm_tools_dir = path(r"@LLVM_TOOLS_DIR@") +config.llvm_src_root = path("@LLVM_SOURCE_DIR@") +config.llvm_obj_root = path("@LLVM_BINARY_DIR@") +config.llvm_tools_dir = path("@LLVM_TOOLS_DIR@") config.llvm_build_mode = "@LLVM_BUILD_MODE@" config.enable_shared = @ENABLE_SHARED@ -config.shlibdir = path(r"@SHLIBDIR@") +config.shlibdir = path("@SHLIBDIR@") # Support substitution of the tools_dir and build_mode with user parameters. # This is used when we can't determine the tool dir at configuration time. diff --git a/llvm/test/lit.site.cfg.py.in b/llvm/test/lit.site.cfg.py.in index ee9e5941a39e..2af0ec336089 100644 --- a/llvm/test/lit.site.cfg.py.in +++ b/llvm/test/lit.site.cfg.py.in @@ -4,14 +4,14 @@ import sys config.host_triple = "@LLVM_HOST_TRIPLE@" config.target_triple = "@TARGET_TRIPLE@" -config.llvm_src_root = path(r"@LLVM_SOURCE_DIR@") -config.llvm_obj_root = path(r"@LLVM_BINARY_DIR@") -config.llvm_tools_dir = path(r"@LLVM_TOOLS_DIR@") -config.llvm_lib_dir = path(r"@LLVM_LIBRARY_DIR@") -config.llvm_shlib_dir = path(r"@SHLIBDIR@") +config.llvm_src_root = path("@LLVM_SOURCE_DIR@") +config.llvm_obj_root = path("@LLVM_BINARY_DIR@") +config.llvm_tools_dir = path("@LLVM_TOOLS_DIR@") +config.llvm_lib_dir = path("@LLVM_LIBRARY_DIR@") +config.llvm_shlib_dir = path("@SHLIBDIR@") config.llvm_shlib_ext = "@SHLIBEXT@" config.llvm_exe_ext = "@EXEEXT@" -config.lit_tools_dir = path(r"@LLVM_LIT_TOOLS_DIR@") +config.lit_tools_dir = path("@LLVM_LIT_TOOLS_DIR@") config.python_executable = "@PYTHON_EXECUTABLE@" config.gold_executable = "@GOLD_EXECUTABLE@" config.ld64_executable = "@LD64_EXECUTABLE@" From cfe-commits at lists.llvm.org Thu Apr 2 17:22:32 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 00:22:32 +0000 (UTC) Subject: [PATCH] D77335: [AST] clang::VectorType supports any size (that fits in unsigned) In-Reply-To: References: Message-ID: <367051476d5dd396a3aa68fb97d8f3e3@localhost.localdomain> sammccall added a comment. In D77335#1958106 , @efriedma wrote: > If you're going to add code to check for it, we might as well add testcases for ridiculous sizes, like `(__int128_t)1 << 100`. Done. Looks like this was previously an assertion failure. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77335/new/ https://reviews.llvm.org/D77335 From cfe-commits at lists.llvm.org Thu Apr 2 17:22:33 2020 From: cfe-commits at lists.llvm.org (Fangrui Song via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 00:22:33 +0000 (UTC) Subject: [PATCH] D77342: Sema: check for null TInfo in ActOnBaseSpecifier In-Reply-To: References: Message-ID: MaskRay added a comment. This needs a reduced test case to demonstrate the problem and ensure clang will not regress in the future. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77342/new/ https://reviews.llvm.org/D77342 From cfe-commits at lists.llvm.org Thu Apr 2 17:22:34 2020 From: cfe-commits at lists.llvm.org (Richard Smith - zygoloid via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 00:22:34 +0000 (UTC) Subject: [PATCH] D77246: Instead of scream, why not roll? In-Reply-To: References: Message-ID: <1c89a22f2a51e6eab8f069a831065db2@localhost.localdomain> rsmith requested changes to this revision. rsmith added a comment. This revision now requires changes to proceed. I'm sorry, but I can't accept this patch as-is because it removes the `u` suffix from the literal. We're never gonna give `u` up. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77246/new/ https://reviews.llvm.org/D77246 From cfe-commits at lists.llvm.org Thu Apr 2 17:22:35 2020 From: cfe-commits at lists.llvm.org (Zola Bridges via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 00:22:35 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: <17d801a02386cf86e9c404b8de9b210b@localhost.localdomain> zbrid accepted this revision. zbrid added a subscriber: jyknight. zbrid added a comment. This revision is now accepted and ready to land. LGTM. I would prefer if an actual LLVM maintainer also gave LGTM. @jyknight, @george.burgess.iv, @craig.topper? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 From cfe-commits at lists.llvm.org Thu Apr 2 17:22:35 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 00:22:35 +0000 (UTC) Subject: [PATCH] D77348: [clangd] Enable some nice clang-tidy checks by default. In-Reply-To: References: Message-ID: <00aacb465f101f02b69942eb4da8a7e4@localhost.localdomain> sammccall updated this revision to Diff 254650. sammccall added a comment. revert debugging noise Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77348/new/ https://reviews.llvm.org/D77348 Files: clang-tools-extra/clangd/tool/ClangdMain.cpp Index: clang-tools-extra/clangd/tool/ClangdMain.cpp =================================================================== --- clang-tools-extra/clangd/tool/ClangdMain.cpp +++ clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -691,18 +691,42 @@ std::unique_ptr ClangTidyOptProvider; /*GUARDED_BY(ClangTidyOptMu)*/ if (EnableClangTidy) { - auto OverrideClangTidyOptions = tidy::ClangTidyOptions::getDefaults(); - OverrideClangTidyOptions.Checks = ClangTidyChecks; + auto EmptyDefaults = tidy::ClangTidyOptions::getDefaults(); + EmptyDefaults.Checks.reset(); // So we can tell if checks were ever set. + tidy::ClangTidyOptions OverrideClangTidyOptions; + if (!ClangTidyChecks.empty()) + OverrideClangTidyOptions.Checks = ClangTidyChecks; ClangTidyOptProvider = std::make_unique( tidy::ClangTidyGlobalOptions(), - /* Default */ tidy::ClangTidyOptions::getDefaults(), + /* Default */ EmptyDefaults, /* Override */ OverrideClangTidyOptions, FSProvider.getFileSystem()); Opts.GetClangTidyOptions = [&](llvm::vfs::FileSystem &, llvm::StringRef File) { // This function must be thread-safe and tidy option providers are not. - std::lock_guard Lock(ClangTidyOptMu); - // FIXME: use the FS provided to the function. - return ClangTidyOptProvider->getOptions(File); + tidy::ClangTidyOptions Opts; + { + std::lock_guard Lock(ClangTidyOptMu); + // FIXME: use the FS provided to the function. + Opts = ClangTidyOptProvider->getOptions(File); + } + if (!Opts.Checks) { + // If the user hasn't configured clang-tidy checks at all, including + // via .clang-tidy, give them a nice set of checks. + // (This should be what the "default" options does, but it isn't...) + // + // These default checks are chosen for: + // - low false-positive rate + // - providing a lot of value + // - being reasonably efficient + Opts.Checks = llvm::join_items( + ",", "readability-misleading-indentation", + "readability-deleted-default", "bugprone-integer-division", + "bugprone-sizeof-expression", "bugprone-suspicious-include", + "bugprone-suspicious-missing-comma", "bugprone-unused-raii", + "bugprone-unused-return-value", "misc-unused-using-decls", + "misc-unused-alias-decls", "misc-definitions-in-headers"); + } + return Opts; }; } Opts.SuggestMissingIncludes = SuggestMissingIncludes; -------------- next part -------------- A non-text attachment was scrubbed... Name: D77348.254650.patch Type: text/x-patch Size: 2669 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 17:55:29 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 00:55:29 +0000 (UTC) Subject: [PATCH] D77335: [AST] clang::VectorType supports any size (that fits in unsigned) In-Reply-To: References: Message-ID: <5b97d87093bf63121b3188f8ae521a5c@localhost.localdomain> efriedma accepted this revision. efriedma added a comment. This revision is now accepted and ready to land. LGTM Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77335/new/ https://reviews.llvm.org/D77335 From cfe-commits at lists.llvm.org Thu Apr 2 18:27:19 2020 From: cfe-commits at lists.llvm.org (Richard Smith - zygoloid via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 01:27:19 +0000 (UTC) Subject: [PATCH] D77342: Sema: check for null TInfo in ActOnBaseSpecifier In-Reply-To: References: Message-ID: <1e05bd44abdeeb7d17a271ec7c1bcead@localhost.localdomain> rsmith added a comment. I think the problem this aims to address was fixed by rG330873230071ffc2aebc0fe74db55e7a530c2f1b . Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77342/new/ https://reviews.llvm.org/D77342 From cfe-commits at lists.llvm.org Thu Apr 2 18:27:24 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 01:27:24 +0000 (UTC) Subject: [PATCH] D77355: [clangd] show layout info when hovering on a class/field definition. Message-ID: sammccall created this revision. sammccall added a reviewer: kadircet. Herald added subscribers: cfe-commits, usaxena95, arphaman, jkorous, MaskRay, ilya-biryukov. Herald added a project: clang. This triggers only on the definition itself, not on references (probably too noisy). Inspecting the definition seems like a decent hint for being interested in layout. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77355 Files: clang-tools-extra/clangd/Hover.cpp clang-tools-extra/clangd/Hover.h clang-tools-extra/clangd/unittests/HoverTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77355.254663.patch Type: text/x-patch Size: 5046 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 18:27:26 2020 From: cfe-commits at lists.llvm.org (Manoj Gupta via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 01:27:26 +0000 (UTC) Subject: [PATCH] D71082: Allow system header to provide their own implementation of some builtin In-Reply-To: References: Message-ID: <8f1f6f3560d4a1acdf05517ccf3d06a6@localhost.localdomain> manojgupta added a comment. Yes, it'd be nice if all of the FORTIFY handling can be improved. For a simple call like memcpy of 8 bytes in the example, there is no reason to emit all these stack/range checks since they'd degrade memcpy performance. I still think this change should be reverted if it can't handle Linux kernel's FORTIFY implementation. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71082/new/ https://reviews.llvm.org/D71082 From cfe-commits at lists.llvm.org Thu Apr 2 18:27:35 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 01:27:35 +0000 (UTC) Subject: [PATCH] D77329: [AMDGPU] Allow AGPR in inline asm In-Reply-To: References: Message-ID: yaxunl updated this revision to Diff 254668. yaxunl added a comment. fix test CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77329/new/ https://reviews.llvm.org/D77329 Files: clang/lib/Basic/Targets/AMDGPU.cpp clang/lib/Basic/Targets/AMDGPU.h clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl -------------- next part -------------- A non-text attachment was scrubbed... Name: D77329.254668.patch Type: text/x-patch Size: 6109 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 18:45:02 2020 From: cfe-commits at lists.llvm.org (Brian Gesiak via cfe-commits) Date: Thu, 02 Apr 2020 18:45:02 -0700 (PDT) Subject: [clang] 627e01f - [coroutines] Don't build promise init with no args Message-ID: <5e86951e.1c69fb81.76221.60ea@mx.google.com> Author: Brian Gesiak Date: 2020-04-02T21:44:54-04:00 New Revision: 627e01feb718dd1aa8e184545976b7229de312a2 URL: https://github.com/llvm/llvm-project/commit/627e01feb718dd1aa8e184545976b7229de312a2 DIFF: https://github.com/llvm/llvm-project/commit/627e01feb718dd1aa8e184545976b7229de312a2.diff LOG: [coroutines] Don't build promise init with no args Summary: In the case of a coroutine that takes no arguments, `Sema::buildCoroutinePromise` constructs a list-initialization (`clang::InitializationKind::InitKind::IK_DirectList`) of the promise variable, using a list of empty arguments. So, if one were to dump the promise `VarDecl` immediately after `Sema::ActOnCoroutineBodyStart` calls `checkCoroutineContext`, for a coroutine function that takes no arguments, they'd see the following: ``` VarDecl 0xb514490 col:3 __promise '' callinit `-ParenListExpr 0xb514510 'NULL TYPE' ``` But after this patch, the `ParenListExpr` is no longer constructed, and the promise variable uses default initialization (`clang::InitializationKind::InitKind::IK_Default`): ``` VarDecl 0x63100012dae0 col:3 __promise '' ``` As far as I know, there's no case in which list-initialization with no arguments differs from default initialization, but if I'm wrong please let me know (and I'll add a test case that demonstrates the change -- but as-is I can't think of a functional test case for this). I think both comply with the wording of C++20 `[dcl.fct.def.coroutine]p5`: > _promise-constructor-arguments_ is determined as follows: overload resolution is performed on a promise constructor call created by assembling an argument list with lvalues `p1 ... pn`. If a viable constructor is found (12.4.2), then _promise-constructor-arguments_ is `(p1, ... , pn)`, otherwise _promise-constructor-arguments_ is empty. Still, I think this patch is an improvement regardless, because it reduces the size of the AST. Reviewers: GorNishanov, rsmith, lewissbaker Subscribers: EricWF, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D70555 Added: Modified: clang/lib/Sema/SemaCoroutine.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index 6dc9e342beb9..5ed0bbd6041d 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -502,8 +502,9 @@ VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) { return nullptr; auto *ScopeInfo = getCurFunction(); - // Build a list of arguments, based on the coroutine functions arguments, - // that will be passed to the promise type's constructor. + + // Build a list of arguments, based on the coroutine function's arguments, + // that if present will be passed to the promise type's constructor. llvm::SmallVector CtorArgExprs; // Add implicit object parameter. @@ -519,6 +520,7 @@ VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) { } } + // Add the coroutine function's parameters. auto &Moves = ScopeInfo->CoroutineParameterMoves; for (auto *PD : FD->parameters()) { if (PD->getType()->isDependentType()) @@ -540,28 +542,33 @@ VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) { CtorArgExprs.push_back(RefExpr.get()); } - // Create an initialization sequence for the promise type using the - // constructor arguments, wrapped in a parenthesized list expression. - Expr *PLE = ParenListExpr::Create(Context, FD->getLocation(), - CtorArgExprs, FD->getLocation()); - InitializedEntity Entity = InitializedEntity::InitializeVariable(VD); - InitializationKind Kind = InitializationKind::CreateForInit( - VD->getLocation(), /*DirectInit=*/true, PLE); - InitializationSequence InitSeq(*this, Entity, Kind, CtorArgExprs, - /*TopLevelOfInitList=*/false, - /*TreatUnavailableAsInvalid=*/false); - - // Attempt to initialize the promise type with the arguments. - // If that fails, fall back to the promise type's default constructor. - if (InitSeq) { - ExprResult Result = InitSeq.Perform(*this, Entity, Kind, CtorArgExprs); - if (Result.isInvalid()) { - VD->setInvalidDecl(); - } else if (Result.get()) { - VD->setInit(MaybeCreateExprWithCleanups(Result.get())); - VD->setInitStyle(VarDecl::CallInit); - CheckCompleteVariableDeclaration(VD); - } + // If we have a non-zero number of constructor arguments, try to use them. + // Otherwise, fall back to the promise type's default constructor. + if (!CtorArgExprs.empty()) { + // Create an initialization sequence for the promise type using the + // constructor arguments, wrapped in a parenthesized list expression. + Expr *PLE = ParenListExpr::Create(Context, FD->getLocation(), + CtorArgExprs, FD->getLocation()); + InitializedEntity Entity = InitializedEntity::InitializeVariable(VD); + InitializationKind Kind = InitializationKind::CreateForInit( + VD->getLocation(), /*DirectInit=*/true, PLE); + InitializationSequence InitSeq(*this, Entity, Kind, CtorArgExprs, + /*TopLevelOfInitList=*/false, + /*TreatUnavailableAsInvalid=*/false); + + // Attempt to initialize the promise type with the arguments. + // If that fails, fall back to the promise type's default constructor. + if (InitSeq) { + ExprResult Result = InitSeq.Perform(*this, Entity, Kind, CtorArgExprs); + if (Result.isInvalid()) { + VD->setInvalidDecl(); + } else if (Result.get()) { + VD->setInit(MaybeCreateExprWithCleanups(Result.get())); + VD->setInitStyle(VarDecl::CallInit); + CheckCompleteVariableDeclaration(VD); + } + } else + ActOnUninitializedDecl(VD); } else ActOnUninitializedDecl(VD); From cfe-commits at lists.llvm.org Thu Apr 2 19:00:22 2020 From: cfe-commits at lists.llvm.org (Brian Gesiak via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 02:00:22 +0000 (UTC) Subject: [PATCH] D70555: [coroutines] Don't build promise init with no args In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rG627e01feb718: [coroutines] Don't build promise init with no args (authored by modocache). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70555/new/ https://reviews.llvm.org/D70555 Files: clang/lib/Sema/SemaCoroutine.cpp Index: clang/lib/Sema/SemaCoroutine.cpp =================================================================== --- clang/lib/Sema/SemaCoroutine.cpp +++ clang/lib/Sema/SemaCoroutine.cpp @@ -502,8 +502,9 @@ return nullptr; auto *ScopeInfo = getCurFunction(); - // Build a list of arguments, based on the coroutine functions arguments, - // that will be passed to the promise type's constructor. + + // Build a list of arguments, based on the coroutine function's arguments, + // that if present will be passed to the promise type's constructor. llvm::SmallVector CtorArgExprs; // Add implicit object parameter. @@ -519,6 +520,7 @@ } } + // Add the coroutine function's parameters. auto &Moves = ScopeInfo->CoroutineParameterMoves; for (auto *PD : FD->parameters()) { if (PD->getType()->isDependentType()) @@ -540,28 +542,33 @@ CtorArgExprs.push_back(RefExpr.get()); } - // Create an initialization sequence for the promise type using the - // constructor arguments, wrapped in a parenthesized list expression. - Expr *PLE = ParenListExpr::Create(Context, FD->getLocation(), - CtorArgExprs, FD->getLocation()); - InitializedEntity Entity = InitializedEntity::InitializeVariable(VD); - InitializationKind Kind = InitializationKind::CreateForInit( - VD->getLocation(), /*DirectInit=*/true, PLE); - InitializationSequence InitSeq(*this, Entity, Kind, CtorArgExprs, - /*TopLevelOfInitList=*/false, - /*TreatUnavailableAsInvalid=*/false); - - // Attempt to initialize the promise type with the arguments. - // If that fails, fall back to the promise type's default constructor. - if (InitSeq) { - ExprResult Result = InitSeq.Perform(*this, Entity, Kind, CtorArgExprs); - if (Result.isInvalid()) { - VD->setInvalidDecl(); - } else if (Result.get()) { - VD->setInit(MaybeCreateExprWithCleanups(Result.get())); - VD->setInitStyle(VarDecl::CallInit); - CheckCompleteVariableDeclaration(VD); - } + // If we have a non-zero number of constructor arguments, try to use them. + // Otherwise, fall back to the promise type's default constructor. + if (!CtorArgExprs.empty()) { + // Create an initialization sequence for the promise type using the + // constructor arguments, wrapped in a parenthesized list expression. + Expr *PLE = ParenListExpr::Create(Context, FD->getLocation(), + CtorArgExprs, FD->getLocation()); + InitializedEntity Entity = InitializedEntity::InitializeVariable(VD); + InitializationKind Kind = InitializationKind::CreateForInit( + VD->getLocation(), /*DirectInit=*/true, PLE); + InitializationSequence InitSeq(*this, Entity, Kind, CtorArgExprs, + /*TopLevelOfInitList=*/false, + /*TreatUnavailableAsInvalid=*/false); + + // Attempt to initialize the promise type with the arguments. + // If that fails, fall back to the promise type's default constructor. + if (InitSeq) { + ExprResult Result = InitSeq.Perform(*this, Entity, Kind, CtorArgExprs); + if (Result.isInvalid()) { + VD->setInvalidDecl(); + } else if (Result.get()) { + VD->setInit(MaybeCreateExprWithCleanups(Result.get())); + VD->setInitStyle(VarDecl::CallInit); + CheckCompleteVariableDeclaration(VD); + } + } else + ActOnUninitializedDecl(VD); } else ActOnUninitializedDecl(VD); -------------- next part -------------- A non-text attachment was scrubbed... Name: D70555.254674.patch Type: text/x-patch Size: 3566 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 20:04:32 2020 From: cfe-commits at lists.llvm.org (Jakub Kuderski via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 03:04:32 +0000 (UTC) Subject: [PATCH] D77341: [DomTree] Replace ChildrenGetter with GraphTraits over GraphDiff. In-Reply-To: References: Message-ID: <3aa733cf46f17b7ecf52e8166c15d1f4@localhost.localdomain> kuhar added inline comments. ================ Comment at: llvm/include/llvm/IR/CFGDiff.h:199 +namespace { +template struct reverse_if_helper; +template <> struct reverse_if_helper { ---------------- You can use two helper functions taking `integral_constant` tags -- should be less verbose ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:89 bool IsRecalculated = false; + GraphDiffT *PreViewOfCFG; + const size_t NumLegalized; ---------------- nit: Why pointer instead of keeping a reference? ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:177 constexpr bool Direction = IsReverse != IsPostDom; // XOR. - for (const NodePtr Succ : - ChildrenGetter::Get(BB, BatchUpdates)) { + typedef + typename std::conditional, NodePtr>::type ---------------- nit: use `using` instead of `typefef`. ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:178 + typedef + typename std::conditional, NodePtr>::type + IsRevType; ---------------- nit: can we use `std::conditional_t<...>` in c++14 to get rid of `typename` and `::type`? Or does it make some buildbots unhappy? ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:179 + typename std::conditional, NodePtr>::type + IsRevType; + using GraphDiffBBPair = std::pair; ---------------- nit: I don't find this name very informative. Maybe something like `DirectedBB`? ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:183 + BatchUpdates ? BatchUpdates->PreViewOfCFG : EmptyGD.get(); + std::pair GDNodePair = + std::make_pair(GDTmp, BB); ---------------- `std::pair GDNodePair(GDTmp, BB)` ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:185 + std::make_pair(GDTmp, BB); + for (auto &Pair : children(GDNodePair)) { + const NodePtr Succ = Pair.second; ---------------- Won't children infer the template parameter based on the passes value? I don't get why the template argument type is a pair where the second argument is a directed nodeptr, but the runtime value is always a plain nodeptr. Couldn't the second pair type also be directed for `GDNodePair`? ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:186 + for (auto &Pair : children(GDNodePair)) { + const NodePtr Succ = Pair.second; const auto SIT = NodeToInfo.find(Succ); ---------------- Could this new code be a hoisted into a helper function? ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:1146 if (Update.getKind() == UpdateKind::Insert) - DT.insertEdge(Update.getFrom(), Update.getTo()); + InsertEdge(DT, nullptr, Update.getFrom(), Update.getTo()); else ---------------- Could you add a comment next to the nullptr with the argument name? ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:1543 + // FIXME: Updated to use the PreViewCFG and behave the same as until now. + // This behavior is however incorrect; this actually needs the PostViewCFG. + GraphDiff PreViewCFG( ---------------- Does this care about the direction (pre- or post-) at all, or does it need some CFG view? Why is pre-view incorrect? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77341/new/ https://reviews.llvm.org/D77341 From cfe-commits at lists.llvm.org Thu Apr 2 20:04:33 2020 From: cfe-commits at lists.llvm.org (Jakub Kuderski via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 03:04:33 +0000 (UTC) Subject: [PATCH] D77341: [DomTree] Replace ChildrenGetter with GraphTraits over GraphDiff. In-Reply-To: References: Message-ID: kuhar added inline comments. ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:186 + for (auto &Pair : children(GDNodePair)) { + const NodePtr Succ = Pair.second; const auto SIT = NodeToInfo.find(Succ); ---------------- kuhar wrote: > Could this new code be a hoisted into a helper function? Or alternatively, could the old `ChildrenGetter` be implemented with these 5 magic lines? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77341/new/ https://reviews.llvm.org/D77341 From cfe-commits at lists.llvm.org Thu Apr 2 20:36:40 2020 From: cfe-commits at lists.llvm.org (Arthur Eubanks via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 03:36:40 +0000 (UTC) Subject: [PATCH] D66490: [NewPM] Enable the New Pass Manager by Default in Clang In-Reply-To: References: Message-ID: <669095fb09babd594c5991bd5ad63963@localhost.localdomain> aeubanks added a comment. In D66490#1638708 , @hfinkel wrote: > In D66490#1638162 , @rupprecht wrote: > > > We already know that we don't want this enabled for tsan builds due to https://bugs.llvm.org/show_bug.cgi?id=42877, but I don't even know if anyone else will hit it (it's only when building one particular library). > > > Under the circumstances, that seems like one particular library too many. PR42877 looks like a generic bug, so if we're hitting it here, I see no reason to suspect that others would not hit it elsewhere. https://bugs.llvm.org/show_bug.cgi?id=42877 is marked fixed, any update on this? LLVM 10.0.0 has branched. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D66490/new/ https://reviews.llvm.org/D66490 From cfe-commits at lists.llvm.org Thu Apr 2 20:39:30 2020 From: cfe-commits at lists.llvm.org (Craig Topper via cfe-commits) Date: Thu, 02 Apr 2020 20:39:30 -0700 (PDT) Subject: [clang] be0a4fe - [X86] Add -flax-vector-conversions=none to more of the clang CodeGen tests Message-ID: <5e86aff2.1c69fb81.285d.4e71@mx.google.com> Author: Craig Topper Date: 2020-04-02T20:39:18-07:00 New Revision: be0a4fef6e789a8f25316af988b2d312d83d0d1c URL: https://github.com/llvm/llvm-project/commit/be0a4fef6e789a8f25316af988b2d312d83d0d1c DIFF: https://github.com/llvm/llvm-project/commit/be0a4fef6e789a8f25316af988b2d312d83d0d1c.diff LOG: [X86] Add -flax-vector-conversions=none to more of the clang CodeGen tests Thankfully no issues found. Added: Modified: clang/test/CodeGen/avx512cdintrin.c clang/test/CodeGen/avx512vbmivl-builtin.c clang/test/CodeGen/avx512vl-builtins-constrained-cmp.c clang/test/CodeGen/avx512vpopcntdqintrin.c clang/test/CodeGen/avx512vpopcntdqvlintrin.c clang/test/CodeGen/gfni-builtins.c clang/test/CodeGen/intel-avx512vlvp2intersect.c clang/test/CodeGen/intel-avx512vp2intersect.c clang/test/CodeGen/vaes-builtins.c clang/test/CodeGen/vpclmulqdq-builtins.c Removed: ################################################################################ diff --git a/clang/test/CodeGen/avx512cdintrin.c b/clang/test/CodeGen/avx512cdintrin.c index 6483d7e8dda5..b15126808b80 100644 --- a/clang/test/CodeGen/avx512cdintrin.c +++ b/clang/test/CodeGen/avx512cdintrin.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512cd -emit-llvm -o - -Wall -Werror | FileCheck %s +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512cd -emit-llvm -o - -Wall -Werror | FileCheck %s #include diff --git a/clang/test/CodeGen/avx512vbmivl-builtin.c b/clang/test/CodeGen/avx512vbmivl-builtin.c index 0bf9165f6c6a..2562da26d6ce 100644 --- a/clang/test/CodeGen/avx512vbmivl-builtin.c +++ b/clang/test/CodeGen/avx512vbmivl-builtin.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512vbmi -target-feature +avx512vl -target-feature +avx512bw -emit-llvm -o - -Wall -Werror | FileCheck %s +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512vbmi -target-feature +avx512vl -target-feature +avx512bw -emit-llvm -o - -Wall -Werror | FileCheck %s #include diff --git a/clang/test/CodeGen/avx512vl-builtins-constrained-cmp.c b/clang/test/CodeGen/avx512vl-builtins-constrained-cmp.c index ae052dfffbab..6be4f614561a 100644 --- a/clang/test/CodeGen/avx512vl-builtins-constrained-cmp.c +++ b/clang/test/CodeGen/avx512vl-builtins-constrained-cmp.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -ffreestanding %s -fexperimental-new-pass-manager -triple=x86_64-apple-darwin -target-feature +avx512f -target-feature +avx512vl -emit-llvm -ffp-exception-behavior=strict -o - -Wall -Werror | FileCheck %s +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -fexperimental-new-pass-manager -triple=x86_64-apple-darwin -target-feature +avx512f -target-feature +avx512vl -emit-llvm -ffp-exception-behavior=strict -o - -Wall -Werror | FileCheck %s #include diff --git a/clang/test/CodeGen/avx512vpopcntdqintrin.c b/clang/test/CodeGen/avx512vpopcntdqintrin.c index e7c797c19549..22c44bc21edf 100644 --- a/clang/test/CodeGen/avx512vpopcntdqintrin.c +++ b/clang/test/CodeGen/avx512vpopcntdqintrin.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512vpopcntdq -emit-llvm -o - -Wall -Werror | FileCheck %s +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512vpopcntdq -emit-llvm -o - -Wall -Werror | FileCheck %s #include diff --git a/clang/test/CodeGen/avx512vpopcntdqvlintrin.c b/clang/test/CodeGen/avx512vpopcntdqvlintrin.c index 010cb6b4f344..686bfb986ceb 100644 --- a/clang/test/CodeGen/avx512vpopcntdqvlintrin.c +++ b/clang/test/CodeGen/avx512vpopcntdqvlintrin.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512vpopcntdq -target-feature +avx512vl -emit-llvm -o - -Wall -Werror | FileCheck %s +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512vpopcntdq -target-feature +avx512vl -emit-llvm -o - -Wall -Werror | FileCheck %s #include diff --git a/clang/test/CodeGen/gfni-builtins.c b/clang/test/CodeGen/gfni-builtins.c index 0d10d7aeacd6..61d957d59e76 100644 --- a/clang/test/CodeGen/gfni-builtins.c +++ b/clang/test/CodeGen/gfni-builtins.c @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +gfni -emit-llvm -o - | FileCheck %s --check-prefix SSE -// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +gfni -target-feature +avx -emit-llvm -o - | FileCheck %s --check-prefixes SSE,AVX -// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +gfni -target-feature +avx512bw -target-feature +avx512vl -emit-llvm -o - | FileCheck %s --check-prefixes SSE,AVX,AVX512 +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +gfni -emit-llvm -o - | FileCheck %s --check-prefix SSE +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +gfni -target-feature +avx -emit-llvm -o - | FileCheck %s --check-prefixes SSE,AVX +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +gfni -target-feature +avx512bw -target-feature +avx512vl -emit-llvm -o - | FileCheck %s --check-prefixes SSE,AVX,AVX512 #include diff --git a/clang/test/CodeGen/intel-avx512vlvp2intersect.c b/clang/test/CodeGen/intel-avx512vlvp2intersect.c index c607a6996928..1b360d1d7c5b 100644 --- a/clang/test/CodeGen/intel-avx512vlvp2intersect.c +++ b/clang/test/CodeGen/intel-avx512vlvp2intersect.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx512vp2intersect -target-feature +avx512vl -emit-llvm -o - -Wall -Werror | FileCheck %s -// RUN: %clang_cc1 %s -ffreestanding -triple=i386-unknown-unknown -target-feature +avx512vp2intersect -target-feature +avx512vl -emit-llvm -o - -Wall -Werror | FileCheck %s +// RUN: %clang_cc1 %s -flax-vector-conversions=none -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx512vp2intersect -target-feature +avx512vl -emit-llvm -o - -Wall -Werror | FileCheck %s +// RUN: %clang_cc1 %s -flax-vector-conversions=none -ffreestanding -triple=i386-unknown-unknown -target-feature +avx512vp2intersect -target-feature +avx512vl -emit-llvm -o - -Wall -Werror | FileCheck %s #include diff --git a/clang/test/CodeGen/intel-avx512vp2intersect.c b/clang/test/CodeGen/intel-avx512vp2intersect.c index bcbf6076eec3..2a3d38acfbf2 100644 --- a/clang/test/CodeGen/intel-avx512vp2intersect.c +++ b/clang/test/CodeGen/intel-avx512vp2intersect.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 %s -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx512vp2intersect -emit-llvm -o - -Wall -Werror | FileCheck %s -// RUN: %clang_cc1 %s -ffreestanding -triple=i386-unknown-unknown -target-feature +avx512vp2intersect -emit-llvm -o - -Wall -Werror | FileCheck %s +// RUN: %clang_cc1 %s -flax-vector-conversions=none -ffreestanding -triple=x86_64-unknown-unknown -target-feature +avx512vp2intersect -emit-llvm -o - -Wall -Werror | FileCheck %s +// RUN: %clang_cc1 %s -flax-vector-conversions=none -ffreestanding -triple=i386-unknown-unknown -target-feature +avx512vp2intersect -emit-llvm -o - -Wall -Werror | FileCheck %s #include diff --git a/clang/test/CodeGen/vaes-builtins.c b/clang/test/CodeGen/vaes-builtins.c index 1dd5784814d3..eea1f408b3ce 100644 --- a/clang/test/CodeGen/vaes-builtins.c +++ b/clang/test/CodeGen/vaes-builtins.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +vaes -emit-llvm -o - | FileCheck %s --check-prefix AVX -// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +vaes -target-feature +avx512f -emit-llvm -o - | FileCheck %s --check-prefixes AVX,AVX512 +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +vaes -emit-llvm -o - | FileCheck %s --check-prefix AVX +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +vaes -target-feature +avx512f -emit-llvm -o - | FileCheck %s --check-prefixes AVX,AVX512 #include diff --git a/clang/test/CodeGen/vpclmulqdq-builtins.c b/clang/test/CodeGen/vpclmulqdq-builtins.c index 15eef399bcdf..aa2b8bca9126 100644 --- a/clang/test/CodeGen/vpclmulqdq-builtins.c +++ b/clang/test/CodeGen/vpclmulqdq-builtins.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +vpclmulqdq -emit-llvm -o - | FileCheck %s --check-prefix AVX -// RUN: %clang_cc1 -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +vpclmulqdq -target-feature +avx512f -emit-llvm -o - | FileCheck %s --check-prefixes AVX,AVX512 +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +vpclmulqdq -emit-llvm -o - | FileCheck %s --check-prefix AVX +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +vpclmulqdq -target-feature +avx512f -emit-llvm -o - | FileCheck %s --check-prefixes AVX,AVX512 #include From cfe-commits at lists.llvm.org Thu Apr 2 21:09:01 2020 From: cfe-commits at lists.llvm.org (Wang Tianqing via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 04:09:01 +0000 (UTC) Subject: [PATCH] D77205: [X86] Add TSXLDTRK instructions. In-Reply-To: References: Message-ID: tianqing updated this revision to Diff 254693. tianqing added a comment. Updated to resolve conflicts with https://reviews.llvm.org/D77193. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77205/new/ https://reviews.llvm.org/D77205 Files: clang/docs/ClangCommandLineReference.rst clang/include/clang/Basic/BuiltinsX86.def clang/include/clang/Driver/Options.td clang/lib/Basic/Targets/X86.cpp clang/lib/Basic/Targets/X86.h clang/lib/Headers/CMakeLists.txt clang/lib/Headers/cpuid.h clang/lib/Headers/immintrin.h clang/lib/Headers/tsxldtrkintrin.h clang/test/CodeGen/x86-tsxldtrk-builtins.c clang/test/Driver/x86-target-features.c clang/test/Preprocessor/x86_target_features.c llvm/include/llvm/IR/IntrinsicsX86.td llvm/lib/Support/Host.cpp llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86InstrInfo.td llvm/lib/Target/X86/X86Subtarget.h llvm/test/CodeGen/X86/tsxldtrk-intrinsic.ll llvm/test/MC/Disassembler/X86/x86-16.txt llvm/test/MC/Disassembler/X86/x86-32.txt llvm/test/MC/Disassembler/X86/x86-64.txt llvm/test/MC/X86/x86-16.s llvm/test/MC/X86/x86-32-coverage.s llvm/test/MC/X86/x86-64.s -------------- next part -------------- A non-text attachment was scrubbed... Name: D77205.254693.patch Type: text/x-patch Size: 17026 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 21:09:03 2020 From: cfe-commits at lists.llvm.org (Wang Tianqing via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 04:09:03 +0000 (UTC) Subject: [PATCH] D77205: [X86] Add TSXLDTRK instructions. In-Reply-To: References: Message-ID: <8a4ffdcb1c9d12d29b63c7e7fc2a78cb@localhost.localdomain> tianqing updated this revision to Diff 254694. tianqing added a comment. Removed extra "//". CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77205/new/ https://reviews.llvm.org/D77205 Files: clang/docs/ClangCommandLineReference.rst clang/include/clang/Basic/BuiltinsX86.def clang/include/clang/Driver/Options.td clang/lib/Basic/Targets/X86.cpp clang/lib/Basic/Targets/X86.h clang/lib/Headers/CMakeLists.txt clang/lib/Headers/cpuid.h clang/lib/Headers/immintrin.h clang/lib/Headers/tsxldtrkintrin.h clang/test/CodeGen/x86-tsxldtrk-builtins.c clang/test/Driver/x86-target-features.c clang/test/Preprocessor/x86_target_features.c llvm/include/llvm/IR/IntrinsicsX86.td llvm/lib/Support/Host.cpp llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86InstrInfo.td llvm/lib/Target/X86/X86Subtarget.h llvm/test/CodeGen/X86/tsxldtrk-intrinsic.ll llvm/test/MC/Disassembler/X86/x86-16.txt llvm/test/MC/Disassembler/X86/x86-32.txt llvm/test/MC/Disassembler/X86/x86-64.txt llvm/test/MC/X86/x86-16.s llvm/test/MC/X86/x86-32-coverage.s llvm/test/MC/X86/x86-64.s -------------- next part -------------- A non-text attachment was scrubbed... Name: D77205.254694.patch Type: text/x-patch Size: 17026 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Thu Apr 2 22:45:49 2020 From: cfe-commits at lists.llvm.org (Nathan Ridge via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 05:45:49 +0000 (UTC) Subject: [PATCH] D77194: [clang] Persist Attr::IsPackExpansion into the serialized AST In-Reply-To: References: Message-ID: nridge updated this revision to Diff 254712. nridge added a comment. Add test Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77194/new/ https://reviews.llvm.org/D77194 Files: clang/test/PCH/cxx-attrs-packexpansion.cpp clang/utils/TableGen/ClangAttrEmitter.cpp Index: clang/utils/TableGen/ClangAttrEmitter.cpp =================================================================== --- clang/utils/TableGen/ClangAttrEmitter.cpp +++ clang/utils/TableGen/ClangAttrEmitter.cpp @@ -2911,6 +2911,7 @@ if (R.isSubClassOf(InhClass)) OS << " bool isInherited = Record.readInt();\n"; OS << " bool isImplicit = Record.readInt();\n"; + OS << " bool isPackExpansion = Record.readInt();\n"; ArgRecords = R.getValueAsListOfDefs("Args"); Args.clear(); for (const auto *Arg : ArgRecords) { @@ -2926,6 +2927,7 @@ if (R.isSubClassOf(InhClass)) OS << " cast(New)->setInherited(isInherited);\n"; OS << " New->setImplicit(isImplicit);\n"; + OS << " New->setPackExpansion(isPackExpansion);\n"; OS << " break;\n"; OS << " }\n"; } @@ -2952,6 +2954,7 @@ if (R.isSubClassOf(InhClass)) OS << " Record.push_back(SA->isInherited());\n"; OS << " Record.push_back(A->isImplicit());\n"; + OS << " Record.push_back(A->isPackExpansion());\n"; for (const auto *Arg : Args) createArgument(*Arg, R.getName())->writePCHWrite(OS); Index: clang/test/PCH/cxx-attrs-packexpansion.cpp =================================================================== --- /dev/null +++ clang/test/PCH/cxx-attrs-packexpansion.cpp @@ -0,0 +1,25 @@ +// Test this without pch. +// RUN: %clang_cc1 -include %s -emit-llvm -o - %s + +// Test with pch. +// RUN: %clang_cc1 -emit-pch -o %t %s +// RUN: %clang_cc1 -include-pch %t -emit-llvm -o - %s + +#ifndef HEADER +#define HEADER + +template +struct static_variant { + alignas(Types...) T storage[10]; +}; + +#else + +struct A { + static_variant a; +}; +struct B { + static_variant _b; +}; + +#endif -------------- next part -------------- A non-text attachment was scrubbed... Name: D77194.254712.patch Type: text/x-patch Size: 1818 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 00:30:09 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Balogh, _=C3=81d=C3=A1m_via_Phabricator?= via cfe-commits) Date: Fri, 03 Apr 2020 07:30:09 +0000 (UTC) Subject: [PATCH] D77150: [Analyzer] New Option for ContainerModeling: AggressiveEraseModeling In-Reply-To: References: Message-ID: <32f70abae31ea6784daefad495e7153d@localhost.localdomain> baloghadamsoftware marked an inline comment as done. baloghadamsoftware added inline comments. ================ Comment at: clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp:692-699 + std::tie(StateEnd, StateNotEnd) = State->assume(*RetEnd); + if (StateEnd) { + C.addTransition(StateEnd); + } + if (StateNotEnd) { + C.addTransition(StateNotEnd); + } ---------------- Szelethus wrote: > Szelethus wrote: > > Right, so the const is a state split. That doesn't sound like something regular users should fine-tune. > cost* :^) We made something like this (upon suggestion from @NoQ) in `STLAlgorithmModeling`. There is an option which is disabled by default, but if the user enables it, then `std::find()` and the like will aggressively assume that the element may not be found thus they return their second iterator parameter. This option is very similar to that one. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77150/new/ https://reviews.llvm.org/D77150 From cfe-commits at lists.llvm.org Fri Apr 3 00:30:10 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 07:30:10 +0000 (UTC) Subject: [PATCH] D77335: [AST] clang::VectorType supports any size (that fits in unsigned) In-Reply-To: References: Message-ID: <3f83ba085c4c57cee8adbd77c0e8eef3@localhost.localdomain> hokein accepted this revision. hokein added a comment. Thanks! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77335/new/ https://reviews.llvm.org/D77335 From cfe-commits at lists.llvm.org Fri Apr 3 00:30:10 2020 From: cfe-commits at lists.llvm.org (serge via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 07:30:10 +0000 (UTC) Subject: [PATCH] D71082: Allow system header to provide their own implementation of some builtin In-Reply-To: References: Message-ID: <8e4a2fe274d4ff975ab8c00de7d4690e@localhost.localdomain> serge-sans-paille added a comment. In D71082#1958597 , @manojgupta wrote: > Yes, it'd be nice if all of the FORTIFY handling can be improved. For a simple call like memcpy of 8 bytes in the example, there is no reason to emit all these stack/range checks since they'd degrade memcpy performance. > > I still think this change should be reverted if it can't handle Linux kernel's FORTIFY implementation. I think there's a misunderstanding there. This patch has nothing to do with clang being unable to correctly handle the kernel's memcpy implementation. The only thing it does is actually *picking* the kernel's memcpy implementation instead of relying on the builtin, non-fortified, version of it. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71082/new/ https://reviews.llvm.org/D71082 From cfe-commits at lists.llvm.org Fri Apr 3 00:35:51 2020 From: cfe-commits at lists.llvm.org (Craig Topper via cfe-commits) Date: Fri, 03 Apr 2020 00:35:51 -0700 (PDT) Subject: [clang] 5b519cf - [X86] Add Indirect Thunk Support to X86 to mitigate Load Value Injection (LVI) Message-ID: <5e86e757.1c69fb81.35aea.8943@mx.google.com> Author: Scott Constable Date: 2020-04-03T00:34:39-07:00 New Revision: 5b519cf1fc6737054cf90b53667e7ddd3a51225f URL: https://github.com/llvm/llvm-project/commit/5b519cf1fc6737054cf90b53667e7ddd3a51225f DIFF: https://github.com/llvm/llvm-project/commit/5b519cf1fc6737054cf90b53667e7ddd3a51225f.diff LOG: [X86] Add Indirect Thunk Support to X86 to mitigate Load Value Injection (LVI) This pass replaces each indirect call/jump with a direct call to a thunk that looks like: lfence jmpq *%r11 This ensures that if the value in register %r11 was loaded from memory, then the value in %r11 is (architecturally) correct prior to the jump. Also adds a new target feature to X86: +lvi-cfi ("cfi" meaning control-flow integrity) The feature can be added via clang CLI using -mlvi-cfi. This is an alternate implementation to https://reviews.llvm.org/D75934 That merges the thunk insertion functionality with the existing X86 retpoline code. Differential Revision: https://reviews.llvm.org/D76812 Added: llvm/test/CodeGen/X86/lvi-hardening-indirectbr.ll Modified: clang/docs/ClangCommandLineReference.rst clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Arch/X86.cpp clang/test/Driver/x86-target-features.c llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86ISelLowering.cpp llvm/lib/Target/X86/X86IndirectThunks.cpp llvm/lib/Target/X86/X86Subtarget.h Removed: ################################################################################ diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst index 51d4f32edec4..511f3145e7e8 100644 --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -2625,6 +2625,10 @@ Use Intel MCU ABI Generate branches with extended addressability, usually via indirect jumps. +.. option:: -mlvi-cfi, -mno-lvi-cfi + +Enable only control-flow mitigations for Load Value Injection (LVI) + .. option:: -mmacosx-version-min=, -mmacos-version-min= Set Mac OS X deployment target diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 61e1d4128016..0d057ac579f5 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2309,6 +2309,10 @@ def mspeculative_load_hardening : Flag<["-"], "mspeculative-load-hardening">, Group, Flags<[CoreOption,CC1Option]>; def mno_speculative_load_hardening : Flag<["-"], "mno-speculative-load-hardening">, Group, Flags<[CoreOption]>; +def mlvi_cfi : Flag<["-"], "mlvi-cfi">, Group, Flags<[CoreOption,DriverOption]>, + HelpText<"Enable only control-flow mitigations for Load Value Injection (LVI)">; +def mno_lvi_cfi : Flag<["-"], "mno-lvi-cfi">, Group, Flags<[CoreOption,DriverOption]>, + HelpText<"Disable control-flow mitigations for Load Value Injection (LVI)">; def mrelax : Flag<["-"], "mrelax">, Group, HelpText<"Enable linker relaxation">; diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp index 44a636dcfd1c..aafba6915d0b 100644 --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -146,6 +146,7 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, // flags). This is a bit hacky but keeps existing usages working. We should // consider deprecating this and instead warn if the user requests external // retpoline thunks and *doesn't* request some form of retpolines. + auto SpectreOpt = clang::driver::options::ID::OPT_INVALID; if (Args.hasArgNoClaim(options::OPT_mretpoline, options::OPT_mno_retpoline, options::OPT_mspeculative_load_hardening, options::OPT_mno_speculative_load_hardening)) { @@ -153,12 +154,14 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, false)) { Features.push_back("+retpoline-indirect-calls"); Features.push_back("+retpoline-indirect-branches"); + SpectreOpt = options::OPT_mretpoline; } else if (Args.hasFlag(options::OPT_mspeculative_load_hardening, options::OPT_mno_speculative_load_hardening, false)) { // On x86, speculative load hardening relies on at least using retpolines // for indirect calls. Features.push_back("+retpoline-indirect-calls"); + SpectreOpt = options::OPT_mspeculative_load_hardening; } } else if (Args.hasFlag(options::OPT_mretpoline_external_thunk, options::OPT_mno_retpoline_external_thunk, false)) { @@ -166,6 +169,20 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, // eventually switch to an error here. Features.push_back("+retpoline-indirect-calls"); Features.push_back("+retpoline-indirect-branches"); + SpectreOpt = options::OPT_mretpoline_external_thunk; + } + + auto LVIOpt = clang::driver::options::ID::OPT_INVALID; + if (Args.hasFlag(options::OPT_mlvi_cfi, options::OPT_mno_lvi_cfi, false)) { + Features.push_back("+lvi-cfi"); + LVIOpt = options::OPT_mlvi_cfi; + } + + if (SpectreOpt != clang::driver::options::ID::OPT_INVALID && + LVIOpt != clang::driver::options::ID::OPT_INVALID) { + D.Diag(diag::err_drv_argument_not_allowed_with) + << D.getOpts().getOptionName(SpectreOpt) + << D.getOpts().getOptionName(LVIOpt); } // Now add any that the user explicitly requested on the command line, diff --git a/clang/test/Driver/x86-target-features.c b/clang/test/Driver/x86-target-features.c index 58e7a45c0a83..872a228c2a33 100644 --- a/clang/test/Driver/x86-target-features.c +++ b/clang/test/Driver/x86-target-features.c @@ -154,6 +154,11 @@ // SLH: "-mspeculative-load-hardening" // NO-SLH-NOT: retpoline +// RUN: %clang -target i386-linux-gnu -mlvi-cfi %s -### -o %t.o 2>&1 | FileCheck -check-prefix=LVICFI %s +// RUN: %clang -target i386-linux-gnu -mno-lvi-cfi %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-LVICFI %s +// LVICFI: "-target-feature" "+lvi-cfi" +// NO-LVICFI-NOT: lvi-cfi + // RUN: %clang -target i386-linux-gnu -mwaitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=WAITPKG %s // RUN: %clang -target i386-linux-gnu -mno-waitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-WAITPKG %s // WAITPKG: "-target-feature" "+waitpkg" diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index 94818796530c..13ccf3c940b9 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -433,6 +433,15 @@ def FeatureRetpolineExternalThunk "ourselves. Only has effect when combined with some other retpoline " "feature", [FeatureRetpolineIndirectCalls]>; +// Mitigate LVI attacks against indirect calls/branches and call returns +def FeatureLVIControlFlowIntegrity + : SubtargetFeature< + "lvi-cfi", "UseLVIControlFlowIntegrity", "true", + "Prevent indirect calls/branches from using a memory operand, and " + "precede all indirect calls/branches from a register with an " + "LFENCE instruction to serialize control flow. Also decompose RET " + "instructions into a POP+LFENCE+JMP sequence.">; + // Direct Move instructions. def FeatureMOVDIRI : SubtargetFeature<"movdiri", "HasMOVDIRI", "true", "Support movdiri instruction">; diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index f2da0d3d1283..b75e49e5f59e 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -31972,6 +31972,11 @@ static const char *getIndirectThunkSymbol(const X86Subtarget &Subtarget, } llvm_unreachable("unexpected reg for retpoline"); } + + if (Subtarget.useLVIControlFlowIntegrity()) { + assert(Subtarget.is64Bit() && "Should not be using a 64-bit thunk!"); + return "__llvm_lvi_thunk_r11"; + } llvm_unreachable("getIndirectThunkSymbol() invoked without thunk feature"); } diff --git a/llvm/lib/Target/X86/X86IndirectThunks.cpp b/llvm/lib/Target/X86/X86IndirectThunks.cpp index e6408e986f1a..36b9c3ccc959 100644 --- a/llvm/lib/Target/X86/X86IndirectThunks.cpp +++ b/llvm/lib/Target/X86/X86IndirectThunks.cpp @@ -14,6 +14,8 @@ /// /// Currently supported thunks include: /// - Retpoline -- A RET-implemented trampoline that lowers indirect calls +/// - LVI Thunk -- A CALL/JMP-implemented thunk that forces load serialization +/// before making an indirect call/jump /// /// Note that the reason that this is implemented as a MachineFunctionPass and /// not a ModulePass is that ModulePasses at this point in the LLVM X86 pipeline @@ -44,11 +46,14 @@ using namespace llvm; #define DEBUG_TYPE "x86-retpoline-thunks" static const char RetpolineNamePrefix[] = "__llvm_retpoline_"; -static const char R11RetpolineName[] = "__llvm_retpoline_r11"; -static const char EAXRetpolineName[] = "__llvm_retpoline_eax"; -static const char ECXRetpolineName[] = "__llvm_retpoline_ecx"; -static const char EDXRetpolineName[] = "__llvm_retpoline_edx"; -static const char EDIRetpolineName[] = "__llvm_retpoline_edi"; +static const char R11RetpolineName[] = "__llvm_retpoline_r11"; +static const char EAXRetpolineName[] = "__llvm_retpoline_eax"; +static const char ECXRetpolineName[] = "__llvm_retpoline_ecx"; +static const char EDXRetpolineName[] = "__llvm_retpoline_edx"; +static const char EDIRetpolineName[] = "__llvm_retpoline_edi"; + +static const char LVIThunkNamePrefix[] = "__llvm_lvi_thunk_"; +static const char R11LVIThunkName[] = "__llvm_lvi_thunk_r11"; namespace { template class ThunkInserter { @@ -80,6 +85,38 @@ struct RetpolineThunkInserter : ThunkInserter { void populateThunk(MachineFunction &MF); }; +struct LVIThunkInserter : ThunkInserter { + const char *getThunkPrefix() { return LVIThunkNamePrefix; } + bool mayUseThunk(const MachineFunction &MF) { + return MF.getSubtarget().useLVIControlFlowIntegrity(); + } + void insertThunks(MachineModuleInfo &MMI) { + createThunkFunction(MMI, R11LVIThunkName); + } + void populateThunk(MachineFunction &MF) { + // Grab the entry MBB and erase any other blocks. O0 codegen appears to + // generate two bbs for the entry block. + MachineBasicBlock *Entry = &MF.front(); + Entry->clear(); + while (MF.size() > 1) + MF.erase(std::next(MF.begin())); + + // This code mitigates LVI by replacing each indirect call/jump with a + // direct call/jump to a thunk that looks like: + // ``` + // lfence + // jmpq *%r11 + // ``` + // This ensures that if the value in register %r11 was loaded from memory, + // then the value in %r11 is (architecturally) correct prior to the jump. + const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); + BuildMI(&MF.front(), DebugLoc(), TII->get(X86::LFENCE)); + BuildMI(&MF.front(), DebugLoc(), TII->get(X86::JMP64r)).addReg(X86::R11); + MF.front().addLiveIn(X86::R11); + return; + } +}; + class X86IndirectThunks : public MachineFunctionPass { public: static char ID; @@ -98,7 +135,7 @@ class X86IndirectThunks : public MachineFunctionPass { } private: - std::tuple TIs; + std::tuple TIs; // FIXME: When LLVM moves to C++17, these can become folds template diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index 5b7147f9303b..a23588a07e57 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -428,6 +428,12 @@ class X86Subtarget final : public X86GenSubtargetInfo { /// than emitting one inside the compiler. bool UseRetpolineExternalThunk = false; + /// Prevent generation of indirect call/branch instructions from memory, + /// and force all indirect call/branch instructions from a register to be + /// preceded by an LFENCE. Also decompose RET instructions into a + /// POP+LFENCE+JMP sequence. + bool UseLVIControlFlowIntegrity = false; + /// Use software floating point for code generation. bool UseSoftFloat = false; @@ -719,13 +725,16 @@ class X86Subtarget final : public X86GenSubtargetInfo { // These are generic getters that OR together all of the thunk types // supported by the subtarget. Therefore useIndirectThunk*() will return true // if any respective thunk feature is enabled. - bool useIndirectThunkCalls() const { return useRetpolineIndirectCalls(); } + bool useIndirectThunkCalls() const { + return useRetpolineIndirectCalls() || useLVIControlFlowIntegrity(); + } bool useIndirectThunkBranches() const { - return useRetpolineIndirectBranches(); + return useRetpolineIndirectBranches() || useLVIControlFlowIntegrity(); } bool preferMaskRegisters() const { return PreferMaskRegisters; } bool useGLMDivSqrtCosts() const { return UseGLMDivSqrtCosts; } + bool useLVIControlFlowIntegrity() const { return UseLVIControlFlowIntegrity; } unsigned getPreferVectorWidth() const { return PreferVectorWidth; } unsigned getRequiredVectorWidth() const { return RequiredVectorWidth; } diff --git a/llvm/test/CodeGen/X86/lvi-hardening-indirectbr.ll b/llvm/test/CodeGen/X86/lvi-hardening-indirectbr.ll new file mode 100644 index 000000000000..d2caf6e1e9eb --- /dev/null +++ b/llvm/test/CodeGen/X86/lvi-hardening-indirectbr.ll @@ -0,0 +1,281 @@ +; RUN: llc -verify-machineinstrs -mtriple=x86_64-unknown -mattr=+lvi-cfi < %s | FileCheck %s --check-prefix=X64 +; RUN: llc -verify-machineinstrs -mtriple=x86_64-unknown -mattr=+lvi-cfi -O0 < %s | FileCheck %s --check-prefix=X64FAST +; +; Note that a lot of this code was lifted from retpoline.ll. + +declare void @bar(i32) + +; Test a simple indirect call and tail call. +define void @icall_reg(void (i32)* %fp, i32 %x) { +entry: + tail call void @bar(i32 %x) + tail call void %fp(i32 %x) + tail call void @bar(i32 %x) + tail call void %fp(i32 %x) + ret void +} + +; X64-LABEL: icall_reg: +; X64-DAG: movq %rdi, %[[fp:[^ ]*]] +; X64-DAG: movl %esi, %[[x:[^ ]*]] +; X64: movl %esi, %edi +; X64: callq bar +; X64-DAG: movl %[[x]], %edi +; X64-DAG: movq %[[fp]], %r11 +; X64: callq __llvm_lvi_thunk_r11 +; X64: movl %[[x]], %edi +; X64: callq bar +; X64-DAG: movl %[[x]], %edi +; X64-DAG: movq %[[fp]], %r11 +; X64: jmp __llvm_lvi_thunk_r11 # TAILCALL + +; X64FAST-LABEL: icall_reg: +; X64FAST: callq bar +; X64FAST: callq __llvm_lvi_thunk_r11 +; X64FAST: callq bar +; X64FAST: jmp __llvm_lvi_thunk_r11 # TAILCALL + + + at global_fp = external global void (i32)* + +; Test an indirect call through a global variable. +define void @icall_global_fp(i32 %x, void (i32)** %fpp) #0 { + %fp1 = load void (i32)*, void (i32)** @global_fp + call void %fp1(i32 %x) + %fp2 = load void (i32)*, void (i32)** @global_fp + tail call void %fp2(i32 %x) + ret void +} + +; X64-LABEL: icall_global_fp: +; X64-DAG: movl %edi, %[[x:[^ ]*]] +; X64-DAG: movq global_fp(%rip), %r11 +; X64: callq __llvm_lvi_thunk_r11 +; X64-DAG: movl %[[x]], %edi +; X64-DAG: movq global_fp(%rip), %r11 +; X64: jmp __llvm_lvi_thunk_r11 # TAILCALL + +; X64FAST-LABEL: icall_global_fp: +; X64FAST: movq global_fp(%rip), %r11 +; X64FAST: callq __llvm_lvi_thunk_r11 +; X64FAST: movq global_fp(%rip), %r11 +; X64FAST: jmp __llvm_lvi_thunk_r11 # TAILCALL + + +%struct.Foo = type { void (%struct.Foo*)** } + +; Test an indirect call through a vtable. +define void @vcall(%struct.Foo* %obj) #0 { + %vptr_field = getelementptr %struct.Foo, %struct.Foo* %obj, i32 0, i32 0 + %vptr = load void (%struct.Foo*)**, void (%struct.Foo*)*** %vptr_field + %vslot = getelementptr void(%struct.Foo*)*, void(%struct.Foo*)** %vptr, i32 1 + %fp = load void(%struct.Foo*)*, void(%struct.Foo*)** %vslot + tail call void %fp(%struct.Foo* %obj) + tail call void %fp(%struct.Foo* %obj) + ret void +} + +; X64-LABEL: vcall: +; X64: movq %rdi, %[[obj:[^ ]*]] +; X64: movq (%rdi), %[[vptr:[^ ]*]] +; X64: movq 8(%[[vptr]]), %[[fp:[^ ]*]] +; X64: movq %[[fp]], %r11 +; X64: callq __llvm_lvi_thunk_r11 +; X64-DAG: movq %[[obj]], %rdi +; X64-DAG: movq %[[fp]], %r11 +; X64: jmp __llvm_lvi_thunk_r11 # TAILCALL + +; X64FAST-LABEL: vcall: +; X64FAST: callq __llvm_lvi_thunk_r11 +; X64FAST: jmp __llvm_lvi_thunk_r11 # TAILCALL + + +declare void @direct_callee() + +define void @direct_tail() #0 { + tail call void @direct_callee() + ret void +} + +; X64-LABEL: direct_tail: +; X64: jmp direct_callee # TAILCALL +; X64FAST-LABEL: direct_tail: +; X64FAST: jmp direct_callee # TAILCALL + + +declare void @nonlazybind_callee() #1 + +define void @nonlazybind_caller() #0 { + call void @nonlazybind_callee() + tail call void @nonlazybind_callee() + ret void +} + +; X64-LABEL: nonlazybind_caller: +; X64: movq nonlazybind_callee at GOTPCREL(%rip), %[[REG:.*]] +; X64: movq %[[REG]], %r11 +; X64: callq __llvm_lvi_thunk_r11 +; X64: movq %[[REG]], %r11 +; X64: jmp __llvm_lvi_thunk_r11 # TAILCALL +; X64FAST-LABEL: nonlazybind_caller: +; X64FAST: movq nonlazybind_callee at GOTPCREL(%rip), %r11 +; X64FAST: callq __llvm_lvi_thunk_r11 +; X64FAST: movq nonlazybind_callee at GOTPCREL(%rip), %r11 +; X64FAST: jmp __llvm_lvi_thunk_r11 # TAILCALL + + +; Check that a switch gets lowered using a jump table +define void @switch_jumptable(i32* %ptr, i64* %sink) #0 { +; X64-LABEL: switch_jumptable: +; X64_NOT: jmpq * +entry: + br label %header + +header: + %i = load volatile i32, i32* %ptr + switch i32 %i, label %bb0 [ + i32 1, label %bb1 + i32 2, label %bb2 + i32 3, label %bb3 + i32 4, label %bb4 + i32 5, label %bb5 + i32 6, label %bb6 + i32 7, label %bb7 + i32 8, label %bb8 + i32 9, label %bb9 + ] + +bb0: + store volatile i64 0, i64* %sink + br label %header + +bb1: + store volatile i64 1, i64* %sink + br label %header + +bb2: + store volatile i64 2, i64* %sink + br label %header + +bb3: + store volatile i64 3, i64* %sink + br label %header + +bb4: + store volatile i64 4, i64* %sink + br label %header + +bb5: + store volatile i64 5, i64* %sink + br label %header + +bb6: + store volatile i64 6, i64* %sink + br label %header + +bb7: + store volatile i64 7, i64* %sink + br label %header + +bb8: + store volatile i64 8, i64* %sink + br label %header + +bb9: + store volatile i64 9, i64* %sink + br label %header +} + + + at indirectbr_rewrite.targets = constant [10 x i8*] [i8* blockaddress(@indirectbr_rewrite, %bb0), + i8* blockaddress(@indirectbr_rewrite, %bb1), + i8* blockaddress(@indirectbr_rewrite, %bb2), + i8* blockaddress(@indirectbr_rewrite, %bb3), + i8* blockaddress(@indirectbr_rewrite, %bb4), + i8* blockaddress(@indirectbr_rewrite, %bb5), + i8* blockaddress(@indirectbr_rewrite, %bb6), + i8* blockaddress(@indirectbr_rewrite, %bb7), + i8* blockaddress(@indirectbr_rewrite, %bb8), + i8* blockaddress(@indirectbr_rewrite, %bb9)] + +; Check that when thunks are enabled the indirectbr instruction gets +; rewritten to use switch, and that in turn doesn't get lowered as a jump +; table. +define void @indirectbr_rewrite(i64* readonly %p, i64* %sink) #0 { +; X64-LABEL: indirectbr_rewrite: +; X64-NOT: jmpq * +entry: + %i0 = load i64, i64* %p + %target.i0 = getelementptr [10 x i8*], [10 x i8*]* @indirectbr_rewrite.targets, i64 0, i64 %i0 + %target0 = load i8*, i8** %target.i0 + indirectbr i8* %target0, [label %bb1, label %bb3] + +bb0: + store volatile i64 0, i64* %sink + br label %latch + +bb1: + store volatile i64 1, i64* %sink + br label %latch + +bb2: + store volatile i64 2, i64* %sink + br label %latch + +bb3: + store volatile i64 3, i64* %sink + br label %latch + +bb4: + store volatile i64 4, i64* %sink + br label %latch + +bb5: + store volatile i64 5, i64* %sink + br label %latch + +bb6: + store volatile i64 6, i64* %sink + br label %latch + +bb7: + store volatile i64 7, i64* %sink + br label %latch + +bb8: + store volatile i64 8, i64* %sink + br label %latch + +bb9: + store volatile i64 9, i64* %sink + br label %latch + +latch: + %i.next = load i64, i64* %p + %target.i.next = getelementptr [10 x i8*], [10 x i8*]* @indirectbr_rewrite.targets, i64 0, i64 %i.next + %target.next = load i8*, i8** %target.i.next + ; Potentially hit a full 10 successors here so that even if we rewrite as + ; a switch it will try to be lowered with a jump table. + indirectbr i8* %target.next, [label %bb0, + label %bb1, + label %bb2, + label %bb3, + label %bb4, + label %bb5, + label %bb6, + label %bb7, + label %bb8, + label %bb9] +} + +; Lastly check that the necessary thunks were emitted. +; +; X64-LABEL: .section .text.__llvm_lvi_thunk_r11,{{.*}},__llvm_lvi_thunk_r11,comdat +; X64-NEXT: .hidden __llvm_lvi_thunk_r11 +; X64-NEXT: .weak __llvm_lvi_thunk_r11 +; X64: __llvm_lvi_thunk_r11: +; X64-NEXT: # {{.*}} # %entry +; X64-NEXT: lfence +; X64-NEXT: jmpq *%r11 + +attributes #1 = { nonlazybind } From cfe-commits at lists.llvm.org Fri Apr 3 01:02:30 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 08:02:30 +0000 (UTC) Subject: [PATCH] D77348: [clangd] Enable some nice clang-tidy checks by default. In-Reply-To: References: Message-ID: <7ef8071819dec6e834d7db1ba3ff58c7@localhost.localdomain> hokein accepted this revision. hokein added inline comments. This revision is now accepted and ready to land. ================ Comment at: clang-tools-extra/clangd/tool/ClangdMain.cpp:695 + auto EmptyDefaults = tidy::ClangTidyOptions::getDefaults(); + EmptyDefaults.Checks.reset(); // So we can tell if checks were ever set. + tidy::ClangTidyOptions OverrideClangTidyOptions; ---------------- `EmptyDefaults.Checks` is not none, but it is an empty string I think , we could even assign our default checks to `EmptyDefaults.Checks` (instead of setting it in `GetCalngTidyOptions`). ================ Comment at: clang-tools-extra/clangd/tool/ClangdMain.cpp:724 + "readability-deleted-default", "bugprone-integer-division", + "bugprone-sizeof-expression", "bugprone-suspicious-include", + "bugprone-suspicious-missing-comma", "bugprone-unused-raii", ---------------- `bugprone-suspicious-include` is a fairly new check, and hasn't been run internally, so I'd be conservative, not enable it. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77348/new/ https://reviews.llvm.org/D77348 From cfe-commits at lists.llvm.org Fri Apr 3 01:02:45 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 08:02:45 +0000 (UTC) Subject: [PATCH] D76812: [X86] Add Indirect Thunk Support to X86 to mitigate Load Value Injection (LVI) [3/3] In-Reply-To: References: Message-ID: <1f8d5065187d098b97396aad8ec04c33@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG5b519cf1fc67: [X86] Add Indirect Thunk Support to X86 to mitigate Load Value Injection (LVI) (authored by sconstab, committed by craig.topper). Herald added a project: clang. Changed prior to commit: https://reviews.llvm.org/D76812?vs=254276&id=254720#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76812/new/ https://reviews.llvm.org/D76812 Files: clang/docs/ClangCommandLineReference.rst clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Arch/X86.cpp clang/test/Driver/x86-target-features.c llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86ISelLowering.cpp llvm/lib/Target/X86/X86IndirectThunks.cpp llvm/lib/Target/X86/X86Subtarget.h llvm/test/CodeGen/X86/lvi-hardening-indirectbr.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D76812.254720.patch Type: text/x-patch Size: 19715 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 01:34:54 2020 From: cfe-commits at lists.llvm.org (Carlos Alberto Enciso via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 08:34:54 +0000 (UTC) Subject: [PATCH] D77184: Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang In-Reply-To: References: Message-ID: CarlosAlbertoEnciso added a comment. In D77184#1957632 , @thakis wrote: > Thanks! Hi, After the series of changes you have done, I am experiencing a build error on Windows. These are some of the errors: - Attribute ignored -- Loadable modules not supported on this platform. Traceback (most recent call last): File "", line 1, in File "", line 1, in File "C:\ProgramData\Python27\lib\ntpath.py", line 529, in relpath % (path_prefix, start_prefix)) ValueError: path is on drive X:, start on drive E: CMake Error at X:/llvm-root/llvm-project/llvm/cmake/modules/AddLLVM.cmake:1508 (message): PATHS lengths got confused Call Stack (most recent call first): X:/llvm-root/llvm-project/clang/test/CMakeLists.txt:33 (configure_lit_site_cfg) CMake Error at X:/llvm-root/llvm-project/llvm/cmake/modules/AddLLVM.cmake:1517 (list): list GET given empty list Call Stack (most recent call first): X:/llvm-root/llvm-project/clang/test/CMakeLists.txt:33 (configure_lit_site_cfg) CMake Error at X:/llvm-root/llvm-project/llvm/cmake/modules/AddLLVM.cmake:1517 (list): list GET given empty list Call Stack (most recent call first): X:/llvm-root/llvm-project/clang/test/CMakeLists.txt:33 (configure_lit_site_cfg) CMake Error at X:/llvm-root/llvm-project/llvm/cmake/modules/AddLLVM.cmake:1517 (list): list GET given empty list Call Stack (most recent call first): X:/llvm-root/llvm-project/clang/test/CMakeLists.txt:33 (configure_lit_site_cfg) CMake Error at X:/llvm-root/llvm-project/llvm/cmake/modules/AddLLVM.cmake:1517 (list): list GET given empty list Call Stack (most recent call first): X:/llvm-root/llvm-project/clang/test/CMakeLists.txt:33 (configure_lit_site_cfg) My CMake command line is: E:\llvm-root\builds\win\debug\x64>cmake -G"Visual Studio 15 2017 Win64" -Thost=x64 -DCMAKE_BUILD_TYPE=Debug -DLLVM_DEFAULT_TARGET_TRIPLE=x86_64-pc-linux-gnu -DLLVM_ENABLE_PROJECTS="clang" x:\llvm-root\llvm-project\llvm -DLLVM_ENABLE_ZLIB=OFF Drive E: contains the build files Drive X: contains the llvm sources The only way to have a successful build is to revert : ab11b9eefa16661017c2c7b3b34c46b069f43fb7 Thanks Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77184/new/ https://reviews.llvm.org/D77184 From cfe-commits at lists.llvm.org Fri Apr 3 01:34:54 2020 From: cfe-commits at lists.llvm.org (Vitaly Buka via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 08:34:54 +0000 (UTC) Subject: [PATCH] D77373: Add more -fsanitize=array-bounds tests Message-ID: vitalybuka created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77373 Files: clang/test/CodeGen/bounds-checking.c clang/test/CodeGen/bounds-checking.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77373.254723.patch Type: text/x-patch Size: 5001 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 02:07:24 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Endre_F=C3=BCl=C3=B6p_via_Phabricator?= via cfe-commits) Date: Fri, 03 Apr 2020 09:07:24 +0000 (UTC) Subject: [PATCH] D77229: [Analyzer][WIP] Avoid handling of LazyCompundVals in IteratorModeling In-Reply-To: References: Message-ID: gamesh411 added inline comments. ================ Comment at: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h:436 + /// context from where the region of its return value can be retrieved. + const ConstructionContext *getConstructionContext(unsigned BlockCount) const; + ---------------- Maybe indicating wheter the call returns a C++ record type should be done via using and Optional here (to modernize the api)? ================ Comment at: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp:342 + if (const auto *CC = Call.getConstructionContext(C.blockCount())) { + llvm::errs()<<" Bingo!\n"; + auto &Engine = C.getExprEngine(); ---------------- Debug comment left here :) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77229/new/ https://reviews.llvm.org/D77229 From cfe-commits at lists.llvm.org Fri Apr 3 02:07:26 2020 From: cfe-commits at lists.llvm.org (Vitaly Buka via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 09:07:26 +0000 (UTC) Subject: [PATCH] D77374: Fix -fsanitize=array-bounds with comma operator Message-ID: vitalybuka created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. vitalybuka added a reviewer: rsmith. vitalybuka updated this revision to Diff 254728. vitalybuka added a comment. vitalybuka marked 2 inline comments as done. remove debug dump ================ Comment at: clang/test/CodeGen/bounds-checking.c:116 + // CHECK-NOT: @llvm.trap + return (s->t, s->a)[i]; + // CHECK: } ---------------- C version works even without patch Depends on D77373 . Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77374 Files: clang/lib/CodeGen/CGExpr.cpp clang/test/CodeGen/bounds-checking.c clang/test/CodeGen/bounds-checking.cpp Index: clang/test/CodeGen/bounds-checking.cpp =================================================================== --- clang/test/CodeGen/bounds-checking.cpp +++ clang/test/CodeGen/bounds-checking.cpp @@ -98,3 +98,19 @@ return s->a[i]; // CHECK: } } + +// CHECK-LABEL: define {{.*}} @_Z10SFlexComma +int SFlexComma(struct SFlex *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return (s->t, s->a)[i]; + // CHECK: } +} + +// CHECK-LABEL: define {{.*}} @_Z7S1Comma +int S1Comma(struct S1 *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return ((s->t, (1, s->a)))[i]; + // CHECK: } +} Index: clang/test/CodeGen/bounds-checking.c =================================================================== --- clang/test/CodeGen/bounds-checking.c +++ clang/test/CodeGen/bounds-checking.c @@ -100,3 +100,19 @@ return s->a[i]; // CHECK: } } + +// CHECK-LABEL: define {{.*}} @SFlexComma +int SFlexComma(struct SFlex *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return (s->t, s->a)[i]; + // CHECK: } +} + +// CHECK-LABEL: define {{.*}} @S1Comma +int S1Comma(struct S1 *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return (s->t, s->a)[i]; + // CHECK: } +} Index: clang/lib/CodeGen/CGExpr.cpp =================================================================== --- clang/lib/CodeGen/CGExpr.cpp +++ clang/lib/CodeGen/CGExpr.cpp @@ -879,6 +879,13 @@ E = E->IgnoreParens(); + while (const BinaryOperator *BO = dyn_cast(E)) { + if (!BO->isCommaOp()) + break; + E = BO->getRHS(); + E = E->IgnoreParens(); + } + // A flexible array member must be the last member in the class. if (const auto *ME = dyn_cast(E)) { // FIXME: If the base type of the member expr is not FD->getParent(), -------------- next part -------------- A non-text attachment was scrubbed... Name: D77374.254728.patch Type: text/x-patch Size: 1938 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 02:07:26 2020 From: cfe-commits at lists.llvm.org (Marcus Johnson via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 09:07:26 +0000 (UTC) Subject: [PATCH] D75791: [clang-format] Added new option IndentExternBlock In-Reply-To: References: Message-ID: MarcusJohnson91 added a comment. I agree that changing formatting randomly isn't a good idea, and I think converting AfterExternBlock to an enum is the way to go, but I'm just not sure on how it should be implemented. Ok, I've got an idea to deprecate the AfterExternBlock option and map it to a new option, I'm gonna start implementing it right now. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75791/new/ https://reviews.llvm.org/D75791 From cfe-commits at lists.llvm.org Fri Apr 3 02:07:27 2020 From: cfe-commits at lists.llvm.org (Vitaly Buka via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 09:07:27 +0000 (UTC) Subject: [PATCH] D77374: Fix -fsanitize=array-bounds with comma operator In-Reply-To: References: Message-ID: <14356c45b646b10e141c3fcfd4617e6e@localhost.localdomain> vitalybuka marked 2 inline comments as done. vitalybuka added inline comments. ================ Comment at: clang/test/CodeGen/bounds-checking.c:116 + // CHECK-NOT: @llvm.trap + return (s->t, s->a)[i]; + // CHECK: } ---------------- C version works even without patch Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77374/new/ https://reviews.llvm.org/D77374 From cfe-commits at lists.llvm.org Fri Apr 3 02:07:28 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 09:07:28 +0000 (UTC) Subject: [PATCH] D77355: [clangd] show layout info when hovering on a class/field definition. In-Reply-To: References: Message-ID: <03b87cd52a41586bb052cd1cff66dd59@localhost.localdomain> kadircet added inline comments. ================ Comment at: clang-tools-extra/clangd/Hover.cpp:571 + if (auto Size = Ctx.getTypeSizeInCharsIfKnown(RD->getTypeForDecl())) + HI.Size = Size->getQuantity(); + ---------------- QuantityType seems to be an alias for int64_t, not sure how likely it is that someone will have a type that's bigger than 4GB, but still, should we make typeof HoverInfo::Size optional instead of unsigned? ================ Comment at: clang-tools-extra/clangd/Hover.cpp:573 + + if (const auto *FD = llvm::dyn_cast(&ND)) { + const auto *Record = FD->getParent()->getDefinition(); ---------------- nit: either make this `else if` or put a return above ? ================ Comment at: clang-tools-extra/clangd/Hover.cpp:576 + if (Record && !Record->isDependentType()) { + unsigned OffsetBits = Ctx.getFieldOffset(FD); + if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType())) { ---------------- similar to size, offset is also of type uint64_t ================ Comment at: clang-tools-extra/clangd/unittests/HoverTests.cpp:69 struct Foo { - int [[b^ar]]; + char [[b^ar]]; }; ---------------- any reason for changing these from int to char ? ================ Comment at: clang-tools-extra/clangd/unittests/HoverTests.cpp:1830 HI.Kind = index::SymbolKind::Class; + HI.Size = 10; HI.TemplateParameters = { ---------------- maybe also add offset? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77355/new/ https://reviews.llvm.org/D77355 From cfe-commits at lists.llvm.org Fri Apr 3 02:07:28 2020 From: cfe-commits at lists.llvm.org (Vitaly Buka via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 09:07:28 +0000 (UTC) Subject: [PATCH] D77373: Add more -fsanitize=array-bounds tests In-Reply-To: References: Message-ID: vitalybuka updated this revision to Diff 254729. vitalybuka added a comment. tmp Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77373/new/ https://reviews.llvm.org/D77373 Files: clang/test/CodeGen/bounds-checking.c clang/test/CodeGen/bounds-checking.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77373.254729.patch Type: text/x-patch Size: 5001 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 02:07:29 2020 From: cfe-commits at lists.llvm.org (Vitaly Buka via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 09:07:29 +0000 (UTC) Subject: [PATCH] D77374: Fix -fsanitize=array-bounds with comma operator In-Reply-To: References: Message-ID: <969fbca5eb32cc3cfbee4c446b47d409@localhost.localdomain> vitalybuka updated this revision to Diff 254728. vitalybuka added a comment. remove debug dump Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77374/new/ https://reviews.llvm.org/D77374 Files: clang/lib/CodeGen/CGExpr.cpp clang/test/CodeGen/bounds-checking.c clang/test/CodeGen/bounds-checking.cpp Index: clang/test/CodeGen/bounds-checking.cpp =================================================================== --- clang/test/CodeGen/bounds-checking.cpp +++ clang/test/CodeGen/bounds-checking.cpp @@ -98,3 +98,19 @@ return s->a[i]; // CHECK: } } + +// CHECK-LABEL: define {{.*}} @_Z10SFlexComma +int SFlexComma(struct SFlex *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return (s->t, s->a)[i]; + // CHECK: } +} + +// CHECK-LABEL: define {{.*}} @_Z7S1Comma +int S1Comma(struct S1 *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return ((s->t, (1, s->a)))[i]; + // CHECK: } +} Index: clang/test/CodeGen/bounds-checking.c =================================================================== --- clang/test/CodeGen/bounds-checking.c +++ clang/test/CodeGen/bounds-checking.c @@ -100,3 +100,19 @@ return s->a[i]; // CHECK: } } + +// CHECK-LABEL: define {{.*}} @SFlexComma +int SFlexComma(struct SFlex *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return (s->t, s->a)[i]; + // CHECK: } +} + +// CHECK-LABEL: define {{.*}} @S1Comma +int S1Comma(struct S1 *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return (s->t, s->a)[i]; + // CHECK: } +} Index: clang/lib/CodeGen/CGExpr.cpp =================================================================== --- clang/lib/CodeGen/CGExpr.cpp +++ clang/lib/CodeGen/CGExpr.cpp @@ -879,6 +879,13 @@ E = E->IgnoreParens(); + while (const BinaryOperator *BO = dyn_cast(E)) { + if (!BO->isCommaOp()) + break; + E = BO->getRHS(); + E = E->IgnoreParens(); + } + // A flexible array member must be the last member in the class. if (const auto *ME = dyn_cast(E)) { // FIXME: If the base type of the member expr is not FD->getParent(), -------------- next part -------------- A non-text attachment was scrubbed... Name: D77374.254728.patch Type: text/x-patch Size: 1938 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 02:07:30 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 09:07:30 +0000 (UTC) Subject: [PATCH] D77194: [clang] Persist Attr::IsPackExpansion into the serialized AST In-Reply-To: References: Message-ID: kadircet accepted this revision. kadircet added a comment. This revision is now accepted and ready to land. thanks LGTM! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77194/new/ https://reviews.llvm.org/D77194 From cfe-commits at lists.llvm.org Fri Apr 3 03:11:49 2020 From: cfe-commits at lists.llvm.org (Florian Hahn via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 10:11:49 +0000 (UTC) Subject: [PATCH] D77335: [AST] clang::VectorType supports any size (that fits in unsigned) In-Reply-To: References: Message-ID: <4966eac86e185c3fe71b765b127ea82d@localhost.localdomain> fhahn added inline comments. ================ Comment at: clang/include/clang/AST/Type.h:3236 QualType ElementType; + unsigned NumElements; ---------------- I think you could keep NumElements in VectorTypeBitfields (just remove the bit specifier), as the size of those bitfields can be up to 8 bytes (see the static asserts around line 1775). That should be fine as long as NumTypeBits + 3 <= 32. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77335/new/ https://reviews.llvm.org/D77335 From cfe-commits at lists.llvm.org Fri Apr 3 03:11:49 2020 From: cfe-commits at lists.llvm.org (Roman Lebedev via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 10:11:49 +0000 (UTC) Subject: [PATCH] D70265: [clang-tidy] Add CppCoreGuidelines I.2 "Avoid non-const global variables" check In-Reply-To: References: Message-ID: <585034177059032d2ae969f821a7ad2d@localhost.localdomain> lebedev.ri added a comment. In D70265#1954925 , @vingeldal wrote: > After looking more closely at the code I think the issue is within hasLocalStorage() which is called in hasGlobalStorage(). My expectation would be that anything inside of function scope would be considered local but I'm not very certain. > Any thoughts on whether hasLocalStorage() should be modified or if I should change the check and use some more ad-hoc implementation, instead of hasGlobalStorage(), to determine if the variable is local or global? It's not ideal to have known-false-positive for long, so please post //some// fix, i think we'll figure it out there. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70265/new/ https://reviews.llvm.org/D70265 From cfe-commits at lists.llvm.org Fri Apr 3 03:11:49 2020 From: cfe-commits at lists.llvm.org (Sjoerd Meijer via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 10:11:49 +0000 (UTC) Subject: [PATCH] D76680: [SveEmitter] Add immediate checks for lanes and complex imms In-Reply-To: References: Message-ID: <62b10614ac2830557ea583c8db7dd313@localhost.localdomain> SjoerdMeijer added a comment. Looks good to me, but just one question about the tests. If I haven't overlooked anything, I don't see tests that check the new diagnostics: "argument should be the value 90 or 270" "argument should be the value 0,90,180 or 270" Should they be here, or are they somewhere else? ================ Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:9208 +def err_rotation_argument_to_cmla + : Error<"argument should be the value 0,90,180 or 270">; def warn_neon_vector_initializer_non_portable : Warning< ---------------- A proper nit, perhaps some spaces here: "0,90,180". Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76680/new/ https://reviews.llvm.org/D76680 From cfe-commits at lists.llvm.org Fri Apr 3 03:43:50 2020 From: cfe-commits at lists.llvm.org (Florian Hahn via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 10:43:50 +0000 (UTC) Subject: [PATCH] D77378: [Clang] Include size and maximum in vector size error message. Message-ID: fhahn created this revision. fhahn added reviewers: hokein, sammccall, rnk. Herald added a project: clang. The error message for invalid vector sizes can be a bit more helpful by including the actual maximum. This should match the recently added suggestions for error messages in the coding standard. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77378 Files: clang/include/clang/AST/Type.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaType.cpp clang/test/Sema/types.c clang/test/SemaCXX/vector.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77378.254738.patch Type: text/x-patch Size: 5124 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 03:43:50 2020 From: cfe-commits at lists.llvm.org (Sjoerd Meijer via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 10:43:50 +0000 (UTC) Subject: [PATCH] D76617: [SveEmitter] Fix encoding/decoding of SVETypeFlags In-Reply-To: References: Message-ID: SjoerdMeijer added inline comments. ================ Comment at: clang/utils/TableGen/SveEmitter.cpp:229 + // Returns the SVETypeFlags for a given value and mask. + unsigned encodeFlag(unsigned V, StringRef MaskName) const { + auto It = FlagTypes.find(MaskName); ---------------- Should `V` now be an `uint64_t`? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76617/new/ https://reviews.llvm.org/D76617 From cfe-commits at lists.llvm.org Fri Apr 3 03:43:51 2020 From: cfe-commits at lists.llvm.org (MyDeveloperDay via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 10:43:51 +0000 (UTC) Subject: [PATCH] D75791: [clang-format] Added new option IndentExternBlock In-Reply-To: References: Message-ID: <0c5c8d2868e7dd3a700bd3e1ef177bac@localhost.localdomain> MyDeveloperDay added a comment. > Ok, I've got an idea to deprecate the AfterExternBlock option and map it to a new option Really? can't you just model IndentExternBlock as an enum? then say bool shouldIndent = Style.IndentExternBlock==Indented || ( AfterExternBlock && Style.IndentExternBlock==NotSpecified) parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/shouldIndent); You can even keep "true" and "false" the the enumeration marshaller and you don't even have to change the documentation. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75791/new/ https://reviews.llvm.org/D75791 From cfe-commits at lists.llvm.org Fri Apr 3 03:43:52 2020 From: cfe-commits at lists.llvm.org (Martin Probst via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 10:43:52 +0000 (UTC) Subject: [PATCH] D77311: clang-format: [JS] detect C++ keywords. In-Reply-To: References: Message-ID: mprobst added a comment. Thanks for the feedback. Indeed, whitelisting the JS keywords is better, but we still needed a way to blacklist all C++ keywords then - Krasimir's suggestion with the #include did the trick, thanks. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77311/new/ https://reviews.llvm.org/D77311 From cfe-commits at lists.llvm.org Fri Apr 3 03:43:53 2020 From: cfe-commits at lists.llvm.org (Martin Probst via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 10:43:53 +0000 (UTC) Subject: [PATCH] D77311: clang-format: [JS] detect C++ keywords. In-Reply-To: References: Message-ID: <3ce3bf3df47cbb34293d49b18e1d36cd@localhost.localdomain> mprobst updated this revision to Diff 254740. mprobst added a comment. - - improve handling of keywors - rather than blacklisting all C++ Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77311/new/ https://reviews.llvm.org/D77311 Files: clang/lib/Format/FormatToken.h clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTestJS.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77311.254740.patch Type: text/x-patch Size: 6563 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 03:43:53 2020 From: cfe-commits at lists.llvm.org (Martin Probst via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 10:43:53 +0000 (UTC) Subject: [PATCH] D77311: clang-format: [JS] detect C++ keywords. In-Reply-To: References: Message-ID: mprobst updated this revision to Diff 254741. mprobst added a comment. - fix formatting Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77311/new/ https://reviews.llvm.org/D77311 Files: clang/lib/Format/FormatToken.h clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTestJS.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77311.254741.patch Type: text/x-patch Size: 6552 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 03:44:03 2020 From: cfe-commits at lists.llvm.org (Serge Pavlov via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 10:44:03 +0000 (UTC) Subject: [PATCH] D77379: [FPEnv] Use single enum to represent rounding mode Message-ID: sepavloff created this revision. sepavloff added reviewers: rjmccall, andrew.w.kaylor, arsenm, kpn, cameron.mcinally, uweigand. Herald added subscribers: dexonsmith, hiraditya, wdng. Herald added a project: clang. Now compiler defines 5 sets of constants to represent rounding mode. These are: 1. `llvm::APFloatBase::roundingMode`. It specifies all 5 rounding modes defined by IEEE-754 and is used in `APFloat` implementation. 2. `clang::LangOptions::FPRoundingModeKind`. It specifies 4 of 5 IEEE-754 rounding modes and a special value for dynamic rounding mode. It is used in clang frontend. 3. `llvm::fp::RoundingMode`. Defines the same values as `clang::LangOptions::FPRoundingModeKind` but in different order. It is used to specify rounding mode in IR and functions that operate IR. 4. Rounding mode representation used by `FLT_ROUNDS` (C11, 5.2.4.2.2p7). Besides constants for rounding mode it also defines a special value to indicate errors. It is convenient to use in intrinsic functions, as it is a platform-independent representation for rounding mode. In this role it is used in some pending patches. 5. Values like `FE_DOWNWARD` and other, which specify rounding mode in library calls `fesetround` and `fegetround`. Often they represent bits of some control register, so they are target-dependent. The same names (not values) and a special name `FE_DYNAMIC` are used in `#pragma STDC FENV_ROUND`. The first 4 sets of constants are target independent and could have the same numerical representation. It would simplify conversion between the representations. Also now `clang::LangOptions::FPRoundingModeKind` and `llvm::fp::RoundingMode` do not contain the value for IEEE-754 rounding direction `roundTiesToAway`, although it is supported natively on some targets. This change defines all the rounding mode types via one enumeration `llvm::RoundingMode`, which also contains rounding mode for IEEE rounding direction `roundTiesToAway`. This enumeration uses the encoding specified by C standard for `FLT_ROUNDS`, as it is the only representation in which numerical values of rounding modes is fixed. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77379 Files: clang/include/clang/Basic/LangOptions.def clang/include/clang/Basic/LangOptions.h clang/include/clang/Sema/Sema.h clang/lib/Basic/LangOptions.cpp clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/lib/Sema/SemaAttr.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Serialization/ASTReader.cpp llvm/include/llvm/ADT/APFloat.h llvm/include/llvm/ADT/FloatingPointMode.h llvm/include/llvm/IR/FPEnv.h llvm/include/llvm/IR/IRBuilder.h llvm/include/llvm/IR/IntrinsicInst.h llvm/lib/Analysis/ConstantFolding.cpp llvm/lib/IR/FPEnv.cpp llvm/lib/IR/IntrinsicInst.cpp llvm/lib/Support/APFloat.cpp llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp llvm/unittests/IR/IRBuilderTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77379.254743.patch Type: text/x-patch Size: 29244 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 03:44:24 2020 From: cfe-commits at lists.llvm.org (Florian Hahn via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 10:44:24 +0000 (UTC) Subject: [PATCH] D77378: [Clang] Include size and maximum in vector size error message. In-Reply-To: References: Message-ID: <312128afd7e7483b0ef924bc89620d78@localhost.localdomain> fhahn updated this revision to Diff 254744. fhahn added a comment. Fix wrong formatting of check lines.. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77378/new/ https://reviews.llvm.org/D77378 Files: clang/include/clang/AST/Type.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaType.cpp clang/test/Sema/types.c clang/test/SemaCXX/vector.cpp Index: clang/test/SemaCXX/vector.cpp =================================================================== --- clang/test/SemaCXX/vector.cpp +++ clang/test/SemaCXX/vector.cpp @@ -359,18 +359,18 @@ // expected-error@#1 {{vector size not an integral multiple of component size}} // expected-note at +1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} const TemplateVectorType::type BadSize; - // expected-error@#1 {{vector size too large}} + // expected-error@#1 {{vector size too large. Size is 8192 when the maximum allowed is 4092}} // expected-note at +1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} const TemplateVectorType::type TooLarge; // expected-error@#1 {{zero vector size}} // expected-note at +1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} const TemplateVectorType::type Zero; - // expected-error@#2 {{vector size too large}} + // expected-error@#2 {{vector size too large. Size is 8192 when the maximum allowed is 4092}} // expected-error@#3 {{vector size not an integral multiple of component size}} // expected-note at +1 {{in instantiation of template class 'Templates::PR15730<8, int>' requested here}} const PR15730<8, int>::type PR15730_1 = {}; - // expected-error@#2 {{vector size too large}} + // expected-error@#2 {{vector size too large. Size is 8192 when the maximum allowed is 1023}} // expected-note at +1 {{in instantiation of template class 'Templates::PR15730<8, char>' requested here}} const PR15730<8, char>::type2 PR15730_2 = {}; } Index: clang/test/Sema/types.c =================================================================== --- clang/test/Sema/types.c +++ clang/test/Sema/types.c @@ -70,8 +70,8 @@ } // vector size too large -int __attribute__ ((vector_size(8192))) x1; // expected-error {{vector size too large}} -typedef int __attribute__ ((ext_vector_type(8192))) x2; // expected-error {{vector size too large}} +int __attribute__((vector_size(8192))) x1; // expected-error {{vector size too large. Size is 8192 when the maximum allowed is 4092}} +typedef int __attribute__((ext_vector_type(8192))) x2; // expected-error {{vector size too large. Size is 8192 when the maximum allowed is 1023}} // no support for vector enum type enum { e_2 } x3 __attribute__((vector_size(64))); // expected-error {{invalid vector element type}} Index: clang/lib/Sema/SemaType.cpp =================================================================== --- clang/lib/Sema/SemaType.cpp +++ clang/lib/Sema/SemaType.cpp @@ -2453,7 +2453,10 @@ if (VectorType::isVectorSizeTooLarge(VectorSize / TypeSize)) { Diag(AttrLoc, diag::err_attribute_size_too_large) - << SizeExpr->getSourceRange(); + // Display sizes in error messages in bytes. + << SizeExpr->getSourceRange() + << static_cast(VecSize.getZExtValue()) + << (VectorType::getMaxNumElements() * (TypeSize / 8)); return QualType(); } @@ -2501,7 +2504,8 @@ if (VectorType::isVectorSizeTooLarge(vectorSize)) { Diag(AttrLoc, diag::err_attribute_size_too_large) - << ArraySize->getSourceRange(); + << ArraySize->getSourceRange() << vectorSize + << VectorType::getMaxNumElements(); return QualType(); } Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2868,7 +2868,7 @@ def err_attribute_invalid_size : Error< "vector size not an integral multiple of component size">; def err_attribute_zero_size : Error<"zero vector size">; -def err_attribute_size_too_large : Error<"vector size too large">; +def err_attribute_size_too_large : Error<"vector size too large. Size is %0 when the maximum allowed is %1">; def err_typecheck_vector_not_convertable_implict_truncation : Error< "cannot convert between %select{scalar|vector}0 type %1 and vector type" " %2 as implicit conversion would cause truncation">; Index: clang/include/clang/AST/Type.h =================================================================== --- clang/include/clang/AST/Type.h +++ clang/include/clang/AST/Type.h @@ -3253,6 +3253,10 @@ return NumElements > VectorTypeBitfields::MaxNumElements; } + static unsigned getMaxNumElements() { + return VectorTypeBitfields::MaxNumElements; + } + bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77378.254744.patch Type: text/x-patch Size: 4681 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 03:48:37 2020 From: cfe-commits at lists.llvm.org (Benjamin Kramer via cfe-commits) Date: Fri, 03 Apr 2020 03:48:37 -0700 (PDT) Subject: [clang-tools-extra] 02cb21d - Make helpers static. NFC. Message-ID: <5e871485.1c69fb81.c7187.a6e6@mx.google.com> Author: Benjamin Kramer Date: 2020-04-03T12:48:25+02:00 New Revision: 02cb21df3f4a8c27f3c84fc27e435433fe7f5653 URL: https://github.com/llvm/llvm-project/commit/02cb21df3f4a8c27f3c84fc27e435433fe7f5653 DIFF: https://github.com/llvm/llvm-project/commit/02cb21df3f4a8c27f3c84fc27e435433fe7f5653.diff LOG: Make helpers static. NFC. Added: Modified: clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp lld/COFF/InputFiles.cpp mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp index d30552734679..2e30a3b403e8 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -296,8 +296,8 @@ static bool IsNOLINTFound(StringRef NolintDirectiveText, StringRef Line, return true; } -llvm::Optional getBuffer(const SourceManager &SM, FileID File, - bool AllowIO) { +static llvm::Optional getBuffer(const SourceManager &SM, FileID File, + bool AllowIO) { // This is similar to the implementation of SourceManager::getBufferData(), // but uses ContentCache::getRawBuffer() rather than getBuffer() if // AllowIO=false, to avoid triggering file I/O if the file contents aren't diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index 8cf2a037af54..afe8ef455336 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -829,7 +829,7 @@ Optional ObjFile::getDILineInfo(uint32_t offset, return dwarf->getDILineInfo(offset, sectionIndex); } -StringRef ltrim1(StringRef s, const char *chars) { +static StringRef ltrim1(StringRef s, const char *chars) { if (!s.empty() && strchr(chars, s[0])) return s.substr(1); return s; diff --git a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp index 077b34c320ec..24dcf7370943 100644 --- a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp +++ b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp @@ -862,7 +862,7 @@ static LogicalResult verify(ConvOp op) { } template -LogicalResult verifySingleInputPoolingOp(PoolingOp op) { +static LogicalResult verifySingleInputPoolingOp(PoolingOp op) { auto inputType = op.input().getType().template cast(); auto outputType = op.output().getType().template cast(); if (outputType.getElementType() != inputType.getElementType()) From cfe-commits at lists.llvm.org Fri Apr 3 03:48:42 2020 From: cfe-commits at lists.llvm.org (Benjamin Kramer via cfe-commits) Date: Fri, 03 Apr 2020 03:48:42 -0700 (PDT) Subject: [clang] 6aecf0c - Drop unused diagnostic. NFC. Message-ID: <5e87148a.1c69fb81.a790b.8876@mx.google.com> Author: Benjamin Kramer Date: 2020-04-03T12:48:25+02:00 New Revision: 6aecf0cfef04e282d2840eb01f998f281d1e7c75 URL: https://github.com/llvm/llvm-project/commit/6aecf0cfef04e282d2840eb01f998f281d1e7c75 DIFF: https://github.com/llvm/llvm-project/commit/6aecf0cfef04e282d2840eb01f998f281d1e7c75.diff LOG: Drop unused diagnostic. NFC. Added: Modified: clang/include/clang/Basic/DiagnosticSemaKinds.td Removed: ################################################################################ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 901ac758b383..6ccb1c4af951 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9762,8 +9762,6 @@ def err_omp_ambiguous_conversion : Error< "enumeration type">; def err_omp_iterator_not_integral_or_pointer : Error< "expected integral or pointer type as the iterator-type, not %0">; -def err_omp_iterator_constant : Error< - "expected non-constant type as the iterator-type, constant %0 is provided">; def err_omp_iterator_step_not_integral : Error< "iterator step expression %0 is not the integral expression">; def err_omp_iterator_step_constant_zero : Error< From cfe-commits at lists.llvm.org Fri Apr 3 04:16:02 2020 From: cfe-commits at lists.llvm.org (Kerry McLaughlin via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 11:16:02 +0000 (UTC) Subject: [PATCH] D77054: [AArch64][SVE] Add SVE intrinsics for saturating add & subtract In-Reply-To: References: Message-ID: <1c1ae647cccef81801a91b6dbac399c0@localhost.localdomain> kmclaughlin updated this revision to Diff 254742. kmclaughlin added a comment. Moved patterns for the new intrinsics into the// sve_int_bin_cons_arit_0// and //sve_int_arith_imm0// multiclasses CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77054/new/ https://reviews.llvm.org/D77054 Files: llvm/include/llvm/IR/IntrinsicsAArch64.td llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td llvm/lib/Target/AArch64/SVEInstrFormats.td llvm/test/CodeGen/AArch64/sve-intrinsics-int-arith-imm.ll llvm/test/CodeGen/AArch64/sve-intrinsics-int-arith.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D77054.254742.patch Type: text/x-patch Size: 33114 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 04:16:03 2020 From: cfe-commits at lists.llvm.org (Florian Hahn via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 11:16:03 +0000 (UTC) Subject: [PATCH] D72281: [Matrix] Add matrix type to Clang. In-Reply-To: References: Message-ID: <2ee328ea51085068eb1d8288e094bf87@localhost.localdomain> fhahn updated this revision to Diff 254746. fhahn marked an inline comment as done. fhahn added a comment. Use 20 bits in MatrixTypeBitfields for both number of rows and number of columns. This leaves 24 bits for NumTypeBits, while providing a large ranges for number of rows/columns. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72281/new/ https://reviews.llvm.org/D72281 Files: clang/include/clang/AST/ASTContext.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/AST/Type.h clang/include/clang/AST/TypeLoc.h clang/include/clang/AST/TypeProperties.td clang/include/clang/Basic/Attr.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Basic/LangOptions.def clang/include/clang/Basic/TypeNodes.td clang/include/clang/Driver/Options.td clang/include/clang/Sema/Sema.h clang/include/clang/Serialization/TypeBitCodes.def clang/lib/AST/ASTContext.cpp clang/lib/AST/ASTStructuralEquivalence.cpp clang/lib/AST/ExprConstant.cpp clang/lib/AST/ItaniumMangle.cpp clang/lib/AST/MicrosoftMangle.cpp clang/lib/AST/Type.cpp clang/lib/AST/TypePrinter.cpp clang/lib/Basic/Targets/OSTargets.cpp clang/lib/CodeGen/CGDebugInfo.cpp clang/lib/CodeGen/CGDebugInfo.h clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CodeGenFunction.cpp clang/lib/CodeGen/CodeGenTypes.cpp clang/lib/CodeGen/ItaniumCXXABI.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaLookup.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/lib/Sema/SemaType.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/test/CodeGen/matrix-type.c clang/test/CodeGenCXX/matrix-type.cpp clang/test/SemaCXX/matrix-type.cpp clang/tools/libclang/CIndex.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D72281.254746.patch Type: text/x-patch Size: 80055 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 04:16:04 2020 From: cfe-commits at lists.llvm.org (Denys Petrov via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 11:16:04 +0000 (UTC) Subject: [PATCH] D77062: [analyzer] Added check for unacceptable equality operation between Loc and NonLoc types In-Reply-To: References: Message-ID: <7f1c03619772a25cef9853e1ffa315d8@localhost.localdomain> ASDenysPetrov added a comment. @Szelethus , @NoQ please, look at my solution. I'm not sure if it is correct, but it actually passes all the tests and throw off the issue. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77062/new/ https://reviews.llvm.org/D77062 From cfe-commits at lists.llvm.org Fri Apr 3 04:16:04 2020 From: cfe-commits at lists.llvm.org (Aaron Ballman via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 11:16:04 +0000 (UTC) Subject: [PATCH] D77194: [clang] Persist Attr::IsPackExpansion into the serialized AST In-Reply-To: References: Message-ID: <66482c24a6a5eab822ceddef781818fa@localhost.localdomain> aaron.ballman accepted this revision. aaron.ballman added a comment. LGTM! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77194/new/ https://reviews.llvm.org/D77194 From cfe-commits at lists.llvm.org Fri Apr 3 04:16:06 2020 From: cfe-commits at lists.llvm.org (MyDeveloperDay via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 11:16:06 +0000 (UTC) Subject: [PATCH] D77311: clang-format: [JS] detect C++ keywords. In-Reply-To: References: Message-ID: <1d362f4c97a6711d080e55ba3e81ab3b@localhost.localdomain> MyDeveloperDay accepted this revision. MyDeveloperDay added a comment. I think this LGTM and brings more clarity as its much easier to look for things in the positive than the negative Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77311/new/ https://reviews.llvm.org/D77311 From cfe-commits at lists.llvm.org Fri Apr 3 04:16:06 2020 From: cfe-commits at lists.llvm.org (MyDeveloperDay via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 11:16:06 +0000 (UTC) Subject: [PATCH] D33029: [clang-format] add option for dangling parenthesis In-Reply-To: References: Message-ID: MyDeveloperDay added a comment. > I personally say fuck backwards compatibility when maintaining it requires ever more workarounds to fix an obviously flawed abstraction, but I'm just some dude and AFAIK the guys in charge support the status quo. When LLVM itself isn't prepared to run clang-format over the the whole project because of the churn and the annoyance it would cause for existing forks and "git blame" (despite their being work around to ignore whitespace change commits), Then I feel we have to keep one eye on ensuring we allow people to incrementally upgrade their clang-format. Even including a new option to the .clang-format file is a problem because it forces all users of that project to upgrade to a version of clang-format that recognises the option or clang-format will complain. With this in mind it means we need to allow existing users to use new binaries which where possible has zero changes to the code UNLESS they use the option. (even if that means many people delaying in using an option until its been supported for some time) With Visual Studio and ClangPower tools always lagging behind the current capabilities due to the binaries they ship, we need to understand it may be a year+ before the majority of users are on a version that supports such changes. Then we can multiply that annoyance to every other project using clang-format (both public and private projects), and so whilst a commit that changes such things are good by their own merit, that goodness might be lost in the noise of the complaints that come from time to time that clang-format causes huge changes version to version (even when those changes are bug fixes, let alone new features) This is not about supporting the status quo, but about ensuring we aren't fairly/unfairly the brunt of peoples complaints. (https://travisdowns.github.io/blog/2019/11/19/toupper.html, http://lists.llvm.org/pipermail/cfe-dev/2017-June/054342.html) CHANGES SINCE LAST ACTION https://reviews.llvm.org/D33029/new/ https://reviews.llvm.org/D33029 From cfe-commits at lists.llvm.org Fri Apr 3 04:16:06 2020 From: cfe-commits at lists.llvm.org (MyDeveloperDay via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 11:16:06 +0000 (UTC) Subject: [PATCH] D33029: [clang-format] add option for dangling parenthesis In-Reply-To: References: Message-ID: MyDeveloperDay added a comment. In D33029#1951346 , @bbassi wrote: > @MyDeveloperDay Can you please share your thoughts on my comment above? I'm tempted to agree that perhaps having as an enumeration `BreakBeforeClosingBracket` with various options might give us greater control its recently also come to my attention that perhaps we should NEVER use a boolean as an option, as nearly every option that started out as a boolean ended up either needing to add another additional new option or being changed from a boolean to an enumeration later. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D33029/new/ https://reviews.llvm.org/D33029 From cfe-commits at lists.llvm.org Fri Apr 3 04:16:07 2020 From: cfe-commits at lists.llvm.org (Krasimir Georgiev via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 11:16:07 +0000 (UTC) Subject: [PATCH] D77311: clang-format: [JS] detect C++ keywords. In-Reply-To: References: Message-ID: <4d14a77168d3cfb0f1486a903f2c0374@localhost.localdomain> krasimir accepted this revision. krasimir added a comment. This revision is now accepted and ready to land. Thank you! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77311/new/ https://reviews.llvm.org/D77311 From cfe-commits at lists.llvm.org Fri Apr 3 04:48:23 2020 From: cfe-commits at lists.llvm.org (Krasimir Georgiev via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 11:48:23 +0000 (UTC) Subject: [PATCH] D77311: clang-format: [JS] detect C++ keywords. In-Reply-To: References: Message-ID: <108e00d3d71e90d152a3bc99f3c0770f@localhost.localdomain> krasimir added inline comments. ================ Comment at: clang/lib/Format/FormatToken.h:913 bool IsJavaScriptIdentifier(const FormatToken &Tok) const { - return Tok.is(tok::identifier) && - JsExtraKeywords.find(Tok.Tok.getIdentifierInfo()) == - JsExtraKeywords.end(); + switch (Tok.Tok.getKind()) { + case tok::kw_break: ---------------- nit: may be worth adding a comment linking to: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77311/new/ https://reviews.llvm.org/D77311 From cfe-commits at lists.llvm.org Fri Apr 3 05:20:37 2020 From: cfe-commits at lists.llvm.org (Martin Probst via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 12:20:37 +0000 (UTC) Subject: [PATCH] D77311: clang-format: [JS] detect C++ keywords. In-Reply-To: References: Message-ID: mprobst marked 2 inline comments as done. mprobst added inline comments. ================ Comment at: clang/lib/Format/FormatToken.h:913 bool IsJavaScriptIdentifier(const FormatToken &Tok) const { - return Tok.is(tok::identifier) && - JsExtraKeywords.find(Tok.Tok.getIdentifierInfo()) == - JsExtraKeywords.end(); + switch (Tok.Tok.getKind()) { + case tok::kw_break: ---------------- krasimir wrote: > nit: may be worth adding a comment linking to: > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords Done, though I used the TS list of keywords (as it's a superset of the JS keywords). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77311/new/ https://reviews.llvm.org/D77311 From cfe-commits at lists.llvm.org Fri Apr 3 05:20:38 2020 From: cfe-commits at lists.llvm.org (Andrew Ng via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 12:20:38 +0000 (UTC) Subject: [PATCH] D77184: Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang In-Reply-To: References: Message-ID: andrewng added a comment. The following patch fixes my issues on Windows, but I haven't tested that it doesn't break anything else: diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index 91bec7d8081..f630af211fd 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -1495,7 +1495,7 @@ function(configure_lit_site_cfg site_in site_out) string(REPLACE ";" "\\;" ARG_PATH_VALUES_ESCAPED "${ARG_PATH_VALUES}") get_filename_component(OUTPUT_DIR ${site_out} DIRECTORY) execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" - "import os, sys; sys.stdout.write(';'.join(os.path.relpath(p, sys.argv[1]).replace(os.sep, '/') if p else '' for p in sys.argv[2].split(';')))" + "import os, sys; drive = os.path.splitdrive(sys.argv[1])[0]; sys.stdout.write(';'.join('' if not p else p if os.path.splitdrive(p)[0] != drive else os.path.relpath(p, sys.argv[1]).replace(os.sep, '/') for p in sys.argv[2].split(';')))" ${OUTPUT_DIR} ${ARG_PATH_VALUES_ESCAPED} OUTPUT_VARIABLE ARG_PATH_VALUES_RELATIVE) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77184/new/ https://reviews.llvm.org/D77184 From cfe-commits at lists.llvm.org Fri Apr 3 05:20:39 2020 From: cfe-commits at lists.llvm.org (Andrzej Warzynski via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 12:20:39 +0000 (UTC) Subject: [PATCH] D76929: [AArch64][SVE] Add SVE intrinsic for LD1RQ In-Reply-To: References: Message-ID: <62b14c93d766cfae392e9b06631a3e87@localhost.localdomain> andwar added a comment. Btw, could you also add some negative tests? (e.g. out-of-range immediate) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76929/new/ https://reviews.llvm.org/D76929 From cfe-commits at lists.llvm.org Fri Apr 3 05:24:07 2020 From: cfe-commits at lists.llvm.org (Martin Probst via cfe-commits) Date: Fri, 03 Apr 2020 05:24:07 -0700 (PDT) Subject: [clang] 146d685 - clang-format: [JS] detect C++ keywords. Message-ID: <5e872ae7.1c69fb81.74310.ae8b@mx.google.com> Author: Martin Probst Date: 2020-04-03T14:23:56+02:00 New Revision: 146d685cd657399a4698015f16cc5910cc828728 URL: https://github.com/llvm/llvm-project/commit/146d685cd657399a4698015f16cc5910cc828728 DIFF: https://github.com/llvm/llvm-project/commit/146d685cd657399a4698015f16cc5910cc828728.diff LOG: clang-format: [JS] detect C++ keywords. Summary: C++ defines a number of keywords that are regular identifiers in JavaScript, e.g. `concept`: const concept = 1; // legit JS This change expands the existing `IsJavaScriptIdentifier(Tok)` function to return false for C++ keywords that aren't keywords in JS. Reviewers: krasimir Subscribers: jfb, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77311 Added: Modified: clang/lib/Format/FormatToken.h clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTestJS.cpp Removed: ################################################################################ diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 10a5f0e96f96..48ec7602c21c 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -910,9 +910,64 @@ struct AdditionalKeywords { /// Returns \c true if \p Tok is a true JavaScript identifier, returns /// \c false if it is a keyword or a pseudo keyword. bool IsJavaScriptIdentifier(const FormatToken &Tok) const { - return Tok.is(tok::identifier) && - JsExtraKeywords.find(Tok.Tok.getIdentifierInfo()) == - JsExtraKeywords.end(); + // Based on the list of JavaScript & TypeScript keywords here: + // https://github.com/microsoft/TypeScript/blob/master/src/compiler/scanner.ts#L74 + switch (Tok.Tok.getKind()) { + case tok::kw_break: + case tok::kw_case: + case tok::kw_catch: + case tok::kw_class: + case tok::kw_continue: + case tok::kw_const: + case tok::kw_default: + case tok::kw_delete: + case tok::kw_do: + case tok::kw_else: + case tok::kw_enum: + case tok::kw_export: + case tok::kw_false: + case tok::kw_for: + case tok::kw_if: + case tok::kw_import: + case tok::kw_module: + case tok::kw_new: + case tok::kw_private: + case tok::kw_protected: + case tok::kw_public: + case tok::kw_return: + case tok::kw_static: + case tok::kw_switch: + case tok::kw_this: + case tok::kw_throw: + case tok::kw_true: + case tok::kw_try: + case tok::kw_typeof: + case tok::kw_void: + case tok::kw_while: + // These are JS keywords that are lexed by LLVM/clang as keywords. + return false; + case tok::identifier: + // For identifiers, make sure they are true identifiers, excluding the + // JavaScript pseudo-keywords (not lexed by LLVM/clang as keywords). + return JsExtraKeywords.find(Tok.Tok.getIdentifierInfo()) == + JsExtraKeywords.end(); + default: + // Other keywords are handled in the switch below, to avoid problems due + // to duplicate case labels when using the #include trick. + break; + } + + switch (Tok.Tok.getKind()) { + // Handle C++ keywords not included above: these are all JS identifiers. +#define KEYWORD(X, Y) case tok::kw_##X: +#include "clang/Basic/TokenKinds.def" + // #undef KEYWORD is not needed -- it's #undef-ed at the end of + // TokenKinds.def + return true; + default: + // All other tokens (punctuation etc) are not JS identifiers. + return false; + } } /// Returns \c true if \p Tok is a C# keyword, returns diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index a3cd4f42f8f8..029741c3dce7 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1522,9 +1522,9 @@ class AnnotatingParser { if (Style.Language == FormatStyle::LK_JavaScript) { if (Current.is(tok::exclaim)) { if (Current.Previous && - (Current.Previous->isOneOf(tok::identifier, tok::kw_namespace, - tok::r_paren, tok::r_square, - tok::r_brace) || + (Keywords.IsJavaScriptIdentifier(*Current.Previous) || + Current.Previous->isOneOf(tok::kw_namespace, tok::r_paren, + tok::r_square, tok::r_brace) || Current.Previous->Tok.isLiteral())) { Current.Type = TT_JsNonNullAssertion; return; @@ -3070,10 +3070,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, (Right.is(TT_TemplateString) && Right.TokenText.startswith("}"))) return false; // In tagged template literals ("html`bar baz`"), there is no space between - // the tag identifier and the template string. getIdentifierInfo makes sure - // that the identifier is not a pseudo keyword like `yield`, either. - if (Left.is(tok::identifier) && Keywords.IsJavaScriptIdentifier(Left) && - Right.is(TT_TemplateString)) + // the tag identifier and the template string. + if (Keywords.IsJavaScriptIdentifier(Left) && Right.is(TT_TemplateString)) return false; if (Right.is(tok::star) && Left.isOneOf(Keywords.kw_function, Keywords.kw_yield)) diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp index 6efb8662f0f5..3fd795c526b1 100644 --- a/clang/unittests/Format/FormatTestJS.cpp +++ b/clang/unittests/Format/FormatTestJS.cpp @@ -386,13 +386,6 @@ TEST_F(FormatTestJS, ReservedWordsParenthesized) { "return (x);\n"); } -TEST_F(FormatTestJS, CppKeywords) { - // Make sure we don't mess stuff up because of C++ keywords. - verifyFormat("return operator && (aa);"); - // .. or QT ones. - verifyFormat("slots: Slot[];"); -} - TEST_F(FormatTestJS, ES6DestructuringAssignment) { verifyFormat("var [a, b, c] = [1, 2, 3];"); verifyFormat("const [a, b, c] = [1, 2, 3];"); @@ -2366,6 +2359,61 @@ TEST_F(FormatTestJS, NonNullAssertionOperator) { verifyFormat("return !!x;\n"); } +TEST_F(FormatTestJS, CppKeywords) { + // Make sure we don't mess stuff up because of C++ keywords. + verifyFormat("return operator && (aa);"); + // .. or QT ones. + verifyFormat("const slots: Slot[];"); + // use the "!" assertion operator to validate that clang-format understands + // these C++ keywords aren't keywords in JS/TS. + verifyFormat("auto!;"); + verifyFormat("char!;"); + verifyFormat("concept!;"); + verifyFormat("double!;"); + verifyFormat("extern!;"); + verifyFormat("float!;"); + verifyFormat("inline!;"); + verifyFormat("int!;"); + verifyFormat("long!;"); + verifyFormat("register!;"); + verifyFormat("restrict!;"); + verifyFormat("sizeof!;"); + verifyFormat("struct!;"); + verifyFormat("typedef!;"); + verifyFormat("union!;"); + verifyFormat("unsigned!;"); + verifyFormat("volatile!;"); + verifyFormat("_Alignas!;"); + verifyFormat("_Alignof!;"); + verifyFormat("_Atomic!;"); + verifyFormat("_Bool!;"); + verifyFormat("_Complex!;"); + verifyFormat("_Generic!;"); + verifyFormat("_Imaginary!;"); + verifyFormat("_Noreturn!;"); + verifyFormat("_Static_assert!;"); + verifyFormat("_Thread_local!;"); + verifyFormat("__func__!;"); + verifyFormat("__objc_yes!;"); + verifyFormat("__objc_no!;"); + verifyFormat("asm!;"); + verifyFormat("bool!;"); + verifyFormat("const_cast!;"); + verifyFormat("dynamic_cast!;"); + verifyFormat("explicit!;"); + verifyFormat("friend!;"); + verifyFormat("mutable!;"); + verifyFormat("operator!;"); + verifyFormat("reinterpret_cast!;"); + verifyFormat("static_cast!;"); + verifyFormat("template!;"); + verifyFormat("typename!;"); + verifyFormat("typeid!;"); + verifyFormat("using!;"); + verifyFormat("virtual!;"); + verifyFormat("wchar_t!;"); +} + TEST_F(FormatTestJS, NullPropagatingOperator) { verifyFormat("let x = foo?.bar?.baz();\n"); verifyFormat("let x = foo?.(foo);\n"); From cfe-commits at lists.llvm.org Fri Apr 3 05:52:48 2020 From: cfe-commits at lists.llvm.org (Martin Probst via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 12:52:48 +0000 (UTC) Subject: [PATCH] D77311: clang-format: [JS] detect C++ keywords. In-Reply-To: References: Message-ID: <9e1b70fce7f7b91c61a2f0047533a759@localhost.localdomain> This revision was automatically updated to reflect the committed changes. mprobst marked an inline comment as done. Closed by commit rG146d685cd657: clang-format: [JS] detect C++ keywords. (authored by mprobst). Changed prior to commit: https://reviews.llvm.org/D77311?vs=254741&id=254763#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77311/new/ https://reviews.llvm.org/D77311 Files: clang/lib/Format/FormatToken.h clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTestJS.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77311.254763.patch Type: text/x-patch Size: 6708 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 06:14:05 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via cfe-commits) Date: Fri, 03 Apr 2020 06:14:05 -0700 (PDT) Subject: [clang] a46e7d7 - [AMDGPU] Allow AGPR in inline asm Message-ID: <5e87369d.1c69fb81.2b297.ac36@mx.google.com> Author: Yaxun (Sam) Liu Date: 2020-04-03T09:08:13-04:00 New Revision: a46e7d7a5f60b452340eb8ebc873538659c73e78 URL: https://github.com/llvm/llvm-project/commit/a46e7d7a5f60b452340eb8ebc873538659c73e78 DIFF: https://github.com/llvm/llvm-project/commit/a46e7d7a5f60b452340eb8ebc873538659c73e78.diff LOG: [AMDGPU] Allow AGPR in inline asm Differential Revision: https://reviews.llvm.org/D77329 Added: Modified: clang/lib/Basic/Targets/AMDGPU.cpp clang/lib/Basic/Targets/AMDGPU.h clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl Removed: ################################################################################ diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp index 55d7c081ceac..3fd9008e4660 100644 --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -124,7 +124,36 @@ const char *const AMDGPUTargetInfo::GCCRegNames[] = { "s113", "s114", "s115", "s116", "s117", "s118", "s119", "s120", "s121", "s122", "s123", "s124", "s125", "s126", "s127", "exec", "vcc", "scc", "m0", "flat_scratch", "exec_lo", "exec_hi", "vcc_lo", "vcc_hi", - "flat_scratch_lo", "flat_scratch_hi" + "flat_scratch_lo", "flat_scratch_hi", + "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", + "a9", "a10", "a11", "a12", "a13", "a14", "a15", "a16", "a17", + "a18", "a19", "a20", "a21", "a22", "a23", "a24", "a25", "a26", + "a27", "a28", "a29", "a30", "a31", "a32", "a33", "a34", "a35", + "a36", "a37", "a38", "a39", "a40", "a41", "a42", "a43", "a44", + "a45", "a46", "a47", "a48", "a49", "a50", "a51", "a52", "a53", + "a54", "a55", "a56", "a57", "a58", "a59", "a60", "a61", "a62", + "a63", "a64", "a65", "a66", "a67", "a68", "a69", "a70", "a71", + "a72", "a73", "a74", "a75", "a76", "a77", "a78", "a79", "a80", + "a81", "a82", "a83", "a84", "a85", "a86", "a87", "a88", "a89", + "a90", "a91", "a92", "a93", "a94", "a95", "a96", "a97", "a98", + "a99", "a100", "a101", "a102", "a103", "a104", "a105", "a106", "a107", + "a108", "a109", "a110", "a111", "a112", "a113", "a114", "a115", "a116", + "a117", "a118", "a119", "a120", "a121", "a122", "a123", "a124", "a125", + "a126", "a127", "a128", "a129", "a130", "a131", "a132", "a133", "a134", + "a135", "a136", "a137", "a138", "a139", "a140", "a141", "a142", "a143", + "a144", "a145", "a146", "a147", "a148", "a149", "a150", "a151", "a152", + "a153", "a154", "a155", "a156", "a157", "a158", "a159", "a160", "a161", + "a162", "a163", "a164", "a165", "a166", "a167", "a168", "a169", "a170", + "a171", "a172", "a173", "a174", "a175", "a176", "a177", "a178", "a179", + "a180", "a181", "a182", "a183", "a184", "a185", "a186", "a187", "a188", + "a189", "a190", "a191", "a192", "a193", "a194", "a195", "a196", "a197", + "a198", "a199", "a200", "a201", "a202", "a203", "a204", "a205", "a206", + "a207", "a208", "a209", "a210", "a211", "a212", "a213", "a214", "a215", + "a216", "a217", "a218", "a219", "a220", "a221", "a222", "a223", "a224", + "a225", "a226", "a227", "a228", "a229", "a230", "a231", "a232", "a233", + "a234", "a235", "a236", "a237", "a238", "a239", "a240", "a241", "a242", + "a243", "a244", "a245", "a246", "a247", "a248", "a249", "a250", "a251", + "a252", "a253", "a254", "a255" }; ArrayRef AMDGPUTargetInfo::getGCCRegNames() const { diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h index 46ddc401fb6f..548cadcab9ab 100644 --- a/clang/lib/Basic/Targets/AMDGPU.h +++ b/clang/lib/Basic/Targets/AMDGPU.h @@ -114,11 +114,14 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { /// Accepted register names: (n, m is unsigned integer, n < m) /// v /// s + /// a /// {vn}, {v[n]} /// {sn}, {s[n]} + /// {an}, {a[n]} /// {S} , where S is a special register name ////{v[n:m]} /// {s[n:m]} + /// {a[n:m]} bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override { static const ::llvm::StringSet<> SpecialRegs({ @@ -135,7 +138,7 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { } if (S.empty()) return false; - if (S.front() != 'v' && S.front() != 's') { + if (S.front() != 'v' && S.front() != 's' && S.front() != 'a') { if (!HasLeftParen) return false; auto E = S.find('}'); @@ -153,7 +156,7 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { if (!HasLeftParen) { if (!S.empty()) return false; - // Found s or v. + // Found s, v or a. Info.setAllowsRegister(); Name = S.data() - 1; return true; @@ -184,7 +187,8 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo { S = S.drop_front(); if (!S.empty()) return false; - // Found {vn}, {sn}, {v[n]}, {s[n]}, {v[n:m]}, or {s[n:m]}. + // Found {vn}, {sn}, {an}, {v[n]}, {s[n]}, {a[n]}, {v[n:m]}, {s[n:m]} + // or {a[n:m]}. Info.setAllowsRegister(); Name = S.data() - 1; return true; diff --git a/clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl b/clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl index ccd98210d3a3..37090772f664 100644 --- a/clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl +++ b/clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl @@ -1,8 +1,35 @@ // REQUIRES: amdgpu-registered-target -// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -O0 -o - -triple amdgcn %s | FileCheck %s + +typedef float float32 __attribute__((ext_vector_type(32))); kernel void test_long(int arg0) { long v15_16; - // CHECK: tail call i64 asm sideeffect "v_lshlrev_b64 v[15:16], 0, $0", "={v[15:16]},v"(i32 %arg0) + // CHECK: call i64 asm sideeffect "v_lshlrev_b64 v[15:16], 0, $0", "={v[15:16]},v" __asm volatile("v_lshlrev_b64 v[15:16], 0, %0" : "={v[15:16]}"(v15_16) : "v"(arg0)); } + +kernel void test_agpr() { + float32 acc_c; + float reg_a; + float reg_b; + float32 reg_c; + // CHECK: call <32 x float> asm "v_mfma_f32_32x32x1f32 $0, $1, $2, $3", "=a,v,v,a,~{a0},~{a1},~{a2},~{a3},~{a4},~{a5},~{a6},~{a7},~{a8},~{a9},~{a10},~{a11},~{a12},~{a13},~{a14},~{a15},~{a16},~{a17},~{a18},~{a19},~{a20},~{a21},~{a22},~{a23},~{a24},~{a25},~{a26},~{a27},~{a28},~{a29},~{a30},~{a31}" + __asm ("v_mfma_f32_32x32x1f32 %0, %1, %2, %3" + : "=a"(acc_c) + : "v"(reg_a), "v"(reg_b), "a"(reg_c) + : "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", + "a8", "a9", "a10", "a11", "a12", "a13", "a14", "a15", + "a16", "a17", "a18", "a19", "a20", "a21", "a22", "a23", + "a24", "a25", "a26", "a27", "a28", "a29", "a30", "a31"); + + // CHECK: call <32 x float> asm sideeffect "v_mfma_f32_32x32x1f32 a[0:31], $0, $1, a[0:31]", "={a[0:31]},v,v,{a[0:31]}" + __asm volatile("v_mfma_f32_32x32x1f32 a[0:31], %0, %1, a[0:31]" + : "={a[0:31]}"(acc_c) + : "v"(reg_a),"v"(reg_b), "{a[0:31]}"(reg_c)); + + // CHECK: call float asm "v_accvgpr_read_b32 $0, $1", "={a1},{a1}" + __asm ("v_accvgpr_read_b32 %0, %1" + : "={a1}"(reg_a) + : "{a1}"(reg_b)); +} From cfe-commits at lists.llvm.org Fri Apr 3 06:24:59 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:24:59 +0000 (UTC) Subject: [PATCH] D76831: [AST] Preserve the DeclRefExpr when it refers to an invalid decl. In-Reply-To: References: Message-ID: <044612dfaa1b5688bfbae71045478c9e@localhost.localdomain> hokein added a comment. In D76831#1952425 , @sammccall wrote: > I like the idea, but it seems to regress quite a lot of diagnostics... e.g. where we fail to deduce auto and then say it's not a pointer. > > Also this is regressing things in the -fno-recovery-ast case, because of the changes to CheckDeclInExpr with the existing callsites that allow invalid decls. (I'm not sure what passing AcceptInvalid actually *did* before) Yeah, the solution makes diagnostics worse... The motivation of the patch is to preserve the DeclRefExpr nodes even the referenced var-decl is invalid, so that clangd features can still work, e.g. the case we care about struct A { A(int); } void t() { A a; // VarDecl a is invalid. a.^ // none of clangd features would work as we don't have any AST node } we have a few options: 1. build DeclRefExpr regardless the validity of VarDecl; 2. mark VarDecl valid even when there are errors during initialization; 3. using RecoveryExpr, e.g. build a RecoveryExpr that wraps a DeclRefExpr if the VarDecl is invalid; as shown in this patch, 1 is not ideal and hurts about clang diagnostics. 2 looks promising, and safer (probably not regress clang diagnostic a lot). I think VarDecls in following cases should be valid. Interestingly, clang doesn't seem to have consistent behavior -- some of them are valid already, so 2 has the greatest chance of not introducing large regressions. struct A { A(int, int); }; void test() { // 1) default initialization (without any initializers) A a1; // invalid // 2) direct initialization A a2(1); // invalid A a3{1}; // invalid A a4(invalid()); // valid A a5{invalid()}; // valid int var; // 3) copy initializaiton A a6 = 1; // invalid A a7 = A(1); // valid A a8 = A(var); // valid A a10 = A{1}; // valid A a9 = {1}; // invalid } Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76831/new/ https://reviews.llvm.org/D76831 From cfe-commits at lists.llvm.org Fri Apr 3 06:25:00 2020 From: cfe-commits at lists.llvm.org (Daniel Kiss via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:25:00 +0000 (UTC) Subject: [PATCH] D75181: [AArch64] Handle BTI/PAC in case of generated functions. In-Reply-To: References: Message-ID: <896e0f70cc35750c7b1efef3db9a6744@localhost.localdomain> danielkiss updated this revision to Diff 254761. danielkiss added a comment. The patched is rebased and the hopefully the logic is now simpler. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75181/new/ https://reviews.llvm.org/D75181 Files: clang/lib/CodeGen/CGCall.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/CodeGen/TargetInfo.cpp clang/test/CodeGen/aarch64-branch-protection-attr.c clang/test/CodeGenCXX/aarch64-branch-target_clang_call_terminate.cpp llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp llvm/lib/Target/AArch64/AArch64BranchTargets.cpp llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-5.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-6.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-7.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-8.ll llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-9.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D75181.254761.patch Type: text/x-patch Size: 19629 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 06:25:01 2020 From: cfe-commits at lists.llvm.org (Mark Nauwelaerts via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:25:01 +0000 (UTC) Subject: [PATCH] D77385: [clangd] Add index inspection helper tool Message-ID: mnauw created this revision. mnauw added a reviewer: sammccall. mnauw added a project: clang-tools-extra. Herald added subscribers: usaxena95, kadircet, arphaman, jkorous, MaskRay, ilya-biryukov, mgorny. Herald added a project: clang. Add a standalone executable that can read indexed data and output in requested format. Typical use is to read RIFF data to dump to YAML for inspection of indexed data. The YAML (de)serialization has also been extended to aid in this regard. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77385 Files: clang-tools-extra/clangd/CMakeLists.txt clang-tools-extra/clangd/index-dump/CMakeLists.txt clang-tools-extra/clangd/index-dump/IndexDumpMain.cpp clang-tools-extra/clangd/index/YAMLSerialization.cpp clang-tools-extra/clangd/test/CMakeLists.txt -------------- next part -------------- A non-text attachment was scrubbed... Name: D77385.254760.patch Type: text/x-patch Size: 9676 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 06:25:03 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Balogh, _=C3=81d=C3=A1m_via_Phabricator?= via cfe-commits) Date: Fri, 03 Apr 2020 13:25:03 +0000 (UTC) Subject: [PATCH] D77229: [Analyzer][WIP] Avoid handling of LazyCompundVals in IteratorModeling In-Reply-To: References: Message-ID: <2dd47a80bf62d2226ddcd8916b0029a3@localhost.localdomain> baloghadamsoftware updated this revision to Diff 254765. baloghadamsoftware added a comment. Lots of things seem to work now. However, I have a question: what to do with the return values of non-inlined calls? It may also be a `LazyCompoundVal`, but non-inlined calls do not have `StackFrameContext`. How to retrieve the `ConstructionContext` in such cases? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77229/new/ https://reviews.llvm.org/D77229 Files: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp clang/lib/StaticAnalyzer/Checkers/Iterator.cpp clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp clang/lib/StaticAnalyzer/Core/CallEvent.cpp clang/lib/StaticAnalyzer/Core/ExprEngine.cpp clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp clang/test/Analysis/iterator-modeling.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77229.254765.patch Type: text/x-patch Size: 26025 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 06:25:03 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Balogh, _=C3=81d=C3=A1m_via_Phabricator?= via cfe-commits) Date: Fri, 03 Apr 2020 13:25:03 +0000 (UTC) Subject: [PATCH] D77229: [Analyzer][WIP] Avoid handling of LazyCompundVals in IteratorModeling In-Reply-To: References: Message-ID: baloghadamsoftware marked an inline comment as done. baloghadamsoftware added inline comments. ================ Comment at: clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp:112 +Optional ExprEngine::retrieveFromConstructionContext( + ProgramStateRef State, const LocationContext *LCtx, ---------------- Maybe we should merge we should merge this function into `handleConstructionContext()`? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77229/new/ https://reviews.llvm.org/D77229 From cfe-commits at lists.llvm.org Fri Apr 3 06:25:05 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Balogh, _=C3=81d=C3=A1m_via_Phabricator?= via cfe-commits) Date: Fri, 03 Apr 2020 13:25:05 +0000 (UTC) Subject: [PATCH] D77229: [Analyzer][WIP] Avoid handling of LazyCompundVals in IteratorModeling In-Reply-To: References: Message-ID: <8bd8f8d091e48c061371db7a6176aba9@localhost.localdomain> baloghadamsoftware added a comment. Output of /home/edmbalo/llvm-project/build/bin/clang -cc1 -internal-isystem /mnt/ssd/edmbalo/llvm-project/build/lib/clang/11.0.0/include -nostdsysteminc -analyze -analyzer-constraints=range -setup-static-analyzer -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=false /home/edmbalo/llvm-project/clang/test/Analysis/iterator-modeling.cpp is the following: Container PostCall Original RetVal: lazyCompoundVal{0x55563691e490,i0} Retrieving Original Updated RetVal: &i0 Generic PostCall Original RetVal: lazyCompoundVal{0x55563691e490,i0} Retrieving Original Updated RetVal: &i0 Container PostCall Original RetVal: lazyCompoundVal{0x555636921ba0,temp_object{std::list::const_iterator, S48444}} Retrieving Original Updated RetVal: &temp_object{std::list::const_iterator, S48444} Generic PostCall Original RetVal: lazyCompoundVal{0x555636921ba0,temp_object{std::list::const_iterator, S48444}} Retrieving Original Updated RetVal: &temp_object{std::list::const_iterator, S48444} Container PostCall Original RetVal: lazyCompoundVal{0x555636922d28,i1} No Stack Frame! No construction context!!! Generic PostCall Original RetVal: lazyCompoundVal{0x555636922d28,i1} No Stack Frame! No construction context!!! Container PostCall Original RetVal: lazyCompoundVal{0x555636925348,i2} Retrieving Original Updated RetVal: &i2 Generic PostCall Original RetVal: lazyCompoundVal{0x555636925348,i2} Retrieving Original Updated RetVal: &i2 Container PostCall Original RetVal: conj_$3{long, LC1, S45775, #1} Updated RetVal: conj_$3{long, LC1, S45775, #1} Container PostCall Original RetVal: Unknown Updated RetVal: Unknown Container PostCall Original RetVal: conj_$11{long, LC1, S48640, #1} Updated RetVal: conj_$11{long, LC1, S48640, #1} Container PostCall Original RetVal: Unknown Updated RetVal: Unknown Container PostCall Original RetVal: 0 S64b Updated RetVal: 0 S64b Container PostCall Original RetVal: Unknown Updated RetVal: Unknown Bind Old: lazyCompoundVal{0x555636925348,i1} Bind New: &temp_object{std::list::const_iterator, S49796} Container PostCall Original RetVal: lazyCompoundVal{0x555636921918,temp_object{std::list::const_iterator, S49796}} Retrieving Original Handling New Updated RetVal: &temp_object{std::list::const_iterator, S49796} Generic PostCall Original RetVal: lazyCompoundVal{0x555636921918,temp_object{std::list::const_iterator, S49796}} Retrieving Original Handling New Updated RetVal: &temp_object{std::list::const_iterator, S49796} Container PostCall Original RetVal: lazyCompoundVal{0x55563692ea10,i3} No Stack Frame! No construction context!!! Generic PostCall Original RetVal: lazyCompoundVal{0x55563692ea10,i3} No Stack Frame! No construction context!!! Container PostCall Original RetVal: 1 S64b Updated RetVal: 1 S64b Container PostCall Original RetVal: Unknown Updated RetVal: Unknown Container PostCall Original RetVal: 0 S64b Updated RetVal: 0 S64b Container PostCall Original RetVal: Unknown Updated RetVal: Unknown Container PostCall Original RetVal: 1 S64b Updated RetVal: 1 S64b Container PostCall Original RetVal: Unknown Updated RetVal: Unknown Container PostCall Original RetVal: conj_$3{long, LC1, S45775, #1} Updated RetVal: conj_$3{long, LC1, S45775, #1} Container PostCall Original RetVal: Unknown Updated RetVal: Unknown Container PostCall Original RetVal: 0 S64b Updated RetVal: 0 S64b Container PostCall Original RetVal: Unknown Updated RetVal: Unknown Container PostCall Original RetVal: conj_$11{long, LC1, S48640, #1} Updated RetVal: conj_$11{long, LC1, S48640, #1} Container PostCall Original RetVal: Unknown Updated RetVal: Unknown /home/edmbalo/llvm-project/clang/test/Analysis/iterator-modeling.cpp:900:3: warning: Not a symbol clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1"); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/edmbalo/llvm-project/clang/test/Analysis/iterator-modeling.cpp:904:3: warning: TRUE clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}} ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/edmbalo/llvm-project/clang/test/Analysis/iterator-modeling.cpp:905:3: warning: FALSE clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}} ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/edmbalo/llvm-project/clang/test/Analysis/iterator-modeling.cpp:906:3: warning: TRUE clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/edmbalo/llvm-project/clang/test/Analysis/iterator-modeling.cpp:908:3: warning: $L.begin() clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/edmbalo/llvm-project/clang/test/Analysis/iterator-modeling.cpp:909:3: warning: Not a symbol clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}} ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/edmbalo/llvm-project/clang/test/Analysis/iterator-modeling.cpp:911:3: warning: $L.end() clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 warnings generated. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77229/new/ https://reviews.llvm.org/D77229 From cfe-commits at lists.llvm.org Fri Apr 3 06:25:06 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:25:06 +0000 (UTC) Subject: [PATCH] D77335: [AST] clang::VectorType supports any size (that fits in unsigned) In-Reply-To: References: Message-ID: <6fd140825c4fe62defcc8a6b9f7ce56f@localhost.localdomain> sammccall updated this revision to Diff 254769. sammccall added a comment. Store NumElements in the bitfield after all. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77335/new/ https://reviews.llvm.org/D77335 Files: clang/include/clang/AST/Type.h clang/lib/Sema/SemaType.cpp clang/test/Sema/types.c clang/test/SemaCXX/vector.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77335.254769.patch Type: text/x-patch Size: 7521 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 06:25:06 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:25:06 +0000 (UTC) Subject: [PATCH] D77335: [AST] clang::VectorType supports any size (that fits in unsigned) In-Reply-To: References: Message-ID: <338c63b9e6e5913fc2b85b20d611436e@localhost.localdomain> sammccall marked an inline comment as done. sammccall added inline comments. ================ Comment at: clang/include/clang/AST/Type.h:3236 QualType ElementType; + unsigned NumElements; ---------------- fhahn wrote: > I think you could keep NumElements in VectorTypeBitfields (just remove the bit specifier), as the size of those bitfields can be up to 8 bytes (see the static asserts around line 1775). That should be fine as long as NumTypeBits + 3 <= 32. Ah, you're right. I just assumed it was taking all the rest of the bits, but there are another 4 bytes free :-\ Done. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77335/new/ https://reviews.llvm.org/D77335 From cfe-commits at lists.llvm.org Fri Apr 3 06:25:16 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:25:16 +0000 (UTC) Subject: [PATCH] D77329: [AMDGPU] Allow AGPR in inline asm In-Reply-To: References: Message-ID: <33b910c647e7b91f413bf031a06d6b96@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGa46e7d7a5f60: [AMDGPU] Allow AGPR in inline asm (authored by yaxunl). Herald added a project: clang. Changed prior to commit: https://reviews.llvm.org/D77329?vs=254668&id=254772#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77329/new/ https://reviews.llvm.org/D77329 Files: clang/lib/Basic/Targets/AMDGPU.cpp clang/lib/Basic/Targets/AMDGPU.h clang/test/CodeGenOpenCL/inline-asm-amdgcn.cl -------------- next part -------------- A non-text attachment was scrubbed... Name: D77329.254772.patch Type: text/x-patch Size: 6108 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 06:40:17 2020 From: cfe-commits at lists.llvm.org (Sam McCall via cfe-commits) Date: Fri, 03 Apr 2020 06:40:17 -0700 (PDT) Subject: [clang-tools-extra] 164ed7b - [clangd] Enable some nice clang-tidy checks by default. Message-ID: <5e873cc1.1c69fb81.fe84e.9bcf@mx.google.com> Author: Sam McCall Date: 2020-04-03T15:40:07+02:00 New Revision: 164ed7b1d0446400123189c9cd168df5448e4233 URL: https://github.com/llvm/llvm-project/commit/164ed7b1d0446400123189c9cd168df5448e4233 DIFF: https://github.com/llvm/llvm-project/commit/164ed7b1d0446400123189c9cd168df5448e4233.diff LOG: [clangd] Enable some nice clang-tidy checks by default. Reviewers: hokein Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77348 Added: Modified: clang-tools-extra/clangd/tool/ClangdMain.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index 9bfc58b55f71..4b3b565ac2b6 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -691,18 +691,42 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var std::unique_ptr ClangTidyOptProvider; /*GUARDED_BY(ClangTidyOptMu)*/ if (EnableClangTidy) { - auto OverrideClangTidyOptions = tidy::ClangTidyOptions::getDefaults(); - OverrideClangTidyOptions.Checks = ClangTidyChecks; + auto EmptyDefaults = tidy::ClangTidyOptions::getDefaults(); + EmptyDefaults.Checks.reset(); // So we can tell if checks were ever set. + tidy::ClangTidyOptions OverrideClangTidyOptions; + if (!ClangTidyChecks.empty()) + OverrideClangTidyOptions.Checks = ClangTidyChecks; ClangTidyOptProvider = std::make_unique( tidy::ClangTidyGlobalOptions(), - /* Default */ tidy::ClangTidyOptions::getDefaults(), + /* Default */ EmptyDefaults, /* Override */ OverrideClangTidyOptions, FSProvider.getFileSystem()); Opts.GetClangTidyOptions = [&](llvm::vfs::FileSystem &, llvm::StringRef File) { // This function must be thread-safe and tidy option providers are not. - std::lock_guard Lock(ClangTidyOptMu); - // FIXME: use the FS provided to the function. - return ClangTidyOptProvider->getOptions(File); + tidy::ClangTidyOptions Opts; + { + std::lock_guard Lock(ClangTidyOptMu); + // FIXME: use the FS provided to the function. + Opts = ClangTidyOptProvider->getOptions(File); + } + if (!Opts.Checks) { + // If the user hasn't configured clang-tidy checks at all, including + // via .clang-tidy, give them a nice set of checks. + // (This should be what the "default" options does, but it isn't...) + // + // These default checks are chosen for: + // - low false-positive rate + // - providing a lot of value + // - being reasonably efficient + Opts.Checks = llvm::join_items( + ",", "readability-misleading-indentation", + "readability-deleted-default", "bugprone-integer-division", + "bugprone-sizeof-expression", "bugprone-suspicious-missing-comma", + "bugprone-unused-raii", "bugprone-unused-return-value", + "misc-unused-using-decls", "misc-unused-alias-decls", + "misc-definitions-in-headers"); + } + return Opts; }; } Opts.SuggestMissingIncludes = SuggestMissingIncludes; From cfe-commits at lists.llvm.org Fri Apr 3 06:57:04 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via cfe-commits) Date: Fri, 03 Apr 2020 06:57:04 -0700 (PDT) Subject: [clang] b72fce1 - Fix __builtin_amdgcn_workgroup_size_x/y/z return type Message-ID: <5e8740b0.1c69fb81.f6a3b.91ab@mx.google.com> Author: Yaxun (Sam) Liu Date: 2020-04-03T09:56:30-04:00 New Revision: b72fce1ffd0a0de5b46b486c7030d54cc5d8c225 URL: https://github.com/llvm/llvm-project/commit/b72fce1ffd0a0de5b46b486c7030d54cc5d8c225 DIFF: https://github.com/llvm/llvm-project/commit/b72fce1ffd0a0de5b46b486c7030d54cc5d8c225.diff LOG: Fix __builtin_amdgcn_workgroup_size_x/y/z return type https://reviews.llvm.org/D77390 Added: Modified: clang/include/clang/Basic/BuiltinsAMDGPU.def clang/test/CodeGenOpenCL/builtins-amdgcn.cl Removed: ################################################################################ diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.def b/clang/include/clang/Basic/BuiltinsAMDGPU.def index e5b256c07a49..b42c8a77c4bc 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPU.def +++ b/clang/include/clang/Basic/BuiltinsAMDGPU.def @@ -33,9 +33,9 @@ BUILTIN(__builtin_amdgcn_workitem_id_x, "Ui", "nc") BUILTIN(__builtin_amdgcn_workitem_id_y, "Ui", "nc") BUILTIN(__builtin_amdgcn_workitem_id_z, "Ui", "nc") -BUILTIN(__builtin_amdgcn_workgroup_size_x, "Ui", "nc") -BUILTIN(__builtin_amdgcn_workgroup_size_y, "Ui", "nc") -BUILTIN(__builtin_amdgcn_workgroup_size_z, "Ui", "nc") +BUILTIN(__builtin_amdgcn_workgroup_size_x, "Us", "nc") +BUILTIN(__builtin_amdgcn_workgroup_size_y, "Us", "nc") +BUILTIN(__builtin_amdgcn_workgroup_size_z, "Us", "nc") BUILTIN(__builtin_amdgcn_mbcnt_hi, "UiUiUi", "nc") BUILTIN(__builtin_amdgcn_mbcnt_lo, "UiUiUi", "nc") diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn.cl index 9d7916c236c5..8f2f149103b3 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn.cl @@ -538,7 +538,7 @@ void test_get_local_id(int d, global int *out) void test_get_workgroup_size(int d, global int *out) { switch (d) { - case 0: *out = __builtin_amdgcn_workgroup_size_x(); break; + case 0: *out = __builtin_amdgcn_workgroup_size_x() + 1; break; case 1: *out = __builtin_amdgcn_workgroup_size_y(); break; case 2: *out = __builtin_amdgcn_workgroup_size_z(); break; default: *out = 0; From cfe-commits at lists.llvm.org Fri Apr 3 06:57:23 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:57:23 +0000 (UTC) Subject: [PATCH] D77390: Fix __builtin_amdgcn_workgroup_size_x/y/z return type Message-ID: yaxunl created this revision. yaxunl added reviewers: b-sumner, arsenm. Herald added subscribers: kerbowa, nhaehnle, wdng, jvesely. arsenm accepted this revision. This revision is now accepted and ready to land. https://reviews.llvm.org/D77390 Files: clang/include/clang/Basic/BuiltinsAMDGPU.def clang/test/CodeGenOpenCL/builtins-amdgcn.cl Index: clang/test/CodeGenOpenCL/builtins-amdgcn.cl =================================================================== --- clang/test/CodeGenOpenCL/builtins-amdgcn.cl +++ clang/test/CodeGenOpenCL/builtins-amdgcn.cl @@ -538,7 +538,7 @@ void test_get_workgroup_size(int d, global int *out) { switch (d) { - case 0: *out = __builtin_amdgcn_workgroup_size_x(); break; + case 0: *out = __builtin_amdgcn_workgroup_size_x() + 1; break; case 1: *out = __builtin_amdgcn_workgroup_size_y(); break; case 2: *out = __builtin_amdgcn_workgroup_size_z(); break; default: *out = 0; Index: clang/include/clang/Basic/BuiltinsAMDGPU.def =================================================================== --- clang/include/clang/Basic/BuiltinsAMDGPU.def +++ clang/include/clang/Basic/BuiltinsAMDGPU.def @@ -33,9 +33,9 @@ BUILTIN(__builtin_amdgcn_workitem_id_y, "Ui", "nc") BUILTIN(__builtin_amdgcn_workitem_id_z, "Ui", "nc") -BUILTIN(__builtin_amdgcn_workgroup_size_x, "Ui", "nc") -BUILTIN(__builtin_amdgcn_workgroup_size_y, "Ui", "nc") -BUILTIN(__builtin_amdgcn_workgroup_size_z, "Ui", "nc") +BUILTIN(__builtin_amdgcn_workgroup_size_x, "Us", "nc") +BUILTIN(__builtin_amdgcn_workgroup_size_y, "Us", "nc") +BUILTIN(__builtin_amdgcn_workgroup_size_z, "Us", "nc") BUILTIN(__builtin_amdgcn_mbcnt_hi, "UiUiUi", "nc") BUILTIN(__builtin_amdgcn_mbcnt_lo, "UiUiUi", "nc") -------------- next part -------------- A non-text attachment was scrubbed... Name: D77390.254774.patch Type: text/x-patch Size: 1362 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 06:57:32 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Fri, 03 Apr 2020 13:57:32 +0000 (UTC) Subject: [PATCH] D77391: [analyzer][AnalysisOrder] Display the CallEvent type for preCall/postCall Message-ID: Szelethus created this revision. Szelethus added reviewers: NoQ, baloghadamsoftware, martong, balazske, steakhal, xazax.hun, rnkovacs. Szelethus added a project: clang. Herald added subscribers: cfe-commits, ASDenysPetrov, Charusso, gamesh411, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, szepet, whisperity. Szelethus added a child revision: D75430: [analyzer][NFC] Introduce CXXDeallocatorCall, deploy it in MallocChecker. Exactly what it says on the tin! The included testfile demonstrates why this is important -- for C++ dynamic memory operators, we don't always recognize custom, or even standard-specified new/delete operators as `CXXAllocatorCall` or `CXXDeallocatorCall`. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77391 Files: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp clang/lib/StaticAnalyzer/Core/CallEvent.cpp clang/test/Analysis/Inputs/system-header-simulator-cxx.h clang/test/Analysis/analyzer-config.c clang/test/Analysis/cxx-dynamic-memory-analysis-order.cpp clang/test/Analysis/diagnostics/explicit-suppression.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77391.254771.patch Type: text/x-patch Size: 21737 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 06:57:33 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:57:33 +0000 (UTC) Subject: [PATCH] D77392: [clangd] Make signatureHelp work with stale preambles Message-ID: kadircet created this revision. kadircet added a reviewer: sammccall. Herald added subscribers: cfe-commits, usaxena95, jfb, arphaman, mgrang, jkorous, MaskRay, javed.absar, ilya-biryukov. Herald added a project: clang. This is achieved by calculating newly added includes and implicitly parsing them as if they were part of the main file. This also gets rid of the need for consistent preamble reads. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77392 Files: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/CodeComplete.cpp clang-tools-extra/clangd/Headers.cpp clang-tools-extra/clangd/Headers.h clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Preamble.h clang-tools-extra/clangd/TUScheduler.cpp clang-tools-extra/clangd/TUScheduler.h clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp clang-tools-extra/clangd/unittests/HeadersTests.cpp clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77392.254779.patch Type: text/x-patch Size: 23163 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 06:57:37 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:57:37 +0000 (UTC) Subject: [PATCH] D77348: [clangd] Enable some nice clang-tidy checks by default. In-Reply-To: References: Message-ID: sammccall marked 2 inline comments as done. sammccall added inline comments. ================ Comment at: clang-tools-extra/clangd/tool/ClangdMain.cpp:695 + auto EmptyDefaults = tidy::ClangTidyOptions::getDefaults(); + EmptyDefaults.Checks.reset(); // So we can tell if checks were ever set. + tidy::ClangTidyOptions OverrideClangTidyOptions; ---------------- hokein wrote: > `EmptyDefaults.Checks` is not none, but it is an empty string I think , we could even assign our default checks to `EmptyDefaults.Checks` (instead of setting it in `GetCalngTidyOptions`). That doesn't work :-( The clang tidy options config is a tangled mess. Ultimately it produces a vector of optionses that are merged in order to produce the final options. In our case this vector is [EmptyDefaults, options from .clang-tidy, OverrideClangTidyOptions]. For the "Checks" field, the merge just joins the comma-separated lists together. So the checks from EmptyDefaults would be enabled unless .clang-tidy *specifically* disables them, which is not the behavior I want - the existence of .clang-tidy should override the defaults. This is what the complainy comment below is supposed to indicate... Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77348/new/ https://reviews.llvm.org/D77348 From cfe-commits at lists.llvm.org Fri Apr 3 06:57:40 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:57:40 +0000 (UTC) Subject: [PATCH] D77385: [clangd] Add index inspection helper tool In-Reply-To: References: Message-ID: <2b66f1177534218786bd7531a594f6d1@localhost.localdomain> kadircet added a comment. Thanks for the patch! We already have one introspection tool called `dexp` have you give it a try? It can read both RIFF and YAML and allows you to run queries on the index. If it is not enough for your use case, can you describe it a little more? Maybe it would be easier to extend dexp to accommodate your use case instead of introducing a new binary. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77385/new/ https://reviews.llvm.org/D77385 From cfe-commits at lists.llvm.org Fri Apr 3 06:57:40 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Fri, 03 Apr 2020 13:57:40 +0000 (UTC) Subject: [PATCH] D75430: [analyzer][NFC] Introduce CXXDeallocatorCall, deploy it in MallocChecker In-Reply-To: References: Message-ID: Szelethus updated this revision to Diff 254780. Szelethus marked 2 inline comments as done. Szelethus added a comment. Herald added a subscriber: mgorny. - Add `PostStmt` - Add PostCall for `CXXDeallocatorCall` - Add a unittest, which is kind of pointless as-is, but I realized only later that most of the delete operators aren't recognized as `CXXDeleteExpr` - Add a bunch of `TODO`s about incorrect `CallEvent` types. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75430/new/ https://reviews.llvm.org/D75430 Files: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h clang/lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp clang/lib/StaticAnalyzer/Core/ExprEngine.cpp clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp clang/test/Analysis/cxx-dynamic-memory-analysis-order.cpp clang/unittests/StaticAnalyzer/CMakeLists.txt clang/unittests/StaticAnalyzer/CallEventTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D75430.254780.patch Type: text/x-patch Size: 15224 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 06:57:41 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:57:41 +0000 (UTC) Subject: [PATCH] D77335: [AST] clang::VectorType supports any size (that fits in unsigned) In-Reply-To: References: Message-ID: <1ec3cc9c1f024689eb38aec4b0e39ea0@localhost.localdomain> hokein accepted this revision. hokein added a comment. still LG. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77335/new/ https://reviews.llvm.org/D77335 From cfe-commits at lists.llvm.org Fri Apr 3 06:57:41 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Fri, 03 Apr 2020 13:57:41 +0000 (UTC) Subject: [PATCH] D75430: [analyzer][NFC] Introduce CXXDeallocatorCall, deploy it in MallocChecker In-Reply-To: References: Message-ID: <266fc88913ed3f4cc3d3ba6d2bc6b982@localhost.localdomain> Szelethus requested review of this revision. Szelethus added a comment. Since this change had a few blocking issues, I'm placing it back to review for greater visibility. ================ Comment at: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h:67 CE_CXXAllocator, + CE_CXXDeallocator, CE_BEG_FUNCTION_CALLS = CE_Function, ---------------- NoQ wrote: > After this you probably received compiler warnings saying "case isn't covered in switch". You'll need to clean them up. > > Another thing to do would be to update `CallEventManager`'s `getCall()` and `getCaller()` methods that'd allow the users to construct the new `CallEvent` easily without thinking about what specific kind of call event it is. No, I did not, infuriatingly. I did however get //errors// after trying to make a `toString` function for `CallEventKind`, apparently both `CE_CXXDeallocator` and `CE_Block` has the value of 7. When I moved the enum, everything was fine, and I did get the warnings you mentioned. ================ Comment at: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h:958 + + unsigned getNumArgs() const override { return getDecl()->getNumParams(); } + ---------------- steakhal wrote: > NoQ wrote: > > Charusso wrote: > > > `return getOriginExpr()->getNumArgs()` > > This wouldn't compile. `CXXDeleteExpr` is not a `CallExpr`. > > > > It sounds like there are currently [[ http://www.cplusplus.com/reference/new/operator%20delete/ | five different `operator delete`s ]]: > > {F11474783} > > > > And, unlike `operator new`, there's no option to provide custom "placement" arguments. > > > > So i think the logic in this patch is correct but we should do some custom logic for all 5 cases in the `getArgExpr` method, where argument expressions for the extra arguments will have to be conjured out of thin air (or we might as well return null). > > It sounds like there are currently five different `operator delete`s: > I think it is even worse since C++17 and C++20 introduced a couple of others like: > - overloads with `std::align_val_t` parameter (C++17) > - overloads with `std::destroying_delete_t` parameter (C++20) which I haven't heard of yet :D > > You can check it in the draft: http://eel.is/c++draft/new.delete > And of course at cppreference as well: https://en.cppreference.com/w/cpp/memory/new/operator_delete Okay so here is the biggest issue: non-simple `delete`s don't appear in the AST as `CXXDeleteExpr`, but rather as a `CXXOperatorCall`. This is a big problem, what could be the reason for it? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75430/new/ https://reviews.llvm.org/D75430 From cfe-commits at lists.llvm.org Fri Apr 3 06:57:43 2020 From: cfe-commits at lists.llvm.org (Sander de Smalen via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:57:43 +0000 (UTC) Subject: [PATCH] D76680: [SveEmitter] Add immediate checks for lanes and complex imms In-Reply-To: References: Message-ID: sdesmalen added a comment. In D76680#1959217 , @SjoerdMeijer wrote: > Looks good to me, but just one question about the tests. If I haven't overlooked anything, I don't see tests that check the new diagnostics: > "argument should be the value 90 or 270" > "argument should be the value 0,90,180 or 270" > > Should they be here, or are they somewhere else? Good point, I seem to have forgotten to add these tests. I'll update the patch! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76680/new/ https://reviews.llvm.org/D76680 From cfe-commits at lists.llvm.org Fri Apr 3 06:57:43 2020 From: cfe-commits at lists.llvm.org (George Rimar via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:57:43 +0000 (UTC) Subject: [PATCH] D77184: Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang In-Reply-To: References: Message-ID: <5c0c3f7f55ea8245cb0c3fba2f87c1ec@localhost.localdomain> grimar added a comment. In D77184#1959351 , @andrewng wrote: > The following patch fixes my issues on Windows, but I haven't tested that it doesn't break anything else: > > diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake > index 91bec7d8081..f630af211fd 100644 > --- a/llvm/cmake/modules/AddLLVM.cmake > +++ b/llvm/cmake/modules/AddLLVM.cmake > @@ -1495,7 +1495,7 @@ function(configure_lit_site_cfg site_in site_out) > string(REPLACE ";" "\\;" ARG_PATH_VALUES_ESCAPED "${ARG_PATH_VALUES}") > get_filename_component(OUTPUT_DIR ${site_out} DIRECTORY) > execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" > - "import os, sys; sys.stdout.write(';'.join(os.path.relpath(p, sys.argv[1]).replace(os.sep, '/') if p else '' for p in sys.argv[2].split(';')))" > + "import os, sys; drive = os.path.splitdrive(sys.argv[1])[0]; sys.stdout.write(';'.join('' if not p else p if os.path.splitdrive(p)[0] != drive else os.path.relpath(p, sys.argv[1]).replace(os.sep, '/') for p in sys.argv[2].split(';')))" > ${OUTPUT_DIR} > ${ARG_PATH_VALUES_ESCAPED} > OUTPUT_VARIABLE ARG_PATH_VALUES_RELATIVE) > This helped me, thanks for posting this! (I've just updated and faced the build issue on windows. Seems it doesn't like that I build it on `D:` drive) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77184/new/ https://reviews.llvm.org/D77184 From cfe-commits at lists.llvm.org Fri Apr 3 06:57:44 2020 From: cfe-commits at lists.llvm.org (pierre gousseau via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:57:44 +0000 (UTC) Subject: [PATCH] D77393: [X86] Fix implicit sign conversion warnings in X86 headers. Message-ID: pgousseau created this revision. pgousseau added reviewers: craig.topper, probinson, filcab. Herald added a project: clang. Herald added a subscriber: cfe-commits. Warnings in emmintrin.h and xmmintrin.h are reported by -fsanitize=implicit-integer-sign-change Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77393 Files: clang/lib/Headers/emmintrin.h clang/lib/Headers/xmmintrin.h clang/test/Headers/warn-cleanup.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77393.254784.patch Type: text/x-patch Size: 4790 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 06:57:45 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:57:45 +0000 (UTC) Subject: [PATCH] D77355: [clangd] show layout info when hovering on a class/field definition. In-Reply-To: References: Message-ID: <69d3de0d3f15082815c15433bafb05dd@localhost.localdomain> sammccall updated this revision to Diff 254786. sammccall marked 5 inline comments as done. sammccall added a comment. address comments Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77355/new/ https://reviews.llvm.org/D77355 Files: clang-tools-extra/clangd/Hover.cpp clang-tools-extra/clangd/Hover.h clang-tools-extra/clangd/unittests/HoverTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77355.254786.patch Type: text/x-patch Size: 5714 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 06:57:46 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:57:46 +0000 (UTC) Subject: [PATCH] D77355: [clangd] show layout info when hovering on a class/field definition. In-Reply-To: References: Message-ID: <96c91b3bf0993ca0486dcdc88e5a4d90@localhost.localdomain> sammccall added inline comments. ================ Comment at: clang-tools-extra/clangd/unittests/HoverTests.cpp:69 struct Foo { - int [[b^ar]]; + char [[b^ar]]; }; ---------------- kadircet wrote: > any reason for changing these from int to char ? hardcoding sizeof(int) isn't portable unless we want to set the target explicitly Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77355/new/ https://reviews.llvm.org/D77355 From cfe-commits at lists.llvm.org Fri Apr 3 06:57:47 2020 From: cfe-commits at lists.llvm.org (Dmitri Gribenko via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:57:47 +0000 (UTC) Subject: [PATCH] D77209: [Syntax] Add mapping from spelled to expanded tokens for TokenBuffer In-Reply-To: References: Message-ID: gribozavr2 added inline comments. ================ Comment at: clang/lib/Tooling/Syntax/Tokens.cpp:239 + + auto It = llvm::partition_point(F.Mappings, [SpelledI](const Mapping &M) { + return M.BeginSpelled <= SpelledI; ---------------- It would be great to add an is_sorted assertion to the builder to check ordering of mappings based on both spelled and expanded token indices. ================ Comment at: clang/lib/Tooling/Syntax/Tokens.cpp:259 + const MarkedFile &File = It->second; + // assert that Spelled is a subarray of File.SpelledTokens. + assert(File.SpelledTokens.data() <= Spelled.data()); ---------------- s/subarray/subrange/ Also no need to repeat "assert". "`Spelled` must be a subrange of `File.SpelledTokens`." ================ Comment at: clang/lib/Tooling/Syntax/Tokens.cpp:261 + assert(File.SpelledTokens.data() <= Spelled.data()); + assert(Spelled.size() <= File.SpelledTokens.size()); + ---------------- I think we can improve the precision of this assertion. Comparing the sizes does not ensure that we really have a subrange. I think the second assert should be comparing end pointers instead of sizes. Something like: `assert(&Spelled.back() <= &File.SpelledTokens.back());` ================ Comment at: clang/lib/Tooling/Syntax/Tokens.cpp:264 + auto *FrontMapping = mappingStartingBeforeSpelled(File, &Spelled.front()); + unsigned SpelledFrontI = &Spelled.front() - File.SpelledTokens.data(); + unsigned ExpandedBegin; ---------------- Or assert that SpelledFrontI is less than File.SpelledTokens.size(). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77209/new/ https://reviews.llvm.org/D77209 From cfe-commits at lists.llvm.org Fri Apr 3 06:58:40 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 13:58:40 +0000 (UTC) Subject: [PATCH] D77348: [clangd] Enable some nice clang-tidy checks by default. In-Reply-To: References: Message-ID: <781eb0914b1fbed900742ae5001ce27c@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG164ed7b1d044: [clangd] Enable some nice clang-tidy checks by default. (authored by sammccall). Changed prior to commit: https://reviews.llvm.org/D77348?vs=254650&id=254789#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77348/new/ https://reviews.llvm.org/D77348 Files: clang-tools-extra/clangd/tool/ClangdMain.cpp Index: clang-tools-extra/clangd/tool/ClangdMain.cpp =================================================================== --- clang-tools-extra/clangd/tool/ClangdMain.cpp +++ clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -691,18 +691,42 @@ std::unique_ptr ClangTidyOptProvider; /*GUARDED_BY(ClangTidyOptMu)*/ if (EnableClangTidy) { - auto OverrideClangTidyOptions = tidy::ClangTidyOptions::getDefaults(); - OverrideClangTidyOptions.Checks = ClangTidyChecks; + auto EmptyDefaults = tidy::ClangTidyOptions::getDefaults(); + EmptyDefaults.Checks.reset(); // So we can tell if checks were ever set. + tidy::ClangTidyOptions OverrideClangTidyOptions; + if (!ClangTidyChecks.empty()) + OverrideClangTidyOptions.Checks = ClangTidyChecks; ClangTidyOptProvider = std::make_unique( tidy::ClangTidyGlobalOptions(), - /* Default */ tidy::ClangTidyOptions::getDefaults(), + /* Default */ EmptyDefaults, /* Override */ OverrideClangTidyOptions, FSProvider.getFileSystem()); Opts.GetClangTidyOptions = [&](llvm::vfs::FileSystem &, llvm::StringRef File) { // This function must be thread-safe and tidy option providers are not. - std::lock_guard Lock(ClangTidyOptMu); - // FIXME: use the FS provided to the function. - return ClangTidyOptProvider->getOptions(File); + tidy::ClangTidyOptions Opts; + { + std::lock_guard Lock(ClangTidyOptMu); + // FIXME: use the FS provided to the function. + Opts = ClangTidyOptProvider->getOptions(File); + } + if (!Opts.Checks) { + // If the user hasn't configured clang-tidy checks at all, including + // via .clang-tidy, give them a nice set of checks. + // (This should be what the "default" options does, but it isn't...) + // + // These default checks are chosen for: + // - low false-positive rate + // - providing a lot of value + // - being reasonably efficient + Opts.Checks = llvm::join_items( + ",", "readability-misleading-indentation", + "readability-deleted-default", "bugprone-integer-division", + "bugprone-sizeof-expression", "bugprone-suspicious-missing-comma", + "bugprone-unused-raii", "bugprone-unused-return-value", + "misc-unused-using-decls", "misc-unused-alias-decls", + "misc-definitions-in-headers"); + } + return Opts; }; } Opts.SuggestMissingIncludes = SuggestMissingIncludes; -------------- next part -------------- A non-text attachment was scrubbed... Name: D77348.254789.patch Type: text/x-patch Size: 2638 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 07:29:58 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 14:29:58 +0000 (UTC) Subject: [PATCH] D77355: [clangd] show layout info when hovering on a class/field definition. In-Reply-To: References: Message-ID: kadircet accepted this revision. kadircet marked an inline comment as done. kadircet added a comment. This revision is now accepted and ready to land. thanks! ================ Comment at: clang-tools-extra/clangd/unittests/HoverTests.cpp:69 struct Foo { - int [[b^ar]]; + char [[b^ar]]; }; ---------------- sammccall wrote: > kadircet wrote: > > any reason for changing these from int to char ? > hardcoding sizeof(int) isn't portable unless we want to set the target explicitly right, the test already sets the target though. I suppose relying less on it is better, so feel free to keep it. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77355/new/ https://reviews.llvm.org/D77355 From cfe-commits at lists.llvm.org Fri Apr 3 07:29:59 2020 From: cfe-commits at lists.llvm.org (Haojian Wu via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 14:29:59 +0000 (UTC) Subject: [PATCH] D77395: [AST] Dont invalidate VarDecl even the default initializaiton is failed. Message-ID: hokein created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. hokein edited the summary of this revision. hokein edited the summary of this revision. hokein added a reviewer: sammccall. hokein retitled this revision from "[AST] Dont invalide VarDecl even the default initializaiton is failed." to "[AST] Dont invalidate VarDecl even the default initializaiton is failed.". This patch would cause clang emit more diagnostics, but it is much better than https://reviews.llvm.org/D76831 cpp struct A { A(int); ~A() = delete; }; void k() { A a; } before the patch: /tmp/t3.cpp:24:5: error: no matching constructor for initialization of 'A' A a; ^ /tmp/t3.cpp:20:3: note: candidate constructor not viable: requires 1 argument, but 0 were provided A(int); ^ /tmp/t3.cpp:19:8: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided struct A { After the patch: /tmp/t3.cpp:24:5: error: no matching constructor for initialization of 'A' A a; ^ /tmp/t3.cpp:20:3: note: candidate constructor not viable: requires 1 argument, but 0 were provided A(int); ^ /tmp/t3.cpp:19:8: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided struct A { ^ /tmp/t3.cpp:24:5: error: attempt to use a deleted function A a; ^ /tmp/t3.cpp:21:3: note: '~A' has been explicitly marked deleted here ~A() = delete; Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77395 Files: clang/lib/Sema/SemaDecl.cpp clang/test/AST/ast-dump-invalid-initialized.cpp clang/test/CXX/class.access/p4.cpp clang/test/CXX/drs/dr3xx.cpp clang/test/CXX/special/class.ctor/p5-0x.cpp clang/test/CodeCompletion/invalid-initialized-class.cpp clang/test/SemaCXX/cxx0x-deleted-default-ctor.cpp clang/test/SemaObjCXX/arc-0x.mm -------------- next part -------------- A non-text attachment was scrubbed... Name: D77395.254793.patch Type: text/x-patch Size: 17102 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 07:30:03 2020 From: cfe-commits at lists.llvm.org (Michael Liao via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 14:30:03 +0000 (UTC) Subject: [PATCH] D77398: [cuda][hip] Fix `RegisterVar` function prototype. Message-ID: hliao created this revision. hliao added reviewers: tra, yaxunl. Herald added a project: clang. Herald added a subscriber: cfe-commits. - `RegisterVar` has `void` return type and `size_t` in its variable size parameter in HIP or CUDA 9.0+. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77398 Files: clang/include/clang/Basic/Cuda.h clang/lib/Basic/Cuda.cpp clang/lib/CodeGen/CGCUDANV.cpp clang/test/CodeGenCUDA/device-stub.cu Index: clang/test/CodeGenCUDA/device-stub.cu =================================================================== --- clang/test/CodeGenCUDA/device-stub.cu +++ clang/test/CodeGenCUDA/device-stub.cu @@ -181,10 +181,10 @@ // Test that we've built a function to register kernels and global vars. // ALL: define internal void @__[[PREFIX]]_register_globals // ALL: call{{.*}}[[PREFIX]]RegisterFunction(i8** %0, {{.*}}kernelfunc{{[^,]*}}, {{[^@]*}}@0 -// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}device_var{{[^,]*}}, {{[^@]*}}@1, {{.*}}i32 0, i32 4, i32 0, i32 0 -// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}constant_var{{[^,]*}}, {{[^@]*}}@2, {{.*}}i32 0, i32 4, i32 1, i32 0 -// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_device_var_def{{[^,]*}}, {{[^@]*}}@3, {{.*}}i32 0, i32 4, i32 0, i32 0 -// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_constant_var_def{{[^,]*}}, {{[^@]*}}@4, {{.*}}i32 0, i32 4, i32 1, i32 0 +// ALL-DAG: call void {{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}device_var{{[^,]*}}, {{[^@]*}}@1, {{.*}}i32 0, {{i32|i64}} 4, i32 0, i32 0 +// ALL-DAG: call void {{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}constant_var{{[^,]*}}, {{[^@]*}}@2, {{.*}}i32 0, {{i32|i64}} 4, i32 1, i32 0 +// ALL-DAG: call void {{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_device_var_def{{[^,]*}}, {{[^@]*}}@3, {{.*}}i32 0, {{i32|i64}} 4, i32 0, i32 0 +// ALL-DAG: call void {{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_constant_var_def{{[^,]*}}, {{[^@]*}}@4, {{.*}}i32 0, {{i32|i64}} 4, i32 1, i32 0 // ALL: ret void // Test that we've built a constructor. Index: clang/lib/CodeGen/CGCUDANV.cpp =================================================================== --- clang/lib/CodeGen/CGCUDANV.cpp +++ clang/lib/CodeGen/CGCUDANV.cpp @@ -440,13 +440,19 @@ Builder.CreateCall(RegisterFunc, Args); } + llvm::Type *VarSizeTy = IntTy; + // For HIP or CUDA 9.0+, device variable size is type of `size_t`. + if (CGM.getLangOpts().HIP || + ToCudaVersion(CGM.getTarget().getSDKVersion()) >= CudaVersion::CUDA_90) + VarSizeTy = SizeTy; + // void __cudaRegisterVar(void **, char *, char *, const char *, // int, int, int, int) llvm::Type *RegisterVarParams[] = {VoidPtrPtrTy, CharPtrTy, CharPtrTy, - CharPtrTy, IntTy, IntTy, + CharPtrTy, IntTy, VarSizeTy, IntTy, IntTy}; llvm::FunctionCallee RegisterVar = CGM.CreateRuntimeFunction( - llvm::FunctionType::get(IntTy, RegisterVarParams, false), + llvm::FunctionType::get(VoidTy, RegisterVarParams, false), addUnderscoredPrefixToName("RegisterVar")); // void __cudaRegisterSurface(void **, const struct surfaceReference *, // const void **, const char *, int, int); @@ -476,7 +482,7 @@ VarName, VarName, llvm::ConstantInt::get(IntTy, Info.Flags.isExtern()), - llvm::ConstantInt::get(IntTy, VarSize), + llvm::ConstantInt::get(VarSizeTy, VarSize), llvm::ConstantInt::get(IntTy, Info.Flags.isConstant()), llvm::ConstantInt::get(IntTy, 0)}; Builder.CreateCall(RegisterVar, Args); Index: clang/lib/Basic/Cuda.cpp =================================================================== --- clang/lib/Basic/Cuda.cpp +++ clang/lib/Basic/Cuda.cpp @@ -365,7 +365,7 @@ } } -static CudaVersion ToCudaVersion(llvm::VersionTuple Version) { +CudaVersion ToCudaVersion(llvm::VersionTuple Version) { int IVer = Version.getMajor() * 10 + Version.getMinor().getValueOr(0); switch(IVer) { Index: clang/include/clang/Basic/Cuda.h =================================================================== --- clang/include/clang/Basic/Cuda.h +++ clang/include/clang/Basic/Cuda.h @@ -118,6 +118,7 @@ CUDA_USES_FATBIN_REGISTER_END, }; +CudaVersion ToCudaVersion(llvm::VersionTuple); bool CudaFeatureEnabled(llvm::VersionTuple, CudaFeature); bool CudaFeatureEnabled(CudaVersion, CudaFeature); -------------- next part -------------- A non-text attachment was scrubbed... Name: D77398.254796.patch Type: text/x-patch Size: 4104 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 07:30:04 2020 From: cfe-commits at lists.llvm.org (Simon Pilgrim via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 14:30:04 +0000 (UTC) Subject: [PATCH] D77393: [X86] Fix implicit sign conversion warnings in X86 headers. In-Reply-To: References: Message-ID: <11f9fd019da098b39a14697da62a5996@localhost.localdomain> RKSimon added a reviewer: RKSimon. RKSimon added a comment. Rename test file to x86-header-warnings.c or something similarly specific? ================ Comment at: clang/test/Headers/warn-cleanup.c:10 +#include +#include + ---------------- Use x8intrin.h directly so its easier to expand in the future? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77393/new/ https://reviews.llvm.org/D77393 From cfe-commits at lists.llvm.org Fri Apr 3 08:02:37 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 15:02:37 +0000 (UTC) Subject: [PATCH] D77398: [cuda][hip] Fix `RegisterVar` function prototype. In-Reply-To: References: Message-ID: yaxunl added a comment. LGTM. Thanks! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77398/new/ https://reviews.llvm.org/D77398 From cfe-commits at lists.llvm.org Fri Apr 3 08:02:41 2020 From: cfe-commits at lists.llvm.org (Brian Sumner via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 15:02:41 +0000 (UTC) Subject: [PATCH] D77390: Fix __builtin_amdgcn_workgroup_size_x/y/z return type In-Reply-To: References: Message-ID: <3533d94e4a2d75159a4282f5627e597e@localhost.localdomain> b-sumner added a comment. LGTM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77390/new/ https://reviews.llvm.org/D77390 From cfe-commits at lists.llvm.org Fri Apr 3 08:30:50 2020 From: cfe-commits at lists.llvm.org (Sam McCall via cfe-commits) Date: Fri, 03 Apr 2020 08:30:50 -0700 (PDT) Subject: [clang] 88fbadd - [AST] clang::VectorType supports any size (that fits in unsigned) Message-ID: <5e8756aa.1c69fb81.722d5.addf@mx.google.com> Author: Sam McCall Date: 2020-04-03T17:30:31+02:00 New Revision: 88fbadd0f5d50ea1d310fb63da6da15b82a9be05 URL: https://github.com/llvm/llvm-project/commit/88fbadd0f5d50ea1d310fb63da6da15b82a9be05 DIFF: https://github.com/llvm/llvm-project/commit/88fbadd0f5d50ea1d310fb63da6da15b82a9be05.diff LOG: [AST] clang::VectorType supports any size (that fits in unsigned) Summary: This matches llvm::VectorType. It moves the size from the type bitfield into VectorType, increasing size by 8 bytes (including padding of 4). This is OK as we don't expect to create terribly many of these types. c.f. D77313 which enables large power-of-two sizes without growing VectorType. Reviewers: efriedma, hokein Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77335 Added: Modified: clang/include/clang/AST/Type.h clang/lib/Sema/SemaType.cpp clang/test/Sema/types.c clang/test/SemaCXX/vector.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 5d2c035ea0fe..f78d9d7670a7 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1650,11 +1650,8 @@ class alignas(8) Type : public ExtQualsTypeCommonBase { /// The kind of vector, either a generic vector type or some /// target-specific vector type such as for AltiVec or Neon. unsigned VecKind : 3; - /// The number of elements in the vector. - unsigned NumElements : 29 - NumTypeBits; - - enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 }; + uint32_t NumElements; }; class AttributedTypeBitfields { @@ -3249,10 +3246,6 @@ class VectorType : public Type, public llvm::FoldingSetNode { QualType getElementType() const { return ElementType; } unsigned getNumElements() const { return VectorTypeBits.NumElements; } - static bool isVectorSizeTooLarge(unsigned NumElements) { - return NumElements > VectorTypeBitfields::MaxNumElements; - } - bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index e128ebf31270..49a5dcbe0c79 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2436,28 +2436,34 @@ QualType Sema::BuildVectorType(QualType CurType, Expr *SizeExpr, return Context.getDependentVectorType(CurType, SizeExpr, AttrLoc, VectorType::GenericVector); - unsigned VectorSize = static_cast(VecSize.getZExtValue() * 8); + // vecSize is specified in bytes - convert to bits. + if (!VecSize.isIntN(61)) { + // Bit size will overflow uint64. + Diag(AttrLoc, diag::err_attribute_size_too_large) + << SizeExpr->getSourceRange(); + return QualType(); + } + uint64_t VectorSizeBits = VecSize.getZExtValue() * 8; unsigned TypeSize = static_cast(Context.getTypeSize(CurType)); - if (VectorSize == 0) { + if (VectorSizeBits == 0) { Diag(AttrLoc, diag::err_attribute_zero_size) << SizeExpr->getSourceRange(); return QualType(); } - // vecSize is specified in bytes - convert to bits. - if (VectorSize % TypeSize) { + if (VectorSizeBits % TypeSize) { Diag(AttrLoc, diag::err_attribute_invalid_size) << SizeExpr->getSourceRange(); return QualType(); } - if (VectorType::isVectorSizeTooLarge(VectorSize / TypeSize)) { + if (VectorSizeBits / TypeSize > std::numeric_limits::max()) { Diag(AttrLoc, diag::err_attribute_size_too_large) << SizeExpr->getSourceRange(); return QualType(); } - return Context.getVectorType(CurType, VectorSize / TypeSize, + return Context.getVectorType(CurType, VectorSizeBits / TypeSize, VectorType::GenericVector); } @@ -2489,6 +2495,11 @@ QualType Sema::BuildExtVectorType(QualType T, Expr *ArraySize, return QualType(); } + if (!vecSize.isIntN(32)) { + Diag(AttrLoc, diag::err_attribute_size_too_large) + << ArraySize->getSourceRange(); + return QualType(); + } // Unlike gcc's vector_size attribute, the size is specified as the // number of elements, not the number of bytes. unsigned vectorSize = static_cast(vecSize.getZExtValue()); @@ -2499,12 +2510,6 @@ QualType Sema::BuildExtVectorType(QualType T, Expr *ArraySize, return QualType(); } - if (VectorType::isVectorSizeTooLarge(vectorSize)) { - Diag(AttrLoc, diag::err_attribute_size_too_large) - << ArraySize->getSourceRange(); - return QualType(); - } - return Context.getExtVectorType(T, vectorSize); } diff --git a/clang/test/Sema/types.c b/clang/test/Sema/types.c index 8869b3427dc5..177e5fbd9704 100644 --- a/clang/test/Sema/types.c +++ b/clang/test/Sema/types.c @@ -69,9 +69,15 @@ void test2(int i) { char c = (char __attribute__((may_alias))) i; } -// vector size too large -int __attribute__ ((vector_size(8192))) x1; // expected-error {{vector size too large}} -typedef int __attribute__ ((ext_vector_type(8192))) x2; // expected-error {{vector size too large}} +// vector size +int __attribute__((vector_size(123456))) v1; +int __attribute__((vector_size(0x1000000000))) v2; // expected-error {{vector size too large}} +int __attribute__((vector_size((__int128_t)1 << 100))) v3; // expected-error {{vector size too large}} +int __attribute__((vector_size(0))) v4; // expected-error {{zero vector size}} +typedef int __attribute__((ext_vector_type(123456))) e1; +typedef int __attribute__((ext_vector_type(0x100000000))) e2; // expected-error {{vector size too large}} +typedef int __attribute__((vector_size((__int128_t)1 << 100))) e3; // expected-error {{vector size too large}} +typedef int __attribute__((ext_vector_type(0))) e4; // expected-error {{zero vector size}} // no support for vector enum type enum { e_2 } x3 __attribute__((vector_size(64))); // expected-error {{invalid vector element type}} diff --git a/clang/test/SemaCXX/vector.cpp b/clang/test/SemaCXX/vector.cpp index cabc525771c3..caa840596d7d 100644 --- a/clang/test/SemaCXX/vector.cpp +++ b/clang/test/SemaCXX/vector.cpp @@ -335,7 +335,7 @@ const int &reference_to_vec_element = vi4(1).x; typedef bool bad __attribute__((__vector_size__(16))); // expected-error {{invalid vector element type 'bool'}} namespace Templates { -template +template struct TemplateVectorType { typedef Elt __attribute__((__vector_size__(Size))) type; // #1 }; @@ -343,7 +343,7 @@ struct TemplateVectorType { template struct PR15730 { typedef T __attribute__((vector_size(N * sizeof(T)))) type; - typedef T __attribute__((vector_size(8192))) type2; // #2 + typedef T __attribute__((vector_size(0x1000000000))) type2; // #2 typedef T __attribute__((vector_size(3))) type3; // #3 }; @@ -352,19 +352,20 @@ void Init() { const TemplateVectorType::type Works2 = {}; // expected-error@#1 {{invalid vector element type 'bool'}} // expected-note at +1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} - const TemplateVectorType::type NoBool; + const TemplateVectorType::type NoBool = {}; // expected-error@#1 {{invalid vector element type 'int __attribute__((ext_vector_type(4)))' (vector of 4 'int' values)}} // expected-note at +1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} - const TemplateVectorType::type NoComplex; + const TemplateVectorType::type NoComplex = {}; // expected-error@#1 {{vector size not an integral multiple of component size}} // expected-note at +1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} - const TemplateVectorType::type BadSize; + const TemplateVectorType::type BadSize = {}; + const TemplateVectorType::type Large = {}; // expected-error@#1 {{vector size too large}} - // expected-note at +1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} - const TemplateVectorType::type TooLarge; + // expected-note at +1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} + const TemplateVectorType::type TooLarge = {}; // expected-error@#1 {{zero vector size}} // expected-note at +1 {{in instantiation of template class 'Templates::TemplateVectorType' requested here}} - const TemplateVectorType::type Zero; + const TemplateVectorType::type Zero = {}; // expected-error@#2 {{vector size too large}} // expected-error@#3 {{vector size not an integral multiple of component size}} From cfe-commits at lists.llvm.org Fri Apr 3 08:35:17 2020 From: cfe-commits at lists.llvm.org (Joerg Sonnenberger via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 15:35:17 +0000 (UTC) Subject: [PATCH] D73245: Avoid using std::max_align_t in pre-C++11 mode In-Reply-To: References: Message-ID: <1a50e8cf5466c1efc04eb8e45df1427f@localhost.localdomain> joerg added a comment. ping2 Louis, did I answer your questions? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73245/new/ https://reviews.llvm.org/D73245 From cfe-commits at lists.llvm.org Fri Apr 3 08:35:19 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Fri, 03 Apr 2020 15:35:19 +0000 (UTC) Subject: [PATCH] D75431: [analyzer][NFC] Merge checkNewAllocator's paramaters into CXXAllocatorCall In-Reply-To: References: Message-ID: Szelethus updated this revision to Diff 254816. Szelethus marked 2 inline comments as done. Szelethus added a comment. Herald added a subscriber: ASDenysPetrov. Inlines addressed, rebase. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75431/new/ https://reviews.llvm.org/D75431 Files: clang/include/clang/StaticAnalyzer/Core/Checker.h clang/include/clang/StaticAnalyzer/Core/CheckerManager.h clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp clang/lib/StaticAnalyzer/Core/CheckerManager.cpp clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D75431.254816.patch Type: text/x-patch Size: 13611 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 08:35:20 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 15:35:20 +0000 (UTC) Subject: [PATCH] D77408: [clang] Annotate trivial getters and setters on hover. Message-ID: sammccall created this revision. sammccall added a reviewer: kadircet. Herald added subscribers: cfe-commits, usaxena95, arphaman, jkorous. Herald added a project: clang. (Only if their definitions are visible and they have no other docs) Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77408 Files: clang-tools-extra/clangd/Hover.cpp clang-tools-extra/clangd/unittests/HoverTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77408.254819.patch Type: text/x-patch Size: 6915 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 08:36:53 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 15:36:53 +0000 (UTC) Subject: [PATCH] D77335: [AST] clang::VectorType supports any size (that fits in unsigned) In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rG88fbadd0f5d5: [AST] clang::VectorType supports any size (that fits in unsigned) (authored by sammccall). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77335/new/ https://reviews.llvm.org/D77335 Files: clang/include/clang/AST/Type.h clang/lib/Sema/SemaType.cpp clang/test/Sema/types.c clang/test/SemaCXX/vector.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77335.254822.patch Type: text/x-patch Size: 7521 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 08:37:13 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 15:37:13 +0000 (UTC) Subject: [PATCH] D77410: [analyzer] StdLibraryFunctionsChecker: match signature based on FunctionDecl Message-ID: martong created this revision. martong added reviewers: NoQ, Szelethus, gamesh411, baloghadamsoftware. Herald added subscribers: cfe-commits, ASDenysPetrov, danielkiss, steakhal, Charusso, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet, kristof.beyls, xazax.hun, whisperity. Herald added a project: clang. Currently we match the summary signature based on the arguments in the CallExpr. There are a few problems with this approach. 1. Variadic arguments are handled badly. Consider the below code: int foo(void *stream, const char *format, ...); void test_arg_constraint_on_variadic_fun() { foo(0, "%d%d", 1, 2); // CallExpr } Here the call expression holds 4 arguments, whereas the function declaration has only 2 `ParmVarDecl`s. So there is no way to create a summary that matches the call expression, because the discrepancy in the number of arguments causes a mismatch. 2. The call expression does not handle the `restrict` type qualifier. In C99, fwrite's signature is the following: size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict); However, in a call expression, like below, the type of the argument does not have the restrict qualifier. void test_fread_fwrite(FILE *fp, int *buf) { size_t x = fwrite(buf, sizeof(int), 10, fp); } This can result in an unmatches signature, so the summary is not applied. The solution is to match the summary against the referened callee `FunctionDecl` that we can query from the `CallExpr`. Further patches will continue with additional refactoring where I am going to do a lookup during the checker initialization and the signature match will happen there. That way, we will not check the signature during every call, rather we will compare only two `FunctionDecl` pointers. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77410 Files: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp clang/test/Analysis/std-c-library-functions-arg-constraints.c clang/test/Analysis/std-c-library-functions.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77410.254824.patch Type: text/x-patch Size: 6834 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 09:07:48 2020 From: cfe-commits at lists.llvm.org (pierre gousseau via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 16:07:48 +0000 (UTC) Subject: [PATCH] D77393: [X86] Fix implicit sign conversion warnings in X86 headers. In-Reply-To: References: Message-ID: pgousseau updated this revision to Diff 254827. pgousseau added a comment. Renaming test and including x86intrin.h instead. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77393/new/ https://reviews.llvm.org/D77393 Files: clang/lib/Headers/emmintrin.h clang/lib/Headers/xmmintrin.h clang/test/Headers/x86-header-warnings.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77393.254827.patch Type: text/x-patch Size: 4780 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 09:07:57 2020 From: cfe-commits at lists.llvm.org (Gabor Marton via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 16:07:57 +0000 (UTC) Subject: [PATCH] D77411: [analyzer] StdLibraryFunctionsChecker: Add test for function with default parameter Message-ID: martong created this revision. martong added reviewers: Szelethus, baloghadamsoftware, gamesh411, steakhal, balazske. Herald added subscribers: cfe-commits, ASDenysPetrov, Charusso, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet, xazax.hun, whisperity. Herald added a project: clang. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77411 Files: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp clang/test/Analysis/std-c-library-functions-arg-constraints.cpp Index: clang/test/Analysis/std-c-library-functions-arg-constraints.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/std-c-library-functions-arg-constraints.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_analyze_cc1 %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctions \ +// RUN: -analyzer-checker=apiModeling.StdCLibraryFunctionArgs \ +// RUN: -analyzer-checker=debug.StdCLibraryFunctionsTester \ +// RUN: -analyzer-checker=debug.ExprInspection \ +// RUN: -analyzer-config eagerly-assume=false \ +// RUN: -triple i686-unknown-linux \ +// RUN: -verify + +void clang_analyzer_eval(int); + +int __defaultparam(void *, int y = 3); + +void test_arg_constraint_on_fun_with_default_param() { + __defaultparam(nullptr); // \ + // expected-warning{{Function argument constraint is not satisfied}} +} Index: clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp @@ -960,6 +960,9 @@ ArgumentCondition(0U, OutOfRange, SingleValue(1))) .ArgConstraint( ArgumentCondition(0U, OutOfRange, SingleValue(2)))}}, + {"__defaultparam", Summaries{Summary(ArgTypes{Irrelevant, IntTy}, + RetType{IntTy}, EvalCallAsPure) + .ArgConstraint(NotNull(ArgNo(0)))}}, }; for (auto &E : TestFunctionSummaryMap) { auto InsertRes = -------------- next part -------------- A non-text attachment was scrubbed... Name: D77411.254830.patch Type: text/x-patch Size: 1715 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 09:08:00 2020 From: cfe-commits at lists.llvm.org (Aaron Ballman via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 16:08:00 +0000 (UTC) Subject: [PATCH] D70265: [clang-tidy] Add CppCoreGuidelines I.2 "Avoid non-const global variables" check In-Reply-To: References: Message-ID: aaron.ballman added a comment. In D70265#1954925 , @vingeldal wrote: > After looking more closely at the code I think the issue is within hasLocalStorage() which is called in hasGlobalStorage(). My expectation would be that anything inside of function scope would be considered local but I'm not very certain. > Any thoughts on whether hasLocalStorage() should be modified or if I should change the check and use some more ad-hoc implementation, instead of hasGlobalStorage(), to determine if the variable is local or global? Not everything at function scope has local storage -- for instance, a variable declared with `static` or `extern` at local scope would not have local storage (storage != scope). `isLocalVarDeclOrParm()` or `isLocalVarDecl()` may help you out here. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70265/new/ https://reviews.llvm.org/D70265 From cfe-commits at lists.llvm.org Fri Apr 3 09:08:01 2020 From: cfe-commits at lists.llvm.org (Tamas Petz via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 16:08:01 +0000 (UTC) Subject: [PATCH] D75181: [AArch64] Handle BTI/PAC in case of generated functions. In-Reply-To: References: Message-ID: tamas.petz added inline comments. ================ Comment at: clang/lib/CodeGen/CGCall.cpp:1827-1828 + + auto RASignKind = getLangOpts().getSignReturnAddressScope(); + if (RASignKind != LangOptions::SignReturnAddressScopeKind::None) { + FuncAttrs.addAttribute("sign-return-address", ---------------- LangOptions has the following functions: - hasSignReturnAddress() - isSignReturnAddressWithAKey() - isSignReturnAddressScopeAll() With these functions some of these lines can be significantly reduced. ================ Comment at: clang/lib/CodeGen/CGCall.cpp:1837 + "sign-return-address-key", + RASignKey == LangOptions::SignReturnAddressKeyKind::AKey ? "a_key" + : "b_key"); ---------------- Use getLangOpts(). isSignReturnAddressWithAKey() ================ Comment at: clang/lib/CodeGen/CodeGenModule.cpp:596 + + LangOptions::SignReturnAddressScopeKind Scope = + Context.getLangOpts().getSignReturnAddressScope(); ---------------- Use new functions please. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75181/new/ https://reviews.llvm.org/D75181 From cfe-commits at lists.llvm.org Fri Apr 3 09:08:03 2020 From: cfe-commits at lists.llvm.org (Sander de Smalen via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 16:08:03 +0000 (UTC) Subject: [PATCH] D76617: [SveEmitter] Fix encoding/decoding of SVETypeFlags In-Reply-To: References: Message-ID: sdesmalen updated this revision to Diff 254832. sdesmalen marked an inline comment as done. sdesmalen added a comment. - Updated encode functions to take/return uint64_t instead of unsigned. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76617/new/ https://reviews.llvm.org/D76617 Files: clang/include/clang/Basic/TargetBuiltins.h clang/include/clang/Basic/arm_sve.td clang/utils/TableGen/SveEmitter.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76617.254832.patch Type: text/x-patch Size: 15927 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 09:08:03 2020 From: cfe-commits at lists.llvm.org (Sander de Smalen via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 16:08:03 +0000 (UTC) Subject: [PATCH] D76617: [SveEmitter] Fix encoding/decoding of SVETypeFlags In-Reply-To: References: Message-ID: sdesmalen added inline comments. ================ Comment at: clang/utils/TableGen/SveEmitter.cpp:229 + // Returns the SVETypeFlags for a given value and mask. + unsigned encodeFlag(unsigned V, StringRef MaskName) const { + auto It = FlagTypes.find(MaskName); ---------------- SjoerdMeijer wrote: > Should `V` now be an `uint64_t`? Yes, good spot! CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76617/new/ https://reviews.llvm.org/D76617 From cfe-commits at lists.llvm.org Fri Apr 3 09:08:06 2020 From: cfe-commits at lists.llvm.org (Sander de Smalen via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 16:08:06 +0000 (UTC) Subject: [PATCH] D76679: [SveEmitter] Add more immediate operand checks. In-Reply-To: References: Message-ID: sdesmalen added a comment. In D76679#1957399 , @SjoerdMeijer wrote: > I think the float16 discussion is an interesting one, but doesn't necessarily need to be done here. I am asking some questions offline, but if we ever come to a different opinion on it, then we can follow up so it's somewhat orthogonal to this change, and so this looks fine to me. Thanks for reviewing the patch Sjoerd! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76679/new/ https://reviews.llvm.org/D76679 From cfe-commits at lists.llvm.org Fri Apr 3 09:08:11 2020 From: cfe-commits at lists.llvm.org (Yvan Roux via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 16:08:11 +0000 (UTC) Subject: [PATCH] D76066: [ARM][MachineOutliner] Add Machine Outliner support for ARM In-Reply-To: References: Message-ID: <87b8d772725c073b22c87a5f1813c3b3@localhost.localdomain> yroux updated this revision to Diff 254834. yroux added a comment. Here is an update of the patch Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76066/new/ https://reviews.llvm.org/D76066 Files: clang/lib/Driver/ToolChains/Clang.cpp llvm/include/llvm/CodeGen/TargetPassConfig.h llvm/lib/CodeGen/MachineOutliner.cpp llvm/lib/CodeGen/TargetPassConfig.cpp llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/lib/Target/ARM/ARMBaseInstrInfo.h llvm/lib/Target/ARM/ARMTargetMachine.cpp llvm/test/CodeGen/ARM/machine-outliner-tail.ll llvm/test/CodeGen/ARM/machine-outliner-thunk.ll llvm/test/CodeGen/ARM/machine-outliner-unoutlinable.mir llvm/test/CodeGen/ARM/machine-outliner-unsafe-registers.mir -------------- next part -------------- A non-text attachment was scrubbed... Name: D76066.254834.patch Type: text/x-patch Size: 34608 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 09:09:54 2020 From: cfe-commits at lists.llvm.org (Aaron Ballman via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 16:09:54 +0000 (UTC) Subject: [PATCH] D76083: [clang-tidy] Expand the list of functions in bugprone-unused-return-value In-Reply-To: References: Message-ID: aaron.ballman added inline comments. ================ Comment at: clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp:98 + "::access;" + "::bind;" + "::connect;" ---------------- sammccall wrote: > aaron.ballman wrote: > > jranieri-grammatech wrote: > > > alexfh wrote: > > > > bind has a side effect and returns a success status. Thus, the result being unused isn't necessarily a bug. Same for `connect`. And probably for `setjmp` as well. > > > In terms of bind, connect, and setjmp: while I personally would say that code not using the return value is bugprone, the data suggests that the vast majority of developers are using these functions in the intended manner and the false-positive rate should be low. > > I think we have sufficient statistical data to suggest that these APIs should be on the list because the majority of programmers *do not* use them solely for side effects without using the return value, so my preference is to keep them in the list. > I stumbled upon this review as we're considering turning this check on by default in clangd. > > There's a significant difference between unused std::async() (programmer misunderstood contract) and unused ::connect() (ignoring error conditions). The former is ~never noise, and the latter may be (e.g. in experimental or incomplete code). > > So there's some value in separating these two lists out either as an option or a separate named check (bugprone-unhandled-error?) I think we probably wouldn't enable this check by default if it includes the error-code functions. > > > the majority of programmers *do not* use them solely for side effects > ...in popular, distributed software :-) > So there's some value in separating these two lists out either as an option or a separate named check (bugprone-unhandled-error?) I think we probably wouldn't enable this check by default if it includes the error-code functions. I think that adds complexity to this check when the complexity isn't necessary. clang-tidy has traditionally been a place for checks that are chattier than what the compiler should provide, and this check has a trivial, well-understood mechanism to silence the diagnostics (cast to void) which also expresses intent properly to the toolchain. >>the majority of programmers *do not* use them solely for side effects > ...in popular, distributed software :-) I have not seen anyone provide data to suggest that the functions in question appear in any statistically significant amount in practice without checking the return value, just worries that they *could*. I don't think that's compelling in the face of data. Remember, this is for bugprone patterns, not bugknown patterns. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76083/new/ https://reviews.llvm.org/D76083 From cfe-commits at lists.llvm.org Fri Apr 3 09:40:59 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 16:40:59 +0000 (UTC) Subject: [PATCH] D77028: [NFC] Refactor DeferredDiagsEmitter and skip redundant visit In-Reply-To: References: Message-ID: <7eae6d811e32e93e49846510a826a40b@localhost.localdomain> yaxunl marked 4 inline comments as done. yaxunl added inline comments. ================ Comment at: clang/lib/Sema/Sema.cpp:1508 void checkFunc(SourceLocation Loc, FunctionDecl *FD) { + auto DiagsCountIt = DiagsCount.find(FD); FunctionDecl *Caller = UseStack.empty() ? nullptr : UseStack.back(); ---------------- rjmccall wrote: > yaxunl wrote: > > rjmccall wrote: > > > It makes me a little uncomfortable to be holding an iterator this long while calling a fair amount of other stuff in the meantime. > > > > > > Your use of DiagsCount is subtle enough that it really needs to be explained in some comments. You're doing stuff conditionally based on both whether the entry exists but also whether it's non-zero. > > added comments > Okay, thanks for that. Two points, then. First, it looks like the count is really just a boolean for whether the function recursively triggers any diagnostics. And second, can't it just be as simple as whether we've visited that function at all in a context that's forcing diagnostics to be emitted? The logic seems to be to try to emit the diagnostics for each use-path, but why would we want that? For the second comment, we need to visit a function again for each use-path because we need to report each use-path that triggers a diagnostic, otherwise users will see a new error after they fix one error, instead of seeing all the errors at once. For the first comment, I will change the count to two flags: one for the case where the function is not in device context, the other is for the case where the function is in device context. This will allow us to avoid redundant visits whether or not we are in a device context. ================ Comment at: clang/lib/Sema/Sema.cpp:1553 if (!Caller) ShouldEmit = IsKnownEmitted; if ((!ShouldEmit && !S.getLangOpts().OpenMP && !Caller) || ---------------- rjmccall wrote: > This becomes global state for the visitor; that doesn't seem like it can be right. This state is for the root node of each traversal initiated from the items in DeclsToCheckForDeferredDiags. It only needs to be set once. Will rename it as ShouldEmitRootNode and move it to checkRecordedDecl. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77028/new/ https://reviews.llvm.org/D77028 From cfe-commits at lists.llvm.org Fri Apr 3 09:41:02 2020 From: cfe-commits at lists.llvm.org (Aaron Ballman via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 16:41:02 +0000 (UTC) Subject: [PATCH] D77085: [clang-tidy] Added support for validating configuration options In-Reply-To: References: Message-ID: <856f0a88686a8dc3e8c6bf82ecd4576f@localhost.localdomain> aaron.ballman added a comment. Thank you for working on this, I think it's going to be a very useful interface! ================ Comment at: clang-tools-extra/clang-tidy/ClangTidyCheck.cpp:25 + llvm::raw_svector_ostream Output(Buffer); + Output << "warning: Option not found '" << OptionName << "'\n"; + return std::string(Buffer); ---------------- I think the diagnostic text should probably not start with a capital letter. Also, the name of the classes are confusing in that they say error but the diagnostic is a warning. When I hear "error", the class name makes me think this would stop compilation and give a nonzero result code from the program. ================ Comment at: clang-tools-extra/clang-tidy/ClangTidyCheck.cpp:108-113 + if (CheckGlobal && Iter == CheckOptions.end()) { + Iter = CheckOptions.find(LocalName.str()); + } + if (Iter == CheckOptions.end()) { + return llvm::make_error((NamePrefix + LocalName).str()); + } ---------------- Elide braces ================ Comment at: clang-tools-extra/clang-tidy/ClangTidyCheck.cpp:122-124 + } else if (Value.equals(NameAndEnum.first)) + return NameAndEnum.second; + else if (Value.equals_lower(NameAndEnum.first)) { ---------------- Preference to add the braces to this case because the surrounding ones do as well. ================ Comment at: clang-tools-extra/clang-tidy/ClangTidyCheck.h:41 +public: + MissingOptionError(std::string OptionName) : OptionName(OptionName) {} + ---------------- Make the constructor `explicit`? (May want to consider the same for the other ctors, but this one seems more dangerous.) ================ Comment at: clang-tools-extra/clang-tidy/ClangTidyCheck.h:197 + std::string get(StringRef LocalName, StringRef Default) const { + if (auto Val = get(LocalName)) + return *Val; ---------------- Don't use `auto` as the type is not spelled out. ================ Comment at: clang-tools-extra/clang-tidy/ClangTidyCheck.h:201 + llvm::consumeError(Val.takeError()); + return std::string(Default); + } ---------------- `Default.str()` instead? ================ Comment at: clang-tools-extra/clang-tidy/ClangTidyCheck.h:219-223 + if (auto Val = getLocalOrGlobal(LocalName)) + return *Val; + else + llvm::consumeError(Val.takeError()); + return std::string(Default); ---------------- Same here as above. ================ Comment at: clang-tools-extra/clang-tidy/ClangTidyCheck.h:280 + ValueOr = getLocalOrGlobal(LocalName); + if (!ValueOr) { + return std::move(ValueOr.takeError()); ---------------- Elide braces Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77085/new/ https://reviews.llvm.org/D77085 From cfe-commits at lists.llvm.org Fri Apr 3 09:41:07 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 16:41:07 +0000 (UTC) Subject: [PATCH] D77028: [NFC] Refactor DeferredDiagsEmitter and skip redundant visit In-Reply-To: References: Message-ID: yaxunl updated this revision to Diff 254840. yaxunl marked 2 inline comments as done. yaxunl added a comment. revised by John's comments CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77028/new/ https://reviews.llvm.org/D77028 Files: clang/include/clang/Sema/Sema.h clang/lib/Sema/Sema.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77028.254840.patch Type: text/x-patch Size: 9245 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 09:41:09 2020 From: cfe-commits at lists.llvm.org (Aaron Ballman via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 16:41:09 +0000 (UTC) Subject: [PATCH] D76990: [clang-tidy]: fix false positive of cert-oop54-cpp check. In-Reply-To: References: Message-ID: <477fde88cd4e7c6da44342ef34bdefc9@localhost.localdomain> aaron.ballman accepted this revision. aaron.ballman added a comment. This revision is now accepted and ready to land. LGTM with a testing request. I agree that the Clang AST is a bit surprising, but not so surprising that I could definitely call it a bug. ================ Comment at: clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp:286-299 +// https://bugs.llvm.org/show_bug.cgi?id=44499 +class Foo; +template +bool operator!=(Foo &, Foo &) { + class Bar { + Bar &operator=(const Bar &other) { + if (this != &other) { ---------------- Thank you for this! Can you also add a test case where the diagnostic should trigger? e.g., ``` class Foo; template bool operator!=(Foo &, Foo &) { class Bar { Bar &operator=(const Bar &other) { p = other.p; return *this; } int *p; }; } ``` Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76990/new/ https://reviews.llvm.org/D76990 From cfe-commits at lists.llvm.org Fri Apr 3 09:41:11 2020 From: cfe-commits at lists.llvm.org (Aaron Ballman via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 16:41:11 +0000 (UTC) Subject: [PATCH] D77199: [clang-tidy] Address false positive in modernize-use-default-member-init In-Reply-To: References: Message-ID: aaron.ballman accepted this revision. aaron.ballman added a comment. This revision is now accepted and ready to land. LGTM with a testing request. ================ Comment at: clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp:436 + +struct PR45363 { + // Ensure no warning is emitted here ---------------- Can you add a test where the value is elided but braced init is still used: ``` struct PR45363 { PR45363() : m_i{} {} // This should still warn int m_i; }; ``` Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77199/new/ https://reviews.llvm.org/D77199 From cfe-commits at lists.llvm.org Fri Apr 3 09:41:12 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 16:41:12 +0000 (UTC) Subject: [PATCH] D77408: [clang] Annotate trivial getters and setters on hover. In-Reply-To: References: Message-ID: kadircet accepted this revision. kadircet added a comment. This revision is now accepted and ready to land. LGTM, thanks! ================ Comment at: clang-tools-extra/clangd/Hover.cpp:376 +llvm::Optional fieldName(const Expr *E) { + const auto *ReturnedMember = llvm::dyn_cast(E->IgnoreCasts()); + const auto *Field = ---------------- if(!ReturnedMember) return None Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77408/new/ https://reviews.llvm.org/D77408 From cfe-commits at lists.llvm.org Fri Apr 3 09:57:19 2020 From: cfe-commits at lists.llvm.org (Michael Liao via cfe-commits) Date: Fri, 03 Apr 2020 09:57:19 -0700 (PDT) Subject: [clang] b952d79 - [cuda][hip] Fix `RegisterVar` function prototype. Message-ID: <5e876aef.1c69fb81.addc8.c4e3@mx.google.com> Author: Michael Liao Date: 2020-04-03T12:57:09-04:00 New Revision: b952d799cacdb7efd44c1c9468bb11471cc16874 URL: https://github.com/llvm/llvm-project/commit/b952d799cacdb7efd44c1c9468bb11471cc16874 DIFF: https://github.com/llvm/llvm-project/commit/b952d799cacdb7efd44c1c9468bb11471cc16874.diff LOG: [cuda][hip] Fix `RegisterVar` function prototype. Summary: - `RegisterVar` has `void` return type and `size_t` in its variable size parameter in HIP or CUDA 9.0+. Reviewers: tra, yaxunl Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77398 Added: Modified: clang/include/clang/Basic/Cuda.h clang/lib/Basic/Cuda.cpp clang/lib/CodeGen/CGCUDANV.cpp clang/test/CodeGenCUDA/device-stub.cu Removed: ################################################################################ diff --git a/clang/include/clang/Basic/Cuda.h b/clang/include/clang/Basic/Cuda.h index da572957d10d..c2ebf8734304 100644 --- a/clang/include/clang/Basic/Cuda.h +++ b/clang/include/clang/Basic/Cuda.h @@ -117,6 +117,7 @@ enum class CudaFeature { CUDA_USES_FATBIN_REGISTER_END, }; +CudaVersion ToCudaVersion(llvm::VersionTuple); bool CudaFeatureEnabled(llvm::VersionTuple, CudaFeature); bool CudaFeatureEnabled(CudaVersion, CudaFeature); diff --git a/clang/lib/Basic/Cuda.cpp b/clang/lib/Basic/Cuda.cpp index e06d120c58bf..74eb5473b71d 100644 --- a/clang/lib/Basic/Cuda.cpp +++ b/clang/lib/Basic/Cuda.cpp @@ -362,7 +362,7 @@ CudaVersion MaxVersionForCudaArch(CudaArch A) { } } -static CudaVersion ToCudaVersion(llvm::VersionTuple Version) { +CudaVersion ToCudaVersion(llvm::VersionTuple Version) { int IVer = Version.getMajor() * 10 + Version.getMinor().getValueOr(0); switch(IVer) { diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp index 6d92ef33b885..351c5058aa4c 100644 --- a/clang/lib/CodeGen/CGCUDANV.cpp +++ b/clang/lib/CodeGen/CGCUDANV.cpp @@ -440,13 +440,19 @@ llvm::Function *CGNVCUDARuntime::makeRegisterGlobalsFn() { Builder.CreateCall(RegisterFunc, Args); } + llvm::Type *VarSizeTy = IntTy; + // For HIP or CUDA 9.0+, device variable size is type of `size_t`. + if (CGM.getLangOpts().HIP || + ToCudaVersion(CGM.getTarget().getSDKVersion()) >= CudaVersion::CUDA_90) + VarSizeTy = SizeTy; + // void __cudaRegisterVar(void **, char *, char *, const char *, // int, int, int, int) llvm::Type *RegisterVarParams[] = {VoidPtrPtrTy, CharPtrTy, CharPtrTy, - CharPtrTy, IntTy, IntTy, + CharPtrTy, IntTy, VarSizeTy, IntTy, IntTy}; llvm::FunctionCallee RegisterVar = CGM.CreateRuntimeFunction( - llvm::FunctionType::get(IntTy, RegisterVarParams, false), + llvm::FunctionType::get(VoidTy, RegisterVarParams, false), addUnderscoredPrefixToName("RegisterVar")); // void __cudaRegisterSurface(void **, const struct surfaceReference *, // const void **, const char *, int, int); @@ -476,7 +482,7 @@ llvm::Function *CGNVCUDARuntime::makeRegisterGlobalsFn() { VarName, VarName, llvm::ConstantInt::get(IntTy, Info.Flags.isExtern()), - llvm::ConstantInt::get(IntTy, VarSize), + llvm::ConstantInt::get(VarSizeTy, VarSize), llvm::ConstantInt::get(IntTy, Info.Flags.isConstant()), llvm::ConstantInt::get(IntTy, 0)}; Builder.CreateCall(RegisterVar, Args); diff --git a/clang/test/CodeGenCUDA/device-stub.cu b/clang/test/CodeGenCUDA/device-stub.cu index 9db5738cdede..0f4a5644fd48 100644 --- a/clang/test/CodeGenCUDA/device-stub.cu +++ b/clang/test/CodeGenCUDA/device-stub.cu @@ -181,10 +181,10 @@ void hostfunc(void) { kernelfunc<<<1, 1>>>(1, 1, 1); } // Test that we've built a function to register kernels and global vars. // ALL: define internal void @__[[PREFIX]]_register_globals // ALL: call{{.*}}[[PREFIX]]RegisterFunction(i8** %0, {{.*}}kernelfunc{{[^,]*}}, {{[^@]*}}@0 -// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}device_var{{[^,]*}}, {{[^@]*}}@1, {{.*}}i32 0, i32 4, i32 0, i32 0 -// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}constant_var{{[^,]*}}, {{[^@]*}}@2, {{.*}}i32 0, i32 4, i32 1, i32 0 -// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_device_var_def{{[^,]*}}, {{[^@]*}}@3, {{.*}}i32 0, i32 4, i32 0, i32 0 -// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_constant_var_def{{[^,]*}}, {{[^@]*}}@4, {{.*}}i32 0, i32 4, i32 1, i32 0 +// ALL-DAG: call void {{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}device_var{{[^,]*}}, {{[^@]*}}@1, {{.*}}i32 0, {{i32|i64}} 4, i32 0, i32 0 +// ALL-DAG: call void {{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}constant_var{{[^,]*}}, {{[^@]*}}@2, {{.*}}i32 0, {{i32|i64}} 4, i32 1, i32 0 +// ALL-DAG: call void {{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_device_var_def{{[^,]*}}, {{[^@]*}}@3, {{.*}}i32 0, {{i32|i64}} 4, i32 0, i32 0 +// ALL-DAG: call void {{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_constant_var_def{{[^,]*}}, {{[^@]*}}@4, {{.*}}i32 0, {{i32|i64}} 4, i32 1, i32 0 // ALL: ret void // Test that we've built a constructor. From cfe-commits at lists.llvm.org Fri Apr 3 10:15:11 2020 From: cfe-commits at lists.llvm.org (Digger via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 17:15:11 +0000 (UTC) Subject: [PATCH] D76932: [AIX] emit .extern and .weak directive linkage In-Reply-To: References: Message-ID: <831f947217c8c7a6a5ddb61350b972fe@localhost.localdomain> DiggerLin updated this revision to Diff 254846. DiggerLin marked 7 inline comments as done. DiggerLin added a comment. 1. address comment 2. add two new test cases. 3. split a bit test case into three small test case. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76932/new/ https://reviews.llvm.org/D76932 Files: clang/lib/Driver/ToolChains/AIX.cpp clang/test/Driver/aix-as.c llvm/include/llvm/MC/MCAsmInfo.h llvm/include/llvm/MC/MCDirectives.h llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp llvm/lib/MC/MCAsmInfoXCOFF.cpp llvm/lib/MC/MCAsmStreamer.cpp llvm/lib/MC/MCXCOFFStreamer.cpp llvm/lib/MC/XCOFFObjectWriter.cpp llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp llvm/test/CodeGen/PowerPC/aix-LinkOnceAnyLinkage.ll llvm/test/CodeGen/PowerPC/aix-LinkOnceODRLinkage.ll llvm/test/CodeGen/PowerPC/aix-WeakODRLinkage.ll llvm/test/CodeGen/PowerPC/aix-extern-weak.ll llvm/test/CodeGen/PowerPC/aix-extern.ll llvm/test/CodeGen/PowerPC/aix-reference-func-addr-const.ll llvm/test/CodeGen/PowerPC/aix-weak.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D76932.254846.patch Type: text/x-patch Size: 51882 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 10:15:12 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 17:15:12 +0000 (UTC) Subject: [PATCH] D77414: [OpenMP] Add match_{all,any,none} declare variant selector extensions. Message-ID: jdoerfert created this revision. jdoerfert added reviewers: mikerice, kiranchandramohan, ABataev, RaviNarayanaswamy, gtbercea, grokos, sdmitriev, JonChesterfield, hfinkel, fghanim, aaron.ballman. Herald added subscribers: guansong, bollu, hiraditya, yaxunl. Herald added a project: clang. By default, all traits in the OpenMP context selector have to match for it to be acceptable. Though, we sometimes want a single property out of multiple to match (=any) or no match at all (=none). We offer these choices as extensions via `implementation={extension(match_{all,any,none})}` to the user. The choice will affect the entire context selector not only the traits following the match property. The first user will be D75788 . There we can replace #pragma omp begin declare variant match(device={arch(nvptx64)}) #define __CUDA__ #include <__clang_cuda_cmath.h> // TODO: Hack until we support an extension to the match clause that allows "or". #undef __CLANG_CUDA_CMATH_H__ #undef __CUDA__ #pragma omp end declare variant #pragma omp begin declare variant match(device={arch(nvptx)}) #define __CUDA__ #include <__clang_cuda_cmath.h> #undef __CUDA__ #pragma omp end declare variant with the much simpler #pragma omp begin declare variant match(device={arch(nvptx, nvptx64)}, implementation={extension(match_any)}) #define __CUDA__ #include <__clang_cuda_cmath.h> #undef __CUDA__ #pragma omp end declare variant Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77414 Files: clang/include/clang/Basic/AttrDocs.td clang/include/clang/Basic/DiagnosticParseKinds.td clang/lib/Parse/ParseOpenMP.cpp clang/test/AST/ast-dump-openmp-declare-variant-extensions-messages.c clang/test/AST/ast-dump-openmp-declare-variant-extensions.c clang/test/OpenMP/declare_variant_ast_print.c clang/test/OpenMP/declare_variant_messages.c llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPContext.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77414.254847.patch Type: text/x-patch Size: 41286 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 10:15:12 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 17:15:12 +0000 (UTC) Subject: [PATCH] D76083: [clang-tidy] Expand the list of functions in bugprone-unused-return-value In-Reply-To: References: Message-ID: <6edd08353d5fcd9644ce738c1cca02ad@localhost.localdomain> sammccall added inline comments. ================ Comment at: clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp:98 + "::access;" + "::bind;" + "::connect;" ---------------- aaron.ballman wrote: > sammccall wrote: > > aaron.ballman wrote: > > > jranieri-grammatech wrote: > > > > alexfh wrote: > > > > > bind has a side effect and returns a success status. Thus, the result being unused isn't necessarily a bug. Same for `connect`. And probably for `setjmp` as well. > > > > In terms of bind, connect, and setjmp: while I personally would say that code not using the return value is bugprone, the data suggests that the vast majority of developers are using these functions in the intended manner and the false-positive rate should be low. > > > I think we have sufficient statistical data to suggest that these APIs should be on the list because the majority of programmers *do not* use them solely for side effects without using the return value, so my preference is to keep them in the list. > > I stumbled upon this review as we're considering turning this check on by default in clangd. > > > > There's a significant difference between unused std::async() (programmer misunderstood contract) and unused ::connect() (ignoring error conditions). The former is ~never noise, and the latter may be (e.g. in experimental or incomplete code). > > > > So there's some value in separating these two lists out either as an option or a separate named check (bugprone-unhandled-error?) I think we probably wouldn't enable this check by default if it includes the error-code functions. > > > > > the majority of programmers *do not* use them solely for side effects > > ...in popular, distributed software :-) > > So there's some value in separating these two lists out either as an option or a separate named check (bugprone-unhandled-error?) I think we probably wouldn't enable this check by default if it includes the error-code functions. > > I think that adds complexity to this check when the complexity isn't necessary. clang-tidy has traditionally been a place for checks that are chattier than what the compiler should provide, and this check has a trivial, well-understood mechanism to silence the diagnostics (cast to void) which also expresses intent properly to the toolchain. > > >>the majority of programmers *do not* use them solely for side effects > > ...in popular, distributed software :-) > > I have not seen anyone provide data to suggest that the functions in question appear in any statistically significant amount in practice without checking the return value, just worries that they *could*. I don't think that's compelling in the face of data. Remember, this is for bugprone patterns, not bugknown patterns. I think we're talking past each other here. I'm not saying clang-tidy shouldn't have the check, or that it's not a bugprone pattern, or that the clang-tidy default should be different. But there are scenarios where you want one but not the other. Concretely, warnings shown in an IDE **as you type and by default**. If you're misusing an API rendering it completely useless, you should see that ASAP. If you fail to check an error code, some users won't want to be warned about that until later. By bundling them into a single check without options (other than duplicating the whole list), it's hard to create that useful but inoffensive default setup. That's OK, clangd can remove the check from the whitelist, but I think we'd get a lot of value out of it. > I have not seen anyone provide data to suggest that the functions in question appear in any statistically significant amount in practice Right, we don't have data either way on incomplete code. Based on experience of writing code and watching others write code, I believe people write sloppy code they'd never check in, and appreciate being told early when it doesn't do what they intend, but some don't appreciate being told to be less sloppy. Is your intuition different? Do you think the data provided addresses this question? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76083/new/ https://reviews.llvm.org/D76083 From cfe-commits at lists.llvm.org Fri Apr 3 10:15:13 2020 From: cfe-commits at lists.llvm.org (MyDeveloperDay via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 17:15:13 +0000 (UTC) Subject: [PATCH] D75364: [clang-format] Handle macros in function params and return value In-Reply-To: References: Message-ID: <36210044c7695811466c85a473cd7594@localhost.localdomain> MyDeveloperDay added inline comments. ================ Comment at: clang/lib/Format/TokenAnnotator.cpp:164 + /// Parses CPP qualified function names. + bool parse_function_qname(FormatToken *Tok) const { + while (Tok && Tok->isOneOf(tok::coloncolon, tok::identifier)) { ---------------- your naming convention is incorrect it would be `parseFunctionQualifiedName` what are your trying to do here? are you just trying to skip the to the `(` CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75364/new/ https://reviews.llvm.org/D75364 From cfe-commits at lists.llvm.org Fri Apr 3 10:15:15 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 17:15:15 +0000 (UTC) Subject: [PATCH] D77028: [NFC] Refactor DeferredDiagsEmitter and skip redundant visit In-Reply-To: References: Message-ID: <1b4f1f5f011da0442bb034871b91302a@localhost.localdomain> rjmccall added inline comments. ================ Comment at: clang/lib/Sema/Sema.cpp:1508 void checkFunc(SourceLocation Loc, FunctionDecl *FD) { + auto DiagsCountIt = DiagsCount.find(FD); FunctionDecl *Caller = UseStack.empty() ? nullptr : UseStack.back(); ---------------- yaxunl wrote: > rjmccall wrote: > > yaxunl wrote: > > > rjmccall wrote: > > > > It makes me a little uncomfortable to be holding an iterator this long while calling a fair amount of other stuff in the meantime. > > > > > > > > Your use of DiagsCount is subtle enough that it really needs to be explained in some comments. You're doing stuff conditionally based on both whether the entry exists but also whether it's non-zero. > > > added comments > > Okay, thanks for that. Two points, then. First, it looks like the count is really just a boolean for whether the function recursively triggers any diagnostics. And second, can't it just be as simple as whether we've visited that function at all in a context that's forcing diagnostics to be emitted? The logic seems to be to try to emit the diagnostics for each use-path, but why would we want that? > For the second comment, we need to visit a function again for each use-path because we need to report each use-path that triggers a diagnostic, otherwise users will see a new error after they fix one error, instead of seeing all the errors at once. > > For the first comment, I will change the count to two flags: one for the case where the function is not in device context, the other is for the case where the function is in device context. This will allow us to avoid redundant visits whether or not we are in a device context. > For the second comment, we need to visit a function again for each use-path because we need to report each use-path that triggers a diagnostic, otherwise users will see a new error after they fix one error, instead of seeing all the errors at once. This is not what we do in analogous cases where errors are triggered by a use, like in template instantiation. The bug might be that the device program is using a function that it shouldn't be using, or the bug might be that a function that's supposed to be usable from the device is written incorrectly. In the former case, yes, not reporting the errors for each use-path may force the programmer to build multiple times to find all the problematic uses. However, in the latter case you can easily end up emitting a massive number of errors that completely drowns out everything else. It's also non-linear: the number of different use-paths of a particular function can be combinatoric. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77028/new/ https://reviews.llvm.org/D77028 From cfe-commits at lists.llvm.org Fri Apr 3 10:16:00 2020 From: cfe-commits at lists.llvm.org (Michael Liao via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 17:16:00 +0000 (UTC) Subject: [PATCH] D77398: [cuda][hip] Fix `RegisterVar` function prototype. In-Reply-To: References: Message-ID: <1b22c58f839558a5f5cae599806c436a@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGb952d799cacd: [cuda][hip] Fix `RegisterVar` function prototype. (authored by hliao). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77398/new/ https://reviews.llvm.org/D77398 Files: clang/include/clang/Basic/Cuda.h clang/lib/Basic/Cuda.cpp clang/lib/CodeGen/CGCUDANV.cpp clang/test/CodeGenCUDA/device-stub.cu Index: clang/test/CodeGenCUDA/device-stub.cu =================================================================== --- clang/test/CodeGenCUDA/device-stub.cu +++ clang/test/CodeGenCUDA/device-stub.cu @@ -181,10 +181,10 @@ // Test that we've built a function to register kernels and global vars. // ALL: define internal void @__[[PREFIX]]_register_globals // ALL: call{{.*}}[[PREFIX]]RegisterFunction(i8** %0, {{.*}}kernelfunc{{[^,]*}}, {{[^@]*}}@0 -// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}device_var{{[^,]*}}, {{[^@]*}}@1, {{.*}}i32 0, i32 4, i32 0, i32 0 -// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}constant_var{{[^,]*}}, {{[^@]*}}@2, {{.*}}i32 0, i32 4, i32 1, i32 0 -// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_device_var_def{{[^,]*}}, {{[^@]*}}@3, {{.*}}i32 0, i32 4, i32 0, i32 0 -// ALL-DAG: call{{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_constant_var_def{{[^,]*}}, {{[^@]*}}@4, {{.*}}i32 0, i32 4, i32 1, i32 0 +// ALL-DAG: call void {{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}device_var{{[^,]*}}, {{[^@]*}}@1, {{.*}}i32 0, {{i32|i64}} 4, i32 0, i32 0 +// ALL-DAG: call void {{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}constant_var{{[^,]*}}, {{[^@]*}}@2, {{.*}}i32 0, {{i32|i64}} 4, i32 1, i32 0 +// ALL-DAG: call void {{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_device_var_def{{[^,]*}}, {{[^@]*}}@3, {{.*}}i32 0, {{i32|i64}} 4, i32 0, i32 0 +// ALL-DAG: call void {{.*}}[[PREFIX]]RegisterVar(i8** %0, {{.*}}ext_constant_var_def{{[^,]*}}, {{[^@]*}}@4, {{.*}}i32 0, {{i32|i64}} 4, i32 1, i32 0 // ALL: ret void // Test that we've built a constructor. Index: clang/lib/CodeGen/CGCUDANV.cpp =================================================================== --- clang/lib/CodeGen/CGCUDANV.cpp +++ clang/lib/CodeGen/CGCUDANV.cpp @@ -440,13 +440,19 @@ Builder.CreateCall(RegisterFunc, Args); } + llvm::Type *VarSizeTy = IntTy; + // For HIP or CUDA 9.0+, device variable size is type of `size_t`. + if (CGM.getLangOpts().HIP || + ToCudaVersion(CGM.getTarget().getSDKVersion()) >= CudaVersion::CUDA_90) + VarSizeTy = SizeTy; + // void __cudaRegisterVar(void **, char *, char *, const char *, // int, int, int, int) llvm::Type *RegisterVarParams[] = {VoidPtrPtrTy, CharPtrTy, CharPtrTy, - CharPtrTy, IntTy, IntTy, + CharPtrTy, IntTy, VarSizeTy, IntTy, IntTy}; llvm::FunctionCallee RegisterVar = CGM.CreateRuntimeFunction( - llvm::FunctionType::get(IntTy, RegisterVarParams, false), + llvm::FunctionType::get(VoidTy, RegisterVarParams, false), addUnderscoredPrefixToName("RegisterVar")); // void __cudaRegisterSurface(void **, const struct surfaceReference *, // const void **, const char *, int, int); @@ -476,7 +482,7 @@ VarName, VarName, llvm::ConstantInt::get(IntTy, Info.Flags.isExtern()), - llvm::ConstantInt::get(IntTy, VarSize), + llvm::ConstantInt::get(VarSizeTy, VarSize), llvm::ConstantInt::get(IntTy, Info.Flags.isConstant()), llvm::ConstantInt::get(IntTy, 0)}; Builder.CreateCall(RegisterVar, Args); Index: clang/lib/Basic/Cuda.cpp =================================================================== --- clang/lib/Basic/Cuda.cpp +++ clang/lib/Basic/Cuda.cpp @@ -362,7 +362,7 @@ } } -static CudaVersion ToCudaVersion(llvm::VersionTuple Version) { +CudaVersion ToCudaVersion(llvm::VersionTuple Version) { int IVer = Version.getMajor() * 10 + Version.getMinor().getValueOr(0); switch(IVer) { Index: clang/include/clang/Basic/Cuda.h =================================================================== --- clang/include/clang/Basic/Cuda.h +++ clang/include/clang/Basic/Cuda.h @@ -117,6 +117,7 @@ CUDA_USES_FATBIN_REGISTER_END, }; +CudaVersion ToCudaVersion(llvm::VersionTuple); bool CudaFeatureEnabled(llvm::VersionTuple, CudaFeature); bool CudaFeatureEnabled(CudaVersion, CudaFeature); -------------- next part -------------- A non-text attachment was scrubbed... Name: D77398.254850.patch Type: text/x-patch Size: 4104 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 10:38:40 2020 From: cfe-commits at lists.llvm.org (Stephen Neuendorffer via cfe-commits) Date: Fri, 03 Apr 2020 10:38:40 -0700 (PDT) Subject: [clang] ae044c5 - [CMAKE] Plumb include_directories() into tablegen() Message-ID: <5e8774a0.1c69fb81.b5258.d3bd@mx.google.com> Author: Stephen Neuendorffer Date: 2020-04-03T10:38:25-07:00 New Revision: ae044c5b0caa095602b6ef4cca40d57efc26a8f6 URL: https://github.com/llvm/llvm-project/commit/ae044c5b0caa095602b6ef4cca40d57efc26a8f6 DIFF: https://github.com/llvm/llvm-project/commit/ae044c5b0caa095602b6ef4cca40d57efc26a8f6.diff LOG: [CMAKE] Plumb include_directories() into tablegen() Previously, the tablegen() cmake command, which defines custom commands for running tablegen, included several hardcoded paths. This becomes unwieldy as there are more users for which these paths are insufficient. For most targets, cmake uses include_directories() and the INCLUDE_DIRECTORIES directory property to specify include paths. This change picks up the INCLUDE_DIRECTORIES property and adds it to the include path used when running tablegen. As a side effect, this allows us to remove several hard coded paths to tablegen that are redundant with specified include_directories(). I haven't removed the hardcoded path to CMAKE_CURRENT_SOURCE_DIR, which seems generically useful. There are several users in clang which apparently don't have the current directory as an include_directories(). This could be considered separately. Differential Revision: https://reviews.llvm.org/D77156 Added: Modified: clang/cmake/modules/AddClang.cmake llvm/cmake/modules/TableGen.cmake mlir/cmake/modules/AddMLIR.cmake mlir/examples/toy/Ch3/CMakeLists.txt mlir/examples/toy/Ch4/CMakeLists.txt mlir/examples/toy/Ch4/include/toy/CMakeLists.txt mlir/examples/toy/Ch5/CMakeLists.txt mlir/examples/toy/Ch5/include/toy/CMakeLists.txt mlir/examples/toy/Ch6/CMakeLists.txt mlir/examples/toy/Ch6/include/toy/CMakeLists.txt mlir/examples/toy/Ch7/CMakeLists.txt mlir/examples/toy/Ch7/include/toy/CMakeLists.txt Removed: ################################################################################ diff --git a/clang/cmake/modules/AddClang.cmake b/clang/cmake/modules/AddClang.cmake index 577cc11ab015..c1bb386de6f7 100644 --- a/clang/cmake/modules/AddClang.cmake +++ b/clang/cmake/modules/AddClang.cmake @@ -17,7 +17,7 @@ function(clang_tablegen) message(FATAL_ERROR "SOURCE source-file required by clang_tablegen") endif() - set( CLANG_TABLEGEN_ARGUMENTS -I ${CLANG_SOURCE_DIR}/include ) + set( CLANG_TABLEGEN_ARGUMENTS "" ) set( LLVM_TARGET_DEFINITIONS ${CTG_SOURCE} ) tablegen(CLANG ${CTG_UNPARSED_ARGUMENTS} ${CLANG_TABLEGEN_ARGUMENTS}) diff --git a/llvm/cmake/modules/TableGen.cmake b/llvm/cmake/modules/TableGen.cmake index 632f69aa3386..8d0c5afabe96 100644 --- a/llvm/cmake/modules/TableGen.cmake +++ b/llvm/cmake/modules/TableGen.cmake @@ -2,10 +2,6 @@ # Extra parameters for `tblgen' may come after `ofn' parameter. # Adds the name of the generated file to TABLEGEN_OUTPUT. -if(LLVM_MAIN_INCLUDE_DIR) - set(LLVM_TABLEGEN_FLAGS -I ${LLVM_MAIN_INCLUDE_DIR}) -endif() - function(tablegen project ofn) # Validate calling context. if(NOT ${project}_TABLEGEN_EXE) @@ -75,6 +71,8 @@ function(tablegen project ofn) set(tblgen_change_flag "--write-if-changed") endif() + get_directory_property(includes "INCLUDE_DIRECTORIES") + list(TRANSFORM includes PREPEND -I) # We need both _TABLEGEN_TARGET and _TABLEGEN_EXE in the DEPENDS list # (both the target and the file) to have .inc files rebuilt on # a tablegen change, as cmake does not propagate file-level dependencies @@ -86,6 +84,7 @@ function(tablegen project ofn) # but lets us having smaller and cleaner code here. add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn} COMMAND ${${project}_TABLEGEN_EXE} ${ARGN} -I ${CMAKE_CURRENT_SOURCE_DIR} + ${includes} ${LLVM_TABLEGEN_FLAGS} ${LLVM_TARGET_DEFINITIONS_ABSOLUTE} ${tblgen_change_flag} diff --git a/mlir/cmake/modules/AddMLIR.cmake b/mlir/cmake/modules/AddMLIR.cmake index 2adb8f2f2935..7449f54ea877 100644 --- a/mlir/cmake/modules/AddMLIR.cmake +++ b/mlir/cmake/modules/AddMLIR.cmake @@ -1,5 +1,5 @@ function(mlir_tablegen ofn) - tablegen(MLIR ${ARGV} "-I${MLIR_MAIN_SRC_DIR}" "-I${MLIR_INCLUDE_DIR}") + tablegen(MLIR ${ARGV}) set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE) endfunction() diff --git a/mlir/examples/toy/Ch3/CMakeLists.txt b/mlir/examples/toy/Ch3/CMakeLists.txt index 4dab5e4d0626..ef70dcbac309 100644 --- a/mlir/examples/toy/Ch3/CMakeLists.txt +++ b/mlir/examples/toy/Ch3/CMakeLists.txt @@ -1,3 +1,4 @@ +include_directories(include) add_subdirectory(include) set(LLVM_LINK_COMPONENTS @@ -5,7 +6,7 @@ set(LLVM_LINK_COMPONENTS ) set(LLVM_TARGET_DEFINITIONS mlir/ToyCombine.td) -mlir_tablegen(ToyCombine.inc -gen-rewriters "-I${CMAKE_CURRENT_SOURCE_DIR}/include") +mlir_tablegen(ToyCombine.inc -gen-rewriters) add_public_tablegen_target(ToyCh3CombineIncGen) add_toy_chapter(toyc-ch3 @@ -20,7 +21,6 @@ add_toy_chapter(toyc-ch3 ToyCh3CombineIncGen ) -include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) target_link_libraries(toyc-ch3 diff --git a/mlir/examples/toy/Ch4/CMakeLists.txt b/mlir/examples/toy/Ch4/CMakeLists.txt index 3589b10645a6..ae30a691894e 100644 --- a/mlir/examples/toy/Ch4/CMakeLists.txt +++ b/mlir/examples/toy/Ch4/CMakeLists.txt @@ -1,3 +1,4 @@ +include_directories(include) add_subdirectory(include) set(LLVM_LINK_COMPONENTS @@ -5,7 +6,7 @@ set(LLVM_LINK_COMPONENTS ) set(LLVM_TARGET_DEFINITIONS mlir/ToyCombine.td) -mlir_tablegen(ToyCombine.inc -gen-rewriters "-I${CMAKE_CURRENT_SOURCE_DIR}/include") +mlir_tablegen(ToyCombine.inc -gen-rewriters) add_public_tablegen_target(ToyCh4CombineIncGen) add_toy_chapter(toyc-ch4 @@ -22,7 +23,6 @@ add_toy_chapter(toyc-ch4 ToyCh4CombineIncGen ) -include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) target_link_libraries(toyc-ch4 diff --git a/mlir/examples/toy/Ch4/include/toy/CMakeLists.txt b/mlir/examples/toy/Ch4/include/toy/CMakeLists.txt index 798d0df1d8d6..7f60477fc272 100644 --- a/mlir/examples/toy/Ch4/include/toy/CMakeLists.txt +++ b/mlir/examples/toy/Ch4/include/toy/CMakeLists.txt @@ -1,6 +1,6 @@ set(LLVM_TARGET_DEFINITIONS Ops.td) -mlir_tablegen(Ops.h.inc -gen-op-decls "-I${CMAKE_CURRENT_SOURCE_DIR}/..") -mlir_tablegen(Ops.cpp.inc -gen-op-defs "-I${CMAKE_CURRENT_SOURCE_DIR}/..") +mlir_tablegen(Ops.h.inc -gen-op-decls) +mlir_tablegen(Ops.cpp.inc -gen-op-defs) add_public_tablegen_target(ToyCh4OpsIncGen) set(LLVM_TARGET_DEFINITIONS ShapeInferenceInterface.td) diff --git a/mlir/examples/toy/Ch5/CMakeLists.txt b/mlir/examples/toy/Ch5/CMakeLists.txt index c3627cf11cd7..ba3a88e03c0b 100644 --- a/mlir/examples/toy/Ch5/CMakeLists.txt +++ b/mlir/examples/toy/Ch5/CMakeLists.txt @@ -1,3 +1,4 @@ +include_directories(include) add_subdirectory(include) set(LLVM_LINK_COMPONENTS @@ -5,7 +6,7 @@ set(LLVM_LINK_COMPONENTS ) set(LLVM_TARGET_DEFINITIONS mlir/ToyCombine.td) -mlir_tablegen(ToyCombine.inc -gen-rewriters "-I${CMAKE_CURRENT_SOURCE_DIR}/include") +mlir_tablegen(ToyCombine.inc -gen-rewriters) add_public_tablegen_target(ToyCh5CombineIncGen) add_toy_chapter(toyc-ch5 @@ -23,7 +24,6 @@ add_toy_chapter(toyc-ch5 ToyCh5CombineIncGen ) -include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) diff --git a/mlir/examples/toy/Ch5/include/toy/CMakeLists.txt b/mlir/examples/toy/Ch5/include/toy/CMakeLists.txt index aaa932896d0f..e8bd1fc0bc2e 100644 --- a/mlir/examples/toy/Ch5/include/toy/CMakeLists.txt +++ b/mlir/examples/toy/Ch5/include/toy/CMakeLists.txt @@ -1,6 +1,6 @@ set(LLVM_TARGET_DEFINITIONS Ops.td) -mlir_tablegen(Ops.h.inc -gen-op-decls "-I${CMAKE_CURRENT_SOURCE_DIR}/..") -mlir_tablegen(Ops.cpp.inc -gen-op-defs "-I${CMAKE_CURRENT_SOURCE_DIR}/..") +mlir_tablegen(Ops.h.inc -gen-op-decls) +mlir_tablegen(Ops.cpp.inc -gen-op-defs) add_public_tablegen_target(ToyCh5OpsIncGen) set(LLVM_TARGET_DEFINITIONS ShapeInferenceInterface.td) diff --git a/mlir/examples/toy/Ch6/CMakeLists.txt b/mlir/examples/toy/Ch6/CMakeLists.txt index 5d39a9ab5fc1..be797c6c1e96 100644 --- a/mlir/examples/toy/Ch6/CMakeLists.txt +++ b/mlir/examples/toy/Ch6/CMakeLists.txt @@ -1,3 +1,4 @@ +include_directories(include) add_subdirectory(include) set(LLVM_LINK_COMPONENTS @@ -6,7 +7,7 @@ set(LLVM_LINK_COMPONENTS ) set(LLVM_TARGET_DEFINITIONS mlir/ToyCombine.td) -mlir_tablegen(ToyCombine.inc -gen-rewriters "-I${CMAKE_CURRENT_SOURCE_DIR}/include") +mlir_tablegen(ToyCombine.inc -gen-rewriters) add_public_tablegen_target(ToyCh6CombineIncGen) add_toy_chapter(toyc-ch6 @@ -25,7 +26,6 @@ add_toy_chapter(toyc-ch6 ToyCh6CombineIncGen ) -include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) diff --git a/mlir/examples/toy/Ch6/include/toy/CMakeLists.txt b/mlir/examples/toy/Ch6/include/toy/CMakeLists.txt index aecf11fab6c9..c6adf5a15a73 100644 --- a/mlir/examples/toy/Ch6/include/toy/CMakeLists.txt +++ b/mlir/examples/toy/Ch6/include/toy/CMakeLists.txt @@ -1,6 +1,6 @@ set(LLVM_TARGET_DEFINITIONS Ops.td) -mlir_tablegen(Ops.h.inc -gen-op-decls "-I${CMAKE_CURRENT_SOURCE_DIR}/..") -mlir_tablegen(Ops.cpp.inc -gen-op-defs "-I${CMAKE_CURRENT_SOURCE_DIR}/..") +mlir_tablegen(Ops.h.inc -gen-op-decls) +mlir_tablegen(Ops.cpp.inc -gen-op-defs) add_public_tablegen_target(ToyCh6OpsIncGen) set(LLVM_TARGET_DEFINITIONS ShapeInferenceInterface.td) diff --git a/mlir/examples/toy/Ch7/CMakeLists.txt b/mlir/examples/toy/Ch7/CMakeLists.txt index 760052ee840f..9a9f335d3a92 100644 --- a/mlir/examples/toy/Ch7/CMakeLists.txt +++ b/mlir/examples/toy/Ch7/CMakeLists.txt @@ -1,3 +1,4 @@ +include_directories(include) add_subdirectory(include) set(LLVM_LINK_COMPONENTS @@ -6,7 +7,7 @@ set(LLVM_LINK_COMPONENTS ) set(LLVM_TARGET_DEFINITIONS mlir/ToyCombine.td) -mlir_tablegen(ToyCombine.inc -gen-rewriters "-I${CMAKE_CURRENT_SOURCE_DIR}/include") +mlir_tablegen(ToyCombine.inc -gen-rewriters) add_public_tablegen_target(ToyCh7CombineIncGen) add_toy_chapter(toyc-ch7 @@ -25,7 +26,6 @@ add_toy_chapter(toyc-ch7 ToyCh7CombineIncGen ) -include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) diff --git a/mlir/examples/toy/Ch7/include/toy/CMakeLists.txt b/mlir/examples/toy/Ch7/include/toy/CMakeLists.txt index fa30bd2e8e03..43eb23bf93b8 100644 --- a/mlir/examples/toy/Ch7/include/toy/CMakeLists.txt +++ b/mlir/examples/toy/Ch7/include/toy/CMakeLists.txt @@ -1,6 +1,6 @@ set(LLVM_TARGET_DEFINITIONS Ops.td) -mlir_tablegen(Ops.h.inc -gen-op-decls "-I${CMAKE_CURRENT_SOURCE_DIR}/..") -mlir_tablegen(Ops.cpp.inc -gen-op-defs "-I${CMAKE_CURRENT_SOURCE_DIR}/..") +mlir_tablegen(Ops.h.inc -gen-op-decls) +mlir_tablegen(Ops.cpp.inc -gen-op-defs) add_public_tablegen_target(ToyCh7OpsIncGen) set(LLVM_TARGET_DEFINITIONS ShapeInferenceInterface.td) From cfe-commits at lists.llvm.org Fri Apr 3 10:47:32 2020 From: cfe-commits at lists.llvm.org (Serge Pavlov via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 17:47:32 +0000 (UTC) Subject: [PATCH] D76384: Move FPFeatures from BinaryOperator bitfields to Trailing storage In-Reply-To: References: Message-ID: <9e4da31d5b7f7b9f8859afd5d94dd7cd@localhost.localdomain> sepavloff added inline comments. ================ Comment at: clang/include/clang/Basic/LangOptions.h:394 + return true; + } + ---------------- rjmccall wrote: > sepavloff wrote: > > erichkeane wrote: > > > rjmccall wrote: > > > > erichkeane wrote: > > > > > rjmccall wrote: > > > > > > rjmccall wrote: > > > > > > > erichkeane wrote: > > > > > > > > rjmccall wrote: > > > > > > > > > The problem with having both functions that take `ASTContext`s and functions that don't is that it's easy to mix them, so they either need to have the same behavior (in which case it's pointless to have an overload that takes the `ASTContext`) or you're making something really error-prone. > > > > > > > > > > > > > > > > > > I would feel a lot more confident that you were designing and using these APIs correctly if you actually took advantage of the ability to not store trailing FPOptions in some case, like when they match the global settings in the ASTContext. That way you'll actually be verifying that everything behaves correctly if nodes don't store FPOptions. If you do that, I think you'll see my point about not having all these easily-confusable functions that do or do not take `ASTContext`s.. > > > > > > > > I think I disagree with @rjmccall that these requiresTrailingStorage should be here at all. I think we should store in the AST ANY programmer opinion, even if they match the global setting. It seems to me that this would be more tolerant of any global-setting rewrites that modules/et-al introduce, as well as make the AST Print consistent. Always storing FPOptions when the user has explicitly overriding it also better captures the programmer's intent. > > > > > > > I covered this elsewhere in the review. If you want to have that tolerance — and I think you should — then expressions should store (and Sema should track) the active pragma state, which can be most easily expressed as a pair of an FPOptions and a mask to apply to the global FPOptions. When you enter a pragma, you clear the relevant bits from the global FPOptions mask. > > > > > > > > > > > > > > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. > > > > > > > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. > > > > > > > > > > > > I meant to say: for a million nodes that don't care in the slightest about FPOptions, as well as for a million more nodes that aren't using pragma overrides. > > > > > Right, I get the intent, and I completely agree with that. My point was EVERY Expr that is affected by a #pragma should store it. Though, after looking at your Macro concern above, I'm less compelled. > > > > > > > > > > I guess was suggesting that the logic for "requiresTrailingStorage" should just be "modified by a pragma" instead of "FPOptions != The global setting". > > > > Well, "modified by a pragma" still wouldn't make the AST agnostic to global settings, since the pragmas don't override everything in FPOptions at once. But I agree that would achieve the most important goal, which is to stop inflating the AST when pragmas *aren't* in effect, which is approximately 100% of the time. In order to do that, though, we'll need to start tracking pragmas, which we should do but which can wait for a follow-up patch. In the meantime, I don't think you're ever going to get the interfaces right for queries like `BinaryOperator::getFPOptions` unless you actually stop relying on the fact that you're unconditionally storing `FPOptions`. You need to passing around ASTContexts for that. That's why I'm suggesting using an exact match with the global settings as a simple thing you can easily check without modifying what data you collect in `FPOptions`. > > > That sounds like a good plan to me. Thanks for entertaining my conversation/questions. > > > we'll need to start tracking pragmas > > > > This is made in D76599 by representing floating point pragmas with a special statement node. These nodes allow an AST consumer like CodeGen or constant evaluator to maintain current set of floating options when it traverses AST. This approach looks simpler and more consistent as global state is represented as a variable in AST consumer and is not replicated to every relevant node. It makes easier to implement codegen for things like rounding mode, when change of the FP state requires specific instructions. A pragma statement can be used to generate required code. But if the state is spread by several nodes, it is more difficult for codegen to create necessary prolog/epilog code. Now compiler does not have support of properties that need synchronization with hardware, so these problems are not topical yet, but they eventually will arise. > Constant evaluation does not normally traverse the AST in the way you mean. It does this when evaluating a constexpr function, but that's not the dominant case of constant evaluation. > > At the LLVM level, I think inlining, reordering, and ABI requirements on calls argue against a simple implementation model based on setting hardware flags when a pragma is entered and resetting them on exit. > Constant evaluation does not normally traverse the AST in the way you mean. It does this when evaluating a constexpr function, but that's not the dominant case of constant evaluation. `Evaluate*` functions accept `EvalInfo` as argument, it can be extended to contain the current FPOptions, taken from Sema. > At the LLVM level, I think inlining, reordering, and ABI requirements on calls argue against a simple implementation model based on setting hardware flags when a pragma is entered and resetting them on exit. For targets that encode FP environment in instructions this is true. But most targets encode FP environment in hardware registers, and a model, in which required FP environment is set at entry to some region and reset on exit from it, is very attractive. Actually constrained intrinsics is a way to prevent from reordering and similar optimizations that break this simple model. As C language provide setting FP environment only at block (or global) level it would be natural if AST would have similar property. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76384/new/ https://reviews.llvm.org/D76384 From cfe-commits at lists.llvm.org Fri Apr 3 10:47:33 2020 From: cfe-commits at lists.llvm.org (Digger via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 17:47:33 +0000 (UTC) Subject: [PATCH] D76932: [AIX] emit .extern and .weak directive linkage In-Reply-To: References: Message-ID: DiggerLin added inline comments. ================ Comment at: llvm/lib/MC/MCXCOFFStreamer.cpp:48 + Symbol->setStorageClass(XCOFF::C_WEAKEXT); + Symbol->setExternal(true); + break; ---------------- jasonliu wrote: > Maybe we should just move `Symbol->setExternal(true);` outside of the switch, as it is set for every attribute that we are going to emit. I think there is Symbol->setExternal(false ) in other switch cases later . ================ Comment at: llvm/lib/MC/XCOFFObjectWriter.cpp:351 + if (nameShouldBeInStringTable(ContainingCsect->getSectionName())) + Strings.add(ContainingCsect->getSectionName()); + } ---------------- jasonliu wrote: > We should `continue` here if the rest of the logic does not matter. thanks. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76932/new/ https://reviews.llvm.org/D76932 From cfe-commits at lists.llvm.org Fri Apr 3 10:47:33 2020 From: cfe-commits at lists.llvm.org (Aaron Ballman via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 17:47:33 +0000 (UTC) Subject: [PATCH] D76818: [clang-tidy] Add check llvmlibc-implementation-in-namespace. In-Reply-To: References: Message-ID: aaron.ballman added inline comments. ================ Comment at: clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp:21 + Finder->addMatcher( + decl(hasParent(translationUnitDecl()), unless(linkageSpecDecl())) + .bind("child_of_translation_unit"), ---------------- This skips linkage spec declarations, but are there other declarations that should be similarly skipped? For instance `static_assert` declarations? ================ Comment at: clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp:33-34 + + if (isa(MatchedDecl)) { + const auto *NS = cast(MatchedDecl); + if (NS->getName() != RequiredNamespace) { ---------------- Instead of doing an `isa<>` followed by a `cast<>`, the more common pattern is to do: ``` if (const auto *NS = dyn_cast(MatchedDecl)) { ``` ================ Comment at: clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp:36 + if (NS->getName() != RequiredNamespace) { + diag(NS->getLocation(), "'%0' needs to be the outermost namespace.") + << RequiredNamespace; ---------------- clang-tidy diagnostics don't have punctuation, so you should drop the full stop. ================ Comment at: clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.cpp:42 + diag(MatchedDecl->getLocation(), + "Please wrap implentation in '%0' namespace.") + << RequiredNamespace; ---------------- They also aren't grammatically correct sentences, so the capital P and period should both go. While this definitely gets points for politeness, I think a more typical diagnostic might be: `declaration must be declared within the '%0' namespace` ================ Comment at: clang-tools-extra/clang-tidy/llvmlibc/ImplementationInNamespaceCheck.h:35 +private: + std::string RequiredNamespace; +}; ---------------- njames93 wrote: > This can be made const Will there only ever be a single namespace? Or should this be a list (for instance, a main namespace and a details namespace)? ================ Comment at: clang-tools-extra/docs/clang-tidy/checks/llvmlibc-implementation-in-namespace.rst:6 + +Checks all llvm-libc implementation is within the correct namespace. + ---------------- Checks that all declarations in the llvm-libc implementation are within the correct namespace. ================ Comment at: clang-tools-extra/docs/clang-tidy/checks/llvmlibc-implementation-in-namespace.rst:32-35 +.. option:: RequiredNamespace + + The namespace that llvm-libc implementations must be wrapped in. The default + is `__llvm_libc`. ---------------- Given that this check is specific to llvm-libc, why is the option needed at all? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76818/new/ https://reviews.llvm.org/D76818 From cfe-commits at lists.llvm.org Fri Apr 3 10:47:45 2020 From: cfe-commits at lists.llvm.org (Stephen Neuendorffer via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 17:47:45 +0000 (UTC) Subject: [PATCH] D77156: [CMAKE] Plumb include_directories() into tablegen() In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rGae044c5b0caa: [CMAKE] Plumb include_directories() into tablegen() (authored by stephenneuendorffer). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77156/new/ https://reviews.llvm.org/D77156 Files: clang/cmake/modules/AddClang.cmake llvm/cmake/modules/TableGen.cmake mlir/cmake/modules/AddMLIR.cmake mlir/examples/toy/Ch3/CMakeLists.txt mlir/examples/toy/Ch4/CMakeLists.txt mlir/examples/toy/Ch4/include/toy/CMakeLists.txt mlir/examples/toy/Ch5/CMakeLists.txt mlir/examples/toy/Ch5/include/toy/CMakeLists.txt mlir/examples/toy/Ch6/CMakeLists.txt mlir/examples/toy/Ch6/include/toy/CMakeLists.txt mlir/examples/toy/Ch7/CMakeLists.txt mlir/examples/toy/Ch7/include/toy/CMakeLists.txt -------------- next part -------------- A non-text attachment was scrubbed... Name: D77156.254854.patch Type: text/x-patch Size: 8750 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 10:48:31 2020 From: cfe-commits at lists.llvm.org (Stephen Neuendorffer via cfe-commits) Date: Fri, 03 Apr 2020 10:48:31 -0700 (PDT) Subject: [clang] f288c21 - Revert "[CMAKE] Plumb include_directories() into tablegen()" Message-ID: <5e8776ef.1c69fb81.2d80c.ab74@mx.google.com> Author: Stephen Neuendorffer Date: 2020-04-03T10:47:36-07:00 New Revision: f288c216875d6cba6465230cbb0677e839775cd9 URL: https://github.com/llvm/llvm-project/commit/f288c216875d6cba6465230cbb0677e839775cd9 DIFF: https://github.com/llvm/llvm-project/commit/f288c216875d6cba6465230cbb0677e839775cd9.diff LOG: Revert "[CMAKE] Plumb include_directories() into tablegen()" This reverts commit ae044c5b0caa095602b6ef4cca40d57efc26a8f6. This breaks the buildbots, which use an older version of cmake. Added: Modified: clang/cmake/modules/AddClang.cmake llvm/cmake/modules/TableGen.cmake mlir/cmake/modules/AddMLIR.cmake mlir/examples/toy/Ch3/CMakeLists.txt mlir/examples/toy/Ch4/CMakeLists.txt mlir/examples/toy/Ch4/include/toy/CMakeLists.txt mlir/examples/toy/Ch5/CMakeLists.txt mlir/examples/toy/Ch5/include/toy/CMakeLists.txt mlir/examples/toy/Ch6/CMakeLists.txt mlir/examples/toy/Ch6/include/toy/CMakeLists.txt mlir/examples/toy/Ch7/CMakeLists.txt mlir/examples/toy/Ch7/include/toy/CMakeLists.txt Removed: ################################################################################ diff --git a/clang/cmake/modules/AddClang.cmake b/clang/cmake/modules/AddClang.cmake index c1bb386de6f7..577cc11ab015 100644 --- a/clang/cmake/modules/AddClang.cmake +++ b/clang/cmake/modules/AddClang.cmake @@ -17,7 +17,7 @@ function(clang_tablegen) message(FATAL_ERROR "SOURCE source-file required by clang_tablegen") endif() - set( CLANG_TABLEGEN_ARGUMENTS "" ) + set( CLANG_TABLEGEN_ARGUMENTS -I ${CLANG_SOURCE_DIR}/include ) set( LLVM_TARGET_DEFINITIONS ${CTG_SOURCE} ) tablegen(CLANG ${CTG_UNPARSED_ARGUMENTS} ${CLANG_TABLEGEN_ARGUMENTS}) diff --git a/llvm/cmake/modules/TableGen.cmake b/llvm/cmake/modules/TableGen.cmake index 8d0c5afabe96..632f69aa3386 100644 --- a/llvm/cmake/modules/TableGen.cmake +++ b/llvm/cmake/modules/TableGen.cmake @@ -2,6 +2,10 @@ # Extra parameters for `tblgen' may come after `ofn' parameter. # Adds the name of the generated file to TABLEGEN_OUTPUT. +if(LLVM_MAIN_INCLUDE_DIR) + set(LLVM_TABLEGEN_FLAGS -I ${LLVM_MAIN_INCLUDE_DIR}) +endif() + function(tablegen project ofn) # Validate calling context. if(NOT ${project}_TABLEGEN_EXE) @@ -71,8 +75,6 @@ function(tablegen project ofn) set(tblgen_change_flag "--write-if-changed") endif() - get_directory_property(includes "INCLUDE_DIRECTORIES") - list(TRANSFORM includes PREPEND -I) # We need both _TABLEGEN_TARGET and _TABLEGEN_EXE in the DEPENDS list # (both the target and the file) to have .inc files rebuilt on # a tablegen change, as cmake does not propagate file-level dependencies @@ -84,7 +86,6 @@ function(tablegen project ofn) # but lets us having smaller and cleaner code here. add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn} COMMAND ${${project}_TABLEGEN_EXE} ${ARGN} -I ${CMAKE_CURRENT_SOURCE_DIR} - ${includes} ${LLVM_TABLEGEN_FLAGS} ${LLVM_TARGET_DEFINITIONS_ABSOLUTE} ${tblgen_change_flag} diff --git a/mlir/cmake/modules/AddMLIR.cmake b/mlir/cmake/modules/AddMLIR.cmake index 7449f54ea877..2adb8f2f2935 100644 --- a/mlir/cmake/modules/AddMLIR.cmake +++ b/mlir/cmake/modules/AddMLIR.cmake @@ -1,5 +1,5 @@ function(mlir_tablegen ofn) - tablegen(MLIR ${ARGV}) + tablegen(MLIR ${ARGV} "-I${MLIR_MAIN_SRC_DIR}" "-I${MLIR_INCLUDE_DIR}") set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE) endfunction() diff --git a/mlir/examples/toy/Ch3/CMakeLists.txt b/mlir/examples/toy/Ch3/CMakeLists.txt index ef70dcbac309..4dab5e4d0626 100644 --- a/mlir/examples/toy/Ch3/CMakeLists.txt +++ b/mlir/examples/toy/Ch3/CMakeLists.txt @@ -1,4 +1,3 @@ -include_directories(include) add_subdirectory(include) set(LLVM_LINK_COMPONENTS @@ -6,7 +5,7 @@ set(LLVM_LINK_COMPONENTS ) set(LLVM_TARGET_DEFINITIONS mlir/ToyCombine.td) -mlir_tablegen(ToyCombine.inc -gen-rewriters) +mlir_tablegen(ToyCombine.inc -gen-rewriters "-I${CMAKE_CURRENT_SOURCE_DIR}/include") add_public_tablegen_target(ToyCh3CombineIncGen) add_toy_chapter(toyc-ch3 @@ -21,6 +20,7 @@ add_toy_chapter(toyc-ch3 ToyCh3CombineIncGen ) +include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) target_link_libraries(toyc-ch3 diff --git a/mlir/examples/toy/Ch4/CMakeLists.txt b/mlir/examples/toy/Ch4/CMakeLists.txt index ae30a691894e..3589b10645a6 100644 --- a/mlir/examples/toy/Ch4/CMakeLists.txt +++ b/mlir/examples/toy/Ch4/CMakeLists.txt @@ -1,4 +1,3 @@ -include_directories(include) add_subdirectory(include) set(LLVM_LINK_COMPONENTS @@ -6,7 +5,7 @@ set(LLVM_LINK_COMPONENTS ) set(LLVM_TARGET_DEFINITIONS mlir/ToyCombine.td) -mlir_tablegen(ToyCombine.inc -gen-rewriters) +mlir_tablegen(ToyCombine.inc -gen-rewriters "-I${CMAKE_CURRENT_SOURCE_DIR}/include") add_public_tablegen_target(ToyCh4CombineIncGen) add_toy_chapter(toyc-ch4 @@ -23,6 +22,7 @@ add_toy_chapter(toyc-ch4 ToyCh4CombineIncGen ) +include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) target_link_libraries(toyc-ch4 diff --git a/mlir/examples/toy/Ch4/include/toy/CMakeLists.txt b/mlir/examples/toy/Ch4/include/toy/CMakeLists.txt index 7f60477fc272..798d0df1d8d6 100644 --- a/mlir/examples/toy/Ch4/include/toy/CMakeLists.txt +++ b/mlir/examples/toy/Ch4/include/toy/CMakeLists.txt @@ -1,6 +1,6 @@ set(LLVM_TARGET_DEFINITIONS Ops.td) -mlir_tablegen(Ops.h.inc -gen-op-decls) -mlir_tablegen(Ops.cpp.inc -gen-op-defs) +mlir_tablegen(Ops.h.inc -gen-op-decls "-I${CMAKE_CURRENT_SOURCE_DIR}/..") +mlir_tablegen(Ops.cpp.inc -gen-op-defs "-I${CMAKE_CURRENT_SOURCE_DIR}/..") add_public_tablegen_target(ToyCh4OpsIncGen) set(LLVM_TARGET_DEFINITIONS ShapeInferenceInterface.td) diff --git a/mlir/examples/toy/Ch5/CMakeLists.txt b/mlir/examples/toy/Ch5/CMakeLists.txt index ba3a88e03c0b..c3627cf11cd7 100644 --- a/mlir/examples/toy/Ch5/CMakeLists.txt +++ b/mlir/examples/toy/Ch5/CMakeLists.txt @@ -1,4 +1,3 @@ -include_directories(include) add_subdirectory(include) set(LLVM_LINK_COMPONENTS @@ -6,7 +5,7 @@ set(LLVM_LINK_COMPONENTS ) set(LLVM_TARGET_DEFINITIONS mlir/ToyCombine.td) -mlir_tablegen(ToyCombine.inc -gen-rewriters) +mlir_tablegen(ToyCombine.inc -gen-rewriters "-I${CMAKE_CURRENT_SOURCE_DIR}/include") add_public_tablegen_target(ToyCh5CombineIncGen) add_toy_chapter(toyc-ch5 @@ -24,6 +23,7 @@ add_toy_chapter(toyc-ch5 ToyCh5CombineIncGen ) +include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) diff --git a/mlir/examples/toy/Ch5/include/toy/CMakeLists.txt b/mlir/examples/toy/Ch5/include/toy/CMakeLists.txt index e8bd1fc0bc2e..aaa932896d0f 100644 --- a/mlir/examples/toy/Ch5/include/toy/CMakeLists.txt +++ b/mlir/examples/toy/Ch5/include/toy/CMakeLists.txt @@ -1,6 +1,6 @@ set(LLVM_TARGET_DEFINITIONS Ops.td) -mlir_tablegen(Ops.h.inc -gen-op-decls) -mlir_tablegen(Ops.cpp.inc -gen-op-defs) +mlir_tablegen(Ops.h.inc -gen-op-decls "-I${CMAKE_CURRENT_SOURCE_DIR}/..") +mlir_tablegen(Ops.cpp.inc -gen-op-defs "-I${CMAKE_CURRENT_SOURCE_DIR}/..") add_public_tablegen_target(ToyCh5OpsIncGen) set(LLVM_TARGET_DEFINITIONS ShapeInferenceInterface.td) diff --git a/mlir/examples/toy/Ch6/CMakeLists.txt b/mlir/examples/toy/Ch6/CMakeLists.txt index be797c6c1e96..5d39a9ab5fc1 100644 --- a/mlir/examples/toy/Ch6/CMakeLists.txt +++ b/mlir/examples/toy/Ch6/CMakeLists.txt @@ -1,4 +1,3 @@ -include_directories(include) add_subdirectory(include) set(LLVM_LINK_COMPONENTS @@ -7,7 +6,7 @@ set(LLVM_LINK_COMPONENTS ) set(LLVM_TARGET_DEFINITIONS mlir/ToyCombine.td) -mlir_tablegen(ToyCombine.inc -gen-rewriters) +mlir_tablegen(ToyCombine.inc -gen-rewriters "-I${CMAKE_CURRENT_SOURCE_DIR}/include") add_public_tablegen_target(ToyCh6CombineIncGen) add_toy_chapter(toyc-ch6 @@ -26,6 +25,7 @@ add_toy_chapter(toyc-ch6 ToyCh6CombineIncGen ) +include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) diff --git a/mlir/examples/toy/Ch6/include/toy/CMakeLists.txt b/mlir/examples/toy/Ch6/include/toy/CMakeLists.txt index c6adf5a15a73..aecf11fab6c9 100644 --- a/mlir/examples/toy/Ch6/include/toy/CMakeLists.txt +++ b/mlir/examples/toy/Ch6/include/toy/CMakeLists.txt @@ -1,6 +1,6 @@ set(LLVM_TARGET_DEFINITIONS Ops.td) -mlir_tablegen(Ops.h.inc -gen-op-decls) -mlir_tablegen(Ops.cpp.inc -gen-op-defs) +mlir_tablegen(Ops.h.inc -gen-op-decls "-I${CMAKE_CURRENT_SOURCE_DIR}/..") +mlir_tablegen(Ops.cpp.inc -gen-op-defs "-I${CMAKE_CURRENT_SOURCE_DIR}/..") add_public_tablegen_target(ToyCh6OpsIncGen) set(LLVM_TARGET_DEFINITIONS ShapeInferenceInterface.td) diff --git a/mlir/examples/toy/Ch7/CMakeLists.txt b/mlir/examples/toy/Ch7/CMakeLists.txt index 9a9f335d3a92..760052ee840f 100644 --- a/mlir/examples/toy/Ch7/CMakeLists.txt +++ b/mlir/examples/toy/Ch7/CMakeLists.txt @@ -1,4 +1,3 @@ -include_directories(include) add_subdirectory(include) set(LLVM_LINK_COMPONENTS @@ -7,7 +6,7 @@ set(LLVM_LINK_COMPONENTS ) set(LLVM_TARGET_DEFINITIONS mlir/ToyCombine.td) -mlir_tablegen(ToyCombine.inc -gen-rewriters) +mlir_tablegen(ToyCombine.inc -gen-rewriters "-I${CMAKE_CURRENT_SOURCE_DIR}/include") add_public_tablegen_target(ToyCh7CombineIncGen) add_toy_chapter(toyc-ch7 @@ -26,6 +25,7 @@ add_toy_chapter(toyc-ch7 ToyCh7CombineIncGen ) +include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) diff --git a/mlir/examples/toy/Ch7/include/toy/CMakeLists.txt b/mlir/examples/toy/Ch7/include/toy/CMakeLists.txt index 43eb23bf93b8..fa30bd2e8e03 100644 --- a/mlir/examples/toy/Ch7/include/toy/CMakeLists.txt +++ b/mlir/examples/toy/Ch7/include/toy/CMakeLists.txt @@ -1,6 +1,6 @@ set(LLVM_TARGET_DEFINITIONS Ops.td) -mlir_tablegen(Ops.h.inc -gen-op-decls) -mlir_tablegen(Ops.cpp.inc -gen-op-defs) +mlir_tablegen(Ops.h.inc -gen-op-decls "-I${CMAKE_CURRENT_SOURCE_DIR}/..") +mlir_tablegen(Ops.cpp.inc -gen-op-defs "-I${CMAKE_CURRENT_SOURCE_DIR}/..") add_public_tablegen_target(ToyCh7OpsIncGen) set(LLVM_TARGET_DEFINITIONS ShapeInferenceInterface.td) From cfe-commits at lists.llvm.org Fri Apr 3 11:20:24 2020 From: cfe-commits at lists.llvm.org (Mark Nauwelaerts via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:20:24 +0000 (UTC) Subject: [PATCH] D77385: [clangd] Add index inspection helper tool In-Reply-To: References: Message-ID: <2c6d544c2ff066467ef32a326faaebd7@localhost.localdomain> mnauw added a comment. Thanks for having a look at this patch. My use-case/goal would be to have a way to run/do a command that reads some index and dumps it (in e.g. YAML) to (e.g.) stdout. That way it can be inspected/viewed all at once by plain viewer. And not only symbols, refs, but also recorded paths (that form the include-graph). The latter in particular was/is useful when investigating some not-entirely-consistent symlink-resolution issues. The goal is not necessarily a separate binary, so if it's ok to extend dexp to achieve the former (e.g. by adding option(s)) then I can also update to patch that way accordingly. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77385/new/ https://reviews.llvm.org/D77385 From cfe-commits at lists.llvm.org Fri Apr 3 11:20:24 2020 From: cfe-commits at lists.llvm.org (Yitzhak Mandelbaum via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:20:24 +0000 (UTC) Subject: [PATCH] D77419: [libTooling] Simplify the representation of Transformer's RewriteRules. Message-ID: ymandel created this revision. ymandel added a reviewer: gribozavr2. Herald added a subscriber: jfb. Herald added a project: clang. This revision simplifies the representation of edits in rewrite rules. The simplified form is more general, allowing the user more flexibility in building custom edit specifications. The changes extend the API, without changing the signature of existing functions. So this only risks breaking users that directly accessed the `RewriteRule` struct. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77419 Files: clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp clang/include/clang/Tooling/Transformer/RewriteRule.h clang/lib/Tooling/Transformer/RewriteRule.cpp clang/lib/Tooling/Transformer/Transformer.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77419.254859.patch Type: text/x-patch Size: 9877 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 11:20:24 2020 From: cfe-commits at lists.llvm.org (Aaron Ballman via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:20:24 +0000 (UTC) Subject: [PATCH] D76083: [clang-tidy] Expand the list of functions in bugprone-unused-return-value In-Reply-To: References: Message-ID: aaron.ballman added inline comments. ================ Comment at: clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp:98 + "::access;" + "::bind;" + "::connect;" ---------------- sammccall wrote: > aaron.ballman wrote: > > sammccall wrote: > > > aaron.ballman wrote: > > > > jranieri-grammatech wrote: > > > > > alexfh wrote: > > > > > > bind has a side effect and returns a success status. Thus, the result being unused isn't necessarily a bug. Same for `connect`. And probably for `setjmp` as well. > > > > > In terms of bind, connect, and setjmp: while I personally would say that code not using the return value is bugprone, the data suggests that the vast majority of developers are using these functions in the intended manner and the false-positive rate should be low. > > > > I think we have sufficient statistical data to suggest that these APIs should be on the list because the majority of programmers *do not* use them solely for side effects without using the return value, so my preference is to keep them in the list. > > > I stumbled upon this review as we're considering turning this check on by default in clangd. > > > > > > There's a significant difference between unused std::async() (programmer misunderstood contract) and unused ::connect() (ignoring error conditions). The former is ~never noise, and the latter may be (e.g. in experimental or incomplete code). > > > > > > So there's some value in separating these two lists out either as an option or a separate named check (bugprone-unhandled-error?) I think we probably wouldn't enable this check by default if it includes the error-code functions. > > > > > > > the majority of programmers *do not* use them solely for side effects > > > ...in popular, distributed software :-) > > > So there's some value in separating these two lists out either as an option or a separate named check (bugprone-unhandled-error?) I think we probably wouldn't enable this check by default if it includes the error-code functions. > > > > I think that adds complexity to this check when the complexity isn't necessary. clang-tidy has traditionally been a place for checks that are chattier than what the compiler should provide, and this check has a trivial, well-understood mechanism to silence the diagnostics (cast to void) which also expresses intent properly to the toolchain. > > > > >>the majority of programmers *do not* use them solely for side effects > > > ...in popular, distributed software :-) > > > > I have not seen anyone provide data to suggest that the functions in question appear in any statistically significant amount in practice without checking the return value, just worries that they *could*. I don't think that's compelling in the face of data. Remember, this is for bugprone patterns, not bugknown patterns. > I think we're talking past each other here. I'm not saying clang-tidy shouldn't have the check, or that it's not a bugprone pattern, or that the clang-tidy default should be different. > > But there are scenarios where you want one but not the other. Concretely, warnings shown in an IDE **as you type and by default**. If you're misusing an API rendering it completely useless, you should see that ASAP. If you fail to check an error code, some users won't want to be warned about that until later. > > By bundling them into a single check without options (other than duplicating the whole list), it's hard to create that useful but inoffensive default setup. That's OK, clangd can remove the check from the whitelist, but I think we'd get a lot of value out of it. > > > I have not seen anyone provide data to suggest that the functions in question appear in any statistically significant amount in practice > Right, we don't have data either way on incomplete code. Based on experience of writing code and watching others write code, I believe people write sloppy code they'd never check in, and appreciate being told early when it doesn't do what they intend, but some don't appreciate being told to be less sloppy. Is your intuition different? Do you think the data provided addresses this question? > But there are scenarios where you want one but not the other. Concretely, warnings shown in an IDE as you type and by default. If you're misusing an API rendering it completely useless, you should see that ASAP. If you fail to check an error code, some users won't want to be warned about that until later. You're right, we were talking past one another because this was not a scenario I had in mind at all. Thank you for raising it! > Is your intuition different? Do you think the data provided addresses this question? I will have to spend some time figuring out what my intuition is for checks that are run as you are typing the code, but my wildly unconsidered opinion is that there's not a big difference between as-you-type and not for these checks. Either it's a bad idea to ignore the return value or it's not a bad idea -- whether you're still typing or not does seem to change the answer. However, as I said, this is an unconsidered opinion. :-) However, the data we've found *definitely* does not address the question. One thing this check does not do is add a fix-it hint to automatically cast to void. If such a fixit were added, would that help the as-you-type scenario by providing a way to quickly insert the way to silence the diagnostic for those who really do want to ignore the return value? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76083/new/ https://reviews.llvm.org/D76083 From cfe-commits at lists.llvm.org Fri Apr 3 11:20:26 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:20:26 +0000 (UTC) Subject: [PATCH] D76384: Move FPFeatures from BinaryOperator bitfields to Trailing storage In-Reply-To: References: Message-ID: <4a1ad8a9b54afa11fa7818578723d17c@localhost.localdomain> rjmccall added inline comments. ================ Comment at: clang/include/clang/Basic/LangOptions.h:394 + return true; + } + ---------------- sepavloff wrote: > rjmccall wrote: > > sepavloff wrote: > > > erichkeane wrote: > > > > rjmccall wrote: > > > > > erichkeane wrote: > > > > > > rjmccall wrote: > > > > > > > rjmccall wrote: > > > > > > > > erichkeane wrote: > > > > > > > > > rjmccall wrote: > > > > > > > > > > The problem with having both functions that take `ASTContext`s and functions that don't is that it's easy to mix them, so they either need to have the same behavior (in which case it's pointless to have an overload that takes the `ASTContext`) or you're making something really error-prone. > > > > > > > > > > > > > > > > > > > > I would feel a lot more confident that you were designing and using these APIs correctly if you actually took advantage of the ability to not store trailing FPOptions in some case, like when they match the global settings in the ASTContext. That way you'll actually be verifying that everything behaves correctly if nodes don't store FPOptions. If you do that, I think you'll see my point about not having all these easily-confusable functions that do or do not take `ASTContext`s.. > > > > > > > > > I think I disagree with @rjmccall that these requiresTrailingStorage should be here at all. I think we should store in the AST ANY programmer opinion, even if they match the global setting. It seems to me that this would be more tolerant of any global-setting rewrites that modules/et-al introduce, as well as make the AST Print consistent. Always storing FPOptions when the user has explicitly overriding it also better captures the programmer's intent. > > > > > > > > I covered this elsewhere in the review. If you want to have that tolerance — and I think you should — then expressions should store (and Sema should track) the active pragma state, which can be most easily expressed as a pair of an FPOptions and a mask to apply to the global FPOptions. When you enter a pragma, you clear the relevant bits from the global FPOptions mask. > > > > > > > > > > > > > > > > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. > > > > > > > > But the whole point of putting this stuff in trailing storage is so that you can make FPOptions as big as you need without actually inflating the AST size for a million nodes that don't care in the slightest about FPOptions. > > > > > > > > > > > > > > I meant to say: for a million nodes that don't care in the slightest about FPOptions, as well as for a million more nodes that aren't using pragma overrides. > > > > > > Right, I get the intent, and I completely agree with that. My point was EVERY Expr that is affected by a #pragma should store it. Though, after looking at your Macro concern above, I'm less compelled. > > > > > > > > > > > > I guess was suggesting that the logic for "requiresTrailingStorage" should just be "modified by a pragma" instead of "FPOptions != The global setting". > > > > > Well, "modified by a pragma" still wouldn't make the AST agnostic to global settings, since the pragmas don't override everything in FPOptions at once. But I agree that would achieve the most important goal, which is to stop inflating the AST when pragmas *aren't* in effect, which is approximately 100% of the time. In order to do that, though, we'll need to start tracking pragmas, which we should do but which can wait for a follow-up patch. In the meantime, I don't think you're ever going to get the interfaces right for queries like `BinaryOperator::getFPOptions` unless you actually stop relying on the fact that you're unconditionally storing `FPOptions`. You need to passing around ASTContexts for that. That's why I'm suggesting using an exact match with the global settings as a simple thing you can easily check without modifying what data you collect in `FPOptions`. > > > > That sounds like a good plan to me. Thanks for entertaining my conversation/questions. > > > > we'll need to start tracking pragmas > > > > > > This is made in D76599 by representing floating point pragmas with a special statement node. These nodes allow an AST consumer like CodeGen or constant evaluator to maintain current set of floating options when it traverses AST. This approach looks simpler and more consistent as global state is represented as a variable in AST consumer and is not replicated to every relevant node. It makes easier to implement codegen for things like rounding mode, when change of the FP state requires specific instructions. A pragma statement can be used to generate required code. But if the state is spread by several nodes, it is more difficult for codegen to create necessary prolog/epilog code. Now compiler does not have support of properties that need synchronization with hardware, so these problems are not topical yet, but they eventually will arise. > > Constant evaluation does not normally traverse the AST in the way you mean. It does this when evaluating a constexpr function, but that's not the dominant case of constant evaluation. > > > > At the LLVM level, I think inlining, reordering, and ABI requirements on calls argue against a simple implementation model based on setting hardware flags when a pragma is entered and resetting them on exit. > > Constant evaluation does not normally traverse the AST in the way you mean. It does this when evaluating a constexpr function, but that's not the dominant case of constant evaluation. > > `Evaluate*` functions accept `EvalInfo` as argument, it can be extended to contain the current FPOptions, taken from Sema. > > > At the LLVM level, I think inlining, reordering, and ABI requirements on calls argue against a simple implementation model based on setting hardware flags when a pragma is entered and resetting them on exit. > > For targets that encode FP environment in instructions this is true. But most targets encode FP environment in hardware registers, and a model, in which required FP environment is set at entry to some region and reset on exit from it, is very attractive. Actually constrained intrinsics is a way to prevent from reordering and similar optimizations that break this simple model. As C language provide setting FP environment only at block (or global) level it would be natural if AST would have similar property. Many clients of the constant evaluator are not tied to Sema or are analyzing code that wasn't necessarily written in the current context. What you're discussing is *extremely* error-prone. > For targets that encode FP environment in instructions this is true. But most targets encode FP environment in hardware registers, and a model, in which required FP environment is set at entry to some region and reset on exit from it, is very attractive. The constrained-intrinsics representation records options on each intrinsic, so no, it wouldn't naturally support a setup where the frontend emits intrinsics that change hardware flags on entry/exit to a region. That nicely matches a model where options are set on each expression. It also, fortunately, naturally supports optimizations like inlining as long as we turn non-intrinsic operations into intrinsics where necessary. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76384/new/ https://reviews.llvm.org/D76384 From cfe-commits at lists.llvm.org Fri Apr 3 11:20:26 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Fri, 03 Apr 2020 18:20:26 +0000 (UTC) Subject: [PATCH] D77411: [analyzer] StdLibraryFunctionsChecker: Add test for function with default parameter In-Reply-To: References: Message-ID: Szelethus accepted this revision. Szelethus added a comment. This revision is now accepted and ready to land. Yay. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77411/new/ https://reviews.llvm.org/D77411 From cfe-commits at lists.llvm.org Fri Apr 3 11:20:27 2020 From: cfe-commits at lists.llvm.org (Stephan Dollberg via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:20:27 +0000 (UTC) Subject: [PATCH] D77420: Also look for devtoolset-9 gcc toolchain Message-ID: stephan.dollberg created this revision. stephan.dollberg added a reviewer: chandlerc. Herald added a project: clang. devtoolset-9 has been out for a while so also look for it. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77420 Files: clang/lib/Driver/ToolChains/Gnu.cpp Index: clang/lib/Driver/ToolChains/Gnu.cpp =================================================================== --- clang/lib/Driver/ToolChains/Gnu.cpp +++ clang/lib/Driver/ToolChains/Gnu.cpp @@ -1977,6 +1977,7 @@ // Non-Solaris is much simpler - most systems just go with "/usr". if (SysRoot.empty() && TargetTriple.getOS() == llvm::Triple::Linux) { // Yet, still look for RHEL devtoolsets. + Prefixes.push_back("/opt/rh/devtoolset-9/root/usr"); Prefixes.push_back("/opt/rh/devtoolset-8/root/usr"); Prefixes.push_back("/opt/rh/devtoolset-7/root/usr"); Prefixes.push_back("/opt/rh/devtoolset-6/root/usr"); -------------- next part -------------- A non-text attachment was scrubbed... Name: D77420.254860.patch Type: text/x-patch Size: 634 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 11:20:27 2020 From: cfe-commits at lists.llvm.org (Mitchell via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:20:27 +0000 (UTC) Subject: [PATCH] D75364: [clang-format] Handle macros in function params and return value In-Reply-To: References: Message-ID: mitchell-stellar added inline comments. ================ Comment at: clang/unittests/Format/FormatTest.cpp:7359 verifyIndependentOfContext("bool a = f() && final.f();"); + verifyFormat("int f(M(x) *p1 = nullptr, M(x) *p2, volatile M(x) *p3);"); + verifyFormat("M(x) *foo();"); ---------------- I would like to see the macro definitions in your tests. It's not clear from looking at just the test line that `M` is supposed to be a macro. It looks like a syntax error. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75364/new/ https://reviews.llvm.org/D75364 From cfe-commits at lists.llvm.org Fri Apr 3 11:20:27 2020 From: cfe-commits at lists.llvm.org (Florian Hahn via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:20:27 +0000 (UTC) Subject: [PATCH] D76612: [Matrix] Add draft specification for matrix support in Clang. In-Reply-To: References: Message-ID: fhahn updated this revision to Diff 254861. fhahn added a comment. Specify that standard conversion rules do not apply to assignments for matrix types. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76612/new/ https://reviews.llvm.org/D76612 Files: clang/docs/LanguageExtensions.rst clang/docs/MatrixSupport.rst -------------- next part -------------- A non-text attachment was scrubbed... Name: D76612.254861.patch Type: text/x-patch Size: 12893 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 11:24:32 2020 From: cfe-commits at lists.llvm.org (Stephen Neuendorffer via cfe-commits) Date: Fri, 03 Apr 2020 11:24:32 -0700 (PDT) Subject: [clang] 0c0831f - [CMAKE] Plumb include_directories() into tablegen() Message-ID: <5e877f60.1c69fb81.bfa6c.da43@mx.google.com> Author: Stephen Neuendorffer Date: 2020-04-03T11:23:38-07:00 New Revision: 0c0831f74b7181268a777a39ee087c9337ffa0c5 URL: https://github.com/llvm/llvm-project/commit/0c0831f74b7181268a777a39ee087c9337ffa0c5 DIFF: https://github.com/llvm/llvm-project/commit/0c0831f74b7181268a777a39ee087c9337ffa0c5.diff LOG: [CMAKE] Plumb include_directories() into tablegen() Previously, the tablegen() cmake command, which defines custom commands for running tablegen, included several hardcoded paths. This becomes unwieldy as there are more users for which these paths are insufficient. For most targets, cmake uses include_directories() and the INCLUDE_DIRECTORIES directory property to specify include paths. This change picks up the INCLUDE_DIRECTORIES property and adds it to the include path used when running tablegen. As a side effect, this allows us to remove several hard coded paths to tablegen that are redundant with specified include_directories(). I haven't removed the hardcoded path to CMAKE_CURRENT_SOURCE_DIR, which seems generically useful. There are several users in clang which apparently don't have the current directory as an include_directories(). This could be considered separately. The new version of this path uses list APPEND rather than list TRANSFORM, in order to be compatible with cmake 3.4.3. If we update to cmake 3.12 then we can use list TRANSFORM instead. Differential Revision: https://reviews.llvm.org/D77156 Added: Modified: clang/cmake/modules/AddClang.cmake llvm/cmake/modules/TableGen.cmake mlir/cmake/modules/AddMLIR.cmake mlir/examples/toy/Ch3/CMakeLists.txt mlir/examples/toy/Ch4/CMakeLists.txt mlir/examples/toy/Ch4/include/toy/CMakeLists.txt mlir/examples/toy/Ch5/CMakeLists.txt mlir/examples/toy/Ch5/include/toy/CMakeLists.txt mlir/examples/toy/Ch6/CMakeLists.txt mlir/examples/toy/Ch6/include/toy/CMakeLists.txt mlir/examples/toy/Ch7/CMakeLists.txt mlir/examples/toy/Ch7/include/toy/CMakeLists.txt Removed: ################################################################################ diff --git a/clang/cmake/modules/AddClang.cmake b/clang/cmake/modules/AddClang.cmake index 577cc11ab015..c1bb386de6f7 100644 --- a/clang/cmake/modules/AddClang.cmake +++ b/clang/cmake/modules/AddClang.cmake @@ -17,7 +17,7 @@ function(clang_tablegen) message(FATAL_ERROR "SOURCE source-file required by clang_tablegen") endif() - set( CLANG_TABLEGEN_ARGUMENTS -I ${CLANG_SOURCE_DIR}/include ) + set( CLANG_TABLEGEN_ARGUMENTS "" ) set( LLVM_TARGET_DEFINITIONS ${CTG_SOURCE} ) tablegen(CLANG ${CTG_UNPARSED_ARGUMENTS} ${CLANG_TABLEGEN_ARGUMENTS}) diff --git a/llvm/cmake/modules/TableGen.cmake b/llvm/cmake/modules/TableGen.cmake index 632f69aa3386..65e31d0624f0 100644 --- a/llvm/cmake/modules/TableGen.cmake +++ b/llvm/cmake/modules/TableGen.cmake @@ -2,10 +2,6 @@ # Extra parameters for `tblgen' may come after `ofn' parameter. # Adds the name of the generated file to TABLEGEN_OUTPUT. -if(LLVM_MAIN_INCLUDE_DIR) - set(LLVM_TABLEGEN_FLAGS -I ${LLVM_MAIN_INCLUDE_DIR}) -endif() - function(tablegen project ofn) # Validate calling context. if(NOT ${project}_TABLEGEN_EXE) @@ -75,6 +71,14 @@ function(tablegen project ofn) set(tblgen_change_flag "--write-if-changed") endif() + # With CMake 3.12 this can be reduced to: + # get_directory_property(tblgen_includes "INCLUDE_DIRECTORIES") + # list(TRANSFORM tblgen_includes PREPEND -I) + set(tblgen_includes) + get_directory_property(includes "INCLUDE_DIRECTORIES") + foreach(include ${includes}) + list(APPEND tblgen_includes -I ${include}) + endforeach() # We need both _TABLEGEN_TARGET and _TABLEGEN_EXE in the DEPENDS list # (both the target and the file) to have .inc files rebuilt on # a tablegen change, as cmake does not propagate file-level dependencies @@ -86,6 +90,7 @@ function(tablegen project ofn) # but lets us having smaller and cleaner code here. add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn} COMMAND ${${project}_TABLEGEN_EXE} ${ARGN} -I ${CMAKE_CURRENT_SOURCE_DIR} + ${tblgen_includes} ${LLVM_TABLEGEN_FLAGS} ${LLVM_TARGET_DEFINITIONS_ABSOLUTE} ${tblgen_change_flag} diff --git a/mlir/cmake/modules/AddMLIR.cmake b/mlir/cmake/modules/AddMLIR.cmake index 2adb8f2f2935..7449f54ea877 100644 --- a/mlir/cmake/modules/AddMLIR.cmake +++ b/mlir/cmake/modules/AddMLIR.cmake @@ -1,5 +1,5 @@ function(mlir_tablegen ofn) - tablegen(MLIR ${ARGV} "-I${MLIR_MAIN_SRC_DIR}" "-I${MLIR_INCLUDE_DIR}") + tablegen(MLIR ${ARGV}) set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} PARENT_SCOPE) endfunction() diff --git a/mlir/examples/toy/Ch3/CMakeLists.txt b/mlir/examples/toy/Ch3/CMakeLists.txt index 4dab5e4d0626..ef70dcbac309 100644 --- a/mlir/examples/toy/Ch3/CMakeLists.txt +++ b/mlir/examples/toy/Ch3/CMakeLists.txt @@ -1,3 +1,4 @@ +include_directories(include) add_subdirectory(include) set(LLVM_LINK_COMPONENTS @@ -5,7 +6,7 @@ set(LLVM_LINK_COMPONENTS ) set(LLVM_TARGET_DEFINITIONS mlir/ToyCombine.td) -mlir_tablegen(ToyCombine.inc -gen-rewriters "-I${CMAKE_CURRENT_SOURCE_DIR}/include") +mlir_tablegen(ToyCombine.inc -gen-rewriters) add_public_tablegen_target(ToyCh3CombineIncGen) add_toy_chapter(toyc-ch3 @@ -20,7 +21,6 @@ add_toy_chapter(toyc-ch3 ToyCh3CombineIncGen ) -include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) target_link_libraries(toyc-ch3 diff --git a/mlir/examples/toy/Ch4/CMakeLists.txt b/mlir/examples/toy/Ch4/CMakeLists.txt index 3589b10645a6..ae30a691894e 100644 --- a/mlir/examples/toy/Ch4/CMakeLists.txt +++ b/mlir/examples/toy/Ch4/CMakeLists.txt @@ -1,3 +1,4 @@ +include_directories(include) add_subdirectory(include) set(LLVM_LINK_COMPONENTS @@ -5,7 +6,7 @@ set(LLVM_LINK_COMPONENTS ) set(LLVM_TARGET_DEFINITIONS mlir/ToyCombine.td) -mlir_tablegen(ToyCombine.inc -gen-rewriters "-I${CMAKE_CURRENT_SOURCE_DIR}/include") +mlir_tablegen(ToyCombine.inc -gen-rewriters) add_public_tablegen_target(ToyCh4CombineIncGen) add_toy_chapter(toyc-ch4 @@ -22,7 +23,6 @@ add_toy_chapter(toyc-ch4 ToyCh4CombineIncGen ) -include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) target_link_libraries(toyc-ch4 diff --git a/mlir/examples/toy/Ch4/include/toy/CMakeLists.txt b/mlir/examples/toy/Ch4/include/toy/CMakeLists.txt index 798d0df1d8d6..7f60477fc272 100644 --- a/mlir/examples/toy/Ch4/include/toy/CMakeLists.txt +++ b/mlir/examples/toy/Ch4/include/toy/CMakeLists.txt @@ -1,6 +1,6 @@ set(LLVM_TARGET_DEFINITIONS Ops.td) -mlir_tablegen(Ops.h.inc -gen-op-decls "-I${CMAKE_CURRENT_SOURCE_DIR}/..") -mlir_tablegen(Ops.cpp.inc -gen-op-defs "-I${CMAKE_CURRENT_SOURCE_DIR}/..") +mlir_tablegen(Ops.h.inc -gen-op-decls) +mlir_tablegen(Ops.cpp.inc -gen-op-defs) add_public_tablegen_target(ToyCh4OpsIncGen) set(LLVM_TARGET_DEFINITIONS ShapeInferenceInterface.td) diff --git a/mlir/examples/toy/Ch5/CMakeLists.txt b/mlir/examples/toy/Ch5/CMakeLists.txt index c3627cf11cd7..ba3a88e03c0b 100644 --- a/mlir/examples/toy/Ch5/CMakeLists.txt +++ b/mlir/examples/toy/Ch5/CMakeLists.txt @@ -1,3 +1,4 @@ +include_directories(include) add_subdirectory(include) set(LLVM_LINK_COMPONENTS @@ -5,7 +6,7 @@ set(LLVM_LINK_COMPONENTS ) set(LLVM_TARGET_DEFINITIONS mlir/ToyCombine.td) -mlir_tablegen(ToyCombine.inc -gen-rewriters "-I${CMAKE_CURRENT_SOURCE_DIR}/include") +mlir_tablegen(ToyCombine.inc -gen-rewriters) add_public_tablegen_target(ToyCh5CombineIncGen) add_toy_chapter(toyc-ch5 @@ -23,7 +24,6 @@ add_toy_chapter(toyc-ch5 ToyCh5CombineIncGen ) -include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) diff --git a/mlir/examples/toy/Ch5/include/toy/CMakeLists.txt b/mlir/examples/toy/Ch5/include/toy/CMakeLists.txt index aaa932896d0f..e8bd1fc0bc2e 100644 --- a/mlir/examples/toy/Ch5/include/toy/CMakeLists.txt +++ b/mlir/examples/toy/Ch5/include/toy/CMakeLists.txt @@ -1,6 +1,6 @@ set(LLVM_TARGET_DEFINITIONS Ops.td) -mlir_tablegen(Ops.h.inc -gen-op-decls "-I${CMAKE_CURRENT_SOURCE_DIR}/..") -mlir_tablegen(Ops.cpp.inc -gen-op-defs "-I${CMAKE_CURRENT_SOURCE_DIR}/..") +mlir_tablegen(Ops.h.inc -gen-op-decls) +mlir_tablegen(Ops.cpp.inc -gen-op-defs) add_public_tablegen_target(ToyCh5OpsIncGen) set(LLVM_TARGET_DEFINITIONS ShapeInferenceInterface.td) diff --git a/mlir/examples/toy/Ch6/CMakeLists.txt b/mlir/examples/toy/Ch6/CMakeLists.txt index 5d39a9ab5fc1..be797c6c1e96 100644 --- a/mlir/examples/toy/Ch6/CMakeLists.txt +++ b/mlir/examples/toy/Ch6/CMakeLists.txt @@ -1,3 +1,4 @@ +include_directories(include) add_subdirectory(include) set(LLVM_LINK_COMPONENTS @@ -6,7 +7,7 @@ set(LLVM_LINK_COMPONENTS ) set(LLVM_TARGET_DEFINITIONS mlir/ToyCombine.td) -mlir_tablegen(ToyCombine.inc -gen-rewriters "-I${CMAKE_CURRENT_SOURCE_DIR}/include") +mlir_tablegen(ToyCombine.inc -gen-rewriters) add_public_tablegen_target(ToyCh6CombineIncGen) add_toy_chapter(toyc-ch6 @@ -25,7 +26,6 @@ add_toy_chapter(toyc-ch6 ToyCh6CombineIncGen ) -include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) diff --git a/mlir/examples/toy/Ch6/include/toy/CMakeLists.txt b/mlir/examples/toy/Ch6/include/toy/CMakeLists.txt index aecf11fab6c9..c6adf5a15a73 100644 --- a/mlir/examples/toy/Ch6/include/toy/CMakeLists.txt +++ b/mlir/examples/toy/Ch6/include/toy/CMakeLists.txt @@ -1,6 +1,6 @@ set(LLVM_TARGET_DEFINITIONS Ops.td) -mlir_tablegen(Ops.h.inc -gen-op-decls "-I${CMAKE_CURRENT_SOURCE_DIR}/..") -mlir_tablegen(Ops.cpp.inc -gen-op-defs "-I${CMAKE_CURRENT_SOURCE_DIR}/..") +mlir_tablegen(Ops.h.inc -gen-op-decls) +mlir_tablegen(Ops.cpp.inc -gen-op-defs) add_public_tablegen_target(ToyCh6OpsIncGen) set(LLVM_TARGET_DEFINITIONS ShapeInferenceInterface.td) diff --git a/mlir/examples/toy/Ch7/CMakeLists.txt b/mlir/examples/toy/Ch7/CMakeLists.txt index 760052ee840f..9a9f335d3a92 100644 --- a/mlir/examples/toy/Ch7/CMakeLists.txt +++ b/mlir/examples/toy/Ch7/CMakeLists.txt @@ -1,3 +1,4 @@ +include_directories(include) add_subdirectory(include) set(LLVM_LINK_COMPONENTS @@ -6,7 +7,7 @@ set(LLVM_LINK_COMPONENTS ) set(LLVM_TARGET_DEFINITIONS mlir/ToyCombine.td) -mlir_tablegen(ToyCombine.inc -gen-rewriters "-I${CMAKE_CURRENT_SOURCE_DIR}/include") +mlir_tablegen(ToyCombine.inc -gen-rewriters) add_public_tablegen_target(ToyCh7CombineIncGen) add_toy_chapter(toyc-ch7 @@ -25,7 +26,6 @@ add_toy_chapter(toyc-ch7 ToyCh7CombineIncGen ) -include_directories(include/) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/) get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) diff --git a/mlir/examples/toy/Ch7/include/toy/CMakeLists.txt b/mlir/examples/toy/Ch7/include/toy/CMakeLists.txt index fa30bd2e8e03..43eb23bf93b8 100644 --- a/mlir/examples/toy/Ch7/include/toy/CMakeLists.txt +++ b/mlir/examples/toy/Ch7/include/toy/CMakeLists.txt @@ -1,6 +1,6 @@ set(LLVM_TARGET_DEFINITIONS Ops.td) -mlir_tablegen(Ops.h.inc -gen-op-decls "-I${CMAKE_CURRENT_SOURCE_DIR}/..") -mlir_tablegen(Ops.cpp.inc -gen-op-defs "-I${CMAKE_CURRENT_SOURCE_DIR}/..") +mlir_tablegen(Ops.h.inc -gen-op-decls) +mlir_tablegen(Ops.cpp.inc -gen-op-defs) add_public_tablegen_target(ToyCh7OpsIncGen) set(LLVM_TARGET_DEFINITIONS ShapeInferenceInterface.td) From cfe-commits at lists.llvm.org Fri Apr 3 11:43:53 2020 From: cfe-commits at lists.llvm.org (Nathan James via cfe-commits) Date: Fri, 03 Apr 2020 11:43:53 -0700 (PDT) Subject: [clang-tools-extra] 2c7ea1c - [clang-tidy] Address false positive in modernize-use-default-member-init Message-ID: <5e8783e9.1c69fb81.8155d.e1c6@mx.google.com> Author: Nathan James Date: 2020-04-03T19:43:46+01:00 New Revision: 2c7ea1c4c5f7dde562bac684a59ad67f1f062726 URL: https://github.com/llvm/llvm-project/commit/2c7ea1c4c5f7dde562bac684a59ad67f1f062726 DIFF: https://github.com/llvm/llvm-project/commit/2c7ea1c4c5f7dde562bac684a59ad67f1f062726.diff LOG: [clang-tidy] Address false positive in modernize-use-default-member-init Summary: Fixes [[ https://bugs.llvm.org/show_bug.cgi?id=45363 | incorrect warning emitted by "modernize-use-default-member-init" (new to 10.0.0) ]]. Reviewers: aaron.ballman, alexfh, gribozavr2 Reviewed By: aaron.ballman Subscribers: xazax.hun, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77199 Added: Modified: clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp index cb275ab58f1b..04cc7aa9d449 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp @@ -17,6 +17,12 @@ namespace clang { namespace tidy { namespace modernize { +namespace { +AST_MATCHER_P(InitListExpr, initCountIs, unsigned, N) { + return Node.getNumInits() == N; +} +} // namespace + static StringRef getValueOfValueInit(const QualType InitType) { switch (InitType->getScalarTypeKind()) { case Type::STK_CPointer: @@ -190,7 +196,7 @@ void UseDefaultMemberInitCheck::storeOptions( } void UseDefaultMemberInitCheck::registerMatchers(MatchFinder *Finder) { - auto Init = + auto InitBase = anyOf(stringLiteral(), characterLiteral(), integerLiteral(), unaryOperator(hasAnyOperatorName("+", "-"), hasUnaryOperand(integerLiteral())), @@ -198,7 +204,13 @@ void UseDefaultMemberInitCheck::registerMatchers(MatchFinder *Finder) { unaryOperator(hasAnyOperatorName("+", "-"), hasUnaryOperand(floatLiteral())), cxxBoolLiteral(), cxxNullPtrLiteralExpr(), implicitValueInitExpr(), - initListExpr(), declRefExpr(to(enumConstantDecl()))); + declRefExpr(to(enumConstantDecl()))); + + auto Init = + anyOf(initListExpr(anyOf( + allOf(initCountIs(1), hasInit(0, ignoringImplicit(InitBase))), + initCountIs(0))), + InitBase); Finder->addMatcher( cxxConstructorDecl( diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp index 3570fcff4a5c..60344e06dc31 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp @@ -432,3 +432,17 @@ class FunctionTryBlock { // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: use default member initializer for 'k' [modernize-use-default-member-init] // CHECK-FIXES: int i{5}, k{8}; }; + +struct PR45363 { + // Ensure no warning is emitted here + PR45363(int i = 0) : m_i{i} {} + int m_i; +}; + +struct EmptyBracedIntDefault { + EmptyBracedIntDefault() : m_i{} {} + int m_i; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'm_i' [modernize-use-default-member-init] + // CHECK-FIXES: {{^ }}EmptyBracedIntDefault() {} + // CHECK-FIXES-NEXT: {{^ }}int m_i{}; +}; From cfe-commits at lists.llvm.org Fri Apr 3 11:53:38 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:53:38 +0000 (UTC) Subject: [PATCH] D77408: [clang] Annotate trivial getters and setters on hover. In-Reply-To: References: Message-ID: <725295fe90be9cbe9bfddd1821ec0028@localhost.localdomain> sammccall marked 2 inline comments as done. sammccall added inline comments. ================ Comment at: clang-tools-extra/clangd/Hover.cpp:376 +llvm::Optional fieldName(const Expr *E) { + const auto *ReturnedMember = llvm::dyn_cast(E->IgnoreCasts()); + const auto *Field = ---------------- kadircet wrote: > if(!ReturnedMember) return None Oops, also forgot to check the base of the MemberExpr was CXXThisExpr. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77408/new/ https://reviews.llvm.org/D77408 From cfe-commits at lists.llvm.org Fri Apr 3 11:53:37 2020 From: cfe-commits at lists.llvm.org (Stephen Neuendorffer via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:53:37 +0000 (UTC) Subject: [PATCH] D77156: [CMAKE] Plumb include_directories() into tablegen() In-Reply-To: References: Message-ID: stephenneuendorffer edited the summary of this revision. stephenneuendorffer updated this revision to Diff 254867. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77156/new/ https://reviews.llvm.org/D77156 Files: clang/cmake/modules/AddClang.cmake llvm/cmake/modules/TableGen.cmake mlir/cmake/modules/AddMLIR.cmake mlir/examples/toy/Ch3/CMakeLists.txt mlir/examples/toy/Ch4/CMakeLists.txt mlir/examples/toy/Ch4/include/toy/CMakeLists.txt mlir/examples/toy/Ch5/CMakeLists.txt mlir/examples/toy/Ch5/include/toy/CMakeLists.txt mlir/examples/toy/Ch6/CMakeLists.txt mlir/examples/toy/Ch6/include/toy/CMakeLists.txt mlir/examples/toy/Ch7/CMakeLists.txt mlir/examples/toy/Ch7/include/toy/CMakeLists.txt -------------- next part -------------- A non-text attachment was scrubbed... Name: D77156.254867.patch Type: text/x-patch Size: 8999 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 11:53:39 2020 From: cfe-commits at lists.llvm.org (Leonard Chan via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:53:39 +0000 (UTC) Subject: [PATCH] D66490: [NewPM] Enable the New Pass Manager by Default in Clang In-Reply-To: References: Message-ID: <91f33e3e4ff95dec5915991901fbf6b7@localhost.localdomain> leonardchan added a comment. In D66490#1958747 , @aeubanks wrote: > In D66490#1638708 , @hfinkel wrote: > > > In D66490#1638162 , @rupprecht wrote: > > > > > We already know that we don't want this enabled for tsan builds due to https://bugs.llvm.org/show_bug.cgi?id=42877, but I don't even know if anyone else will hit it (it's only when building one particular library). > > > > > > Under the circumstances, that seems like one particular library too many. PR42877 looks like a generic bug, so if we're hitting it here, I see no reason to suspect that others would not hit it elsewhere. > > > https://bugs.llvm.org/show_bug.cgi?id=42877 is marked fixed, any update on this? LLVM 10.0.0 has branched. It seems that we can go ahead with this patch if there's no other objections. I reran a `ninja check-clang` with this patch and all tests seem to pass (at least when running on x64-linux). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D66490/new/ https://reviews.llvm.org/D66490 From cfe-commits at lists.llvm.org Fri Apr 3 11:53:39 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:53:39 +0000 (UTC) Subject: [PATCH] D77385: [clangd] Add index inspection helper tool In-Reply-To: References: Message-ID: sammccall added a comment. Yeah, I think adding a dump/export command to dexp would be nice. We'd have to make dexp keep the parsed input file around, or just the path and reopen it when the command is issued, but that seems OK to me. (One of the costs of adding a new binary is you have to at least build it to keep the code from rotting, and linking binaries is often the bottleneck for iterating with `check-clangd`) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77385/new/ https://reviews.llvm.org/D77385 From cfe-commits at lists.llvm.org Fri Apr 3 11:53:40 2020 From: cfe-commits at lists.llvm.org (Louis Dionne via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:53:40 +0000 (UTC) Subject: [PATCH] D73245: Avoid using std::max_align_t in pre-C++11 mode In-Reply-To: References: Message-ID: ldionne accepted this revision. ldionne added a comment. LGTM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73245/new/ https://reviews.llvm.org/D73245 From cfe-commits at lists.llvm.org Fri Apr 3 11:53:41 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:53:41 +0000 (UTC) Subject: [PATCH] D77199: [clang-tidy] Address false positive in modernize-use-default-member-init In-Reply-To: References: Message-ID: njames93 updated this revision to Diff 254870. njames93 added a comment. - Added test case Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77199/new/ https://reviews.llvm.org/D77199 Files: clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp Index: clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp +++ clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp @@ -432,3 +432,17 @@ // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: use default member initializer for 'k' [modernize-use-default-member-init] // CHECK-FIXES: int i{5}, k{8}; }; + +struct PR45363 { + // Ensure no warning is emitted here + PR45363(int i = 0) : m_i{i} {} + int m_i; +}; + +struct EmptyBracedIntDefault { + EmptyBracedIntDefault() : m_i{} {} + int m_i; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'm_i' [modernize-use-default-member-init] + // CHECK-FIXES: {{^ }}EmptyBracedIntDefault() {} + // CHECK-FIXES-NEXT: {{^ }}int m_i{}; +}; Index: clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp +++ clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp @@ -17,6 +17,12 @@ namespace tidy { namespace modernize { +namespace { +AST_MATCHER_P(InitListExpr, initCountIs, unsigned, N) { + return Node.getNumInits() == N; +} +} // namespace + static StringRef getValueOfValueInit(const QualType InitType) { switch (InitType->getScalarTypeKind()) { case Type::STK_CPointer: @@ -190,7 +196,7 @@ } void UseDefaultMemberInitCheck::registerMatchers(MatchFinder *Finder) { - auto Init = + auto InitBase = anyOf(stringLiteral(), characterLiteral(), integerLiteral(), unaryOperator(hasAnyOperatorName("+", "-"), hasUnaryOperand(integerLiteral())), @@ -198,7 +204,13 @@ unaryOperator(hasAnyOperatorName("+", "-"), hasUnaryOperand(floatLiteral())), cxxBoolLiteral(), cxxNullPtrLiteralExpr(), implicitValueInitExpr(), - initListExpr(), declRefExpr(to(enumConstantDecl()))); + declRefExpr(to(enumConstantDecl()))); + + auto Init = + anyOf(initListExpr(anyOf( + allOf(initCountIs(1), hasInit(0, ignoringImplicit(InitBase))), + initCountIs(0))), + InitBase); Finder->addMatcher( cxxConstructorDecl( -------------- next part -------------- A non-text attachment was scrubbed... Name: D77199.254870.patch Type: text/x-patch Size: 2446 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 11:53:41 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:53:41 +0000 (UTC) Subject: [PATCH] D77054: [AArch64][SVE] Add SVE intrinsics for saturating add & subtract In-Reply-To: References: Message-ID: <196696313333dac305cf1aad784acec6@localhost.localdomain> efriedma accepted this revision. efriedma added a comment. This revision is now accepted and ready to land. LGTM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77054/new/ https://reviews.llvm.org/D77054 From cfe-commits at lists.llvm.org Fri Apr 3 11:53:43 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:53:43 +0000 (UTC) Subject: [PATCH] D70366: Add new 'flatten' LLVM attribute to fix clang's 'flatten' function attribute In-Reply-To: References: Message-ID: jdoerfert added a comment. I'm fine with this. I would hope a C/C++/Clang person will also take a look though. ================ Comment at: llvm/docs/LangRef.rst:1398 + This attribute is similar to ``alwaysinline``, but also applies recursively to + all inlined function calls. ``builtin`` ---------------- Maybe mention the correspondence to the `flatten` C/C++ attribute here. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70366/new/ https://reviews.llvm.org/D70366 From cfe-commits at lists.llvm.org Fri Apr 3 11:55:21 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:55:21 +0000 (UTC) Subject: [PATCH] D77199: [clang-tidy] Address false positive in modernize-use-default-member-init In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rG2c7ea1c4c5f7: [clang-tidy] Address false positive in modernize-use-default-member-init (authored by njames93). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77199/new/ https://reviews.llvm.org/D77199 Files: clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp Index: clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp +++ clang-tools-extra/test/clang-tidy/checkers/modernize-use-default-member-init.cpp @@ -432,3 +432,17 @@ // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: use default member initializer for 'k' [modernize-use-default-member-init] // CHECK-FIXES: int i{5}, k{8}; }; + +struct PR45363 { + // Ensure no warning is emitted here + PR45363(int i = 0) : m_i{i} {} + int m_i; +}; + +struct EmptyBracedIntDefault { + EmptyBracedIntDefault() : m_i{} {} + int m_i; + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use default member initializer for 'm_i' [modernize-use-default-member-init] + // CHECK-FIXES: {{^ }}EmptyBracedIntDefault() {} + // CHECK-FIXES-NEXT: {{^ }}int m_i{}; +}; Index: clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp +++ clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp @@ -17,6 +17,12 @@ namespace tidy { namespace modernize { +namespace { +AST_MATCHER_P(InitListExpr, initCountIs, unsigned, N) { + return Node.getNumInits() == N; +} +} // namespace + static StringRef getValueOfValueInit(const QualType InitType) { switch (InitType->getScalarTypeKind()) { case Type::STK_CPointer: @@ -190,7 +196,7 @@ } void UseDefaultMemberInitCheck::registerMatchers(MatchFinder *Finder) { - auto Init = + auto InitBase = anyOf(stringLiteral(), characterLiteral(), integerLiteral(), unaryOperator(hasAnyOperatorName("+", "-"), hasUnaryOperand(integerLiteral())), @@ -198,7 +204,13 @@ unaryOperator(hasAnyOperatorName("+", "-"), hasUnaryOperand(floatLiteral())), cxxBoolLiteral(), cxxNullPtrLiteralExpr(), implicitValueInitExpr(), - initListExpr(), declRefExpr(to(enumConstantDecl()))); + declRefExpr(to(enumConstantDecl()))); + + auto Init = + anyOf(initListExpr(anyOf( + allOf(initCountIs(1), hasInit(0, ignoringImplicit(InitBase))), + initCountIs(0))), + InitBase); Finder->addMatcher( cxxConstructorDecl( -------------- next part -------------- A non-text attachment was scrubbed... Name: D77199.254876.patch Type: text/x-patch Size: 2446 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 11:53:41 2020 From: cfe-commits at lists.llvm.org (Leonard Chan via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:53:41 +0000 (UTC) Subject: [PATCH] D77249: [MSan] Pass command line options to MSan with new pass manager In-Reply-To: References: Message-ID: leonardchan added inline comments. ================ Comment at: compiler-rt/test/msan/chained_origin_empty_stack_npm.cpp:4 +// this test. +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 \ +// RUN: -fexperimental-new-pass-manager -O3 %s -o %t && \ ---------------- nemanjai wrote: > nemanjai wrote: > > vitalybuka wrote: > > > Why not to add RUN: section with -fexperimental-new-pass-manager into original tests? > > I just felt that this is a simpler way forward for a couple of reasons: > > 1. Once the default switches, it is a very obvious change to just delete these files rather than digging through the code inside the existing ones > > 2. Many of the tests actually contain the testing that is split up into multiple steps so I would have to duplicate all the steps for the NPM vs. default builds: > > - compile/link > > - run with one option set and FileCheck > > - run with another option set and FileCheck > > - rinse/repeat > > (example: chained_origin_limits.cpp) > > > > But of course, if there are strong objections to this approach, I can certainly go the other way. > Seems Phabricator reformatted what I wrote here. Points 3, 4, 5, 6 were supposed to be sub-bullets for 2. > Basically, I tried to describe that in the mentioned test case, I would have to replicate a number of subsequent steps for each `RUN` directive that invokes the compiler. If we're going this way, I think the original tests should explicitly have `-fno-experimental-new-pass-manager`. Also no strong preference towards either way. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77249/new/ https://reviews.llvm.org/D77249 From cfe-commits at lists.llvm.org Fri Apr 3 11:57:55 2020 From: cfe-commits at lists.llvm.org (Roman Lebedev via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 18:57:55 +0000 (UTC) Subject: [PATCH] D70366: Add new 'flatten' LLVM attribute to fix clang's 'flatten' function attribute In-Reply-To: References: Message-ID: lebedev.ri added a comment. In D70366#1960300 , @jdoerfert wrote: > I'm fine with this. I would hope a C/C++/Clang person will also take a look though. This is missing clang codegen test[s]. Seems to look fine to me otherwise. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70366/new/ https://reviews.llvm.org/D70366 From cfe-commits at lists.llvm.org Fri Apr 3 12:00:00 2020 From: cfe-commits at lists.llvm.org (Kevin P. Neal via cfe-commits) Date: Fri, 03 Apr 2020 12:00:00 -0700 (PDT) Subject: [clang] ba87430 - [PowerPC] Replace subtract-from-zero float in version with fneg in PowerPC special fma compiler builtins Message-ID: <5e8787b0.1c69fb81.ea56d.f77e@mx.google.com> Author: Andrew Wock Date: 2020-04-03T14:59:33-04:00 New Revision: ba87430cadb2d5d0ee8e4b75101d7abcf6b321bf URL: https://github.com/llvm/llvm-project/commit/ba87430cadb2d5d0ee8e4b75101d7abcf6b321bf DIFF: https://github.com/llvm/llvm-project/commit/ba87430cadb2d5d0ee8e4b75101d7abcf6b321bf.diff LOG: [PowerPC] Replace subtract-from-zero float in version with fneg in PowerPC special fma compiler builtins This patch adds a test for the PowerPC fma compiler builtins, some variations of which negate inputs and outputs. The code to generate IR for these builtins was untested before this patch. Originally, the code used the outdated method of subtracting floating point values from -0.0 as floating point negation. This patch remedies that. Patch by: Drew Wock Differential Revision: https://reviews.llvm.org/D76949 Added: clang/test/CodeGen/builtins-ppc-fma.c Modified: clang/lib/CodeGen/CGBuiltin.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 880fe0e271f5..3545ccda5d4d 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -13214,25 +13214,24 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *Z = EmitScalarExpr(E->getArg(2)); - Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); switch (BuiltinID) { case PPC::BI__builtin_vsx_xvmaddadp: case PPC::BI__builtin_vsx_xvmaddasp: return Builder.CreateCall(F, {X, Y, Z}); + case PPC::BI__builtin_vsx_xvnmaddadp: case PPC::BI__builtin_vsx_xvnmaddasp: - return Builder.CreateFSub(Zero, - Builder.CreateCall(F, {X, Y, Z}), "sub"); + return Builder.CreateFNeg(Builder.CreateCall(F, {X, Y, Z}), "neg"); + case PPC::BI__builtin_vsx_xvmsubadp: case PPC::BI__builtin_vsx_xvmsubasp: - return Builder.CreateCall(F, - {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); + return Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}); + case PPC::BI__builtin_vsx_xvnmsubadp: case PPC::BI__builtin_vsx_xvnmsubasp: - Value *FsubRes = - Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); - return Builder.CreateFSub(Zero, FsubRes, "sub"); + return Builder.CreateFNeg( + Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}), "neg"); } llvm_unreachable("Unknown FMA operation"); return nullptr; // Suppress no-return warning diff --git a/clang/test/CodeGen/builtins-ppc-fma.c b/clang/test/CodeGen/builtins-ppc-fma.c new file mode 100644 index 000000000000..3a628f7613b5 --- /dev/null +++ b/clang/test/CodeGen/builtins-ppc-fma.c @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -triple powerpc64le-gnu-linux \ +// RUN: -target-feature +altivec -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck \ +// RUN: %s + +typedef __attribute__((vector_size(4 * sizeof(float)))) float vec_float; +typedef __attribute__((vector_size(2 * sizeof(double)))) double vec_double; + +volatile vec_double vd; +volatile vec_float vf; + +void test_fma(void) { + vf = __builtin_vsx_xvmaddasp(vf, vf, vf); + // CHECK: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) + + vd = __builtin_vsx_xvmaddadp(vd, vd, vd); + // CHECK: @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + + vf = __builtin_vsx_xvnmaddasp(vf, vf, vf); + // CHECK: [[RESULT:%[^ ]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK: fneg <4 x float> [[RESULT]] + + vd = __builtin_vsx_xvnmaddadp(vd, vd, vd); + // CHECK: [[RESULT:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK: fneg <2 x double> [[RESULT]] + + vf = __builtin_vsx_xvmsubasp(vf, vf, vf); + // CHECK: [[RESULT:%[^ ]+]] fneg <4 x float> %{{.*}} + // CHECK: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]]) + + vd = __builtin_vsx_xvmsubadp(vd, vd, vd); + // CHECK: fneg <2 x double> [[RESULT]] + // CHECK: [[RESULT:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + + vf = __builtin_vsx_xvnmsubasp(vf, vf, vf); + // CHECK: [[RESULT:%[^ ]+]] = fneg <4 x float> %{{.*}} + // CHECK: [[RESULT2:%[^ ]+]] = call <4 x float> @llvm.fma.v2f64(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]]) + // CHECK: fneg <4 x float> [[RESULT2]] + + vd = __builtin_vsx_xvnmsubadp(vd, vd, vd); + // CHECK: [[RESULT:%[^ ]+]] = fneg <2 x double> %{{.*}} + // CHECK: [[RESULT2:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT]]) + // CHECK: fneg <2 x double> [[RESULT2]] +} From cfe-commits at lists.llvm.org Fri Apr 3 12:24:16 2020 From: cfe-commits at lists.llvm.org (Kevin P. Neal via cfe-commits) Date: Fri, 03 Apr 2020 12:24:16 -0700 (PDT) Subject: [clang] d7a0516 - Fix typo in test. Message-ID: <5e878d60.1c69fb81.4341c.fd87@mx.google.com> Author: Kevin P. Neal Date: 2020-04-03T15:23:49-04:00 New Revision: d7a0516ddcfe373bb780d6fc19d76fe74ecc0061 URL: https://github.com/llvm/llvm-project/commit/d7a0516ddcfe373bb780d6fc19d76fe74ecc0061 DIFF: https://github.com/llvm/llvm-project/commit/d7a0516ddcfe373bb780d6fc19d76fe74ecc0061.diff LOG: Fix typo in test. Differential Revision: https://reviews.llvm.org/D76949 Added: Modified: clang/test/CodeGen/builtins-ppc-fma.c Removed: ################################################################################ diff --git a/clang/test/CodeGen/builtins-ppc-fma.c b/clang/test/CodeGen/builtins-ppc-fma.c index 3a628f7613b5..e91b45b0daa7 100644 --- a/clang/test/CodeGen/builtins-ppc-fma.c +++ b/clang/test/CodeGen/builtins-ppc-fma.c @@ -24,7 +24,7 @@ void test_fma(void) { // CHECK: fneg <2 x double> [[RESULT]] vf = __builtin_vsx_xvmsubasp(vf, vf, vf); - // CHECK: [[RESULT:%[^ ]+]] fneg <4 x float> %{{.*}} + // CHECK: [[RESULT:%[^ ]+]] = fneg <4 x float> %{{.*}} // CHECK: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]]) vd = __builtin_vsx_xvmsubadp(vd, vd, vd); From cfe-commits at lists.llvm.org Fri Apr 3 12:26:05 2020 From: cfe-commits at lists.llvm.org (Erich Keane via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 19:26:05 +0000 (UTC) Subject: [PATCH] D70366: Add new 'flatten' LLVM attribute to fix clang's 'flatten' function attribute In-Reply-To: References: Message-ID: <1a812a349d5d5d312e263bdc13151c51@localhost.localdomain> erichkeane added a comment. The semantics of this llvm attribute seem to better match 'flatten'. However, it is unfortunate that this doesn't change any clang tests. Can you add/alter a test in clang to validate the IR? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70366/new/ https://reviews.llvm.org/D70366 From cfe-commits at lists.llvm.org Fri Apr 3 12:26:31 2020 From: cfe-commits at lists.llvm.org (Christopher Tetreault via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 19:26:31 +0000 (UTC) Subject: [PATCH] D75661: Remove SequentialType from the type heirarchy. In-Reply-To: References: Message-ID: <379726b87c45fdbe370505ee49c1172e@localhost.localdomain> ctetreau added a comment. Herald added a subscriber: grosul1. What's the status on this? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75661/new/ https://reviews.llvm.org/D75661 From cfe-commits at lists.llvm.org Fri Apr 3 12:26:55 2020 From: cfe-commits at lists.llvm.org (Kevin P. Neal via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 19:26:55 +0000 (UTC) Subject: [PATCH] D76949: Replace subtract-from-zero float in version with fneg in PowerPC special fma compiler builtins In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rGba87430cadb2: [PowerPC] Replace subtract-from-zero float in version with fneg in PowerPC… (authored by ajwock, committed by kpn). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76949/new/ https://reviews.llvm.org/D76949 Files: clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/builtins-ppc-fma.c Index: clang/test/CodeGen/builtins-ppc-fma.c =================================================================== --- /dev/null +++ clang/test/CodeGen/builtins-ppc-fma.c @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -triple powerpc64le-gnu-linux \ +// RUN: -target-feature +altivec -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck \ +// RUN: %s + +typedef __attribute__((vector_size(4 * sizeof(float)))) float vec_float; +typedef __attribute__((vector_size(2 * sizeof(double)))) double vec_double; + +volatile vec_double vd; +volatile vec_float vf; + +void test_fma(void) { + vf = __builtin_vsx_xvmaddasp(vf, vf, vf); + // CHECK: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) + + vd = __builtin_vsx_xvmaddadp(vd, vd, vd); + // CHECK: @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + + vf = __builtin_vsx_xvnmaddasp(vf, vf, vf); + // CHECK: [[RESULT:%[^ ]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) + // CHECK: fneg <4 x float> [[RESULT]] + + vd = __builtin_vsx_xvnmaddadp(vd, vd, vd); + // CHECK: [[RESULT:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + // CHECK: fneg <2 x double> [[RESULT]] + + vf = __builtin_vsx_xvmsubasp(vf, vf, vf); + // CHECK: [[RESULT:%[^ ]+]] fneg <4 x float> %{{.*}} + // CHECK: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]]) + + vd = __builtin_vsx_xvmsubadp(vd, vd, vd); + // CHECK: fneg <2 x double> [[RESULT]] + // CHECK: [[RESULT:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) + + vf = __builtin_vsx_xvnmsubasp(vf, vf, vf); + // CHECK: [[RESULT:%[^ ]+]] = fneg <4 x float> %{{.*}} + // CHECK: [[RESULT2:%[^ ]+]] = call <4 x float> @llvm.fma.v2f64(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]]) + // CHECK: fneg <4 x float> [[RESULT2]] + + vd = __builtin_vsx_xvnmsubadp(vd, vd, vd); + // CHECK: [[RESULT:%[^ ]+]] = fneg <2 x double> %{{.*}} + // CHECK: [[RESULT2:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT]]) + // CHECK: fneg <2 x double> [[RESULT2]] +} Index: clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- clang/lib/CodeGen/CGBuiltin.cpp +++ clang/lib/CodeGen/CGBuiltin.cpp @@ -13214,25 +13214,24 @@ Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *Z = EmitScalarExpr(E->getArg(2)); - Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); switch (BuiltinID) { case PPC::BI__builtin_vsx_xvmaddadp: case PPC::BI__builtin_vsx_xvmaddasp: return Builder.CreateCall(F, {X, Y, Z}); + case PPC::BI__builtin_vsx_xvnmaddadp: case PPC::BI__builtin_vsx_xvnmaddasp: - return Builder.CreateFSub(Zero, - Builder.CreateCall(F, {X, Y, Z}), "sub"); + return Builder.CreateFNeg(Builder.CreateCall(F, {X, Y, Z}), "neg"); + case PPC::BI__builtin_vsx_xvmsubadp: case PPC::BI__builtin_vsx_xvmsubasp: - return Builder.CreateCall(F, - {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); + return Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}); + case PPC::BI__builtin_vsx_xvnmsubadp: case PPC::BI__builtin_vsx_xvnmsubasp: - Value *FsubRes = - Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); - return Builder.CreateFSub(Zero, FsubRes, "sub"); + return Builder.CreateFNeg( + Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}), "neg"); } llvm_unreachable("Unknown FMA operation"); return nullptr; // Suppress no-return warning -------------- next part -------------- A non-text attachment was scrubbed... Name: D76949.254886.patch Type: text/x-patch Size: 3990 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 12:27:16 2020 From: cfe-commits at lists.llvm.org (Nico Weber via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 19:27:16 +0000 (UTC) Subject: [PATCH] D77184: Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang In-Reply-To: References: Message-ID: thakis added a comment. grimar, andrewng: You both have checkout and build on different drives too, yes? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77184/new/ https://reviews.llvm.org/D77184 From cfe-commits at lists.llvm.org Fri Apr 3 12:47:31 2020 From: cfe-commits at lists.llvm.org (Kevin P. Neal via cfe-commits) Date: Fri, 03 Apr 2020 12:47:31 -0700 (PDT) Subject: [clang] 9f1c35d - Revert "[PowerPC] Replace subtract-from-zero float in version with fneg in PowerPC special fma compiler builtins" Message-ID: <5e8792d3.1c69fb81.c17d2.e951@mx.google.com> Author: Kevin P. Neal Date: 2020-04-03T15:47:19-04:00 New Revision: 9f1c35d8b14f026b7bc4b21b9eecafbbb42c42a2 URL: https://github.com/llvm/llvm-project/commit/9f1c35d8b14f026b7bc4b21b9eecafbbb42c42a2 DIFF: https://github.com/llvm/llvm-project/commit/9f1c35d8b14f026b7bc4b21b9eecafbbb42c42a2.diff LOG: Revert "[PowerPC] Replace subtract-from-zero float in version with fneg in PowerPC special fma compiler builtins" The new test case causes bot failures. This reverts commit ba87430cadb2d5d0ee8e4b75101d7abcf6b321bf. Added: Modified: clang/lib/CodeGen/CGBuiltin.cpp Removed: clang/test/CodeGen/builtins-ppc-fma.c ################################################################################ diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 3545ccda5d4d..880fe0e271f5 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -13214,24 +13214,25 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *Z = EmitScalarExpr(E->getArg(2)); + Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); switch (BuiltinID) { case PPC::BI__builtin_vsx_xvmaddadp: case PPC::BI__builtin_vsx_xvmaddasp: return Builder.CreateCall(F, {X, Y, Z}); - case PPC::BI__builtin_vsx_xvnmaddadp: case PPC::BI__builtin_vsx_xvnmaddasp: - return Builder.CreateFNeg(Builder.CreateCall(F, {X, Y, Z}), "neg"); - + return Builder.CreateFSub(Zero, + Builder.CreateCall(F, {X, Y, Z}), "sub"); case PPC::BI__builtin_vsx_xvmsubadp: case PPC::BI__builtin_vsx_xvmsubasp: - return Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}); - + return Builder.CreateCall(F, + {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); case PPC::BI__builtin_vsx_xvnmsubadp: case PPC::BI__builtin_vsx_xvnmsubasp: - return Builder.CreateFNeg( - Builder.CreateCall(F, {X, Y, Builder.CreateFNeg(Z, "neg")}), "neg"); + Value *FsubRes = + Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); + return Builder.CreateFSub(Zero, FsubRes, "sub"); } llvm_unreachable("Unknown FMA operation"); return nullptr; // Suppress no-return warning diff --git a/clang/test/CodeGen/builtins-ppc-fma.c b/clang/test/CodeGen/builtins-ppc-fma.c deleted file mode 100644 index e91b45b0daa7..000000000000 --- a/clang/test/CodeGen/builtins-ppc-fma.c +++ /dev/null @@ -1,43 +0,0 @@ -// RUN: %clang_cc1 -triple powerpc64le-gnu-linux \ -// RUN: -target-feature +altivec -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck \ -// RUN: %s - -typedef __attribute__((vector_size(4 * sizeof(float)))) float vec_float; -typedef __attribute__((vector_size(2 * sizeof(double)))) double vec_double; - -volatile vec_double vd; -volatile vec_float vf; - -void test_fma(void) { - vf = __builtin_vsx_xvmaddasp(vf, vf, vf); - // CHECK: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) - - vd = __builtin_vsx_xvmaddadp(vd, vd, vd); - // CHECK: @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) - - vf = __builtin_vsx_xvnmaddasp(vf, vf, vf); - // CHECK: [[RESULT:%[^ ]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}}) - // CHECK: fneg <4 x float> [[RESULT]] - - vd = __builtin_vsx_xvnmaddadp(vd, vd, vd); - // CHECK: [[RESULT:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) - // CHECK: fneg <2 x double> [[RESULT]] - - vf = __builtin_vsx_xvmsubasp(vf, vf, vf); - // CHECK: [[RESULT:%[^ ]+]] = fneg <4 x float> %{{.*}} - // CHECK: @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]]) - - vd = __builtin_vsx_xvmsubadp(vd, vd, vd); - // CHECK: fneg <2 x double> [[RESULT]] - // CHECK: [[RESULT:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}}) - - vf = __builtin_vsx_xvnmsubasp(vf, vf, vf); - // CHECK: [[RESULT:%[^ ]+]] = fneg <4 x float> %{{.*}} - // CHECK: [[RESULT2:%[^ ]+]] = call <4 x float> @llvm.fma.v2f64(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[RESULT]]) - // CHECK: fneg <4 x float> [[RESULT2]] - - vd = __builtin_vsx_xvnmsubadp(vd, vd, vd); - // CHECK: [[RESULT:%[^ ]+]] = fneg <2 x double> %{{.*}} - // CHECK: [[RESULT2:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[RESULT]]) - // CHECK: fneg <2 x double> [[RESULT2]] -} From cfe-commits at lists.llvm.org Fri Apr 3 12:57:53 2020 From: cfe-commits at lists.llvm.org (Arthur O'Dwyer via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 19:57:53 +0000 (UTC) Subject: [PATCH] D76572: Replace `T(x)` with `reinterpret_cast(x)` everywhere it means reinterpret_cast. No functional change In-Reply-To: References: Message-ID: Quuxplusone marked an inline comment as done. Quuxplusone added a comment. @DiggerLin @ahatanak @espindola @reames Gentle ping! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76572/new/ https://reviews.llvm.org/D76572 From cfe-commits at lists.llvm.org Fri Apr 3 12:57:54 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 19:57:54 +0000 (UTC) Subject: [PATCH] D76184: [OpenMP][NFC] Remove the need to include `OpenMPClause.h` In-Reply-To: References: Message-ID: <9675b3588b331da26467c7dccd665e0e@localhost.localdomain> rnk commandeered this revision. rnk edited reviewers, added: jdoerfert; removed: rnk. rnk added a comment. This revision now requires review to proceed. I got it building... Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76184/new/ https://reviews.llvm.org/D76184 From cfe-commits at lists.llvm.org Fri Apr 3 12:57:55 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 19:57:55 +0000 (UTC) Subject: [PATCH] D76184: [OpenMP][NFC] Remove the need to include `OpenMPClause.h` In-Reply-To: References: Message-ID: <79add3a5447849eaa26b6dae0e94d6cd@localhost.localdomain> rnk updated this revision to Diff 254889. rnk added a comment. Herald added subscribers: usaxena95, kadircet, arphaman, jkorous. - seems to build all.. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76184/new/ https://reviews.llvm.org/D76184 Files: clang-tools-extra/clangd/XRefs.cpp clang/include/clang/AST/Attr.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/Basic/OpenMPKinds.h clang/include/clang/Parse/Parser.h clang/include/clang/Sema/Sema.h clang/lib/AST/AttrImpl.cpp clang/lib/AST/OpenMPClause.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76184.254889.patch Type: text/x-patch Size: 20517 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 12:57:56 2020 From: cfe-commits at lists.llvm.org (Nico Weber via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 19:57:56 +0000 (UTC) Subject: [PATCH] D77184: Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang In-Reply-To: References: Message-ID: <838a32025eff56c3c59092cbccc3e26a@localhost.localdomain> thakis added a comment. I pushed Andrew's fix (thanks!) (with minor formatting tweaks) in dbb0d8ecb3a024bd6817ebd8ad8c5c199a51d933 . Let me know if you still see issues. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77184/new/ https://reviews.llvm.org/D77184 From cfe-commits at lists.llvm.org Fri Apr 3 12:57:57 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 19:57:57 +0000 (UTC) Subject: [PATCH] D77085: [clang-tidy] Added support for validating configuration options In-Reply-To: References: Message-ID: njames93 updated this revision to Diff 254890. njames93 added a comment. - Address nits Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77085/new/ https://reviews.llvm.org/D77085 Files: clang-tools-extra/clang-tidy/ClangTidyCheck.cpp clang-tools-extra/clang-tidy/ClangTidyCheck.h clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77085.254890.patch Type: text/x-patch Size: 26611 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 12:57:58 2020 From: cfe-commits at lists.llvm.org (Scott Constable via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 19:57:58 +0000 (UTC) Subject: [PATCH] D77427: [X86] Add tests to clang Driver to ensure that SLH/Retpoline features are not enabled with LVI-CFI Message-ID: sconstab created this revision. sconstab added a reviewer: craig.topper. https://reviews.llvm.org/D77427 Files: clang/test/Driver/x86-target-features.c Index: clang/test/Driver/x86-target-features.c =================================================================== --- clang/test/Driver/x86-target-features.c +++ clang/test/Driver/x86-target-features.c @@ -159,6 +159,13 @@ // LVICFI: "-target-feature" "+lvi-cfi" // NO-LVICFI-NOT: lvi-cfi +// RUN: %clang -target i386-linux-gnu -mlvi-cfi -mspeculative-load-hardening %s -### -o %t.o 2>&1 | FileCheck -check-prefix=LVICFI-SLH %s +// LVICFI-SLH: error: invalid argument 'mspeculative-load-hardening' not allowed with 'mlvi-cfi' +// RUN: %clang -target i386-linux-gnu -mlvi-cfi -mretpoline %s -### -o %t.o 2>&1 | FileCheck -check-prefix=LVICFI-RETPOLINE %s +// LVICFI-RETPOLINE: error: invalid argument 'mretpoline' not allowed with 'mlvi-cfi' +// RUN: %clang -target i386-linux-gnu -mlvi-cfi -mretpoline-external-thunk %s -### -o %t.o 2>&1 | FileCheck -check-prefix=LVICFI-RETPOLINE-EXTERNAL-THUNK %s +// LVICFI-RETPOLINE-EXTERNAL-THUNK: error: invalid argument 'mretpoline-external-thunk' not allowed with 'mlvi-cfi' + // RUN: %clang -target i386-linux-gnu -mwaitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=WAITPKG %s // RUN: %clang -target i386-linux-gnu -mno-waitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-WAITPKG %s // WAITPKG: "-target-feature" "+waitpkg" -------------- next part -------------- A non-text attachment was scrubbed... Name: D77427.254891.patch Type: text/x-patch Size: 1285 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 12:58:01 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 19:58:01 +0000 (UTC) Subject: [PATCH] D77390: Fix __builtin_amdgcn_workgroup_size_x/y/z return type In-Reply-To: References: Message-ID: <76a704a6707389bbc9559e27718d4777@localhost.localdomain> yaxunl closed this revision. yaxunl added a comment. b72fce1ffd0a0de5b46b486c7030d54cc5d8c225 CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77390/new/ https://reviews.llvm.org/D77390 From cfe-commits at lists.llvm.org Fri Apr 3 12:58:03 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Fri, 03 Apr 2020 19:58:03 +0000 (UTC) Subject: [PATCH] D77150: [Analyzer] New Option for ContainerModeling: AggressiveEraseModeling In-Reply-To: References: Message-ID: <48135a760f341daef764cbec4e7f8358@localhost.localdomain> Szelethus added inline comments. ================ Comment at: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td:647-653 CmdLineOption ]>, ---------------- Ah, okay, I see which one you refer to. We should totally make this non-user facing as well. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77150/new/ https://reviews.llvm.org/D77150 From cfe-commits at lists.llvm.org Fri Apr 3 12:58:07 2020 From: cfe-commits at lists.llvm.org (Leonard Chan via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 19:58:07 +0000 (UTC) Subject: [PATCH] D66490: [NewPM] Enable the New Pass Manager by Default in Clang In-Reply-To: References: Message-ID: <4aaf84772f5cffc189b0dbb9ac051589@localhost.localdomain> leonardchan added a comment. > It seems that we can go ahead with this patch if there's no other objections. I reran a `ninja check-clang` with this patch and all tests seem to pass (at least when running on x64-linux). Actually disregard this. It seems that there are some compiler-rt tests that don't pass with the NPM yet (see D77249 ). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D66490/new/ https://reviews.llvm.org/D66490 From cfe-commits at lists.llvm.org Fri Apr 3 12:58:08 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 19:58:08 +0000 (UTC) Subject: [PATCH] D77028: [NFC] Refactor DeferredDiagsEmitter and skip redundant visit In-Reply-To: References: Message-ID: <8448399ac0ad65fe688faebf595e3bc3@localhost.localdomain> yaxunl marked 2 inline comments as done. yaxunl added inline comments. ================ Comment at: clang/lib/Sema/Sema.cpp:1508 void checkFunc(SourceLocation Loc, FunctionDecl *FD) { + auto DiagsCountIt = DiagsCount.find(FD); FunctionDecl *Caller = UseStack.empty() ? nullptr : UseStack.back(); ---------------- rjmccall wrote: > yaxunl wrote: > > rjmccall wrote: > > > yaxunl wrote: > > > > rjmccall wrote: > > > > > It makes me a little uncomfortable to be holding an iterator this long while calling a fair amount of other stuff in the meantime. > > > > > > > > > > Your use of DiagsCount is subtle enough that it really needs to be explained in some comments. You're doing stuff conditionally based on both whether the entry exists but also whether it's non-zero. > > > > added comments > > > Okay, thanks for that. Two points, then. First, it looks like the count is really just a boolean for whether the function recursively triggers any diagnostics. And second, can't it just be as simple as whether we've visited that function at all in a context that's forcing diagnostics to be emitted? The logic seems to be to try to emit the diagnostics for each use-path, but why would we want that? > > For the second comment, we need to visit a function again for each use-path because we need to report each use-path that triggers a diagnostic, otherwise users will see a new error after they fix one error, instead of seeing all the errors at once. > > > > For the first comment, I will change the count to two flags: one for the case where the function is not in device context, the other is for the case where the function is in device context. This will allow us to avoid redundant visits whether or not we are in a device context. > > For the second comment, we need to visit a function again for each use-path because we need to report each use-path that triggers a diagnostic, otherwise users will see a new error after they fix one error, instead of seeing all the errors at once. > > This is not what we do in analogous cases where errors are triggered by a use, like in template instantiation. The bug might be that the device program is using a function that it shouldn't be using, or the bug might be that a function that's supposed to be usable from the device is written incorrectly. In the former case, yes, not reporting the errors for each use-path may force the programmer to build multiple times to find all the problematic uses. However, in the latter case you can easily end up emitting a massive number of errors that completely drowns out everything else. It's also non-linear: the number of different use-paths of a particular function can be combinatoric. The deferred diagnostics fall into the first case mostly. Not all diagnostic messages happen in device host functions are deferred. Most of diagnostic messages are emitted immediately, disregarding whether the function is emitted or not. Only a few special types of diagnostic messages e.g. inline assembly errors, exceptions, varags are deferred. This is because clang has to use pragmas to make all functions device and host in some system headers to be able to use them in device compilation, whereas some of these functions will cause error only if they are emitted in device compilation. Since we cannot change these headers, we have to defer such diagnostics to the point where they are actually triggered. Therefore we are mostly interested in "who is calling these functions" instead of the diagnostics themselves. For normal programs containing no diagnostics, the current approach should sufficiently avoid all redundant visits and all functions will be visited once. The functions may be visited multiple times when there are deferred diagnostics, however this should be limited by the maximum number of errors. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77028/new/ https://reviews.llvm.org/D77028 From cfe-commits at lists.llvm.org Fri Apr 3 13:02:31 2020 From: cfe-commits at lists.llvm.org (Craig Topper via cfe-commits) Date: Fri, 03 Apr 2020 13:02:31 -0700 (PDT) Subject: [clang] c74dd64 - [X86] Add a Pass that builds a Condensed CFG for Load Value Injection (LVI) Gadgets Message-ID: <5e879657.1c69fb81.6cb52.aafb@mx.google.com> Author: Scott Constable Date: 2020-04-03T13:02:04-07:00 New Revision: c74dd640fd740c6928f66a39c7c15a014af3f66f URL: https://github.com/llvm/llvm-project/commit/c74dd640fd740c6928f66a39c7c15a014af3f66f DIFF: https://github.com/llvm/llvm-project/commit/c74dd640fd740c6928f66a39c7c15a014af3f66f.diff LOG: [X86] Add a Pass that builds a Condensed CFG for Load Value Injection (LVI) Gadgets Adds a new data structure, ImmutableGraph, and uses RDF to find LVI gadgets and add them to a MachineGadgetGraph. More specifically, a new X86 machine pass finds Load Value Injection (LVI) gadgets consisting of a load from memory (i.e., SOURCE), and any operation that may transmit the value loaded from memory over a covert channel, or use the value loaded from memory to determine a branch/call target (i.e., SINK). Also adds a new target feature to X86: +lvi-load-hardening The feature can be added via the clang CLI using -mlvi-hardening. Differential Revision: https://reviews.llvm.org/D75936 Added: llvm/lib/Target/X86/ImmutableGraph.h llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll Modified: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Arch/X86.cpp clang/test/Driver/x86-target-features.c llvm/lib/Target/X86/CMakeLists.txt llvm/lib/Target/X86/X86.h llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86Subtarget.h llvm/lib/Target/X86/X86TargetMachine.cpp llvm/test/CodeGen/X86/O0-pipeline.ll llvm/test/CodeGen/X86/O3-pipeline.ll Removed: ################################################################################ diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 0d057ac579f5..869d2755f47e 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2309,6 +2309,10 @@ def mspeculative_load_hardening : Flag<["-"], "mspeculative-load-hardening">, Group, Flags<[CoreOption,CC1Option]>; def mno_speculative_load_hardening : Flag<["-"], "mno-speculative-load-hardening">, Group, Flags<[CoreOption]>; +def mlvi_hardening : Flag<["-"], "mlvi-hardening">, Group, Flags<[CoreOption,DriverOption]>, + HelpText<"Enable all mitigations for Load Value Injection (LVI)">; +def mno_lvi_hardening : Flag<["-"], "mno-lvi-hardening">, Group, Flags<[CoreOption,DriverOption]>, + HelpText<"Disable mitigations for Load Value Injection (LVI)">; def mlvi_cfi : Flag<["-"], "mlvi-cfi">, Group, Flags<[CoreOption,DriverOption]>, HelpText<"Enable only control-flow mitigations for Load Value Injection (LVI)">; def mno_lvi_cfi : Flag<["-"], "mno-lvi-cfi">, Group, Flags<[CoreOption,DriverOption]>, diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp index aafba6915d0b..dbbc025de38c 100644 --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -173,7 +173,13 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, } auto LVIOpt = clang::driver::options::ID::OPT_INVALID; - if (Args.hasFlag(options::OPT_mlvi_cfi, options::OPT_mno_lvi_cfi, false)) { + if (Args.hasFlag(options::OPT_mlvi_hardening, options::OPT_mno_lvi_hardening, + false)) { + Features.push_back("+lvi-load-hardening"); + Features.push_back("+lvi-cfi"); // load hardening implies CFI protection + LVIOpt = options::OPT_mlvi_hardening; + } else if (Args.hasFlag(options::OPT_mlvi_cfi, options::OPT_mno_lvi_cfi, + false)) { Features.push_back("+lvi-cfi"); LVIOpt = options::OPT_mlvi_cfi; } diff --git a/clang/test/Driver/x86-target-features.c b/clang/test/Driver/x86-target-features.c index 872a228c2a33..44a3d2e1164b 100644 --- a/clang/test/Driver/x86-target-features.c +++ b/clang/test/Driver/x86-target-features.c @@ -159,6 +159,11 @@ // LVICFI: "-target-feature" "+lvi-cfi" // NO-LVICFI-NOT: lvi-cfi +// RUN: %clang -target i386-linux-gnu -mlvi-hardening %s -### -o %t.o 2>&1 | FileCheck -check-prefix=LVIHARDENING %s +// RUN: %clang -target i386-linux-gnu -mno-lvi-hardening %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-LVIHARDENING %s +// LVIHARDENING: "-target-feature" "+lvi-load-hardening" "-target-feature" "+lvi-cfi" +// NO-LVIHARDENING-NOT: lvi + // RUN: %clang -target i386-linux-gnu -mwaitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=WAITPKG %s // RUN: %clang -target i386-linux-gnu -mno-waitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-WAITPKG %s // WAITPKG: "-target-feature" "+waitpkg" diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt index 5df9978bf11d..e94a82aebca4 100644 --- a/llvm/lib/Target/X86/CMakeLists.txt +++ b/llvm/lib/Target/X86/CMakeLists.txt @@ -52,6 +52,7 @@ set(sources X86InstrInfo.cpp X86EvexToVex.cpp X86LegalizerInfo.cpp + X86LoadValueInjectionLoadHardening.cpp X86LoadValueInjectionRetHardening.cpp X86MCInstLower.cpp X86MachineFunctionInfo.cpp diff --git a/llvm/lib/Target/X86/ImmutableGraph.h b/llvm/lib/Target/X86/ImmutableGraph.h new file mode 100644 index 000000000000..80c9cf489ded --- /dev/null +++ b/llvm/lib/Target/X86/ImmutableGraph.h @@ -0,0 +1,432 @@ +//==========-- ImmutableGraph.h - A fast DAG implementation ---------=========// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// Description: ImmutableGraph is a fast DAG implementation that cannot be +/// modified, except by creating a new ImmutableGraph. ImmutableGraph is +/// implemented as two arrays: one containing nodes, and one containing edges. +/// The advantages to this implementation are two-fold: +/// 1. Iteration and traversal operations should experience terrific caching +/// performance. +/// 2. Set representations and operations on nodes and edges become +/// extraordinarily efficient. For instance, a set of edges is implemented as +/// a bit vector, wherein each bit corresponds to one edge in the edge +/// array. This implies a lower bound of 64x spacial improvement over, e.g., +/// an llvm::DenseSet or llvm::SmallSet. It also means that +/// insert/erase/contains operations complete in negligible constant time: +/// insert and erase require one load and one store, and contains requires +/// just one load. +/// +//===----------------------------------------------------------------------===// + +#ifndef IMMUTABLEGRAPH_H +#define IMMUTABLEGRAPH_H + +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +#include +#include + +namespace llvm { + +template +class ImmutableGraph { + using Traits = GraphTraits *>; + template friend class ImmutableGraphBuilder; + +public: + using NodeValueT = _NodeValueT; + using EdgeValueT = _EdgeValueT; + using size_type = _SizeT; + class Node; + class Edge { + friend class ImmutableGraph; + template friend class ImmutableGraphBuilder; + friend Traits; + + Node *__dest; + EdgeValueT __value; + + public: + EdgeValueT &value() { return __value; } + }; + class Node { + friend class ImmutableGraph; + template friend class ImmutableGraphBuilder; + friend Traits; + + Edge *__edges; + NodeValueT __value; + + public: + NodeValueT &value() { return __value; } + }; + +protected: + ImmutableGraph(Node *Nodes, size_type NodesSize, Edge *Edges, + size_type EdgesSize) + : __nodes{Nodes}, __nodes_size{NodesSize}, __edges{Edges}, + __edges_size{EdgesSize} {} + ImmutableGraph(const ImmutableGraph &) = delete; + ImmutableGraph(ImmutableGraph &&) = delete; + ImmutableGraph &operator=(const ImmutableGraph &) = delete; + ImmutableGraph &operator=(ImmutableGraph &&) = delete; + +public: + ~ImmutableGraph() { + delete[] __edges; + delete[] __nodes; + } + + Node *nodes_begin() const { return __nodes; } + Node *nodes_end() const { return __nodes + __nodes_size; } + Edge *edges_begin() const { return __edges; } + Edge *edges_end() const { return __edges + __edges_size; } + size_type nodes_size() const { return __nodes_size; } + size_type edges_size() const { return __edges_size; } + bool empty() const { return __nodes_size == 0; } + + class NodeSet { + friend class iterator; + + const ImmutableGraph &__g; + BitVector __v; + + public: + NodeSet(const ImmutableGraph &G, bool ContainsAll = false) + : __g{G}, __v{static_cast(__g.nodes_size()), ContainsAll} {} + bool insert(Node *N) { + size_type Idx = std::distance(__g.nodes_begin(), N); + bool AlreadyExists = __v.test(Idx); + __v.set(Idx); + return !AlreadyExists; + } + void erase(Node *N) { + size_type Idx = std::distance(__g.nodes_begin(), N); + __v.reset(Idx); + } + bool contains(Node *N) const { + size_type Idx = std::distance(__g.nodes_begin(), N); + return __v.test(Idx); + } + void clear() { __v.reset(); } + size_type empty() const { return __v.none(); } + /// Return the number of elements in the set + size_type count() const { return __v.count(); } + /// Return the size of the set's domain + size_type size() const { return __v.size(); } + /// Set union + NodeSet &operator|=(const NodeSet &RHS) { + assert(&this->__g == &RHS.__g); + __v |= RHS.__v; + return *this; + } + /// Set intersection + NodeSet &operator&=(const NodeSet &RHS) { + assert(&this->__g == &RHS.__g); + __v &= RHS.__v; + return *this; + } + /// Set disjoint union + NodeSet &operator^=(const NodeSet &RHS) { + assert(&this->__g == &RHS.__g); + __v ^= RHS.__v; + return *this; + } + + using index_iterator = typename BitVector::const_set_bits_iterator; + index_iterator index_begin() const { return __v.set_bits_begin(); } + index_iterator index_end() const { return __v.set_bits_end(); } + void set(size_type Idx) { __v.set(Idx); } + void reset(size_type Idx) { __v.reset(Idx); } + + class iterator { + const NodeSet &__set; + size_type __current; + + void advance() { + assert(__current != -1); + __current = __set.__v.find_next(__current); + } + + public: + iterator(const NodeSet &Set, size_type Begin) + : __set{Set}, __current{Begin} {} + iterator operator++(int) { + iterator Tmp = *this; + advance(); + return Tmp; + } + iterator &operator++() { + advance(); + return *this; + } + Node *operator*() const { + assert(__current != -1); + return __set.__g.nodes_begin() + __current; + } + bool operator==(const iterator &other) const { + assert(&this->__set == &other.__set); + return this->__current == other.__current; + } + bool operator!=(const iterator &other) const { return !(*this == other); } + }; + + iterator begin() const { return iterator{*this, __v.find_first()}; } + iterator end() const { return iterator{*this, -1}; } + }; + + class EdgeSet { + const ImmutableGraph &__g; + BitVector __v; + + public: + EdgeSet(const ImmutableGraph &G, bool ContainsAll = false) + : __g{G}, __v{static_cast(__g.edges_size()), ContainsAll} {} + bool insert(Edge *E) { + size_type Idx = std::distance(__g.edges_begin(), E); + bool AlreadyExists = __v.test(Idx); + __v.set(Idx); + return !AlreadyExists; + } + void erase(Edge *E) { + size_type Idx = std::distance(__g.edges_begin(), E); + __v.reset(Idx); + } + bool contains(Edge *E) const { + size_type Idx = std::distance(__g.edges_begin(), E); + return __v.test(Idx); + } + void clear() { __v.reset(); } + bool empty() const { return __v.none(); } + /// Return the number of elements in the set + size_type count() const { return __v.count(); } + /// Return the size of the set's domain + size_type size() const { return __v.size(); } + /// Set union + EdgeSet &operator|=(const EdgeSet &RHS) { + assert(&this->__g == &RHS.__g); + __v |= RHS.__v; + return *this; + } + /// Set intersection + EdgeSet &operator&=(const EdgeSet &RHS) { + assert(&this->__g == &RHS.__g); + __v &= RHS.__v; + return *this; + } + /// Set disjoint union + EdgeSet &operator^=(const EdgeSet &RHS) { + assert(&this->__g == &RHS.__g); + __v ^= RHS.__v; + return *this; + } + + using index_iterator = typename BitVector::const_set_bits_iterator; + index_iterator index_begin() const { return __v.set_bits_begin(); } + index_iterator index_end() const { return __v.set_bits_end(); } + void set(size_type Idx) { __v.set(Idx); } + void reset(size_type Idx) { __v.reset(Idx); } + + class iterator { + const EdgeSet &__set; + size_type __current; + + void advance() { + assert(__current != -1); + __current = __set.__v.find_next(__current); + } + + public: + iterator(const EdgeSet &Set, size_type Begin) + : __set{Set}, __current{Begin} {} + iterator operator++(int) { + iterator Tmp = *this; + advance(); + return Tmp; + } + iterator &operator++() { + advance(); + return *this; + } + Edge *operator*() const { + assert(__current != -1); + return __set.__g.edges_begin() + __current; + } + bool operator==(const iterator &other) const { + assert(&this->__set == &other.__set); + return this->__current == other.__current; + } + bool operator!=(const iterator &other) const { return !(*this == other); } + }; + + iterator begin() const { return iterator{*this, __v.find_first()}; } + iterator end() const { return iterator{*this, -1}; } + }; + +private: + Node *__nodes; + size_type __nodes_size; + Edge *__edges; + size_type __edges_size; +}; + +template class ImmutableGraphBuilder { + using NodeValueT = typename GraphT::NodeValueT; + using EdgeValueT = typename GraphT::EdgeValueT; + static_assert( + std::is_base_of, GraphT>::value, + "Template argument to ImmutableGraphBuilder must derive from " + "ImmutableGraph<>"); + using size_type = typename GraphT::size_type; + using NodeSet = typename GraphT::NodeSet; + using Node = typename GraphT::Node; + using EdgeSet = typename GraphT::EdgeSet; + using Edge = typename GraphT::Edge; + using BuilderEdge = std::pair; + using EdgeList = std::vector; + using BuilderVertex = std::pair; + using VertexVec = std::vector; + +public: + using NodeRef = size_type; + + NodeRef addVertex(const NodeValueT &V) { + auto I = __adj_list.emplace(__adj_list.end(), V, EdgeList{}); + return std::distance(__adj_list.begin(), I); + } + + void addEdge(const EdgeValueT &E, NodeRef From, NodeRef To) { + __adj_list[From].second.emplace_back(E, To); + } + + bool empty() const { return __adj_list.empty(); } + + template GraphT *get(ArgT &&... Args) { + size_type VertexSize = __adj_list.size(), EdgeSize = 0; + for (const auto &V : __adj_list) { + EdgeSize += V.second.size(); + } + auto *VertexArray = new Node[VertexSize + 1 /* terminator node */]; + auto *EdgeArray = new Edge[EdgeSize]; + size_type VI = 0, EI = 0; + for (; VI < static_cast(__adj_list.size()); ++VI) { + VertexArray[VI].__value = std::move(__adj_list[VI].first); + VertexArray[VI].__edges = &EdgeArray[EI]; + auto NumEdges = static_cast(__adj_list[VI].second.size()); + if (NumEdges > 0) { + for (size_type VEI = 0; VEI < NumEdges; ++VEI, ++EI) { + auto &E = __adj_list[VI].second[VEI]; + EdgeArray[EI].__value = std::move(E.first); + EdgeArray[EI].__dest = VertexArray + E.second; + } + } + } + assert(VI == VertexSize && EI == EdgeSize && "Gadget graph malformed"); + VertexArray[VI].__edges = EdgeArray + EdgeSize; // terminator node + return new GraphT{VertexArray, VertexSize, EdgeArray, EdgeSize, + std::forward(Args)...}; + } + + template + static GraphT *trim(const GraphT &G, const NodeSet &TrimNodes, + const EdgeSet &TrimEdges, ArgT &&... Args) { + size_type NewVertexSize = TrimNodes.size() - TrimNodes.count(); + size_type NewEdgeSize = TrimEdges.size() - TrimEdges.count(); + auto *NewVertexArray = new Node[NewVertexSize + 1 /* terminator node */]; + auto *NewEdgeArray = new Edge[NewEdgeSize]; + size_type TrimmedNodesSoFar = 0, + *TrimmedNodes = new size_type[TrimNodes.size()]; + for (size_type I = 0; I < TrimNodes.size(); ++I) { + TrimmedNodes[I] = TrimmedNodesSoFar; + if (TrimNodes.contains(G.nodes_begin() + I)) + ++TrimmedNodesSoFar; + } + size_type VertexI = 0, EdgeI = 0; + for (Node *NI = G.nodes_begin(), *NE = G.nodes_end(); NI != NE; ++NI) { + if (TrimNodes.contains(NI)) + continue; + size_type NewNumEdges = + static_cast((NI + 1)->__edges - NI->__edges) > 0 + ? std::count_if( + NI->__edges, (NI + 1)->__edges, + [&TrimEdges](Edge &E) { return !TrimEdges.contains(&E); }) + : 0; + NewVertexArray[VertexI].__value = NI->__value; + NewVertexArray[VertexI].__edges = &NewEdgeArray[EdgeI]; + if (NewNumEdges > 0) { + for (Edge *EI = NI->__edges, *EE = (NI + 1)->__edges; EI != EE; ++EI) { + if (TrimEdges.contains(EI)) + continue; + NewEdgeArray[EdgeI].__value = EI->__value; + size_type DestIdx = std::distance(G.nodes_begin(), EI->__dest); + size_type NewIdx = DestIdx - TrimmedNodes[DestIdx]; + assert(NewIdx < NewVertexSize); + NewEdgeArray[EdgeI].__dest = NewVertexArray + NewIdx; + ++EdgeI; + } + } + ++VertexI; + } + delete[] TrimmedNodes; + assert(VertexI == NewVertexSize && EdgeI == NewEdgeSize && + "Gadget graph malformed"); + NewVertexArray[VertexI].__edges = NewEdgeArray + NewEdgeSize; + return new GraphT{NewVertexArray, NewVertexSize, NewEdgeArray, NewEdgeSize, + std::forward(Args)...}; + } + +private: + VertexVec __adj_list; +}; + +template +struct GraphTraits *> { + using GraphT = ImmutableGraph; + using NodeRef = typename GraphT::Node *; + using EdgeRef = typename GraphT::Edge &; + + static NodeRef edge_dest(EdgeRef E) { return E.__dest; } + using ChildIteratorType = + mapped_iterator; + + static NodeRef getEntryNode(GraphT *G) { return G->nodes_begin(); } + static ChildIteratorType child_begin(NodeRef N) { + return {N->__edges, &edge_dest}; + } + static ChildIteratorType child_end(NodeRef N) { + return {(N + 1)->__edges, &edge_dest}; + } + + static NodeRef getNode(typename GraphT::Node &N) { return NodeRef{&N}; } + using nodes_iterator = + mapped_iterator; + static nodes_iterator nodes_begin(GraphT *G) { + return {G->nodes_begin(), &getNode}; + } + static nodes_iterator nodes_end(GraphT *G) { + return {G->nodes_end(), &getNode}; + } + + using ChildEdgeIteratorType = typename GraphT::Edge *; + + static ChildEdgeIteratorType child_edge_begin(NodeRef N) { + return N->__edges; + } + static ChildEdgeIteratorType child_edge_end(NodeRef N) { + return (N + 1)->__edges; + } + static typename GraphT::size_type size(GraphT *G) { return G->nodes_size(); } +}; + +} // end namespace llvm + +#endif // IMMUTABLEGRAPH_H diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h index 1b6e99ae7b9b..0c88a6b746ef 100644 --- a/llvm/lib/Target/X86/X86.h +++ b/llvm/lib/Target/X86/X86.h @@ -142,6 +142,7 @@ InstructionSelector *createX86InstructionSelector(const X86TargetMachine &TM, X86Subtarget &, X86RegisterBankInfo &); +FunctionPass *createX86LoadValueInjectionLoadHardeningPass(); FunctionPass *createX86LoadValueInjectionRetHardeningPass(); FunctionPass *createX86SpeculativeLoadHardeningPass(); @@ -159,6 +160,7 @@ void initializeX86DomainReassignmentPass(PassRegistry &); void initializeX86ExecutionDomainFixPass(PassRegistry &); void initializeX86ExpandPseudoPass(PassRegistry &); void initializeX86FlagsCopyLoweringPassPass(PassRegistry &); +void initializeX86LoadValueInjectionLoadHardeningPassPass(PassRegistry &); void initializeX86LoadValueInjectionRetHardeningPassPass(PassRegistry &); void initializeX86OptimizeLEAPassPass(PassRegistry &); void initializeX86PartialReductionPass(PassRegistry &); diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index 13ccf3c940b9..7bee814232b7 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -442,6 +442,13 @@ def FeatureLVIControlFlowIntegrity "LFENCE instruction to serialize control flow. Also decompose RET " "instructions into a POP+LFENCE+JMP sequence.">; +// Mitigate LVI attacks against data loads +def FeatureLVILoadHardening + : SubtargetFeature< + "lvi-load-hardening", "UseLVILoadHardening", "true", + "Insert LFENCE instructions to prevent data speculatively injected " + "into loads from being used maliciously.">; + // Direct Move instructions. def FeatureMOVDIRI : SubtargetFeature<"movdiri", "HasMOVDIRI", "true", "Support movdiri instruction">; diff --git a/llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp b/llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp new file mode 100644 index 000000000000..7c027e5fca67 --- /dev/null +++ b/llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp @@ -0,0 +1,586 @@ +//==-- X86LoadValueInjectionLoadHardening.cpp - LVI load hardening for x86 --=// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// Description: This pass finds Load Value Injection (LVI) gadgets consisting +/// of a load from memory (i.e., SOURCE), and any operation that may transmit +/// the value loaded from memory over a covert channel, or use the value loaded +/// from memory to determine a branch/call target (i.e., SINK). +/// +//===----------------------------------------------------------------------===// + +#include "ImmutableGraph.h" +#include "X86.h" +#include "X86Subtarget.h" +#include "X86TargetMachine.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineDominanceFrontier.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/RDFGraph.h" +#include "llvm/CodeGen/RDFLiveness.h" +#include "llvm/InitializePasses.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/DOTGraphTraits.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/GraphWriter.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +#define PASS_KEY "x86-lvi-load" +#define DEBUG_TYPE PASS_KEY + +STATISTIC(NumFunctionsConsidered, "Number of functions analyzed"); +STATISTIC(NumFunctionsMitigated, "Number of functions for which mitigations " + "were deployed"); +STATISTIC(NumGadgets, "Number of LVI gadgets detected during analysis"); + +static cl::opt NoConditionalBranches( + PASS_KEY "-no-cbranch", + cl::desc("Don't treat conditional branches as disclosure gadgets. This " + "may improve performance, at the cost of security."), + cl::init(false), cl::Hidden); + +static cl::opt EmitDot( + PASS_KEY "-dot", + cl::desc( + "For each function, emit a dot graph depicting potential LVI gadgets"), + cl::init(false), cl::Hidden); + +static cl::opt EmitDotOnly( + PASS_KEY "-dot-only", + cl::desc("For each function, emit a dot graph depicting potential LVI " + "gadgets, and do not insert any fences"), + cl::init(false), cl::Hidden); + +static cl::opt EmitDotVerify( + PASS_KEY "-dot-verify", + cl::desc("For each function, emit a dot graph to stdout depicting " + "potential LVI gadgets, used for testing purposes only"), + cl::init(false), cl::Hidden); + +static cl::opt NoFixedLoads( + PASS_KEY "-no-fixed", + cl::desc("Don't mitigate RIP-relative or RSP-relative loads. This " + "may improve performance, at the cost of security."), + cl::init(false), cl::Hidden); + +#define ARG_NODE nullptr +#define GADGET_EDGE ((int)(-1)) +#define WEIGHT(EdgeValue) ((double)(2 * (EdgeValue) + 1)) + +namespace { + +class X86LoadValueInjectionLoadHardeningPass : public MachineFunctionPass { +public: + X86LoadValueInjectionLoadHardeningPass() : MachineFunctionPass(ID) {} + + StringRef getPassName() const override { + return "X86 Load Value Injection (LVI) Load Hardening"; + } + void getAnalysisUsage(AnalysisUsage &AU) const override; + bool runOnMachineFunction(MachineFunction &MF) override; + + static char ID; + +private: + struct MachineGadgetGraph : ImmutableGraph { + using GraphT = ImmutableGraph; + using Node = typename GraphT::Node; + using Edge = typename GraphT::Edge; + using size_type = typename GraphT::size_type; + MachineGadgetGraph(Node *Nodes, size_type NodesSize, Edge *Edges, + size_type EdgesSize, int NumFences = 0, + int NumGadgets = 0) + : GraphT{Nodes, NodesSize, Edges, EdgesSize}, NumFences{NumFences}, + NumGadgets{NumGadgets} {} + MachineFunction &getMF() { // FIXME: This function should be cleaner + for (Node *NI = nodes_begin(), *const NE = nodes_end(); NI != NE; ++NI) { + if (NI->value()) { + return *NI->value()->getMF(); + } + } + llvm_unreachable("Could not find a valid node"); + } + static inline bool isCFGEdge(Edge &E) { return E.value() != GADGET_EDGE; } + static inline bool isGadgetEdge(Edge &E) { + return E.value() == GADGET_EDGE; + } + int NumFences; + int NumGadgets; + }; + friend struct llvm::DOTGraphTraits; + using GTraits = llvm::GraphTraits; + using GraphBuilder = ImmutableGraphBuilder; + using EdgeSet = MachineGadgetGraph::EdgeSet; + using Gadget = std::pair; + + const X86Subtarget *STI; + const TargetInstrInfo *TII; + const TargetRegisterInfo *TRI; + + int hardenLoads(MachineFunction &MF, bool Fixed) const; + std::unique_ptr + getGadgetGraph(MachineFunction &MF, const MachineLoopInfo &MLI, + const MachineDominatorTree &MDT, + const MachineDominanceFrontier &MDF, bool FixedLoads) const; + + bool instrUsesRegToAccessMemory(const MachineInstr &I, unsigned Reg) const; + bool instrUsesRegToBranch(const MachineInstr &I, unsigned Reg) const; + template bool hasLoadFrom(const MachineInstr &MI) const; + bool instrAccessesStackSlot(const MachineInstr &MI) const; + bool instrAccessesConstantPool(const MachineInstr &MI) const; + bool instrAccessesGOT(const MachineInstr &MI) const; + inline bool instrIsFixedAccess(const MachineInstr &MI) const { + return instrAccessesConstantPool(MI) || instrAccessesStackSlot(MI) || + instrAccessesGOT(MI); + } + inline bool isFence(const MachineInstr *MI) const { + return MI && (MI->getOpcode() == X86::LFENCE || + (STI->useLVIControlFlowIntegrity() && MI->isCall())); + } +}; + +} // end anonymous namespace + +namespace llvm { + +template <> +struct GraphTraits + : GraphTraits *> {}; + +template <> +struct DOTGraphTraits< + X86LoadValueInjectionLoadHardeningPass::MachineGadgetGraph *> + : DefaultDOTGraphTraits { + using GraphType = X86LoadValueInjectionLoadHardeningPass::MachineGadgetGraph; + using Traits = X86LoadValueInjectionLoadHardeningPass::GTraits; + using NodeRef = typename Traits::NodeRef; + using EdgeRef = typename Traits::EdgeRef; + using ChildIteratorType = typename Traits::ChildIteratorType; + using ChildEdgeIteratorType = typename Traits::ChildEdgeIteratorType; + + DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} + + static std::string getGraphName(GraphType *G) { + std::string GraphName{"Speculative gadgets for \""}; + GraphName += G->getMF().getName(); + GraphName += "\" function"; + return GraphName; + } + + std::string getNodeLabel(NodeRef Node, GraphType *) { + std::string str; + raw_string_ostream str_stream{str}; + if (Node->value() == ARG_NODE) + return "ARGS"; + str_stream << *Node->value(); + return str_stream.str(); + } + + static std::string getNodeAttributes(NodeRef Node, GraphType *) { + MachineInstr *MI = Node->value(); + if (MI == ARG_NODE) + return "color = blue"; + else if (MI->getOpcode() == X86::LFENCE) + return "color = green"; + else + return ""; + } + + static std::string getEdgeAttributes(NodeRef, ChildIteratorType E, + GraphType *) { + int EdgeVal = (*E.getCurrent()).value(); + return EdgeVal >= 0 ? "label = " + std::to_string(EdgeVal) + : "color = red, style = \"dashed\""; + } +}; + +} // end namespace llvm + +char X86LoadValueInjectionLoadHardeningPass::ID = 0; + +void X86LoadValueInjectionLoadHardeningPass::getAnalysisUsage( + AnalysisUsage &AU) const { + MachineFunctionPass::getAnalysisUsage(AU); + AU.addRequired(); + AU.addRequired(); + AU.addRequired(); + AU.setPreservesCFG(); +} + +bool X86LoadValueInjectionLoadHardeningPass::runOnMachineFunction( + MachineFunction &MF) { + LLVM_DEBUG(dbgs() << "***** " << getPassName() << " : " << MF.getName() + << " *****\n"); + STI = &MF.getSubtarget(); + if (!STI->useLVILoadHardening() || !STI->is64Bit()) + return false; // FIXME: support 32-bit + + // Don't skip functions with the "optnone" attr but participate in opt-bisect. + const Function &F = MF.getFunction(); + if (!F.hasOptNone() && skipFunction(F)) + return false; + + ++NumFunctionsConsidered; + TII = STI->getInstrInfo(); + TRI = STI->getRegisterInfo(); + LLVM_DEBUG(dbgs() << "Hardening data-dependent loads...\n"); + hardenLoads(MF, false); + LLVM_DEBUG(dbgs() << "Hardening data-dependent loads... Done\n"); + if (!NoFixedLoads) { + LLVM_DEBUG(dbgs() << "Hardening fixed loads...\n"); + hardenLoads(MF, true); + LLVM_DEBUG(dbgs() << "Hardening fixed loads... Done\n"); + } + return false; +} + +// Apply the mitigation to `MF`, return the number of fences inserted. +// If `FixedLoads` is `true`, then the mitigation will be applied to fixed +// loads; otherwise, mitigation will be applied to non-fixed loads. +int X86LoadValueInjectionLoadHardeningPass::hardenLoads(MachineFunction &MF, + bool FixedLoads) const { + LLVM_DEBUG(dbgs() << "Building gadget graph...\n"); + const auto &MLI = getAnalysis(); + const auto &MDT = getAnalysis(); + const auto &MDF = getAnalysis(); + std::unique_ptr Graph = + getGadgetGraph(MF, MLI, MDT, MDF, FixedLoads); + LLVM_DEBUG(dbgs() << "Building gadget graph... Done\n"); + if (Graph == nullptr) + return 0; // didn't find any gadgets + + if (EmitDotVerify) { + WriteGraph(outs(), Graph.get()); + return 0; + } + + if (EmitDot || EmitDotOnly) { + LLVM_DEBUG(dbgs() << "Emitting gadget graph...\n"); + std::error_code FileError; + std::string FileName = "lvi."; + if (FixedLoads) + FileName += "fixed."; + FileName += Graph->getMF().getName(); + FileName += ".dot"; + raw_fd_ostream FileOut(FileName, FileError); + if (FileError) + errs() << FileError.message(); + WriteGraph(FileOut, Graph.get()); + FileOut.close(); + LLVM_DEBUG(dbgs() << "Emitting gadget graph... Done\n"); + if (EmitDotOnly) + return 0; + } + + return 0; +} + +std::unique_ptr +X86LoadValueInjectionLoadHardeningPass::getGadgetGraph( + MachineFunction &MF, const MachineLoopInfo &MLI, + const MachineDominatorTree &MDT, const MachineDominanceFrontier &MDF, + bool FixedLoads) const { + using namespace rdf; + + // Build the Register Dataflow Graph using the RDF framework + TargetOperandInfo TOI{*TII}; + DataFlowGraph DFG{MF, *TII, *TRI, MDT, MDF, TOI}; + DFG.build(); + Liveness L{MF.getRegInfo(), DFG}; + L.computePhiInfo(); + + GraphBuilder Builder; + using GraphIter = typename GraphBuilder::NodeRef; + DenseMap NodeMap; + int FenceCount = 0; + auto MaybeAddNode = [&NodeMap, &Builder](MachineInstr *MI) { + auto Ref = NodeMap.find(MI); + if (Ref == NodeMap.end()) { + auto I = Builder.addVertex(MI); + NodeMap[MI] = I; + return std::pair{I, true}; + } else { + return std::pair{Ref->getSecond(), false}; + } + }; + + // Analyze all machine instructions to find gadgets and LFENCEs, adding + // each interesting value to `Nodes` + DenseSet> GadgetEdgeSet; + auto AnalyzeDef = [&](NodeAddr Def) { + MachineInstr *MI = Def.Addr->getFlags() & NodeAttrs::PhiRef + ? ARG_NODE + : Def.Addr->getOp().getParent(); + auto AnalyzeUse = [&](NodeAddr Use) { + assert(!(Use.Addr->getFlags() & NodeAttrs::PhiRef)); + MachineOperand &UseMO = Use.Addr->getOp(); + MachineInstr &UseMI = *UseMO.getParent(); + assert(UseMO.isReg()); + // We naively assume that an instruction propagates any loaded Uses + // to all Defs, unless the instruction is a call + if (UseMI.isCall()) + return false; + if (instrUsesRegToAccessMemory(UseMI, UseMO.getReg()) || + (!NoConditionalBranches && + instrUsesRegToBranch(UseMI, UseMO.getReg()))) { // found a gadget! + // add the root of this chain + auto GadgetBegin = MaybeAddNode(MI); + // and the instruction that (transitively) discloses the root + auto GadgetEnd = MaybeAddNode(&UseMI); + if (GadgetEdgeSet.insert({GadgetBegin.first, GadgetEnd.first}).second) + Builder.addEdge(GADGET_EDGE, GadgetBegin.first, GadgetEnd.first); + if (UseMI.mayLoad()) // FIXME: This should be more precise + return false; // stop traversing further uses of `Reg` + } + return true; + }; + SmallSet NodesVisited; + std::function)> AnalyzeDefUseChain = + [&](NodeAddr Def) { + if (Def.Addr->getAttrs() & NodeAttrs::Dead) + return; + RegisterRef DefReg = DFG.getPRI().normalize(Def.Addr->getRegRef(DFG)); + NodeList Uses; + for (auto UseID : L.getAllReachedUses(DefReg, Def)) { + auto Use = DFG.addr(UseID); + if (Use.Addr->getFlags() & NodeAttrs::PhiRef) { // phi node + NodeAddr Phi = Use.Addr->getOwner(DFG); + for (auto I : L.getRealUses(Phi.Id)) { + if (DFG.getPRI().alias(RegisterRef(I.first), DefReg)) { + for (auto UA : I.second) { + auto PhiUse = DFG.addr(UA.first); + Uses.push_back(PhiUse); + } + } + } + } else { // not a phi node + Uses.push_back(Use); + } + } + for (auto N : Uses) { + NodeAddr Use{N}; + if (NodesVisited.insert(Use.Id).second && AnalyzeUse(Use)) { + NodeAddr Owner{Use.Addr->getOwner(DFG)}; + NodeList Defs = Owner.Addr->members_if(DataFlowGraph::IsDef, DFG); + std::for_each(Defs.begin(), Defs.end(), AnalyzeDefUseChain); + } + } + }; + AnalyzeDefUseChain(Def); + }; + + LLVM_DEBUG(dbgs() << "Analyzing def-use chains to find gadgets\n"); + // Analyze function arguments + if (!FixedLoads) { // only need to analyze function args once + NodeAddr EntryBlock = DFG.getFunc().Addr->getEntryBlock(DFG); + for (NodeAddr ArgPhi : + EntryBlock.Addr->members_if(DataFlowGraph::IsPhi, DFG)) { + NodeList Defs = ArgPhi.Addr->members_if(DataFlowGraph::IsDef, DFG); + std::for_each(Defs.begin(), Defs.end(), AnalyzeDef); + } + } + // Analyze every instruction in MF + for (NodeAddr BA : DFG.getFunc().Addr->members(DFG)) { + for (NodeAddr SA : + BA.Addr->members_if(DataFlowGraph::IsCode, DFG)) { + MachineInstr *MI = SA.Addr->getCode(); + if (isFence(MI)) { + MaybeAddNode(MI); + ++FenceCount; + } else if (MI->mayLoad() && ((FixedLoads && instrIsFixedAccess(*MI)) || + (!FixedLoads && !instrIsFixedAccess(*MI)))) { + NodeList Defs = SA.Addr->members_if(DataFlowGraph::IsDef, DFG); + std::for_each(Defs.begin(), Defs.end(), AnalyzeDef); + } + } + } + int GadgetCount = static_cast(GadgetEdgeSet.size()); + LLVM_DEBUG(dbgs() << "Found " << FenceCount << " fences\n"); + LLVM_DEBUG(dbgs() << "Found " << GadgetCount << " gadgets\n"); + if (GadgetCount == 0) + return nullptr; + NumGadgets += GadgetCount; + + // Traverse CFG to build the rest of the graph + SmallSet BlocksVisited; + std::function TraverseCFG = + [&](MachineBasicBlock *MBB, GraphIter GI, unsigned ParentDepth) { + unsigned LoopDepth = MLI.getLoopDepth(MBB); + if (!MBB->empty()) { + // Always add the first instruction in each block + auto NI = MBB->begin(); + auto BeginBB = MaybeAddNode(&*NI); + Builder.addEdge(ParentDepth, GI, BeginBB.first); + if (!BlocksVisited.insert(MBB).second) + return; + + // Add any instructions within the block that are gadget components + GI = BeginBB.first; + while (++NI != MBB->end()) { + auto Ref = NodeMap.find(&*NI); + if (Ref != NodeMap.end()) { + Builder.addEdge(LoopDepth, GI, Ref->getSecond()); + GI = Ref->getSecond(); + } + } + + // Always add the terminator instruction, if one exists + auto T = MBB->getFirstTerminator(); + if (T != MBB->end()) { + auto EndBB = MaybeAddNode(&*T); + if (EndBB.second) + Builder.addEdge(LoopDepth, GI, EndBB.first); + GI = EndBB.first; + } + } + for (MachineBasicBlock *Succ : MBB->successors()) + TraverseCFG(Succ, GI, LoopDepth); + }; + // ARG_NODE is a pseudo-instruction that represents MF args in the GadgetGraph + GraphIter ArgNode = MaybeAddNode(ARG_NODE).first; + TraverseCFG(&MF.front(), ArgNode, 0); + std::unique_ptr G{Builder.get(FenceCount, GadgetCount)}; + LLVM_DEBUG(dbgs() << "Found " << GTraits::size(G.get()) << " nodes\n"); + return G; +} + +bool X86LoadValueInjectionLoadHardeningPass::instrUsesRegToAccessMemory( + const MachineInstr &MI, unsigned Reg) const { + if (!MI.mayLoadOrStore() || MI.getOpcode() == X86::MFENCE || + MI.getOpcode() == X86::SFENCE || MI.getOpcode() == X86::LFENCE) + return false; + + // FIXME: This does not handle pseudo loading instruction like TCRETURN* + const MCInstrDesc &Desc = MI.getDesc(); + int MemRefBeginIdx = X86II::getMemoryOperandNo(Desc.TSFlags); + if (MemRefBeginIdx < 0) { + LLVM_DEBUG(dbgs() << "Warning: unable to obtain memory operand for loading " + "instruction:\n"; + MI.print(dbgs()); dbgs() << '\n';); + return false; + } + MemRefBeginIdx += X86II::getOperandBias(Desc); + + const MachineOperand &BaseMO = + MI.getOperand(MemRefBeginIdx + X86::AddrBaseReg); + const MachineOperand &IndexMO = + MI.getOperand(MemRefBeginIdx + X86::AddrIndexReg); + return (BaseMO.isReg() && BaseMO.getReg() != X86::NoRegister && + TRI->regsOverlap(BaseMO.getReg(), Reg)) || + (IndexMO.isReg() && IndexMO.getReg() != X86::NoRegister && + TRI->regsOverlap(IndexMO.getReg(), Reg)); +} + +bool X86LoadValueInjectionLoadHardeningPass::instrUsesRegToBranch( + const MachineInstr &MI, unsigned Reg) const { + if (!MI.isConditionalBranch()) + return false; + for (const MachineOperand &Use : MI.uses()) + if (Use.isReg() && Use.getReg() == Reg) + return true; + return false; +} + +template +bool X86LoadValueInjectionLoadHardeningPass::hasLoadFrom( + const MachineInstr &MI) const { + for (auto &MMO : MI.memoperands()) { + const PseudoSourceValue *PSV = MMO->getPseudoValue(); + if (PSV && PSV->kind() == K && MMO->isLoad()) + return true; + } + return false; +} + +bool X86LoadValueInjectionLoadHardeningPass::instrAccessesStackSlot( + const MachineInstr &MI) const { + // Check the PSV first + if (hasLoadFrom(MI)) + return true; + // Some loads are not marked with a PSV, so we always need to double check + const MCInstrDesc &Desc = MI.getDesc(); + int MemRefBeginIdx = X86II::getMemoryOperandNo(Desc.TSFlags); + if (MemRefBeginIdx < 0) + return false; + MemRefBeginIdx += X86II::getOperandBias(Desc); + return MI.getOperand(MemRefBeginIdx + X86::AddrBaseReg).isFI() && + MI.getOperand(MemRefBeginIdx + X86::AddrScaleAmt).isImm() && + MI.getOperand(MemRefBeginIdx + X86::AddrIndexReg).isReg() && + MI.getOperand(MemRefBeginIdx + X86::AddrDisp).isImm() && + MI.getOperand(MemRefBeginIdx + X86::AddrScaleAmt).getImm() == 1 && + MI.getOperand(MemRefBeginIdx + X86::AddrIndexReg).getReg() == + X86::NoRegister && + MI.getOperand(MemRefBeginIdx + X86::AddrDisp).getImm() == 0; +} + +bool X86LoadValueInjectionLoadHardeningPass::instrAccessesConstantPool( + const MachineInstr &MI) const { + if (hasLoadFrom(MI)) + return true; + const MCInstrDesc &Desc = MI.getDesc(); + int MemRefBeginIdx = X86II::getMemoryOperandNo(Desc.TSFlags); + if (MemRefBeginIdx < 0) + return false; + MemRefBeginIdx += X86II::getOperandBias(Desc); + return MI.getOperand(MemRefBeginIdx + X86::AddrBaseReg).isReg() && + MI.getOperand(MemRefBeginIdx + X86::AddrScaleAmt).isImm() && + MI.getOperand(MemRefBeginIdx + X86::AddrIndexReg).isReg() && + MI.getOperand(MemRefBeginIdx + X86::AddrDisp).isCPI() && + (MI.getOperand(MemRefBeginIdx + X86::AddrBaseReg).getReg() == + X86::RIP || + MI.getOperand(MemRefBeginIdx + X86::AddrBaseReg).getReg() == + X86::NoRegister) && + MI.getOperand(MemRefBeginIdx + X86::AddrScaleAmt).getImm() == 1 && + MI.getOperand(MemRefBeginIdx + X86::AddrIndexReg).getReg() == + X86::NoRegister; +} + +bool X86LoadValueInjectionLoadHardeningPass::instrAccessesGOT( + const MachineInstr &MI) const { + if (hasLoadFrom(MI)) + return true; + const MCInstrDesc &Desc = MI.getDesc(); + int MemRefBeginIdx = X86II::getMemoryOperandNo(Desc.TSFlags); + if (MemRefBeginIdx < 0) + return false; + MemRefBeginIdx += X86II::getOperandBias(Desc); + return MI.getOperand(MemRefBeginIdx + X86::AddrBaseReg).isReg() && + MI.getOperand(MemRefBeginIdx + X86::AddrScaleAmt).isImm() && + MI.getOperand(MemRefBeginIdx + X86::AddrIndexReg).isReg() && + MI.getOperand(MemRefBeginIdx + X86::AddrDisp).getTargetFlags() == + X86II::MO_GOTPCREL && + MI.getOperand(MemRefBeginIdx + X86::AddrBaseReg).getReg() == + X86::RIP && + MI.getOperand(MemRefBeginIdx + X86::AddrScaleAmt).getImm() == 1 && + MI.getOperand(MemRefBeginIdx + X86::AddrIndexReg).getReg() == + X86::NoRegister; +} + +INITIALIZE_PASS_BEGIN(X86LoadValueInjectionLoadHardeningPass, PASS_KEY, + "X86 LVI load hardening", false, false) +INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) +INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) +INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier) +INITIALIZE_PASS_END(X86LoadValueInjectionLoadHardeningPass, PASS_KEY, + "X86 LVI load hardening", false, false) + +FunctionPass *llvm::createX86LoadValueInjectionLoadHardeningPass() { + return new X86LoadValueInjectionLoadHardeningPass(); +} diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index a23588a07e57..b4ad50d88062 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -434,6 +434,10 @@ class X86Subtarget final : public X86GenSubtargetInfo { /// POP+LFENCE+JMP sequence. bool UseLVIControlFlowIntegrity = false; + /// Insert LFENCE instructions to prevent data speculatively injected into + /// loads from being used maliciously. + bool UseLVILoadHardening = false; + /// Use software floating point for code generation. bool UseSoftFloat = false; @@ -735,6 +739,7 @@ class X86Subtarget final : public X86GenSubtargetInfo { bool preferMaskRegisters() const { return PreferMaskRegisters; } bool useGLMDivSqrtCosts() const { return UseGLMDivSqrtCosts; } bool useLVIControlFlowIntegrity() const { return UseLVIControlFlowIntegrity; } + bool useLVILoadHardening() const { return UseLVILoadHardening; } unsigned getPreferVectorWidth() const { return PreferVectorWidth; } unsigned getRequiredVectorWidth() const { return RequiredVectorWidth; } diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp index b2551b64eb0d..8446ee9f4e03 100644 --- a/llvm/lib/Target/X86/X86TargetMachine.cpp +++ b/llvm/lib/Target/X86/X86TargetMachine.cpp @@ -83,6 +83,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86Target() { initializeX86SpeculativeLoadHardeningPassPass(PR); initializeX86FlagsCopyLoweringPassPass(PR); initializeX86CondBrFoldingPassPass(PR); + initializeX86LoadValueInjectionLoadHardeningPassPass(PR); initializeX86LoadValueInjectionRetHardeningPassPass(PR); initializeX86OptimizeLEAPassPass(PR); initializeX86PartialReductionPass(PR); @@ -494,6 +495,7 @@ void X86PassConfig::addMachineSSAOptimization() { void X86PassConfig::addPostRegAlloc() { addPass(createX86FloatingPointStackifierPass()); + addPass(createX86LoadValueInjectionLoadHardeningPass()); } void X86PassConfig::addPreSched2() { addPass(createX86ExpandPseudoPass()); } diff --git a/llvm/test/CodeGen/X86/O0-pipeline.ll b/llvm/test/CodeGen/X86/O0-pipeline.ll index 9af81b77a70b..6b6fed0c7f20 100644 --- a/llvm/test/CodeGen/X86/O0-pipeline.ll +++ b/llvm/test/CodeGen/X86/O0-pipeline.ll @@ -55,6 +55,10 @@ ; CHECK-NEXT: Fast Register Allocator ; CHECK-NEXT: Bundle Machine CFG Edges ; CHECK-NEXT: X86 FP Stackifier +; CHECK-NEXT: MachineDominator Tree Construction +; CHECK-NEXT: Machine Natural Loop Construction +; CHECK-NEXT: Machine Dominance Frontier Construction +; CHECK-NEXT: X86 Load Value Injection (LVI) Load Hardening ; CHECK-NEXT: Lazy Machine Block Frequency Analysis ; CHECK-NEXT: Machine Optimization Remark Emitter ; CHECK-NEXT: Prologue/Epilogue Insertion & Frame Finalization diff --git a/llvm/test/CodeGen/X86/O3-pipeline.ll b/llvm/test/CodeGen/X86/O3-pipeline.ll index 97ce5082d4f7..92b2b818743b 100644 --- a/llvm/test/CodeGen/X86/O3-pipeline.ll +++ b/llvm/test/CodeGen/X86/O3-pipeline.ll @@ -139,9 +139,11 @@ ; CHECK-NEXT: Machine Loop Invariant Code Motion ; CHECK-NEXT: Bundle Machine CFG Edges ; CHECK-NEXT: X86 FP Stackifier +; CHECK-NEXT: MachineDominator Tree Construction +; CHECK-NEXT: Machine Dominance Frontier Construction +; CHECK-NEXT: X86 Load Value Injection (LVI) Load Hardening ; CHECK-NEXT: PostRA Machine Sink ; CHECK-NEXT: Machine Block Frequency Analysis -; CHECK-NEXT: MachineDominator Tree Construction ; CHECK-NEXT: MachinePostDominator Tree Construction ; CHECK-NEXT: Lazy Machine Block Frequency Analysis ; CHECK-NEXT: Machine Optimization Remark Emitter diff --git a/llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll b/llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll new file mode 100644 index 000000000000..ba2ce26142b5 --- /dev/null +++ b/llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll @@ -0,0 +1,129 @@ +; RUN: llc -verify-machineinstrs -mtriple=x86_64-unknown -x86-lvi-load-dot-verify -o %t < %s | FileCheck %s + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i32 @test(i32* %untrusted_user_ptr, i32* %secret, i32 %secret_size) #0 { +entry: + %untrusted_user_ptr.addr = alloca i32*, align 8 + %secret.addr = alloca i32*, align 8 + %secret_size.addr = alloca i32, align 4 + %ret_val = alloca i32, align 4 + %i = alloca i32, align 4 + store i32* %untrusted_user_ptr, i32** %untrusted_user_ptr.addr, align 8 + store i32* %secret, i32** %secret.addr, align 8 + store i32 %secret_size, i32* %secret_size.addr, align 4 + store i32 0, i32* %ret_val, align 4 + call void @llvm.x86.sse2.lfence() + store i32 0, i32* %i, align 4 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %0 = load i32, i32* %i, align 4 + %1 = load i32, i32* %secret_size.addr, align 4 + %cmp = icmp slt i32 %0, %1 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + %2 = load i32, i32* %i, align 4 + %rem = srem i32 %2, 2 + %cmp1 = icmp eq i32 %rem, 0 + br i1 %cmp1, label %if.then, label %if.else + +if.then: ; preds = %for.body + %3 = load i32*, i32** %secret.addr, align 8 + %4 = load i32, i32* %ret_val, align 4 + %idxprom = sext i32 %4 to i64 + %arrayidx = getelementptr inbounds i32, i32* %3, i64 %idxprom + %5 = load i32, i32* %arrayidx, align 4 + %6 = load i32*, i32** %untrusted_user_ptr.addr, align 8 + store i32 %5, i32* %6, align 4 + br label %if.end + +if.else: ; preds = %for.body + %7 = load i32*, i32** %secret.addr, align 8 + %8 = load i32, i32* %ret_val, align 4 + %idxprom2 = sext i32 %8 to i64 + %arrayidx3 = getelementptr inbounds i32, i32* %7, i64 %idxprom2 + store i32 42, i32* %arrayidx3, align 4 + br label %if.end + +if.end: ; preds = %if.else, %if.then + %9 = load i32*, i32** %untrusted_user_ptr.addr, align 8 + %10 = load i32, i32* %9, align 4 + store i32 %10, i32* %ret_val, align 4 + br label %for.inc + +for.inc: ; preds = %if.end + %11 = load i32, i32* %i, align 4 + %inc = add nsw i32 %11, 1 + store i32 %inc, i32* %i, align 4 + br label %for.cond + +for.end: ; preds = %for.cond + %12 = load i32, i32* %ret_val, align 4 + ret i32 %12 +} + +; CHECK: digraph "Speculative gadgets for \"test\" function" { +; CHECK-NEXT: label="Speculative gadgets for \"test\" function"; +; CHECK: Node0x{{[0-9a-f]+}} [shape=record,color = green,label="{LFENCE\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 0]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $eax = MOV32rm %stack.4.i, 1, $noreg, 0, $noreg :: (dereferenceable load 4 from %ir.i)\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{JCC_1 %bb.6, 13, implicit killed $eflags\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{CMP32rm killed renamable $eax, %stack.2.secret_size.addr, 1, $noreg, 0, $noreg, implicit-def $eflags :: (dereferenceable load 4 from %ir.secret_size.addr)\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $eax = MOV32rm %stack.4.i, 1, $noreg, 0, $noreg :: (dereferenceable load 4 from %ir.i)\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{JCC_1 %bb.4, 5, implicit killed $eflags\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $rax = MOV64rm %stack.1.secret.addr, 1, $noreg, 0, $noreg :: (dereferenceable load 8 from %ir.secret.addr)\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $eax = MOV32rm killed renamable $rax, 4, killed renamable $rcx, 0, $noreg :: (load 4 from %ir.arrayidx)\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $rcx = MOVSX64rm32 %stack.3.ret_val, 1, $noreg, 0, $noreg :: (dereferenceable load 4 from %ir.ret_val)\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $rcx = MOV64rm %stack.0.untrusted_user_ptr.addr, 1, $noreg, 0, $noreg :: (dereferenceable load 8 from %ir.untrusted_user_ptr.addr)\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{MOV32mr killed renamable $rcx, 1, $noreg, 0, $noreg, killed renamable $eax :: (store 4 into %ir.6)\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $rax = MOV64rm %stack.1.secret.addr, 1, $noreg, 0, $noreg :: (dereferenceable load 8 from %ir.secret.addr)\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{MOV32mi killed renamable $rax, 4, killed renamable $rcx, 0, $noreg, 42 :: (store 4 into %ir.arrayidx3)\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $rcx = MOVSX64rm32 %stack.3.ret_val, 1, $noreg, 0, $noreg :: (dereferenceable load 4 from %ir.ret_val)\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $rax = MOV64rm %stack.0.untrusted_user_ptr.addr, 1, $noreg, 0, $noreg :: (dereferenceable load 8 from %ir.untrusted_user_ptr.addr)\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $eax = MOV32rm killed renamable $rax, 1, $noreg, 0, $noreg :: (load 4 from %ir.9)\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,color = blue,label="{ARGS}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 0]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{MOV64mr %stack.0.untrusted_user_ptr.addr, 1, $noreg, 0, $noreg, killed renamable $rdi :: (store 8 into %ir.untrusted_user_ptr.addr)\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 0]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{JMP_1 %bb.5\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{JMP_1 %bb.1\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $eax = MOV32rm %stack.3.ret_val, 1, $noreg, 0, $noreg :: (dereferenceable load 4 from %ir.ret_val)\n}"]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 0]; +; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{RET 0, $eax\n}"]; +; CHECK-NEXT: } + +; Function Attrs: nounwind +declare void @llvm.x86.sse2.lfence() #1 + +attributes #0 = { "target-features"="+lvi-cfi" + "target-features"="+lvi-load-hardening" } +attributes #1 = { nounwind } From cfe-commits at lists.llvm.org Fri Apr 3 13:03:29 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 20:03:29 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: <4dfc73bc74ae272fdac1f97b3b4d7a81@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rGc74dd640fd74: [X86] Add a Pass that builds a Condensed CFG for Load Value Injection (LVI)… (authored by sconstab, committed by craig.topper). Herald added a project: clang. Changed prior to commit: https://reviews.llvm.org/D75936?vs=251242&id=254896#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 Files: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Arch/X86.cpp clang/test/Driver/x86-target-features.c llvm/lib/Target/X86/CMakeLists.txt llvm/lib/Target/X86/ImmutableGraph.h llvm/lib/Target/X86/X86.h llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp llvm/lib/Target/X86/X86Subtarget.h llvm/lib/Target/X86/X86TargetMachine.cpp llvm/test/CodeGen/X86/O0-pipeline.ll llvm/test/CodeGen/X86/O3-pipeline.ll llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D75936.254896.patch Type: text/x-patch Size: 56606 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 13:27:59 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via cfe-commits) Date: Fri, 03 Apr 2020 13:27:59 -0700 (PDT) Subject: [clang-tools-extra] ba1ffd2 - [OpenMP][NFC] Remove the need to include `OpenMPClause.h` Message-ID: <5e879c4f.1c69fb81.4a149.e757@mx.google.com> Author: Reid Kleckner Date: 2020-04-03T13:27:52-07:00 New Revision: ba1ffd25c1f7a3564136b13e49fb1a7185561613 URL: https://github.com/llvm/llvm-project/commit/ba1ffd25c1f7a3564136b13e49fb1a7185561613 DIFF: https://github.com/llvm/llvm-project/commit/ba1ffd25c1f7a3564136b13e49fb1a7185561613.diff LOG: [OpenMP][NFC] Remove the need to include `OpenMPClause.h` See rational here: https://reviews.llvm.org/D76173#1922916 Time to compile Attr.h in isolation goes from 2.6s to 1.8s. Original patch by Johannes, plus some additions from Reid to fix some clang tooling targets. Effect on transitive includes is marginal, though: $ diff -u <(sort thedeps-before.txt) <(sort thedeps-after.txt) \ | grep '^[-+] ' | sort | uniq -c | sort -nr 104 - /usr/local/google/home/rnk/llvm-project/clang/include/clang/AST/OpenMPClause.h 87 - /usr/local/google/home/rnk/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPContext.h 19 - /usr/local/google/home/rnk/llvm-project/llvm/include/llvm/ADT/SmallSet.h 19 - /usr/local/google/home/rnk/llvm-project/llvm/include/llvm/ADT/SetVector.h 14 - /usr/include/c++/9/set ... Differential Revision: https://reviews.llvm.org/D76184 Added: Modified: clang-tools-extra/clangd/XRefs.cpp clang/include/clang/AST/Attr.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/Basic/OpenMPKinds.h clang/include/clang/Parse/Parser.h clang/include/clang/Sema/Sema.h clang/lib/AST/AttrImpl.cpp clang/lib/AST/OpenMPClause.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/Tooling/Transformer/SourceCode.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp index 3bf8d0e818e8..2e2e6602c8d3 100644 --- a/clang-tools-extra/clangd/XRefs.cpp +++ b/clang-tools-extra/clangd/XRefs.cpp @@ -43,6 +43,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/None.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index 5f6035cb0c28..1b457337d658 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -16,10 +16,10 @@ #include "clang/AST/ASTFwd.h" #include "clang/AST/AttrIterator.h" #include "clang/AST/Decl.h" -#include "clang/AST/OpenMPClause.h" #include "clang/AST/Type.h" #include "clang/Basic/AttrKinds.h" #include "clang/Basic/AttributeCommonInfo.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/Sanitizers.h" @@ -40,6 +40,7 @@ class Expr; class QualType; class FunctionDecl; class TypeSourceInfo; +class OMPTraitInfo; /// Attr - This represents one attribute. class Attr : public AttributeCommonInfo { diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 028af6ac9a72..efa6d0554a7c 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -5249,19 +5249,14 @@ class OMPMapClause final : public OMPMappableExprListClause, return getUniqueDeclarationsNum() + getTotalComponentListNum(); } -public: - /// Number of allowed map-type-modifiers. - static constexpr unsigned NumberOfModifiers = - OMPC_MAP_MODIFIER_last - OMPC_MAP_MODIFIER_unknown - 1; - private: /// Map-type-modifiers for the 'map' clause. - OpenMPMapModifierKind MapTypeModifiers[NumberOfModifiers] = { + OpenMPMapModifierKind MapTypeModifiers[NumberOfOMPMapClauseModifiers] = { OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown}; /// Location of map-type-modifiers for the 'map' clause. - SourceLocation MapTypeModifiersLoc[NumberOfModifiers]; + SourceLocation MapTypeModifiersLoc[NumberOfOMPMapClauseModifiers]; /// Map type for the 'map' clause. OpenMPMapClauseKind MapType = OMPC_MAP_unknown; @@ -5330,7 +5325,7 @@ class OMPMapClause final : public OMPMappableExprListClause, /// \param I index for map-type-modifier. /// \param T map-type-modifier for the clause. void setMapTypeModifier(unsigned I, OpenMPMapModifierKind T) { - assert(I < NumberOfModifiers && + assert(I < NumberOfOMPMapClauseModifiers && "Unexpected index to store map type modifier, exceeds array size."); MapTypeModifiers[I] = T; } @@ -5340,7 +5335,7 @@ class OMPMapClause final : public OMPMappableExprListClause, /// \param I index for map-type-modifier location. /// \param TLoc map-type-modifier location. void setMapTypeModifierLoc(unsigned I, SourceLocation TLoc) { - assert(I < NumberOfModifiers && + assert(I < NumberOfOMPMapClauseModifiers && "Index to store map type modifier location exceeds array size."); MapTypeModifiersLoc[I] = TLoc; } @@ -5415,7 +5410,7 @@ class OMPMapClause final : public OMPMappableExprListClause, /// /// \param Cnt index for map-type-modifier. OpenMPMapModifierKind getMapTypeModifier(unsigned Cnt) const LLVM_READONLY { - assert(Cnt < NumberOfModifiers && + assert(Cnt < NumberOfOMPMapClauseModifiers && "Requested modifier exceeds the total number of modifiers."); return MapTypeModifiers[Cnt]; } @@ -5425,7 +5420,7 @@ class OMPMapClause final : public OMPMappableExprListClause, /// /// \param Cnt index for map-type-modifier location. SourceLocation getMapTypeModifierLoc(unsigned Cnt) const LLVM_READONLY { - assert(Cnt < NumberOfModifiers && + assert(Cnt < NumberOfOMPMapClauseModifiers && "Requested modifier location exceeds total number of modifiers."); return MapTypeModifiersLoc[Cnt]; } @@ -7144,6 +7139,19 @@ class OMPClausePrinter final : public OMPClauseVisitor { #include "clang/Basic/OpenMPKinds.def" }; +struct OMPTraitProperty { + llvm::omp::TraitProperty Kind = llvm::omp::TraitProperty::invalid; +}; +struct OMPTraitSelector { + Expr *ScoreOrCondition = nullptr; + llvm::omp::TraitSelector Kind = llvm::omp::TraitSelector::invalid; + llvm::SmallVector Properties; +}; +struct OMPTraitSet { + llvm::omp::TraitSet Kind = llvm::omp::TraitSet::invalid; + llvm::SmallVector Selectors; +}; + /// Helper data structure representing the traits in a match clause of an /// `declare variant` or `metadirective`. The outer level is an ordered /// collection of selector sets, each with an associated kind and an ordered @@ -7158,27 +7166,14 @@ class OMPTraitInfo { /// Reconstruct a (partial) OMPTraitInfo object from a mangled name. OMPTraitInfo(StringRef MangledName); - struct OMPTraitProperty { - llvm::omp::TraitProperty Kind = llvm::omp::TraitProperty::invalid; - }; - struct OMPTraitSelector { - Expr *ScoreOrCondition = nullptr; - llvm::omp::TraitSelector Kind = llvm::omp::TraitSelector::invalid; - llvm::SmallVector Properties; - }; - struct OMPTraitSet { - llvm::omp::TraitSet Kind = llvm::omp::TraitSet::invalid; - llvm::SmallVector Selectors; - }; - /// The outermost level of selector sets. llvm::SmallVector Sets; bool anyScoreOrCondition( llvm::function_ref Cond) { - return llvm::any_of(Sets, [&](OMPTraitInfo::OMPTraitSet &Set) { + return llvm::any_of(Sets, [&](OMPTraitSet &Set) { return llvm::any_of( - Set.Selectors, [&](OMPTraitInfo::OMPTraitSelector &Selector) { + Set.Selectors, [&](OMPTraitSelector &Selector) { return Cond(Selector.ScoreOrCondition, /* IsScore */ Selector.Kind != llvm::omp::TraitSelector::user_condition); diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index b567f89b986e..f12b5545d0c1 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -91,6 +91,10 @@ enum OpenMPMapModifierKind { OMPC_MAP_MODIFIER_last }; + /// Number of allowed map-type-modifiers. +static constexpr unsigned NumberOfOMPMapClauseModifiers = + OMPC_MAP_MODIFIER_last - OMPC_MAP_MODIFIER_unknown - 1; + /// OpenMP modifier kind for 'to' clause. enum OpenMPToModifierKind { #define OPENMP_TO_MODIFIER_KIND(Name) \ diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index ca0a5fd68994..71d216bfb260 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -13,7 +13,6 @@ #ifndef LLVM_CLANG_PARSE_PARSER_H #define LLVM_CLANG_PARSE_PARSER_H -#include "clang/AST/OpenMPClause.h" #include "clang/AST/Availability.h" #include "clang/Basic/BitmaskEnum.h" #include "clang/Basic/OpenMPKinds.h" @@ -24,6 +23,7 @@ #include "clang/Sema/DeclSpec.h" #include "clang/Sema/Sema.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Frontend/OpenMP/OMPContext.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/SaveAndRestore.h" @@ -49,6 +49,10 @@ namespace clang { class OMPClause; class ObjCTypeParamList; class ObjCTypeParameter; + struct OMPTraitProperty; + struct OMPTraitSelector; + struct OMPTraitSet; + class OMPTraitInfo; /// Parser - This implements a parser for the C family of languages. After /// parsing units of the grammar, productions are invoked to handle whatever has @@ -2936,32 +2940,32 @@ class Parser : public CodeCompletionHandler { /// Parse a property kind into \p TIProperty for the selector set \p Set and /// selector \p Selector. - void parseOMPTraitPropertyKind(OMPTraitInfo::OMPTraitProperty &TIProperty, + void parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty, llvm::omp::TraitSet Set, llvm::omp::TraitSelector Selector, llvm::StringMap &Seen); /// Parse a selector kind into \p TISelector for the selector set \p Set. - void parseOMPTraitSelectorKind(OMPTraitInfo::OMPTraitSelector &TISelector, + void parseOMPTraitSelectorKind(OMPTraitSelector &TISelector, llvm::omp::TraitSet Set, llvm::StringMap &Seen); /// Parse a selector set kind into \p TISet. - void parseOMPTraitSetKind(OMPTraitInfo::OMPTraitSet &TISet, + void parseOMPTraitSetKind(OMPTraitSet &TISet, llvm::StringMap &Seen); /// Parses an OpenMP context property. - void parseOMPContextProperty(OMPTraitInfo::OMPTraitSelector &TISelector, + void parseOMPContextProperty(OMPTraitSelector &TISelector, llvm::omp::TraitSet Set, llvm::StringMap &Seen); /// Parses an OpenMP context selector. - void parseOMPContextSelector(OMPTraitInfo::OMPTraitSelector &TISelector, + void parseOMPContextSelector(OMPTraitSelector &TISelector, llvm::omp::TraitSet Set, llvm::StringMap &SeenSelectors); /// Parses an OpenMP context selector set. - void parseOMPContextSelectorSet(OMPTraitInfo::OMPTraitSet &TISet, + void parseOMPContextSelectorSet(OMPTraitSet &TISet, llvm::StringMap &SeenSets); /// Parses OpenMP context selectors. @@ -3107,9 +3111,9 @@ class Parser : public CodeCompletionHandler { DeclarationNameInfo ReductionOrMapperId; int ExtraModifier = -1; ///< Additional modifier for linear, map, depend or ///< lastprivate clause. - SmallVector + SmallVector MapTypeModifiers; - SmallVector + SmallVector MapTypeModifiersLoc; bool IsMapTypeImplicit = false; SourceLocation ExtraModifierLoc; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index e1365e84a0b3..7c689c2a13e8 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -58,6 +58,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallBitVector.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/TinyPtrVector.h" @@ -9861,8 +9862,7 @@ class Sema final { /// The associated OpenMP context selector mangling. std::string NameSuffix; - OMPDeclareVariantScope(OMPTraitInfo &TI) - : TI(&TI), NameSuffix(TI.getMangledName()) {} + OMPDeclareVariantScope(OMPTraitInfo &TI); }; /// The current `omp begin/end declare variant` scopes. diff --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp index a5ff68c18778..bc0db1ba10a2 100644 --- a/clang/lib/AST/AttrImpl.cpp +++ b/clang/lib/AST/AttrImpl.cpp @@ -151,6 +151,11 @@ OMPDeclareTargetDeclAttr::getDeviceType(const ValueDecl *VD) { return llvm::None; } +namespace clang { +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo &TI); +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo *TI); +} + void OMPDeclareVariantAttr::printPrettyPragma( raw_ostream &OS, const PrintingPolicy &Policy) const { if (const Expr *E = getVariantFuncRef()) { @@ -158,9 +163,7 @@ void OMPDeclareVariantAttr::printPrettyPragma( E->printPretty(OS, nullptr, Policy); OS << ")"; } - OS << " match("; - traitInfos->print(OS, Policy); - OS << ")"; + OS << " match(" << traitInfos << ")"; } #include "clang/AST/AttrImpl.inc" diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index eeb690750fb7..a205a1bca1b9 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -1754,7 +1754,7 @@ void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) { if (!Node->varlist_empty()) { OS << "map("; if (Node->getMapType() != OMPC_MAP_unknown) { - for (unsigned I = 0; I < OMPMapClause::NumberOfModifiers; ++I) { + for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) { if (Node->getMapTypeModifier(I) != OMPC_MAP_MODIFIER_unknown) { OS << getOpenMPSimpleClauseTypeName(OMPC_map, Node->getMapTypeModifier(I)); @@ -1934,14 +1934,14 @@ void OMPTraitInfo::getAsVariantMatchInfo(ASTContext &ASTCtx, void OMPTraitInfo::print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const { bool FirstSet = true; - for (const OMPTraitInfo::OMPTraitSet &Set : Sets) { + for (const OMPTraitSet &Set : Sets) { if (!FirstSet) OS << ", "; FirstSet = false; OS << getOpenMPContextTraitSetName(Set.Kind) << "={"; bool FirstSelector = true; - for (const OMPTraitInfo::OMPTraitSelector &Selector : Set.Selectors) { + for (const OMPTraitSelector &Selector : Set.Selectors) { if (!FirstSelector) OS << ", "; FirstSelector = false; @@ -1967,8 +1967,7 @@ void OMPTraitInfo::print(llvm::raw_ostream &OS, } bool FirstProperty = true; - for (const OMPTraitInfo::OMPTraitProperty &Property : - Selector.Properties) { + for (const OMPTraitProperty &Property : Selector.Properties) { if (!FirstProperty) OS << ", "; FirstProperty = false; @@ -1984,9 +1983,9 @@ void OMPTraitInfo::print(llvm::raw_ostream &OS, std::string OMPTraitInfo::getMangledName() const { std::string MangledName; llvm::raw_string_ostream OS(MangledName); - for (const OMPTraitInfo::OMPTraitSet &Set : Sets) { + for (const OMPTraitSet &Set : Sets) { OS << '.' << 'S' << unsigned(Set.Kind); - for (const OMPTraitInfo::OMPTraitSelector &Selector : Set.Selectors) { + for (const OMPTraitSelector &Selector : Set.Selectors) { bool AllowsTraitScore = false; bool RequiresProperty = false; @@ -1998,7 +1997,7 @@ std::string OMPTraitInfo::getMangledName() const { Selector.Kind == TraitSelector::user_condition) continue; - for (const OMPTraitInfo::OMPTraitProperty &Property : Selector.Properties) + for (const OMPTraitProperty &Property : Selector.Properties) OS << '.' << 'P' << getOpenMPContextTraitPropertyName(Property.Kind); } diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 1f5ed3d9c999..4bec5f557ab8 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "clang/AST/ASTContext.h" +#include "clang/AST/OpenMPClause.h" #include "clang/AST/StmtOpenMP.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/TargetInfo.h" @@ -865,7 +866,7 @@ static bool checkForDuplicates(Parser &P, StringRef Name, } // namespace void Parser::parseOMPTraitPropertyKind( - OMPTraitInfo::OMPTraitProperty &TIProperty, llvm::omp::TraitSet Set, + OMPTraitProperty &TIProperty, llvm::omp::TraitSet Set, llvm::omp::TraitSelector Selector, llvm::StringMap &Seen) { TIProperty.Kind = TraitProperty::invalid; @@ -934,14 +935,14 @@ void Parser::parseOMPTraitPropertyKind( << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector); } -void Parser::parseOMPContextProperty(OMPTraitInfo::OMPTraitSelector &TISelector, +void Parser::parseOMPContextProperty(OMPTraitSelector &TISelector, llvm::omp::TraitSet Set, llvm::StringMap &Seen) { assert(TISelector.Kind != TraitSelector::user_condition && "User conditions are special properties not handled here!"); SourceLocation PropertyLoc = Tok.getLocation(); - OMPTraitInfo::OMPTraitProperty TIProperty; + OMPTraitProperty TIProperty; parseOMPTraitPropertyKind(TIProperty, Set, TISelector.Kind, Seen); // If we have an invalid property here we already issued a warning. @@ -975,7 +976,7 @@ void Parser::parseOMPContextProperty(OMPTraitInfo::OMPTraitSelector &TISelector, } void Parser::parseOMPTraitSelectorKind( - OMPTraitInfo::OMPTraitSelector &TISelector, llvm::omp::TraitSet Set, + OMPTraitSelector &TISelector, llvm::omp::TraitSet Set, llvm::StringMap &Seen) { TISelector.Kind = TraitSelector::invalid; @@ -1054,7 +1055,7 @@ static ExprResult parseContextScore(Parser &P) { /// /// ['('[] [, ]* ')'] void Parser::parseOMPContextSelector( - OMPTraitInfo::OMPTraitSelector &TISelector, llvm::omp::TraitSet Set, + OMPTraitSelector &TISelector, llvm::omp::TraitSet Set, llvm::StringMap &SeenSelectors) { unsigned short OuterPC = ParenCount; @@ -1160,7 +1161,7 @@ void Parser::parseOMPContextSelector( BDT.consumeClose(); } -void Parser::parseOMPTraitSetKind(OMPTraitInfo::OMPTraitSet &TISet, +void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet, llvm::StringMap &Seen) { TISet.Kind = TraitSet::invalid; @@ -1224,7 +1225,7 @@ void Parser::parseOMPTraitSetKind(OMPTraitInfo::OMPTraitSet &TISet, /// /// '=' '{' [, ]* '}' void Parser::parseOMPContextSelectorSet( - OMPTraitInfo::OMPTraitSet &TISet, + OMPTraitSet &TISet, llvm::StringMap &SeenSets) { auto OuterBC = BraceCount; @@ -1279,7 +1280,7 @@ void Parser::parseOMPContextSelectorSet( llvm::StringMap SeenSelectors; do { - OMPTraitInfo::OMPTraitSelector TISelector; + OMPTraitSelector TISelector; parseOMPContextSelector(TISelector, TISet.Kind, SeenSelectors); if (TISelector.Kind != TraitSelector::invalid && !TISelector.Properties.empty()) @@ -1301,10 +1302,10 @@ void Parser::parseOMPContextSelectorSet( /// Parse OpenMP context selectors: /// /// [, ]* -bool Parser::parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI) { +bool Parser::parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo& TI) { llvm::StringMap SeenSets; do { - OMPTraitInfo::OMPTraitSet TISet; + OMPTraitSet TISet; parseOMPContextSelectorSet(TISet, SeenSets); if (TISet.Kind != TraitSet::invalid && !TISet.Selectors.empty()) TI.Sets.push_back(TISet); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index df56c3be43fc..f663b1d43659 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -35,6 +35,8 @@ #include "llvm/ADT/PointerEmbeddedInt.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Frontend/OpenMP/OMPConstants.h" +#include + using namespace clang; using namespace llvm::omp; @@ -5543,6 +5545,9 @@ static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, FD->setParams(Params); } +Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) + : TI(&TI), NameSuffix(TI.getMangledName()) {} + FunctionDecl * Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, Declarator &D) { @@ -17054,7 +17059,7 @@ OMPClause *Sema::ActOnOpenMPMapClause( OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown}; - SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; + SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; // Process map-type-modifiers, flag errors for duplicate modifiers. unsigned Count = 0; @@ -17064,7 +17069,7 @@ OMPClause *Sema::ActOnOpenMPMapClause( Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); continue; } - assert(Count < OMPMapClause::NumberOfModifiers && + assert(Count < NumberOfOMPMapClauseModifiers && "Modifiers exceed the allowed number of map type modifiers"); Modifiers[Count] = MapTypeModifiers[I]; ModifiersLoc[Count] = MapTypeModifiersLoc[I]; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 74bb1c7f87dc..7d84f1108c85 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -12335,7 +12335,7 @@ void OMPClauseReader::VisitOMPDeviceClause(OMPDeviceClause *C) { void OMPClauseReader::VisitOMPMapClause(OMPMapClause *C) { C->setLParenLoc(Record.readSourceLocation()); - for (unsigned I = 0; I < OMPMapClause::NumberOfModifiers; ++I) { + for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) { C->setMapTypeModifier( I, static_cast(Record.readInt())); C->setMapTypeModifierLoc(I, Record.readSourceLocation()); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 27f44a706f9f..89ba7e623965 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6403,7 +6403,7 @@ void OMPClauseWriter::VisitOMPMapClause(OMPMapClause *C) { Record.push_back(C->getTotalComponentListNum()); Record.push_back(C->getTotalComponentsNum()); Record.AddSourceLocation(C->getLParenLoc()); - for (unsigned I = 0; I < OMPMapClause::NumberOfModifiers; ++I) { + for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) { Record.push_back(C->getMapTypeModifier(I)); Record.AddSourceLocation(C->getMapTypeModifierLoc(I)); } diff --git a/clang/lib/Tooling/Transformer/SourceCode.cpp b/clang/lib/Tooling/Transformer/SourceCode.cpp index 38b331b0a1c3..0530b3fa0e95 100644 --- a/clang/lib/Tooling/Transformer/SourceCode.cpp +++ b/clang/lib/Tooling/Transformer/SourceCode.cpp @@ -20,6 +20,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" #include "llvm/Support/Errc.h" +#include using namespace clang; From cfe-commits at lists.llvm.org Fri Apr 3 13:33:51 2020 From: cfe-commits at lists.llvm.org (Aaron Ballman via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 20:33:51 +0000 (UTC) Subject: [PATCH] D77085: [clang-tidy] Added support for validating configuration options In-Reply-To: References: Message-ID: aaron.ballman added inline comments. ================ Comment at: clang-tools-extra/clang-tidy/ClangTidyCheck.cpp:25 + llvm::raw_svector_ostream Output(Buffer); + Output << "warning: Option not found '" << OptionName << "'\n"; + return std::string(Buffer); ---------------- aaron.ballman wrote: > I think the diagnostic text should probably not start with a capital letter. Also, the name of the classes are confusing in that they say error but the diagnostic is a warning. When I hear "error", the class name makes me think this would stop compilation and give a nonzero result code from the program. Sorry, I was unclear with what I was looking for. It looks to me like the behavior of `OptionError` is to act more like a warning than an error in that a message is printed and execution of the tool continues, correct? If so, then I'd prefer to rename it to `OptionWarning` (unless you want to generalize it to be either a warning or an error with a return code, then `OptionDiagnostic` would be good), and all the subclasses to be `FooWarning`. Or did I misunderstand the design? Also, I like having the `warning:` in the message (though we could bikeshed if we want to make it look less like a check warning by doing something like `warning [clang-tidy command line]:`), but maybe that's being added by `OptionsView::logErrToStdErr()`? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77085/new/ https://reviews.llvm.org/D77085 From cfe-commits at lists.llvm.org Fri Apr 3 13:33:54 2020 From: cfe-commits at lists.llvm.org (Mike Rice via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 20:33:54 +0000 (UTC) Subject: [PATCH] D77290: [OpenMP] Specialize OpenMP calls after template instantiation In-Reply-To: References: Message-ID: mikerice added inline comments. ================ Comment at: clang/lib/Sema/SemaTemplateInstantiate.cpp:1698 + auto *CE = cast(R.get()); + return SemaRef.ActOnOpenMPCall(R, nullptr, CE->getRParenLoc(), + MultiExprArg(CE->getArgs(), CE->getNumArgs()), ---------------- Is there a parent change that removed the Sema& parameter from this function? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77290/new/ https://reviews.llvm.org/D77290 From cfe-commits at lists.llvm.org Fri Apr 3 13:34:01 2020 From: cfe-commits at lists.llvm.org (Hubert Tong via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 20:34:01 +0000 (UTC) Subject: [PATCH] D76572: Replace `T(x)` with `reinterpret_cast(x)` everywhere it means reinterpret_cast. No functional change In-Reply-To: References: Message-ID: hubert.reinterpretcast added a comment. I am guessing @DiggerLin was pinged with regards to `XCOFFObjectFile.cpp`. @jhenderson already reviewed and approved the changes to that file (it falls under libObject). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76572/new/ https://reviews.llvm.org/D76572 From cfe-commits at lists.llvm.org Fri Apr 3 13:34:44 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 20:34:44 +0000 (UTC) Subject: [PATCH] D76184: [OpenMP][NFC] Remove the need to include `OpenMPClause.h` In-Reply-To: References: Message-ID: This revision was not accepted when it landed; it landed in state "Needs Review". This revision was automatically updated to reflect the committed changes. Closed by commit rGba1ffd25c1f7: [OpenMP][NFC] Remove the need to include `OpenMPClause.h` (authored by rnk). Changed prior to commit: https://reviews.llvm.org/D76184?vs=254889&id=254904#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76184/new/ https://reviews.llvm.org/D76184 Files: clang-tools-extra/clangd/XRefs.cpp clang/include/clang/AST/Attr.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/Basic/OpenMPKinds.h clang/include/clang/Parse/Parser.h clang/include/clang/Sema/Sema.h clang/lib/AST/AttrImpl.cpp clang/lib/AST/OpenMPClause.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/Tooling/Transformer/SourceCode.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76184.254904.patch Type: text/x-patch Size: 20899 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 14:05:57 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 21:05:57 +0000 (UTC) Subject: [PATCH] D77290: [OpenMP] Specialize OpenMP calls after template instantiation In-Reply-To: References: Message-ID: <5e172b7e219bc8da29d7666de87c3a56@localhost.localdomain> jdoerfert marked an inline comment as done. jdoerfert added inline comments. ================ Comment at: clang/lib/Sema/SemaTemplateInstantiate.cpp:1698 + auto *CE = cast(R.get()); + return SemaRef.ActOnOpenMPCall(R, nullptr, CE->getRParenLoc(), + MultiExprArg(CE->getArgs(), CE->getNumArgs()), ---------------- mikerice wrote: > Is there a parent change that removed the Sema& parameter from this function? Yes, locally. I was going to submit is as a NFC patch later today. The parameter was a leftover I simply forgot to remove when I made it a member. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77290/new/ https://reviews.llvm.org/D77290 From cfe-commits at lists.llvm.org Fri Apr 3 14:06:07 2020 From: cfe-commits at lists.llvm.org (Arthur O'Dwyer via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 21:06:07 +0000 (UTC) Subject: [PATCH] D76572: Replace `T(x)` with `reinterpret_cast(x)` everywhere it means reinterpret_cast. No functional change In-Reply-To: References: Message-ID: Quuxplusone added subscribers: kparzysz, Bigcheese. Quuxplusone added a comment. Ah. Then I'm not sure who else to ping, or even which pieces remain in need of review. CODE_OWNERS.TXT isn't being very helpful here... @kparzysz for HexagonCommonGEP.cpp ("Hexagon backend")? @Bigcheese for Binary.h ("Object")? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76572/new/ https://reviews.llvm.org/D76572 From cfe-commits at lists.llvm.org Fri Apr 3 14:09:03 2020 From: cfe-commits at lists.llvm.org (Scott Constable via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 21:09:03 +0000 (UTC) Subject: [PATCH] D77431: [X86] Add tests to clang Driver to ensure that SLH/Retpoline features are not enabled with LVI-hardening Message-ID: sconstab created this revision. sconstab added a reviewer: craig.topper. https://reviews.llvm.org/D77431 Files: clang/test/Driver/x86-target-features.c Index: clang/test/Driver/x86-target-features.c =================================================================== --- clang/test/Driver/x86-target-features.c +++ clang/test/Driver/x86-target-features.c @@ -164,6 +164,13 @@ // LVIHARDENING: "-target-feature" "+lvi-load-hardening" "-target-feature" "+lvi-cfi" // NO-LVIHARDENING-NOT: lvi +// RUN: %clang -target i386-linux-gnu -mlvi-hardening -mspeculative-load-hardening %s -### -o %t.o 2>&1 | FileCheck -check-prefix=LVIHARDENING-SLH %s +// LVIHARDENING-SLH: error: invalid argument 'mspeculative-load-hardening' not allowed with 'mlvi-hardening' +// RUN: %clang -target i386-linux-gnu -mlvi-hardening -mretpoline %s -### -o %t.o 2>&1 | FileCheck -check-prefix=LVIHARDENING-RETPOLINE %s +// LVIHARDENING-RETPOLINE: error: invalid argument 'mretpoline' not allowed with 'mlvi-hardening' +// RUN: %clang -target i386-linux-gnu -mlvi-hardening -mretpoline-external-thunk %s -### -o %t.o 2>&1 | FileCheck -check-prefix=LVIHARDENING-RETPOLINE-EXTERNAL-THUNK %s +// LVIHARDENING-RETPOLINE-EXTERNAL-THUNK: error: invalid argument 'mretpoline-external-thunk' not allowed with 'mlvi-hardening' + // RUN: %clang -target i386-linux-gnu -mwaitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=WAITPKG %s // RUN: %clang -target i386-linux-gnu -mno-waitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-WAITPKG %s // WAITPKG: "-target-feature" "+waitpkg" -------------- next part -------------- A non-text attachment was scrubbed... Name: D77431.254912.patch Type: text/x-patch Size: 1405 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 14:39:01 2020 From: cfe-commits at lists.llvm.org (Roman Lebedev via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 21:39:01 +0000 (UTC) Subject: [PATCH] D76572: Replace `T(x)` with `reinterpret_cast(x)` everywhere it means reinterpret_cast. No functional change In-Reply-To: References: Message-ID: lebedev.ri added a comment. All these changes are rather NFCI, i'm not sure each one needs to be reviewed. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76572/new/ https://reviews.llvm.org/D76572 From cfe-commits at lists.llvm.org Fri Apr 3 14:39:03 2020 From: cfe-commits at lists.llvm.org (Michael Spencer via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 21:39:03 +0000 (UTC) Subject: [PATCH] D76572: Replace `T(x)` with `reinterpret_cast(x)` everywhere it means reinterpret_cast. No functional change In-Reply-To: References: Message-ID: <8aae875ffe40ce76ed909dbca603cec2@localhost.localdomain> Bigcheese accepted this revision. Bigcheese added a comment. LGTM for llvm/{lib,include/llvm}/Object/* and llvm/tools/llvm-readobj/*. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76572/new/ https://reviews.llvm.org/D76572 From cfe-commits at lists.llvm.org Fri Apr 3 14:39:04 2020 From: cfe-commits at lists.llvm.org (Amy Huang via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 21:39:04 +0000 (UTC) Subject: [PATCH] D77432: [DebugInfo] Change to constructor homing debug info mode: skip literal types Message-ID: akhuang created this revision. akhuang added reviewers: rnk, dblaikie. Herald added subscribers: cfe-commits, aprantl. Herald added a project: clang. In constructor type homing mode sometimes complete debug info for constexpr types was missing, because there was not a constructor emitted. This change makes constructor type homing ignore constexpr types. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77432 Files: clang/lib/CodeGen/CGDebugInfo.cpp clang/test/CodeGenCXX/debug-info-limited-ctor.cpp Index: clang/test/CodeGenCXX/debug-info-limited-ctor.cpp =================================================================== --- clang/test/CodeGenCXX/debug-info-limited-ctor.cpp +++ clang/test/CodeGenCXX/debug-info-limited-ctor.cpp @@ -1,30 +1,26 @@ // RUN: %clang -cc1 -debug-info-kind=constructor -emit-llvm %s -o - | FileCheck %s -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "A" -// CHECK-NOT: DIFlagFwdDecl -// CHECK-SAME: ){{$}} -struct A {}; -void TestA() { A a; } +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "A"{{.*}}DIFlagTypePassByValue +struct A { +} TestA; -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "B" -// CHECK-SAME: flags: DIFlagFwdDecl +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "B"{{.*}}flags: DIFlagFwdDecl struct B { B(); -}; -void TestB() { B b; } +} TestB; -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "C" -// CHECK-NOT: flags: DIFlagFwdDecl -// CHECK-SAME: ){{$}} +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "C"{{.*}}DIFlagTypePassByValue struct C { C() {} -}; -void TestC() { C c; } +} TestC; -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "D" -// CHECK-NOT: flags: DIFlagFwdDecl -// CHECK-SAME: ){{$}} +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "D"{{.*}}DIFlagTypePassByValue struct D { D(); }; D::D() {} + +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "E"{{.*}}DIFlagTypePassByValue +struct E { + constexpr E(){}; +} TestE; Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -2260,12 +2260,11 @@ // constructor is emitted. Skip this optimization if the class or any of // its methods are marked dllimport. if (DebugKind == codegenoptions::DebugInfoConstructor && - !CXXDecl->isLambda() && !isClassOrMethodDLLImport(CXXDecl)) { - for (const auto *Ctor : CXXDecl->ctors()) { + !CXXDecl->isLambda() && !CXXDecl->isLiteral() && + !isClassOrMethodDLLImport(CXXDecl)) + for (const auto *Ctor : CXXDecl->ctors()) if (Ctor->isUserProvided()) return true; - } - } TemplateSpecializationKind Spec = TSK_Undeclared; if (const auto *SD = dyn_cast(RD)) -------------- next part -------------- A non-text attachment was scrubbed... Name: D77432.254916.patch Type: text/x-patch Size: 2483 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 14:39:08 2020 From: cfe-commits at lists.llvm.org (Atmn Patel via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 21:39:08 +0000 (UTC) Subject: [PATCH] D75591: [OpenMP] Add firstprivate as a default data-sharing attribute to clang In-Reply-To: References: Message-ID: atmnpatel updated this revision to Diff 254917. atmnpatel added a comment. Fixes clang-tidy check, and hopefully the other unrelated test failure too. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75591/new/ https://reviews.llvm.org/D75591 Files: clang-tools-extra/docs/clang-tidy/checks/openmp-use-default-none.rst clang-tools-extra/test/clang-tidy/checkers/openmp-use-default-none.cpp clang/docs/LibASTMatchersReference.html clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/ASTMatchers/Dynamic/Registry.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/test/OpenMP/distribute_parallel_for_default_messages.cpp clang/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp clang/test/OpenMP/driver.c clang/test/OpenMP/parallel_default_messages.cpp clang/test/OpenMP/parallel_for_default_messages.cpp clang/test/OpenMP/parallel_for_simd_default_messages.cpp clang/test/OpenMP/parallel_master_codegen.cpp clang/test/OpenMP/parallel_master_default_messages.cpp clang/test/OpenMP/parallel_sections_default_messages.cpp clang/test/OpenMP/target_parallel_default_messages.cpp clang/test/OpenMP/target_parallel_for_default_messages.cpp clang/test/OpenMP/target_parallel_for_simd_default_messages.cpp clang/test/OpenMP/target_teams_default_messages.cpp clang/test/OpenMP/target_teams_distribute_default_messages.cpp clang/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp clang/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp clang/test/OpenMP/task_default_messages.cpp clang/test/OpenMP/task_messages.cpp clang/test/OpenMP/teams_default_messages.cpp clang/test/OpenMP/teams_distribute_default_messages.cpp clang/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp clang/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp clang/test/OpenMP/teams_distribute_simd_default_messages.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp clang/unittests/ASTMatchers/ASTMatchersTest.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def -------------- next part -------------- A non-text attachment was scrubbed... Name: D75591.254917.patch Type: text/x-patch Size: 88690 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 14:39:10 2020 From: cfe-commits at lists.llvm.org (Pratyai Mazumder via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 21:39:10 +0000 (UTC) Subject: [PATCH] D77244: [part 1] sancov/inline-bool-flag instrumentation. In-Reply-To: References: Message-ID: <76821fe1701d088a33269af1ea996a7d@localhost.localdomain> pratyai updated this revision to Diff 254919. pratyai retitled this revision from "sancov/inline-bool-flag feature + tests + docs." to "[part 1] sancov/inline-bool-flag instrumentation.". pratyai added a comment. Herald added a project: LLVM. Dropped files from outside llvm/.../Instrumentation* as suggested. The clang flags & compiler-rt tests will be added in diffs. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77244/new/ https://reviews.llvm.org/D77244 Files: llvm/include/llvm/Transforms/Instrumentation.h llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp llvm/test/Instrumentation/SanitizerCoverage/coff-pc-table-inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/inline-bool-flag.ll llvm/test/Instrumentation/SanitizerCoverage/pc-table.ll llvm/test/Instrumentation/SanitizerCoverage/trace-pc-guard-inline-bool-flag.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D77244.254919.patch Type: text/x-patch Size: 12811 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 14:39:11 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 21:39:11 +0000 (UTC) Subject: [PATCH] D77028: [NFC] Refactor DeferredDiagsEmitter and skip redundant visit In-Reply-To: References: Message-ID: <20ff80148f02cf8c67037fafcbbfee7d@localhost.localdomain> rjmccall added inline comments. ================ Comment at: clang/lib/Sema/Sema.cpp:1508 void checkFunc(SourceLocation Loc, FunctionDecl *FD) { + auto DiagsCountIt = DiagsCount.find(FD); FunctionDecl *Caller = UseStack.empty() ? nullptr : UseStack.back(); ---------------- yaxunl wrote: > rjmccall wrote: > > yaxunl wrote: > > > rjmccall wrote: > > > > yaxunl wrote: > > > > > rjmccall wrote: > > > > > > It makes me a little uncomfortable to be holding an iterator this long while calling a fair amount of other stuff in the meantime. > > > > > > > > > > > > Your use of DiagsCount is subtle enough that it really needs to be explained in some comments. You're doing stuff conditionally based on both whether the entry exists but also whether it's non-zero. > > > > > added comments > > > > Okay, thanks for that. Two points, then. First, it looks like the count is really just a boolean for whether the function recursively triggers any diagnostics. And second, can't it just be as simple as whether we've visited that function at all in a context that's forcing diagnostics to be emitted? The logic seems to be to try to emit the diagnostics for each use-path, but why would we want that? > > > For the second comment, we need to visit a function again for each use-path because we need to report each use-path that triggers a diagnostic, otherwise users will see a new error after they fix one error, instead of seeing all the errors at once. > > > > > > For the first comment, I will change the count to two flags: one for the case where the function is not in device context, the other is for the case where the function is in device context. This will allow us to avoid redundant visits whether or not we are in a device context. > > > For the second comment, we need to visit a function again for each use-path because we need to report each use-path that triggers a diagnostic, otherwise users will see a new error after they fix one error, instead of seeing all the errors at once. > > > > This is not what we do in analogous cases where errors are triggered by a use, like in template instantiation. The bug might be that the device program is using a function that it shouldn't be using, or the bug might be that a function that's supposed to be usable from the device is written incorrectly. In the former case, yes, not reporting the errors for each use-path may force the programmer to build multiple times to find all the problematic uses. However, in the latter case you can easily end up emitting a massive number of errors that completely drowns out everything else. It's also non-linear: the number of different use-paths of a particular function can be combinatoric. > The deferred diagnostics fall into the first case mostly. > > Not all diagnostic messages happen in device host functions are deferred. Most of diagnostic messages are emitted immediately, disregarding whether the function is emitted or not. > > Only a few special types of diagnostic messages e.g. inline assembly errors, exceptions, varags are deferred. This is because clang has to use pragmas to make all functions device and host in some system headers to be able to use them in device compilation, whereas some of these functions will cause error only if they are emitted in device compilation. Since we cannot change these headers, we have to defer such diagnostics to the point where they are actually triggered. Therefore we are mostly interested in "who is calling these functions" instead of the diagnostics themselves. > > For normal programs containing no diagnostics, the current approach should sufficiently avoid all redundant visits and all functions will be visited once. > > The functions may be visited multiple times when there are deferred diagnostics, however this should be limited by the maximum number of errors. Okay. I understand the point now about being mostly concerned about using functions in headers. My concern about visiting things a combinatorial number of times is less about generating an excessive number of errors and more about taking an excessive amount of time to finish compilation. The compiler really should not be using any exponential algorithms; a simple visited set will ensure that, but I think what you're doing does not. Can you make a case for why that's not true? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77028/new/ https://reviews.llvm.org/D77028 From cfe-commits at lists.llvm.org Fri Apr 3 15:11:26 2020 From: cfe-commits at lists.llvm.org (Daniel Kiss via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 22:11:26 +0000 (UTC) Subject: [PATCH] D75044: [AArch64] __builtin_extract_return_addr for PAuth. In-Reply-To: References: Message-ID: danielkiss updated this revision to Diff 254921. danielkiss added a comment. Rebased. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75044/new/ https://reviews.llvm.org/D75044 Files: clang/lib/CodeGen/TargetInfo.cpp clang/test/CodeGen/arm64-extractreturnaddress.c llvm/docs/LangRef.rst llvm/include/llvm/CodeGen/ISDOpcodes.h llvm/include/llvm/IR/Intrinsics.td llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/lib/Target/AArch64/AArch64ISelLowering.cpp llvm/lib/Target/AArch64/AArch64ISelLowering.h llvm/test/CodeGen/AArch64/aarch64-extractreturnaddress.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D75044.254921.patch Type: text/x-patch Size: 10529 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 15:13:03 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 22:13:03 +0000 (UTC) Subject: [PATCH] D77085: [clang-tidy] Added support for validating configuration options In-Reply-To: References: Message-ID: <9f726636941a31adbad69a431dc556f4@localhost.localdomain> njames93 marked 8 inline comments as done. njames93 added inline comments. ================ Comment at: clang-tools-extra/clang-tidy/ClangTidyCheck.cpp:25 + llvm::raw_svector_ostream Output(Buffer); + Output << "warning: Option not found '" << OptionName << "'\n"; + return std::string(Buffer); ---------------- aaron.ballman wrote: > aaron.ballman wrote: > > I think the diagnostic text should probably not start with a capital letter. Also, the name of the classes are confusing in that they say error but the diagnostic is a warning. When I hear "error", the class name makes me think this would stop compilation and give a nonzero result code from the program. > Sorry, I was unclear with what I was looking for. > > It looks to me like the behavior of `OptionError` is to act more like a warning than an error in that a message is printed and execution of the tool continues, correct? If so, then I'd prefer to rename it to `OptionWarning` (unless you want to generalize it to be either a warning or an error with a return code, then `OptionDiagnostic` would be good), and all the subclasses to be `FooWarning`. Or did I misunderstand the design? > > Also, I like having the `warning:` in the message (though we could bikeshed if we want to make it look less like a check warning by doing something like `warning [clang-tidy command line]:`), but maybe that's being added by `OptionsView::logErrToStdErr()`? `OptionError` is just there for convenience to avoid having to retype the `log` and `convertToErrorCode` function. Arguably, the `MissingOptionError` isn't really an error, but the `UnparseableEnumOptionError` and `UnparseableIntegerOptionError` should be classed as errors. >From what it seems with other errors, the message function shouldn't contain a `warning:` or `error:` prefix, instead that now gets added in `OptionsView::logErrToStdErr`. The output for enumerations looks like ``` warning: invalid configuration value 'camelback' for option 'readability-identifier-naming.FunctionCase'; did you mean 'camelBack'?``` I do think down the line this should be actually handled as a `ClangTidyDiagnostic` however that is a much larger change to implement given how diagnostics are currently handled. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77085/new/ https://reviews.llvm.org/D77085 From cfe-commits at lists.llvm.org Fri Apr 3 15:31:59 2020 From: cfe-commits at lists.llvm.org (Francis Visoiu Mistrih via cfe-commits) Date: Fri, 03 Apr 2020 15:31:59 -0700 (PDT) Subject: [clang] ba8b305 - [Driver] Handle all optimization-record options for Darwin LTO Message-ID: <5e87b95f.1c69fb81.8952.d489@mx.google.com> Author: Francis Visoiu Mistrih Date: 2020-04-03T15:30:08-07:00 New Revision: ba8b3052b59ebee4311d10bee5209dac8747acea URL: https://github.com/llvm/llvm-project/commit/ba8b3052b59ebee4311d10bee5209dac8747acea DIFF: https://github.com/llvm/llvm-project/commit/ba8b3052b59ebee4311d10bee5209dac8747acea.diff LOG: [Driver] Handle all optimization-record options for Darwin LTO clang with -flto does not handle -foptimization-record-path= This dulicates the code from ToolChains/Clang.cpp with modifications to support everything in the same fashion. Added: clang/test/Driver/darwin-opt-record-ld.c Modified: clang/lib/Driver/ToolChains/Darwin.cpp clang/test/Driver/darwin-ld.c Removed: ################################################################################ diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 451d0d206d07..ab984271555b 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -430,6 +430,75 @@ static bool isObjCRuntimeLinked(const ArgList &Args) { return Args.hasArg(options::OPT_fobjc_link_runtime); } +static bool checkRemarksOptions(const Driver &D, const ArgList &Args, + const llvm::Triple &Triple) { + // When enabling remarks, we need to error if: + // * The remark file is specified but we're targeting multiple architectures, + // which means more than one remark file is being generated. + bool hasMultipleInvocations = + Args.getAllArgValues(options::OPT_arch).size() > 1; + bool hasExplicitOutputFile = + Args.getLastArg(options::OPT_foptimization_record_file_EQ); + if (hasMultipleInvocations && hasExplicitOutputFile) { + D.Diag(diag::err_drv_invalid_output_with_multiple_archs) + << "-foptimization-record-file"; + return false; + } + return true; +} + +static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs, + const llvm::Triple &Triple, + const InputInfo &Output, const JobAction &JA) { + StringRef Format = "yaml"; + if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ)) + Format = A->getValue(); + + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-lto-pass-remarks-output"); + CmdArgs.push_back("-mllvm"); + + const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ); + if (A) { + CmdArgs.push_back(A->getValue()); + } else { + assert(Output.isFilename() && "Unexpected ld output."); + SmallString<128> F; + F = Output.getFilename(); + F += ".opt."; + F += Format; + + CmdArgs.push_back(Args.MakeArgString(F)); + } + + if (const Arg *A = + Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) { + CmdArgs.push_back("-mllvm"); + std::string Passes = + std::string("-lto-pass-remarks-filter=") + A->getValue(); + CmdArgs.push_back(Args.MakeArgString(Passes)); + } + + if (!Format.empty()) { + CmdArgs.push_back("-mllvm"); + Twine FormatArg = Twine("-lto-pass-remarks-format=") + Format; + CmdArgs.push_back(Args.MakeArgString(FormatArg)); + } + + if (getLastProfileUseArg(Args)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-lto-pass-remarks-with-hotness"); + + if (const Arg *A = + Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) { + CmdArgs.push_back("-mllvm"); + std::string Opt = + std::string("-lto-pass-remarks-hotness-threshold=") + A->getValue(); + CmdArgs.push_back(Args.MakeArgString(Opt)); + } + } +} + void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -464,55 +533,9 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, // we follow suite for ease of comparison. AddLinkArgs(C, Args, CmdArgs, Inputs); - // For LTO, pass the name of the optimization record file and other - // opt-remarks flags. - if (Args.hasFlag(options::OPT_fsave_optimization_record, - options::OPT_fsave_optimization_record_EQ, - options::OPT_fno_save_optimization_record, false)) { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back("-lto-pass-remarks-output"); - CmdArgs.push_back("-mllvm"); - - SmallString<128> F; - F = Output.getFilename(); - F += ".opt."; - if (const Arg *A = - Args.getLastArg(options::OPT_fsave_optimization_record_EQ)) - F += A->getValue(); - else - F += "yaml"; - - CmdArgs.push_back(Args.MakeArgString(F)); - - if (getLastProfileUseArg(Args)) { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back("-lto-pass-remarks-with-hotness"); - - if (const Arg *A = - Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) { - CmdArgs.push_back("-mllvm"); - std::string Opt = - std::string("-lto-pass-remarks-hotness-threshold=") + A->getValue(); - CmdArgs.push_back(Args.MakeArgString(Opt)); - } - } - - if (const Arg *A = - Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) { - CmdArgs.push_back("-mllvm"); - std::string Passes = - std::string("-lto-pass-remarks-filter=") + A->getValue(); - CmdArgs.push_back(Args.MakeArgString(Passes)); - } - - if (const Arg *A = - Args.getLastArg(options::OPT_fsave_optimization_record_EQ)) { - CmdArgs.push_back("-mllvm"); - std::string Format = - std::string("-lto-pass-remarks-format=") + A->getValue(); - CmdArgs.push_back(Args.MakeArgString(Format)); - } - } + if (checkRemarksOptions(getToolChain().getDriver(), Args, + getToolChain().getTriple())) + renderRemarksOptions(Args, CmdArgs, getToolChain().getTriple(), Output, JA); // Propagate the -moutline flag to the linker in LTO. if (Arg *A = diff --git a/clang/test/Driver/darwin-ld.c b/clang/test/Driver/darwin-ld.c index 001ed871efe6..3fc0556a2bde 100644 --- a/clang/test/Driver/darwin-ld.c +++ b/clang/test/Driver/darwin-ld.c @@ -309,32 +309,6 @@ // LINK_VERSION_DIGITS: invalid version number in '-mlinker-version=133.3.0.1.a' // LINK_VERSION_DIGITS: invalid version number in '-mlinker-version=133.3.0.1a' -// Check that we're passing -lto-pass-remarks-output for LTO -// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -### -o foo/bar.out 2> %t.log -// RUN: FileCheck -check-prefix=PASS_REMARKS_OUTPUT %s < %t.log -// PASS_REMARKS_OUTPUT: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" -// PASS_REMARKS_OUTPUT-NOT: -lto-pass-remarks-with-hotness - -// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -### 2> %t.log -// RUN: FileCheck -check-prefix=PASS_REMARKS_OUTPUT_NO_O %s < %t.log -// PASS_REMARKS_OUTPUT_NO_O: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "a.out.opt.yaml" - -// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -fprofile-instr-use=blah -### -o foo/bar.out 2> %t.log -// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_HOTNESS %s < %t.log -// PASS_REMARKS_WITH_HOTNESS: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-with-hotness" - -// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -fprofile-instr-use=blah -fdiagnostics-hotness-threshold=100 -### -o foo/bar.out 2> %t.log -// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_HOTNESS_THRESHOLD %s < %t.log -// PASS_REMARKS_WITH_HOTNESS_THRESHOLD: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-with-hotness" "-mllvm" "-lto-pass-remarks-hotness-threshold=100" - -// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -foptimization-record-passes=inline -### -o foo/bar.out 2> %t.log -// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_PASSES %s < %t.log -// PASS_REMARKS_WITH_PASSES: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-filter=inline" -// -// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record=some-format -### -o foo/bar.out 2> %t.log -// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_FORMAT %s < %t.log -// PASS_REMARKS_WITH_FORMAT: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.some-format" "-mllvm" "-lto-pass-remarks-format=some-format" - // RUN: %clang -target x86_64-apple-ios6.0 -miphoneos-version-min=6.0 -fprofile-instr-generate -### %t.o 2> %t.log // RUN: FileCheck -check-prefix=LINK_PROFILE_FIRST %s < %t.log // RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -### %t.o 2> %t.log diff --git a/clang/test/Driver/darwin-opt-record-ld.c b/clang/test/Driver/darwin-opt-record-ld.c new file mode 100644 index 000000000000..0e1e312c493d --- /dev/null +++ b/clang/test/Driver/darwin-opt-record-ld.c @@ -0,0 +1,42 @@ +// REQUIRES: system-darwin + +// RUN: touch %t.o +// +// Check that we're passing -lto-pass-remarks-output for LTO +// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -### -o foo/bar.out 2> %t.log +// RUN: FileCheck -check-prefix=PASS_REMARKS_OUTPUT %s < %t.log +// PASS_REMARKS_OUTPUT: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-format=yaml" +// PASS_REMARKS_OUTPUT-NOT: -lto-pass-remarks-with-hotness + +// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -### 2> %t.log +// RUN: FileCheck -check-prefix=PASS_REMARKS_OUTPUT_NO_O %s < %t.log +// PASS_REMARKS_OUTPUT_NO_O: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "a.out.opt.yaml" + +// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -fprofile-instr-use=blah -### -o foo/bar.out 2> %t.log +// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_HOTNESS %s < %t.log +// PASS_REMARKS_WITH_HOTNESS: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-format=yaml" "-mllvm" "-lto-pass-remarks-with-hotness" + +// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -fprofile-instr-use=blah -fdiagnostics-hotness-threshold=100 -### -o foo/bar.out 2> %t.log +// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_HOTNESS_THRESHOLD %s < %t.log +// PASS_REMARKS_WITH_HOTNESS_THRESHOLD: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-format=yaml" "-mllvm" "-lto-pass-remarks-with-hotness" "-mllvm" "-lto-pass-remarks-hotness-threshold=100" + +// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -foptimization-record-passes=inline -### -o foo/bar.out 2> %t.log +// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_PASSES %s < %t.log +// PASS_REMARKS_WITH_PASSES: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-filter=inline" +// +// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record=some-format -### -o foo/bar.out 2> %t.log +// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_FORMAT %s < %t.log +// PASS_REMARKS_WITH_FORMAT: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.some-format" "-mllvm" "-lto-pass-remarks-format=some-format" + +// RUN: %clang -target x86_64-apple-darwin12 %t.o -foptimization-record-file=remarks-custom.opt.yaml -### -o foo/bar.out 2> %t.log +// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_FILE %s < %t.log +// PASS_REMARKS_WITH_FILE: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "remarks-custom.opt.yaml" + +// RUN: %clang -target x86_64-apple-darwin12 -arch x86_64 -arch x86_64h %t.o -fsave-optimization-record -### -o foo/bar.out 2> %t.log +// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_FAT %s < %t.log +// PASS_REMARKS_WITH_FAT: "-arch" "x86_64"{{.*}}"-mllvm" "-lto-pass-remarks-output" +// PASS_REMARKS_WITH_FAT-NEXT: "-arch" "x86_64h"{{.*}}"-mllvm" "-lto-pass-remarks-output" +// +// RUN: %clang -target x86_64-apple-darwin12 -arch x86_64 -arch x86_64h %t.o -foptimization-record-file=custom.opt.yaml -### -o foo/bar.out 2> %t.log +// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_FILE_FAT %s < %t.log +// PASS_REMARKS_WITH_FILE_FAT: error: cannot use '-foptimization-record-file' output with multiple -arch options From cfe-commits at lists.llvm.org Fri Apr 3 15:43:42 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 22:43:42 +0000 (UTC) Subject: [PATCH] D77379: [FPEnv] Use single enum to represent rounding mode In-Reply-To: References: Message-ID: <55ed7be2d96f9ab3ffcf10151c0b3bf6@localhost.localdomain> rjmccall added inline comments. ================ Comment at: llvm/include/llvm/ADT/FloatingPointMode.h:26 +/// assigned to the rounding modes must agree with the values used by FLT_ROUNDS +/// (C11, 5.2.4.2.2p8). +enum class RoundingMode : int8_t { ---------------- I agree that we should use one enum across LLVM and Clang. I'm not sure that using the `FLT_ROUNDS` values is worthwhile, especially since (1) `FLT_ROUNDS` doesn't specify a value for some of these (like `NearestTiesToAway`) and (2) some of the values it does use (e.g. for "indeterminable") make this actively more awkward to store. And the most useful thing we could do — matching the values of `FE_TONEAREST` and so on — isn't possible because those values are unportable. I'd rather we just pick arbitrary, non-ABI-stable values, like we normally would, and then make the places that rely on matching some external schema translate. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77379/new/ https://reviews.llvm.org/D77379 From cfe-commits at lists.llvm.org Fri Apr 3 16:17:02 2020 From: cfe-commits at lists.llvm.org (Akira Hatanaka via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:17:02 +0000 (UTC) Subject: [PATCH] D76782: [CodeGenObjC] Fix a crash when attempting to copy a zero-sized bit-field in a non-trivial C struct In-Reply-To: References: Message-ID: <5f435703a6491721789eb5fdc7cb7c88@localhost.localdomain> ahatanak added a comment. Thanks for fixing this! ================ Comment at: clang/lib/CodeGen/CGNonTrivialStruct.cpp:545 LValue DstLV, SrcLV; if (FD) { + // No need to copy zero-length bit-fields. ---------------- Can you add the same check to `GenBinaryFuncName::visitVolatileTrivial` to avoid encoding the zero-length bit field into the name of the copy constructor/assignment functions? It isn't necessary to generate different functions for `ZeroBitfield`in the test case and the following struct: ``` struct S { id strong; }; ``` ================ Comment at: clang/test/CodeGenObjC/strong-in-c-struct.m:894 +}; + +void test_zero_bitfield() { ---------------- Can you check that the zero-sized field information isn't encoded into the name of the copy assignment function? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76782/new/ https://reviews.llvm.org/D76782 From cfe-commits at lists.llvm.org Fri Apr 3 16:17:04 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:17:04 +0000 (UTC) Subject: [PATCH] D77432: [DebugInfo] Change to constructor homing debug info mode: skip literal types In-Reply-To: References: Message-ID: rnk added inline comments. ================ Comment at: clang/lib/CodeGen/CGDebugInfo.cpp:2263 if (DebugKind == codegenoptions::DebugInfoConstructor && - !CXXDecl->isLambda() && !isClassOrMethodDLLImport(CXXDecl)) { - for (const auto *Ctor : CXXDecl->ctors()) { + !CXXDecl->isLambda() && !CXXDecl->isLiteral() && + !isClassOrMethodDLLImport(CXXDecl)) ---------------- I'm not sure `isLiteral` is quite the right check. I think there are some ways to: - have a type that is not literal - construct it at compile time with the constexpr constructor - skip object destruction I came up with this example: ``` struct ConstexprCtor { constexpr ConstexprCtor(int a, int b) : a(a + 1), b(b + 1) {} ~ConstexprCtor(); int a, b; }; [[clang::no_destroy]] ConstexprCtor static_gv{1, 2}; ``` I tried to find other ways to construct a class in a constexpr context without running the destructor, but wasn't able to. It would also be interesting to know if StringRef and ArrayRef are literal or not. Those seem like types that we would want to apply this optimization to, and they have constexpr constructors. Maybe we can find a way to apply the optimization by figuring out if a constexpr constructor has been evaluated. You could look at who calls `Sema::MarkFunctionReferenced` and see if there are any callbacks into the ASTConsumer around there. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77432/new/ https://reviews.llvm.org/D77432 From cfe-commits at lists.llvm.org Fri Apr 3 16:17:05 2020 From: cfe-commits at lists.llvm.org (George Burgess IV via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:17:05 +0000 (UTC) Subject: [PATCH] D71082: Allow system header to provide their own implementation of some builtin In-Reply-To: References: Message-ID: <031386537e6f574c931fc080d498929b@localhost.localdomain> george.burgess.iv added a comment. For a more direct comparison, I offer https://godbolt.org/z/fqAhUC . The lack of optimization in the later case is because we're forced to mark the call to `__builtin_memcpy` in the inline memcpy as `nobuiltin`. If we instead rename things, this issue doesn't happen: https://godbolt.org/z/FKNTWo. All other FORTIFY impls I know of defer to `_chk` functions for checking that's not guarded by `__builtin_constant_p`, rather than having size checks inline like the kernel. Both GCC and Clang have special knowledge of these intrinsics, so they can optimize them well: https://godbolt.org/z/L7rVHp . It'd be nice if the kernel's FORTIFY were more like all of the other existing ones in this way. Deferring to `_chk` builtins has the side-benefit that the `inline` `memcpy` is often smaller, which increases the inlineability of any functions that `memcpy` gets inlined into(*). The down-side is that the kernel now needs to carry definitions for `__memcpy_chk` et al. (*) -- not in an underhanded way. It's just that any condition that depends on `__builtin_constant_p` or `__builtin_object_size(obj)` is guaranteed to be folded away at compile-time; not representing them in IR is more "honest" to anything that's trying to determine the inlinability of a function. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71082/new/ https://reviews.llvm.org/D71082 From cfe-commits at lists.llvm.org Fri Apr 3 16:17:05 2020 From: cfe-commits at lists.llvm.org (David Blaikie via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:17:05 +0000 (UTC) Subject: [PATCH] D77432: [DebugInfo] Change to constructor homing debug info mode: skip literal types In-Reply-To: References: Message-ID: <053bcbb2be5eda62d63db6b7d4f5b581@localhost.localdomain> dblaikie added a comment. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77432/new/ https://reviews.llvm.org/D77432 From cfe-commits at lists.llvm.org Fri Apr 3 16:17:05 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Fri, 03 Apr 2020 23:17:05 +0000 (UTC) Subject: [PATCH] D75431: [analyzer][NFC] Merge checkNewAllocator's paramaters into CXXAllocatorCall In-Reply-To: References: Message-ID: <71ec05304419195a2a5a77ef31afeb86@localhost.localdomain> Szelethus added a comment. Hmm, upon taking a look at alignment new in previous patches, I think implementing a checker for MEM57-CPP. Avoid using default operator new for over-aligned types seems a very low hanging fruit, though probably not a common source of bugs. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75431/new/ https://reviews.llvm.org/D75431 From cfe-commits at lists.llvm.org Fri Apr 3 16:17:06 2020 From: cfe-commits at lists.llvm.org (David Blaikie via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:17:06 +0000 (UTC) Subject: [PATCH] D77432: [DebugInfo] Change to constructor homing debug info mode: skip literal types In-Reply-To: References: Message-ID: dblaikie added inline comments. ================ Comment at: clang/lib/CodeGen/CGDebugInfo.cpp:2263 if (DebugKind == codegenoptions::DebugInfoConstructor && - !CXXDecl->isLambda() && !isClassOrMethodDLLImport(CXXDecl)) { - for (const auto *Ctor : CXXDecl->ctors()) { + !CXXDecl->isLambda() && !CXXDecl->isLiteral() && + !isClassOrMethodDLLImport(CXXDecl)) ---------------- rnk wrote: > I'm not sure `isLiteral` is quite the right check. I think there are some ways to: > - have a type that is not literal > - construct it at compile time with the constexpr constructor > - skip object destruction > > I came up with this example: > ``` > struct ConstexprCtor { > constexpr ConstexprCtor(int a, int b) : a(a + 1), b(b + 1) {} > ~ConstexprCtor(); > int a, b; > }; > > [[clang::no_destroy]] ConstexprCtor static_gv{1, 2}; > ``` > > I tried to find other ways to construct a class in a constexpr context without running the destructor, but wasn't able to. > > It would also be interesting to know if StringRef and ArrayRef are literal or not. Those seem like types that we would want to apply this optimization to, and they have constexpr constructors. Maybe we can find a way to apply the optimization by figuring out if a constexpr constructor has been evaluated. You could look at who calls `Sema::MarkFunctionReferenced` and see if there are any callbacks into the ASTConsumer around there. Was (well did, and then realized you'd covered it) going to say the same thing about "is literal type" probably being too narrow here. Testing for the presence of a non-copy/move ctor constexpr ctor I think would be the right test. I'd say it'd be best to fix this broadly first, then in a separate patch/work try to find a way to get some types with constexpr ctors back in - as I think that's going to be extra tricky with optimizations, linkages, etc. Maybe not - but I think there's enough to discuss there that we shouldn't tie that discussion together with this correctness issue. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77432/new/ https://reviews.llvm.org/D77432 From cfe-commits at lists.llvm.org Fri Apr 3 16:17:06 2020 From: cfe-commits at lists.llvm.org (Amy Huang via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:17:06 +0000 (UTC) Subject: [PATCH] D77436: [DebugInfo] Fix for adding "returns cxx udt" option to functions in CodeView. Message-ID: akhuang created this revision. akhuang added reviewers: rnk, dblaikie, aprantl. Herald added a project: clang. Herald added a subscriber: cfe-commits. This change adds DIFlagNonTrivial to forward declarations of DICompositeType. It adds the flag to nontrivial types and types with unknown triviality. It fixes adding the "CxxReturnUdt" flag to functions inconsistently, since it is added based on whether the return type is marked NonTrivial, and that changes if the return type was a forward declaration. continues the discussion at https://reviews.llvm.org/D75215 Bug: https://bugs.llvm.org/show_bug.cgi?id=44785 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77436 Files: clang/lib/CodeGen/CGDebugInfo.cpp clang/test/CodeGenCXX/debug-info-composite-triviality-fwd-decl.cpp Index: clang/test/CodeGenCXX/debug-info-composite-triviality-fwd-decl.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/debug-info-composite-triviality-fwd-decl.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm -gcodeview -debug-info-kind=limited -x c %s -o - | FileCheck %s --check-prefix CHECK-C +// RUN: %clang_cc1 -emit-llvm -gcodeview -debug-info-kind=limited -x c++ %s -o - | FileCheck %s --check-prefix CHECK-CXX +// +// Test for DIFlagNonTrivial on forward declared DICompositeTypes. + +struct Incomplete; +struct Incomplete (*func_ptr)() = 0; +// CHECK-C: !DICompositeType({{.*}}name: "Incomplete" +// CHECK-C-NOT: DIFlagNonTrivial +// CHECK-CXX: !DICompositeType({{.*}}name: "Incomplete" +// CHECK-CXX-SAME: DIFlagNonTrivial Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -991,11 +991,21 @@ uint64_t Size = 0; uint32_t Align = 0; + llvm::DINode::DIFlags Flags = llvm::DINode::FlagFwdDecl; + + // Add flag to nontrivial forward declarations. To be consistent with MSVC, + // add the flag if a record has no definition because we don't know whether + // it will be trivial or not. + if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) + if (!CXXRD->hasDefinition() || + (CXXRD->hasDefinition() && !CXXRD->isTrivial())) + Flags |= llvm::DINode::FlagNonTrivial; + // Create the type. SmallString<256> Identifier = getTypeIdentifier(Ty, CGM, TheCU); llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType( - getTagForRecord(RD), RDName, Ctx, DefUnit, Line, 0, Size, Align, - llvm::DINode::FlagFwdDecl, Identifier); + getTagForRecord(RD), RDName, Ctx, DefUnit, Line, 0, Size, Align, Flags, + Identifier); if (CGM.getCodeGenOpts().DebugFwdTemplateParams) if (auto *TSpecial = dyn_cast(RD)) DBuilder.replaceArrays(RetTy, llvm::DINodeArray(), -------------- next part -------------- A non-text attachment was scrubbed... Name: D77436.254939.patch Type: text/x-patch Size: 2080 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 16:17:06 2020 From: cfe-commits at lists.llvm.org (Akira Hatanaka via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:17:06 +0000 (UTC) Subject: [PATCH] D76572: Replace `T(x)` with `reinterpret_cast(x)` everywhere it means reinterpret_cast. No functional change In-Reply-To: References: Message-ID: <2111df1f6a0117e4e80c94ed083bf164@localhost.localdomain> ahatanak added a comment. I'm not sure which part I'm supposed to look at, but the changes LGTM. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76572/new/ https://reviews.llvm.org/D76572 From cfe-commits at lists.llvm.org Fri Apr 3 16:29:40 2020 From: cfe-commits at lists.llvm.org (Volodymyr Sapsai via cfe-commits) Date: Fri, 03 Apr 2020 16:29:40 -0700 (PDT) Subject: [clang] a8c8b62 - [ObjC generics] Fix not inheriting type bounds in categories/extensions. Message-ID: <5e87c6e4.1c69fb81.35899.fccc@mx.google.com> Author: Volodymyr Sapsai Date: 2020-04-03T16:29:02-07:00 New Revision: a8c8b627f23f204fb621bd2a8c495cfc8bc16ae7 URL: https://github.com/llvm/llvm-project/commit/a8c8b627f23f204fb621bd2a8c495cfc8bc16ae7 DIFF: https://github.com/llvm/llvm-project/commit/a8c8b627f23f204fb621bd2a8c495cfc8bc16ae7.diff LOG: [ObjC generics] Fix not inheriting type bounds in categories/extensions. When a category/extension doesn't repeat a type bound, corresponding type parameter is substituted with `id` when used as a type argument. As a result, in the added test case it was causing errors like > type argument 'T' (aka 'id') does not satisfy the bound ('id') of type parameter 'T' We are already checking that type parameters should be consistent everywhere (see `checkTypeParamListConsistency`) and update `ObjCTypeParamDecl` to have correct underlying type. And when we use the type parameter as a method return type or a method parameter type, it is substituted to the bounded type. But when we use the type parameter as a type argument, we check `ObjCTypeParamType` that wasn't updated and remains `id`. Fix by updating not only `ObjCTypeParamDecl` UnderlyingType but also TypeForDecl as we use the underlying type to create a canonical type for `ObjCTypeParamType` (see `ASTContext::getObjCTypeParamType`). This is a different approach to fixing the issue. The previous one was 02c2ab3d8872416589bd1a6ca3dfb96ba373a3b9 which was reverted in 4c539e8da1b3de38a53ef3f7497f5c45a3243b61. The problem with the previous approach was that `ObjCTypeParamType::desugar` was returning underlying type for `ObjCTypeParamDecl` without applying any protocols stored in `ObjCTypeParamType`. It caused inconsistencies in comparing types before and after desugaring. rdar://problem/54329242 Reviewed By: erik.pilkington Differential Revision: https://reviews.llvm.org/D72872 Added: Modified: clang/include/clang/AST/ASTContext.h clang/lib/AST/ASTContext.cpp clang/lib/AST/Type.cpp clang/lib/Sema/SemaDeclObjC.cpp clang/test/SemaObjC/parameterized_classes_collection_literal.m clang/test/SemaObjC/parameterized_classes_subst.m Removed: ################################################################################ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 6813ab58874e..6360f18217c7 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1442,6 +1442,8 @@ class ASTContext : public RefCountedBase { QualType getObjCTypeParamType(const ObjCTypeParamDecl *Decl, ArrayRef protocols) const; + void adjustObjCTypeParamBoundType(const ObjCTypeParamDecl *Orig, + ObjCTypeParamDecl *New) const; bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl); diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 1e81e0a67b4d..06dcb6fa0580 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -4874,6 +4874,17 @@ ASTContext::getObjCTypeParamType(const ObjCTypeParamDecl *Decl, return QualType(newType, 0); } +void ASTContext::adjustObjCTypeParamBoundType(const ObjCTypeParamDecl *Orig, + ObjCTypeParamDecl *New) const { + New->setTypeSourceInfo(getTrivialTypeSourceInfo(Orig->getUnderlyingType())); + // Update TypeForDecl after updating TypeSourceInfo. + auto NewTypeParamTy = cast(New->getTypeForDecl()); + SmallVector protocols; + protocols.append(NewTypeParamTy->qual_begin(), NewTypeParamTy->qual_end()); + QualType UpdatedTy = getObjCTypeParamType(New, protocols); + New->setTypeForDecl(UpdatedTy.getTypePtr()); +} + /// ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's /// protocol list adopt all protocols in QT's qualified-id protocol /// list. diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 3428437c3146..7c65378261ad 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -3534,6 +3534,7 @@ void ObjCTypeParamType::Profile(llvm::FoldingSetNodeID &ID, const ObjCTypeParamDecl *OTPDecl, ArrayRef protocols) { ID.AddPointer(OTPDecl); + ID.AddPointer(OTPDecl->getUnderlyingType().getAsOpaquePtr()); ID.AddInteger(protocols.size()); for (auto proto : protocols) ID.AddPointer(proto); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 934e1a23141c..6db57898e378 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -938,8 +938,7 @@ static bool checkTypeParamListConsistency(Sema &S, // Override the new type parameter's bound type with the previous type, // so that it's consistent. - newTypeParam->setTypeSourceInfo( - S.Context.getTrivialTypeSourceInfo(prevTypeParam->getUnderlyingType())); + S.Context.adjustObjCTypeParamBoundType(prevTypeParam, newTypeParam); continue; } @@ -966,8 +965,7 @@ static bool checkTypeParamListConsistency(Sema &S, } // Update the new type parameter's bound to match the previous one. - newTypeParam->setTypeSourceInfo( - S.Context.getTrivialTypeSourceInfo(prevTypeParam->getUnderlyingType())); + S.Context.adjustObjCTypeParamBoundType(prevTypeParam, newTypeParam); } return false; diff --git a/clang/test/SemaObjC/parameterized_classes_collection_literal.m b/clang/test/SemaObjC/parameterized_classes_collection_literal.m index 472746e09db9..034d2e8da217 100644 --- a/clang/test/SemaObjC/parameterized_classes_collection_literal.m +++ b/clang/test/SemaObjC/parameterized_classes_collection_literal.m @@ -29,7 +29,9 @@ + (instancetype)arrayWithObjects:(const T [])objects count:(NSUInteger)cnt; @end @interface NSDictionary : NSObject -+ (instancetype)dictionaryWithObjects:(const V [])objects forKeys:(const K [])keys count:(NSUInteger)cnt; ++ (instancetype)dictionaryWithObjects:(const V [])objects + forKeys:(const K [])keys + count:(NSUInteger)cnt; @end void testArrayLiteral(void) { @@ -50,3 +52,9 @@ void testDictionaryLiteral(void) { @"world" : @"blah" // expected-warning{{object of type 'NSString *' is not compatible with dictionary value type 'NSNumber *'}} }; } + +void testCastingInDictionaryLiteral(NSString *arg) { + NSDictionary *dict = @{ + (id)arg : @"foo", + }; +} diff --git a/clang/test/SemaObjC/parameterized_classes_subst.m b/clang/test/SemaObjC/parameterized_classes_subst.m index d14a6e9deb40..b6d884760d29 100644 --- a/clang/test/SemaObjC/parameterized_classes_subst.m +++ b/clang/test/SemaObjC/parameterized_classes_subst.m @@ -467,3 +467,17 @@ - (void)mapUsingBlock:(id (^)(id))block { - (void)mapUsingBlock2:(id)block { // expected-warning{{conflicting parameter types in implementation}} } @end + +// -------------------------------------------------------------------------- +// Use a type parameter as a type argument. +// -------------------------------------------------------------------------- +// Type bounds in a category/extension are omitted. rdar://problem/54329242 + at interface ParameterizedContainer> +- (ParameterizedContainer *)inInterface; + at end + at interface ParameterizedContainer (Cat) +- (ParameterizedContainer *)inCategory; + at end + at interface ParameterizedContainer () +- (ParameterizedContainer *)inExtension; + at end From cfe-commits at lists.llvm.org Fri Apr 3 16:46:14 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via cfe-commits) Date: Fri, 03 Apr 2020 16:46:14 -0700 (PDT) Subject: [clang] e62dc1f - [MS] Fix assert handling enum forward decls in hasVisibleDefinition Message-ID: <5e87cac6.1c69fb81.b1fdd.cc46@mx.google.com> Author: Reid Kleckner Date: 2020-04-03T16:46:07-07:00 New Revision: e62dc1f6252c1dcdcc2a64e8e3b07a32412e9d89 URL: https://github.com/llvm/llvm-project/commit/e62dc1f6252c1dcdcc2a64e8e3b07a32412e9d89 DIFF: https://github.com/llvm/llvm-project/commit/e62dc1f6252c1dcdcc2a64e8e3b07a32412e9d89.diff LOG: [MS] Fix assert handling enum forward decls in hasVisibleDefinition An enum may be considered to be a complete type if it was forward declared. It may be declared with a fixed underlying type, or, in MSVC compatiblity mode, with no type at all. Previously, the code was written with special handling for fixed enums. I generalized the code to check if the underlying integer type is known, which should be the case when targetting the MSVC C++ ABI. Fixes PR45409 Added: clang/test/Modules/Inputs/ms-enums/A.h clang/test/Modules/Inputs/ms-enums/B.h clang/test/Modules/Inputs/ms-enums/module.map clang/test/Modules/ms-enums.cpp Modified: clang/lib/Sema/SemaType.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 49a5dcbe0c79..020e39fedf3f 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -8060,10 +8060,10 @@ bool Sema::hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested, } else if (auto *ED = dyn_cast(D)) { if (auto *Pattern = ED->getTemplateInstantiationPattern()) ED = Pattern; - if (OnlyNeedComplete && ED->isFixed()) { - // If the enum has a fixed underlying type, and we're only looking for a - // complete type (not a definition), any visible declaration of it will - // do. + if (OnlyNeedComplete && !ED->getIntegerType().isNull()) { + // If the enum has an integer type, it may have been forward declared. + // Since we're only looking for a complete type (not a definition), any + // visible declaration of it will do. *Suggested = nullptr; for (auto *Redecl : ED->redecls()) { if (isVisible(Redecl)) diff --git a/clang/test/Modules/Inputs/ms-enums/A.h b/clang/test/Modules/Inputs/ms-enums/A.h new file mode 100644 index 000000000000..168445221c03 --- /dev/null +++ b/clang/test/Modules/Inputs/ms-enums/A.h @@ -0,0 +1 @@ +enum fwd_enum; diff --git a/clang/test/Modules/Inputs/ms-enums/B.h b/clang/test/Modules/Inputs/ms-enums/B.h new file mode 100644 index 000000000000..7a13ba4d72d4 --- /dev/null +++ b/clang/test/Modules/Inputs/ms-enums/B.h @@ -0,0 +1 @@ +#include "A.h" diff --git a/clang/test/Modules/Inputs/ms-enums/module.map b/clang/test/Modules/Inputs/ms-enums/module.map new file mode 100644 index 000000000000..d9aed01430c4 --- /dev/null +++ b/clang/test/Modules/Inputs/ms-enums/module.map @@ -0,0 +1,2 @@ +module A { header "A.h" } +module B { header "B.h" } diff --git a/clang/test/Modules/ms-enums.cpp b/clang/test/Modules/ms-enums.cpp new file mode 100644 index 000000000000..b3a377c6fa63 --- /dev/null +++ b/clang/test/Modules/ms-enums.cpp @@ -0,0 +1,12 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-extensions -fms-compatibility -x c++ -std=c++20 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/ms-enums %s -verify -fno-modules-error-recovery + +#include "B.h" +// expected-note at A.h:1 {{previous declaration is here}} +// expected-note at A.h:1 2 {{previous definition is here}} + +fwd_enum gv_enum; // expected-error {{must be imported}} + +struct Foo { + enum fwd_enum enum_field; // expected-error 2 {{must be imported}} +}; From cfe-commits at lists.llvm.org Fri Apr 3 16:49:09 2020 From: cfe-commits at lists.llvm.org (Volodymyr Sapsai via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:49:09 +0000 (UTC) Subject: [PATCH] D72872: [ObjC generics] Fix not inheriting type bounds in categories/extensions. In-Reply-To: References: Message-ID: vsapsai added a comment. Thanks for the review. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72872/new/ https://reviews.llvm.org/D72872 From cfe-commits at lists.llvm.org Fri Apr 3 16:49:10 2020 From: cfe-commits at lists.llvm.org (Alina Sbirlea via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:49:10 +0000 (UTC) Subject: [PATCH] D77341: [DomTree] Replace ChildrenGetter with GraphTraits over GraphDiff. In-Reply-To: References: Message-ID: asbirlea updated this revision to Diff 254943. asbirlea marked 16 inline comments as done. asbirlea added a comment. Address comments. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77341/new/ https://reviews.llvm.org/D77341 Files: clang/include/clang/Analysis/Analyses/Dominators.h llvm/include/llvm/IR/CFGDiff.h llvm/include/llvm/IR/Dominators.h llvm/include/llvm/Support/GenericDomTree.h llvm/include/llvm/Support/GenericDomTreeConstruction.h llvm/lib/IR/Dominators.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77341.254943.patch Type: text/x-patch Size: 24321 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 16:49:10 2020 From: cfe-commits at lists.llvm.org (Amy Huang via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:49:10 +0000 (UTC) Subject: [PATCH] D77432: [DebugInfo] Change to constructor homing debug info mode: skip constexpr constructed types In-Reply-To: References: Message-ID: akhuang updated this revision to Diff 254942. akhuang added a comment. Change check to hasConstexprNonCopyMoveConstructor() Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77432/new/ https://reviews.llvm.org/D77432 Files: clang/lib/CodeGen/CGDebugInfo.cpp clang/test/CodeGenCXX/debug-info-limited-ctor.cpp Index: clang/test/CodeGenCXX/debug-info-limited-ctor.cpp =================================================================== --- clang/test/CodeGenCXX/debug-info-limited-ctor.cpp +++ clang/test/CodeGenCXX/debug-info-limited-ctor.cpp @@ -1,30 +1,26 @@ // RUN: %clang -cc1 -debug-info-kind=constructor -emit-llvm %s -o - | FileCheck %s -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "A" -// CHECK-NOT: DIFlagFwdDecl -// CHECK-SAME: ){{$}} -struct A {}; -void TestA() { A a; } +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "A"{{.*}}DIFlagTypePassByValue +struct A { +} TestA; -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "B" -// CHECK-SAME: flags: DIFlagFwdDecl +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "B"{{.*}}flags: DIFlagFwdDecl struct B { B(); -}; -void TestB() { B b; } +} TestB; -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "C" -// CHECK-NOT: flags: DIFlagFwdDecl -// CHECK-SAME: ){{$}} +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "C"{{.*}}DIFlagTypePassByValue struct C { C() {} -}; -void TestC() { C c; } +} TestC; -// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "D" -// CHECK-NOT: flags: DIFlagFwdDecl -// CHECK-SAME: ){{$}} +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "D"{{.*}}DIFlagTypePassByValue struct D { D(); }; D::D() {} + +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "E"{{.*}}DIFlagTypePassByValue +struct E { + constexpr E(){}; +} TestE; Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -2260,12 +2260,11 @@ // constructor is emitted. Skip this optimization if the class or any of // its methods are marked dllimport. if (DebugKind == codegenoptions::DebugInfoConstructor && - !CXXDecl->isLambda() && !isClassOrMethodDLLImport(CXXDecl)) { - for (const auto *Ctor : CXXDecl->ctors()) { + !CXXDecl->isLambda() && !CXXDecl->hasConstexprNonCopyMoveConstructor() && + !isClassOrMethodDLLImport(CXXDecl)) + for (const auto *Ctor : CXXDecl->ctors()) if (Ctor->isUserProvided()) return true; - } - } TemplateSpecializationKind Spec = TSK_Undeclared; if (const auto *SD = dyn_cast(RD)) -------------- next part -------------- A non-text attachment was scrubbed... Name: D77432.254942.patch Type: text/x-patch Size: 2508 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 16:49:10 2020 From: cfe-commits at lists.llvm.org (Alina Sbirlea via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:49:10 +0000 (UTC) Subject: [PATCH] D77341: [DomTree] Replace ChildrenGetter with GraphTraits over GraphDiff. In-Reply-To: References: Message-ID: <1d55ca816d4b54dc2ededff55739cf18@localhost.localdomain> asbirlea added inline comments. ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:185 + std::make_pair(GDTmp, BB); + for (auto &Pair : children(GDNodePair)) { + const NodePtr Succ = Pair.second; ---------------- kuhar wrote: > Won't children infer the template parameter based on the passes value? I don't get why the template argument type is a pair where the second argument is a directed nodeptr, but the runtime value is always a plain nodeptr. Couldn't the second pair type also be directed for `GDNodePair`? The directed nodeptr is the equivalent of a bool inside GraphDiff translating to what kind of children do you want; the second pair argument bears no info of that kind, only the actual NodePtr for which we desire the children. ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:186 + for (auto &Pair : children(GDNodePair)) { + const NodePtr Succ = Pair.second; const auto SIT = NodeToInfo.find(Succ); ---------------- kuhar wrote: > kuhar wrote: > > Could this new code be a hoisted into a helper function? > Or alternatively, could the old `ChildrenGetter` be implemented with these 5 magic lines? I think it looks much cleaner after the latest update, let me know what you think. ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:1543 + // FIXME: Updated to use the PreViewCFG and behave the same as until now. + // This behavior is however incorrect; this actually needs the PostViewCFG. + GraphDiff PreViewCFG( ---------------- kuhar wrote: > Does this care about the direction (pre- or post-) at all, or does it need some CFG view? Why is pre-view incorrect? The purpose of this method was to update the DT assuming an additional list of updates (the argument given). In practice, the BUI argument is ignored in the `CalculateFromScratch` call below. Hence we need the additional changes to support this kind of updates inside `CalculateFromScratch` and the other methods. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77341/new/ https://reviews.llvm.org/D77341 From cfe-commits at lists.llvm.org Fri Apr 3 16:49:12 2020 From: cfe-commits at lists.llvm.org (Chandler Carruth via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:49:12 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: <2834dbe1340b6f1c9a71fea3244a0e56@localhost.localdomain> chandlerc added inline comments. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:46-56 + using NodeValueT = _NodeValueT; + using EdgeValueT = _EdgeValueT; + using size_type = _SizeT; + class Node; + class Edge { + friend class ImmutableGraph; + template friend class ImmutableGraphBuilder; ---------------- Folks, this isn't even close to following LLVM's coding conventions or naming conventions. These violate the C++ standard. This shouldn't have been landed as-is. Can you all back this out and actually dig into the review and get this to match LLVM's actual coding style and standards? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 From cfe-commits at lists.llvm.org Fri Apr 3 16:49:14 2020 From: cfe-commits at lists.llvm.org (Amy Huang via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:49:14 +0000 (UTC) Subject: [PATCH] D77432: [DebugInfo] Change to constructor homing debug info mode: skip constexpr constructed types In-Reply-To: References: Message-ID: <48e4546455d6db5326456955ddc70406@localhost.localdomain> akhuang marked an inline comment as done. akhuang added inline comments. ================ Comment at: clang/lib/CodeGen/CGDebugInfo.cpp:2263 if (DebugKind == codegenoptions::DebugInfoConstructor && - !CXXDecl->isLambda() && !isClassOrMethodDLLImport(CXXDecl)) { - for (const auto *Ctor : CXXDecl->ctors()) { + !CXXDecl->isLambda() && !CXXDecl->isLiteral() && + !isClassOrMethodDLLImport(CXXDecl)) ---------------- dblaikie wrote: > rnk wrote: > > I'm not sure `isLiteral` is quite the right check. I think there are some ways to: > > - have a type that is not literal > > - construct it at compile time with the constexpr constructor > > - skip object destruction > > > > I came up with this example: > > ``` > > struct ConstexprCtor { > > constexpr ConstexprCtor(int a, int b) : a(a + 1), b(b + 1) {} > > ~ConstexprCtor(); > > int a, b; > > }; > > > > [[clang::no_destroy]] ConstexprCtor static_gv{1, 2}; > > ``` > > > > I tried to find other ways to construct a class in a constexpr context without running the destructor, but wasn't able to. > > > > It would also be interesting to know if StringRef and ArrayRef are literal or not. Those seem like types that we would want to apply this optimization to, and they have constexpr constructors. Maybe we can find a way to apply the optimization by figuring out if a constexpr constructor has been evaluated. You could look at who calls `Sema::MarkFunctionReferenced` and see if there are any callbacks into the ASTConsumer around there. > Was (well did, and then realized you'd covered it) going to say the same thing about "is literal type" probably being too narrow here. Testing for the presence of a non-copy/move ctor constexpr ctor I think would be the right test. > > I'd say it'd be best to fix this broadly first, then in a separate patch/work try to find a way to get some types with constexpr ctors back in - as I think that's going to be extra tricky with optimizations, linkages, etc. Maybe not - but I think there's enough to discuss there that we shouldn't tie that discussion together with this correctness issue. Sounds good! And yeah, I sort of started looking into how to not ignore all constexpr ctor types, makes sense to put it in a separate patch. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77432/new/ https://reviews.llvm.org/D77432 From cfe-commits at lists.llvm.org Fri Apr 3 16:49:15 2020 From: cfe-commits at lists.llvm.org (Sid Manning via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:49:15 +0000 (UTC) Subject: [PATCH] D77440: [Hexagon] Update include paths for linux/musl Message-ID: sidneym created this revision. sidneym added reviewers: kparzysz, bcain, bcahoon, adasgupt. Herald added a project: clang. Herald added a subscriber: cfe-commits. Update CXX paths for linux/musl. And update the sysroot expectation to match other targets. At this point I might pull out the linux/musl stuff that is in hexagon-toolchain-elf.c and create a new file, hexagon-toolchain-linux.c putting the linux/musl test there. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77440 Files: clang/lib/Driver/ToolChains/Hexagon.cpp clang/lib/Driver/ToolChains/Hexagon.h clang/test/Driver/Inputs/hexagon_tree/Tools/target/hexagon/include/c++/v1/readme clang/test/Driver/hexagon-toolchain-elf.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D77440.254945.patch Type: text/x-patch Size: 11960 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 16:49:28 2020 From: cfe-commits at lists.llvm.org (Joerg Sonnenberger via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:49:28 +0000 (UTC) Subject: [PATCH] D73245: Avoid using std::max_align_t in pre-C++11 mode In-Reply-To: References: Message-ID: This revision was not accepted when it landed; it landed in state "Needs Revision". This revision was automatically updated to reflect the committed changes. Closed by commit rG98f77828a98f: Avoid using std::max_align_t in pre-C++11 mode (authored by joerg). Herald added a project: libc++. Herald added a subscriber: libcxx-commits. Herald added a reviewer: libc++. Changed prior to commit: https://reviews.llvm.org/D73245?vs=250937&id=254949#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73245/new/ https://reviews.llvm.org/D73245 Files: libcxx/include/cstddef libcxx/include/stddef.h libcxx/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp libcxx/test/libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp libcxx/test/std/containers/sequences/array/array.data/data.pass.cpp libcxx/test/std/containers/sequences/array/array.data/data_const.pass.cpp libcxx/test/std/containers/sequences/array/size_and_alignment.pass.cpp libcxx/test/std/depr/depr.c.headers/stddef_h.pass.cpp libcxx/test/std/language.support/support.types/max_align_t.pass.cpp libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/aligned_storage.pass.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D73245.254949.patch Type: text/x-patch Size: 10395 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 16:49:29 2020 From: cfe-commits at lists.llvm.org (Volodymyr Sapsai via Phabricator via cfe-commits) Date: Fri, 03 Apr 2020 23:49:29 +0000 (UTC) Subject: [PATCH] D72872: [ObjC generics] Fix not inheriting type bounds in categories/extensions. In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rGa8c8b627f23f: [ObjC generics] Fix not inheriting type bounds in categories/extensions. (authored by vsapsai). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D72872/new/ https://reviews.llvm.org/D72872 Files: clang/include/clang/AST/ASTContext.h clang/lib/AST/ASTContext.cpp clang/lib/AST/Type.cpp clang/lib/Sema/SemaDeclObjC.cpp clang/test/SemaObjC/parameterized_classes_collection_literal.m clang/test/SemaObjC/parameterized_classes_subst.m -------------- next part -------------- A non-text attachment was scrubbed... Name: D72872.254950.patch Type: text/x-patch Size: 4824 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 17:06:42 2020 From: cfe-commits at lists.llvm.org (Craig Topper via cfe-commits) Date: Fri, 03 Apr 2020 17:06:42 -0700 (PDT) Subject: [clang] 1d42c0d - Revert "[X86] Add a Pass that builds a Condensed CFG for Load Value Injection (LVI) Gadgets" Message-ID: <5e87cf92.1c69fb81.a7aee.0cfb@mx.google.com> Author: Craig Topper Date: 2020-04-03T16:56:08-07:00 New Revision: 1d42c0db9a2b27c149c5bac373caa5a6d38d1f74 URL: https://github.com/llvm/llvm-project/commit/1d42c0db9a2b27c149c5bac373caa5a6d38d1f74 DIFF: https://github.com/llvm/llvm-project/commit/1d42c0db9a2b27c149c5bac373caa5a6d38d1f74.diff LOG: Revert "[X86] Add a Pass that builds a Condensed CFG for Load Value Injection (LVI) Gadgets" This reverts commit c74dd640fd740c6928f66a39c7c15a014af3f66f. Reverting to address coding standard issues raised in post-commit review. Added: Modified: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Arch/X86.cpp clang/test/Driver/x86-target-features.c llvm/lib/Target/X86/CMakeLists.txt llvm/lib/Target/X86/X86.h llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86Subtarget.h llvm/lib/Target/X86/X86TargetMachine.cpp llvm/test/CodeGen/X86/O0-pipeline.ll llvm/test/CodeGen/X86/O3-pipeline.ll Removed: llvm/lib/Target/X86/ImmutableGraph.h llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll ################################################################################ diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 869d2755f47e..0d057ac579f5 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2309,10 +2309,6 @@ def mspeculative_load_hardening : Flag<["-"], "mspeculative-load-hardening">, Group, Flags<[CoreOption,CC1Option]>; def mno_speculative_load_hardening : Flag<["-"], "mno-speculative-load-hardening">, Group, Flags<[CoreOption]>; -def mlvi_hardening : Flag<["-"], "mlvi-hardening">, Group, Flags<[CoreOption,DriverOption]>, - HelpText<"Enable all mitigations for Load Value Injection (LVI)">; -def mno_lvi_hardening : Flag<["-"], "mno-lvi-hardening">, Group, Flags<[CoreOption,DriverOption]>, - HelpText<"Disable mitigations for Load Value Injection (LVI)">; def mlvi_cfi : Flag<["-"], "mlvi-cfi">, Group, Flags<[CoreOption,DriverOption]>, HelpText<"Enable only control-flow mitigations for Load Value Injection (LVI)">; def mno_lvi_cfi : Flag<["-"], "mno-lvi-cfi">, Group, Flags<[CoreOption,DriverOption]>, diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp index dbbc025de38c..aafba6915d0b 100644 --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -173,13 +173,7 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, } auto LVIOpt = clang::driver::options::ID::OPT_INVALID; - if (Args.hasFlag(options::OPT_mlvi_hardening, options::OPT_mno_lvi_hardening, - false)) { - Features.push_back("+lvi-load-hardening"); - Features.push_back("+lvi-cfi"); // load hardening implies CFI protection - LVIOpt = options::OPT_mlvi_hardening; - } else if (Args.hasFlag(options::OPT_mlvi_cfi, options::OPT_mno_lvi_cfi, - false)) { + if (Args.hasFlag(options::OPT_mlvi_cfi, options::OPT_mno_lvi_cfi, false)) { Features.push_back("+lvi-cfi"); LVIOpt = options::OPT_mlvi_cfi; } diff --git a/clang/test/Driver/x86-target-features.c b/clang/test/Driver/x86-target-features.c index 44a3d2e1164b..872a228c2a33 100644 --- a/clang/test/Driver/x86-target-features.c +++ b/clang/test/Driver/x86-target-features.c @@ -159,11 +159,6 @@ // LVICFI: "-target-feature" "+lvi-cfi" // NO-LVICFI-NOT: lvi-cfi -// RUN: %clang -target i386-linux-gnu -mlvi-hardening %s -### -o %t.o 2>&1 | FileCheck -check-prefix=LVIHARDENING %s -// RUN: %clang -target i386-linux-gnu -mno-lvi-hardening %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-LVIHARDENING %s -// LVIHARDENING: "-target-feature" "+lvi-load-hardening" "-target-feature" "+lvi-cfi" -// NO-LVIHARDENING-NOT: lvi - // RUN: %clang -target i386-linux-gnu -mwaitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=WAITPKG %s // RUN: %clang -target i386-linux-gnu -mno-waitpkg %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-WAITPKG %s // WAITPKG: "-target-feature" "+waitpkg" diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt index e94a82aebca4..5df9978bf11d 100644 --- a/llvm/lib/Target/X86/CMakeLists.txt +++ b/llvm/lib/Target/X86/CMakeLists.txt @@ -52,7 +52,6 @@ set(sources X86InstrInfo.cpp X86EvexToVex.cpp X86LegalizerInfo.cpp - X86LoadValueInjectionLoadHardening.cpp X86LoadValueInjectionRetHardening.cpp X86MCInstLower.cpp X86MachineFunctionInfo.cpp diff --git a/llvm/lib/Target/X86/ImmutableGraph.h b/llvm/lib/Target/X86/ImmutableGraph.h deleted file mode 100644 index 80c9cf489ded..000000000000 --- a/llvm/lib/Target/X86/ImmutableGraph.h +++ /dev/null @@ -1,432 +0,0 @@ -//==========-- ImmutableGraph.h - A fast DAG implementation ---------=========// -// -// 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 -// -//===----------------------------------------------------------------------===// -/// -/// Description: ImmutableGraph is a fast DAG implementation that cannot be -/// modified, except by creating a new ImmutableGraph. ImmutableGraph is -/// implemented as two arrays: one containing nodes, and one containing edges. -/// The advantages to this implementation are two-fold: -/// 1. Iteration and traversal operations should experience terrific caching -/// performance. -/// 2. Set representations and operations on nodes and edges become -/// extraordinarily efficient. For instance, a set of edges is implemented as -/// a bit vector, wherein each bit corresponds to one edge in the edge -/// array. This implies a lower bound of 64x spacial improvement over, e.g., -/// an llvm::DenseSet or llvm::SmallSet. It also means that -/// insert/erase/contains operations complete in negligible constant time: -/// insert and erase require one load and one store, and contains requires -/// just one load. -/// -//===----------------------------------------------------------------------===// - -#ifndef IMMUTABLEGRAPH_H -#define IMMUTABLEGRAPH_H - -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/raw_ostream.h" -#include -#include -#include -#include - -namespace llvm { - -template -class ImmutableGraph { - using Traits = GraphTraits *>; - template friend class ImmutableGraphBuilder; - -public: - using NodeValueT = _NodeValueT; - using EdgeValueT = _EdgeValueT; - using size_type = _SizeT; - class Node; - class Edge { - friend class ImmutableGraph; - template friend class ImmutableGraphBuilder; - friend Traits; - - Node *__dest; - EdgeValueT __value; - - public: - EdgeValueT &value() { return __value; } - }; - class Node { - friend class ImmutableGraph; - template friend class ImmutableGraphBuilder; - friend Traits; - - Edge *__edges; - NodeValueT __value; - - public: - NodeValueT &value() { return __value; } - }; - -protected: - ImmutableGraph(Node *Nodes, size_type NodesSize, Edge *Edges, - size_type EdgesSize) - : __nodes{Nodes}, __nodes_size{NodesSize}, __edges{Edges}, - __edges_size{EdgesSize} {} - ImmutableGraph(const ImmutableGraph &) = delete; - ImmutableGraph(ImmutableGraph &&) = delete; - ImmutableGraph &operator=(const ImmutableGraph &) = delete; - ImmutableGraph &operator=(ImmutableGraph &&) = delete; - -public: - ~ImmutableGraph() { - delete[] __edges; - delete[] __nodes; - } - - Node *nodes_begin() const { return __nodes; } - Node *nodes_end() const { return __nodes + __nodes_size; } - Edge *edges_begin() const { return __edges; } - Edge *edges_end() const { return __edges + __edges_size; } - size_type nodes_size() const { return __nodes_size; } - size_type edges_size() const { return __edges_size; } - bool empty() const { return __nodes_size == 0; } - - class NodeSet { - friend class iterator; - - const ImmutableGraph &__g; - BitVector __v; - - public: - NodeSet(const ImmutableGraph &G, bool ContainsAll = false) - : __g{G}, __v{static_cast(__g.nodes_size()), ContainsAll} {} - bool insert(Node *N) { - size_type Idx = std::distance(__g.nodes_begin(), N); - bool AlreadyExists = __v.test(Idx); - __v.set(Idx); - return !AlreadyExists; - } - void erase(Node *N) { - size_type Idx = std::distance(__g.nodes_begin(), N); - __v.reset(Idx); - } - bool contains(Node *N) const { - size_type Idx = std::distance(__g.nodes_begin(), N); - return __v.test(Idx); - } - void clear() { __v.reset(); } - size_type empty() const { return __v.none(); } - /// Return the number of elements in the set - size_type count() const { return __v.count(); } - /// Return the size of the set's domain - size_type size() const { return __v.size(); } - /// Set union - NodeSet &operator|=(const NodeSet &RHS) { - assert(&this->__g == &RHS.__g); - __v |= RHS.__v; - return *this; - } - /// Set intersection - NodeSet &operator&=(const NodeSet &RHS) { - assert(&this->__g == &RHS.__g); - __v &= RHS.__v; - return *this; - } - /// Set disjoint union - NodeSet &operator^=(const NodeSet &RHS) { - assert(&this->__g == &RHS.__g); - __v ^= RHS.__v; - return *this; - } - - using index_iterator = typename BitVector::const_set_bits_iterator; - index_iterator index_begin() const { return __v.set_bits_begin(); } - index_iterator index_end() const { return __v.set_bits_end(); } - void set(size_type Idx) { __v.set(Idx); } - void reset(size_type Idx) { __v.reset(Idx); } - - class iterator { - const NodeSet &__set; - size_type __current; - - void advance() { - assert(__current != -1); - __current = __set.__v.find_next(__current); - } - - public: - iterator(const NodeSet &Set, size_type Begin) - : __set{Set}, __current{Begin} {} - iterator operator++(int) { - iterator Tmp = *this; - advance(); - return Tmp; - } - iterator &operator++() { - advance(); - return *this; - } - Node *operator*() const { - assert(__current != -1); - return __set.__g.nodes_begin() + __current; - } - bool operator==(const iterator &other) const { - assert(&this->__set == &other.__set); - return this->__current == other.__current; - } - bool operator!=(const iterator &other) const { return !(*this == other); } - }; - - iterator begin() const { return iterator{*this, __v.find_first()}; } - iterator end() const { return iterator{*this, -1}; } - }; - - class EdgeSet { - const ImmutableGraph &__g; - BitVector __v; - - public: - EdgeSet(const ImmutableGraph &G, bool ContainsAll = false) - : __g{G}, __v{static_cast(__g.edges_size()), ContainsAll} {} - bool insert(Edge *E) { - size_type Idx = std::distance(__g.edges_begin(), E); - bool AlreadyExists = __v.test(Idx); - __v.set(Idx); - return !AlreadyExists; - } - void erase(Edge *E) { - size_type Idx = std::distance(__g.edges_begin(), E); - __v.reset(Idx); - } - bool contains(Edge *E) const { - size_type Idx = std::distance(__g.edges_begin(), E); - return __v.test(Idx); - } - void clear() { __v.reset(); } - bool empty() const { return __v.none(); } - /// Return the number of elements in the set - size_type count() const { return __v.count(); } - /// Return the size of the set's domain - size_type size() const { return __v.size(); } - /// Set union - EdgeSet &operator|=(const EdgeSet &RHS) { - assert(&this->__g == &RHS.__g); - __v |= RHS.__v; - return *this; - } - /// Set intersection - EdgeSet &operator&=(const EdgeSet &RHS) { - assert(&this->__g == &RHS.__g); - __v &= RHS.__v; - return *this; - } - /// Set disjoint union - EdgeSet &operator^=(const EdgeSet &RHS) { - assert(&this->__g == &RHS.__g); - __v ^= RHS.__v; - return *this; - } - - using index_iterator = typename BitVector::const_set_bits_iterator; - index_iterator index_begin() const { return __v.set_bits_begin(); } - index_iterator index_end() const { return __v.set_bits_end(); } - void set(size_type Idx) { __v.set(Idx); } - void reset(size_type Idx) { __v.reset(Idx); } - - class iterator { - const EdgeSet &__set; - size_type __current; - - void advance() { - assert(__current != -1); - __current = __set.__v.find_next(__current); - } - - public: - iterator(const EdgeSet &Set, size_type Begin) - : __set{Set}, __current{Begin} {} - iterator operator++(int) { - iterator Tmp = *this; - advance(); - return Tmp; - } - iterator &operator++() { - advance(); - return *this; - } - Edge *operator*() const { - assert(__current != -1); - return __set.__g.edges_begin() + __current; - } - bool operator==(const iterator &other) const { - assert(&this->__set == &other.__set); - return this->__current == other.__current; - } - bool operator!=(const iterator &other) const { return !(*this == other); } - }; - - iterator begin() const { return iterator{*this, __v.find_first()}; } - iterator end() const { return iterator{*this, -1}; } - }; - -private: - Node *__nodes; - size_type __nodes_size; - Edge *__edges; - size_type __edges_size; -}; - -template class ImmutableGraphBuilder { - using NodeValueT = typename GraphT::NodeValueT; - using EdgeValueT = typename GraphT::EdgeValueT; - static_assert( - std::is_base_of, GraphT>::value, - "Template argument to ImmutableGraphBuilder must derive from " - "ImmutableGraph<>"); - using size_type = typename GraphT::size_type; - using NodeSet = typename GraphT::NodeSet; - using Node = typename GraphT::Node; - using EdgeSet = typename GraphT::EdgeSet; - using Edge = typename GraphT::Edge; - using BuilderEdge = std::pair; - using EdgeList = std::vector; - using BuilderVertex = std::pair; - using VertexVec = std::vector; - -public: - using NodeRef = size_type; - - NodeRef addVertex(const NodeValueT &V) { - auto I = __adj_list.emplace(__adj_list.end(), V, EdgeList{}); - return std::distance(__adj_list.begin(), I); - } - - void addEdge(const EdgeValueT &E, NodeRef From, NodeRef To) { - __adj_list[From].second.emplace_back(E, To); - } - - bool empty() const { return __adj_list.empty(); } - - template GraphT *get(ArgT &&... Args) { - size_type VertexSize = __adj_list.size(), EdgeSize = 0; - for (const auto &V : __adj_list) { - EdgeSize += V.second.size(); - } - auto *VertexArray = new Node[VertexSize + 1 /* terminator node */]; - auto *EdgeArray = new Edge[EdgeSize]; - size_type VI = 0, EI = 0; - for (; VI < static_cast(__adj_list.size()); ++VI) { - VertexArray[VI].__value = std::move(__adj_list[VI].first); - VertexArray[VI].__edges = &EdgeArray[EI]; - auto NumEdges = static_cast(__adj_list[VI].second.size()); - if (NumEdges > 0) { - for (size_type VEI = 0; VEI < NumEdges; ++VEI, ++EI) { - auto &E = __adj_list[VI].second[VEI]; - EdgeArray[EI].__value = std::move(E.first); - EdgeArray[EI].__dest = VertexArray + E.second; - } - } - } - assert(VI == VertexSize && EI == EdgeSize && "Gadget graph malformed"); - VertexArray[VI].__edges = EdgeArray + EdgeSize; // terminator node - return new GraphT{VertexArray, VertexSize, EdgeArray, EdgeSize, - std::forward(Args)...}; - } - - template - static GraphT *trim(const GraphT &G, const NodeSet &TrimNodes, - const EdgeSet &TrimEdges, ArgT &&... Args) { - size_type NewVertexSize = TrimNodes.size() - TrimNodes.count(); - size_type NewEdgeSize = TrimEdges.size() - TrimEdges.count(); - auto *NewVertexArray = new Node[NewVertexSize + 1 /* terminator node */]; - auto *NewEdgeArray = new Edge[NewEdgeSize]; - size_type TrimmedNodesSoFar = 0, - *TrimmedNodes = new size_type[TrimNodes.size()]; - for (size_type I = 0; I < TrimNodes.size(); ++I) { - TrimmedNodes[I] = TrimmedNodesSoFar; - if (TrimNodes.contains(G.nodes_begin() + I)) - ++TrimmedNodesSoFar; - } - size_type VertexI = 0, EdgeI = 0; - for (Node *NI = G.nodes_begin(), *NE = G.nodes_end(); NI != NE; ++NI) { - if (TrimNodes.contains(NI)) - continue; - size_type NewNumEdges = - static_cast((NI + 1)->__edges - NI->__edges) > 0 - ? std::count_if( - NI->__edges, (NI + 1)->__edges, - [&TrimEdges](Edge &E) { return !TrimEdges.contains(&E); }) - : 0; - NewVertexArray[VertexI].__value = NI->__value; - NewVertexArray[VertexI].__edges = &NewEdgeArray[EdgeI]; - if (NewNumEdges > 0) { - for (Edge *EI = NI->__edges, *EE = (NI + 1)->__edges; EI != EE; ++EI) { - if (TrimEdges.contains(EI)) - continue; - NewEdgeArray[EdgeI].__value = EI->__value; - size_type DestIdx = std::distance(G.nodes_begin(), EI->__dest); - size_type NewIdx = DestIdx - TrimmedNodes[DestIdx]; - assert(NewIdx < NewVertexSize); - NewEdgeArray[EdgeI].__dest = NewVertexArray + NewIdx; - ++EdgeI; - } - } - ++VertexI; - } - delete[] TrimmedNodes; - assert(VertexI == NewVertexSize && EdgeI == NewEdgeSize && - "Gadget graph malformed"); - NewVertexArray[VertexI].__edges = NewEdgeArray + NewEdgeSize; - return new GraphT{NewVertexArray, NewVertexSize, NewEdgeArray, NewEdgeSize, - std::forward(Args)...}; - } - -private: - VertexVec __adj_list; -}; - -template -struct GraphTraits *> { - using GraphT = ImmutableGraph; - using NodeRef = typename GraphT::Node *; - using EdgeRef = typename GraphT::Edge &; - - static NodeRef edge_dest(EdgeRef E) { return E.__dest; } - using ChildIteratorType = - mapped_iterator; - - static NodeRef getEntryNode(GraphT *G) { return G->nodes_begin(); } - static ChildIteratorType child_begin(NodeRef N) { - return {N->__edges, &edge_dest}; - } - static ChildIteratorType child_end(NodeRef N) { - return {(N + 1)->__edges, &edge_dest}; - } - - static NodeRef getNode(typename GraphT::Node &N) { return NodeRef{&N}; } - using nodes_iterator = - mapped_iterator; - static nodes_iterator nodes_begin(GraphT *G) { - return {G->nodes_begin(), &getNode}; - } - static nodes_iterator nodes_end(GraphT *G) { - return {G->nodes_end(), &getNode}; - } - - using ChildEdgeIteratorType = typename GraphT::Edge *; - - static ChildEdgeIteratorType child_edge_begin(NodeRef N) { - return N->__edges; - } - static ChildEdgeIteratorType child_edge_end(NodeRef N) { - return (N + 1)->__edges; - } - static typename GraphT::size_type size(GraphT *G) { return G->nodes_size(); } -}; - -} // end namespace llvm - -#endif // IMMUTABLEGRAPH_H diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h index 0c88a6b746ef..1b6e99ae7b9b 100644 --- a/llvm/lib/Target/X86/X86.h +++ b/llvm/lib/Target/X86/X86.h @@ -142,7 +142,6 @@ InstructionSelector *createX86InstructionSelector(const X86TargetMachine &TM, X86Subtarget &, X86RegisterBankInfo &); -FunctionPass *createX86LoadValueInjectionLoadHardeningPass(); FunctionPass *createX86LoadValueInjectionRetHardeningPass(); FunctionPass *createX86SpeculativeLoadHardeningPass(); @@ -160,7 +159,6 @@ void initializeX86DomainReassignmentPass(PassRegistry &); void initializeX86ExecutionDomainFixPass(PassRegistry &); void initializeX86ExpandPseudoPass(PassRegistry &); void initializeX86FlagsCopyLoweringPassPass(PassRegistry &); -void initializeX86LoadValueInjectionLoadHardeningPassPass(PassRegistry &); void initializeX86LoadValueInjectionRetHardeningPassPass(PassRegistry &); void initializeX86OptimizeLEAPassPass(PassRegistry &); void initializeX86PartialReductionPass(PassRegistry &); diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index 7bee814232b7..13ccf3c940b9 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -442,13 +442,6 @@ def FeatureLVIControlFlowIntegrity "LFENCE instruction to serialize control flow. Also decompose RET " "instructions into a POP+LFENCE+JMP sequence.">; -// Mitigate LVI attacks against data loads -def FeatureLVILoadHardening - : SubtargetFeature< - "lvi-load-hardening", "UseLVILoadHardening", "true", - "Insert LFENCE instructions to prevent data speculatively injected " - "into loads from being used maliciously.">; - // Direct Move instructions. def FeatureMOVDIRI : SubtargetFeature<"movdiri", "HasMOVDIRI", "true", "Support movdiri instruction">; diff --git a/llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp b/llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp deleted file mode 100644 index 7c027e5fca67..000000000000 --- a/llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp +++ /dev/null @@ -1,586 +0,0 @@ -//==-- X86LoadValueInjectionLoadHardening.cpp - LVI load hardening for x86 --=// -// -// 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 -// -//===----------------------------------------------------------------------===// -/// -/// Description: This pass finds Load Value Injection (LVI) gadgets consisting -/// of a load from memory (i.e., SOURCE), and any operation that may transmit -/// the value loaded from memory over a covert channel, or use the value loaded -/// from memory to determine a branch/call target (i.e., SINK). -/// -//===----------------------------------------------------------------------===// - -#include "ImmutableGraph.h" -#include "X86.h" -#include "X86Subtarget.h" -#include "X86TargetMachine.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/SmallSet.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/CodeGen/MachineBasicBlock.h" -#include "llvm/CodeGen/MachineDominanceFrontier.h" -#include "llvm/CodeGen/MachineDominators.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineLoopInfo.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/RDFGraph.h" -#include "llvm/CodeGen/RDFLiveness.h" -#include "llvm/InitializePasses.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/DOTGraphTraits.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/GraphWriter.h" -#include "llvm/Support/raw_ostream.h" - -using namespace llvm; - -#define PASS_KEY "x86-lvi-load" -#define DEBUG_TYPE PASS_KEY - -STATISTIC(NumFunctionsConsidered, "Number of functions analyzed"); -STATISTIC(NumFunctionsMitigated, "Number of functions for which mitigations " - "were deployed"); -STATISTIC(NumGadgets, "Number of LVI gadgets detected during analysis"); - -static cl::opt NoConditionalBranches( - PASS_KEY "-no-cbranch", - cl::desc("Don't treat conditional branches as disclosure gadgets. This " - "may improve performance, at the cost of security."), - cl::init(false), cl::Hidden); - -static cl::opt EmitDot( - PASS_KEY "-dot", - cl::desc( - "For each function, emit a dot graph depicting potential LVI gadgets"), - cl::init(false), cl::Hidden); - -static cl::opt EmitDotOnly( - PASS_KEY "-dot-only", - cl::desc("For each function, emit a dot graph depicting potential LVI " - "gadgets, and do not insert any fences"), - cl::init(false), cl::Hidden); - -static cl::opt EmitDotVerify( - PASS_KEY "-dot-verify", - cl::desc("For each function, emit a dot graph to stdout depicting " - "potential LVI gadgets, used for testing purposes only"), - cl::init(false), cl::Hidden); - -static cl::opt NoFixedLoads( - PASS_KEY "-no-fixed", - cl::desc("Don't mitigate RIP-relative or RSP-relative loads. This " - "may improve performance, at the cost of security."), - cl::init(false), cl::Hidden); - -#define ARG_NODE nullptr -#define GADGET_EDGE ((int)(-1)) -#define WEIGHT(EdgeValue) ((double)(2 * (EdgeValue) + 1)) - -namespace { - -class X86LoadValueInjectionLoadHardeningPass : public MachineFunctionPass { -public: - X86LoadValueInjectionLoadHardeningPass() : MachineFunctionPass(ID) {} - - StringRef getPassName() const override { - return "X86 Load Value Injection (LVI) Load Hardening"; - } - void getAnalysisUsage(AnalysisUsage &AU) const override; - bool runOnMachineFunction(MachineFunction &MF) override; - - static char ID; - -private: - struct MachineGadgetGraph : ImmutableGraph { - using GraphT = ImmutableGraph; - using Node = typename GraphT::Node; - using Edge = typename GraphT::Edge; - using size_type = typename GraphT::size_type; - MachineGadgetGraph(Node *Nodes, size_type NodesSize, Edge *Edges, - size_type EdgesSize, int NumFences = 0, - int NumGadgets = 0) - : GraphT{Nodes, NodesSize, Edges, EdgesSize}, NumFences{NumFences}, - NumGadgets{NumGadgets} {} - MachineFunction &getMF() { // FIXME: This function should be cleaner - for (Node *NI = nodes_begin(), *const NE = nodes_end(); NI != NE; ++NI) { - if (NI->value()) { - return *NI->value()->getMF(); - } - } - llvm_unreachable("Could not find a valid node"); - } - static inline bool isCFGEdge(Edge &E) { return E.value() != GADGET_EDGE; } - static inline bool isGadgetEdge(Edge &E) { - return E.value() == GADGET_EDGE; - } - int NumFences; - int NumGadgets; - }; - friend struct llvm::DOTGraphTraits; - using GTraits = llvm::GraphTraits; - using GraphBuilder = ImmutableGraphBuilder; - using EdgeSet = MachineGadgetGraph::EdgeSet; - using Gadget = std::pair; - - const X86Subtarget *STI; - const TargetInstrInfo *TII; - const TargetRegisterInfo *TRI; - - int hardenLoads(MachineFunction &MF, bool Fixed) const; - std::unique_ptr - getGadgetGraph(MachineFunction &MF, const MachineLoopInfo &MLI, - const MachineDominatorTree &MDT, - const MachineDominanceFrontier &MDF, bool FixedLoads) const; - - bool instrUsesRegToAccessMemory(const MachineInstr &I, unsigned Reg) const; - bool instrUsesRegToBranch(const MachineInstr &I, unsigned Reg) const; - template bool hasLoadFrom(const MachineInstr &MI) const; - bool instrAccessesStackSlot(const MachineInstr &MI) const; - bool instrAccessesConstantPool(const MachineInstr &MI) const; - bool instrAccessesGOT(const MachineInstr &MI) const; - inline bool instrIsFixedAccess(const MachineInstr &MI) const { - return instrAccessesConstantPool(MI) || instrAccessesStackSlot(MI) || - instrAccessesGOT(MI); - } - inline bool isFence(const MachineInstr *MI) const { - return MI && (MI->getOpcode() == X86::LFENCE || - (STI->useLVIControlFlowIntegrity() && MI->isCall())); - } -}; - -} // end anonymous namespace - -namespace llvm { - -template <> -struct GraphTraits - : GraphTraits *> {}; - -template <> -struct DOTGraphTraits< - X86LoadValueInjectionLoadHardeningPass::MachineGadgetGraph *> - : DefaultDOTGraphTraits { - using GraphType = X86LoadValueInjectionLoadHardeningPass::MachineGadgetGraph; - using Traits = X86LoadValueInjectionLoadHardeningPass::GTraits; - using NodeRef = typename Traits::NodeRef; - using EdgeRef = typename Traits::EdgeRef; - using ChildIteratorType = typename Traits::ChildIteratorType; - using ChildEdgeIteratorType = typename Traits::ChildEdgeIteratorType; - - DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} - - static std::string getGraphName(GraphType *G) { - std::string GraphName{"Speculative gadgets for \""}; - GraphName += G->getMF().getName(); - GraphName += "\" function"; - return GraphName; - } - - std::string getNodeLabel(NodeRef Node, GraphType *) { - std::string str; - raw_string_ostream str_stream{str}; - if (Node->value() == ARG_NODE) - return "ARGS"; - str_stream << *Node->value(); - return str_stream.str(); - } - - static std::string getNodeAttributes(NodeRef Node, GraphType *) { - MachineInstr *MI = Node->value(); - if (MI == ARG_NODE) - return "color = blue"; - else if (MI->getOpcode() == X86::LFENCE) - return "color = green"; - else - return ""; - } - - static std::string getEdgeAttributes(NodeRef, ChildIteratorType E, - GraphType *) { - int EdgeVal = (*E.getCurrent()).value(); - return EdgeVal >= 0 ? "label = " + std::to_string(EdgeVal) - : "color = red, style = \"dashed\""; - } -}; - -} // end namespace llvm - -char X86LoadValueInjectionLoadHardeningPass::ID = 0; - -void X86LoadValueInjectionLoadHardeningPass::getAnalysisUsage( - AnalysisUsage &AU) const { - MachineFunctionPass::getAnalysisUsage(AU); - AU.addRequired(); - AU.addRequired(); - AU.addRequired(); - AU.setPreservesCFG(); -} - -bool X86LoadValueInjectionLoadHardeningPass::runOnMachineFunction( - MachineFunction &MF) { - LLVM_DEBUG(dbgs() << "***** " << getPassName() << " : " << MF.getName() - << " *****\n"); - STI = &MF.getSubtarget(); - if (!STI->useLVILoadHardening() || !STI->is64Bit()) - return false; // FIXME: support 32-bit - - // Don't skip functions with the "optnone" attr but participate in opt-bisect. - const Function &F = MF.getFunction(); - if (!F.hasOptNone() && skipFunction(F)) - return false; - - ++NumFunctionsConsidered; - TII = STI->getInstrInfo(); - TRI = STI->getRegisterInfo(); - LLVM_DEBUG(dbgs() << "Hardening data-dependent loads...\n"); - hardenLoads(MF, false); - LLVM_DEBUG(dbgs() << "Hardening data-dependent loads... Done\n"); - if (!NoFixedLoads) { - LLVM_DEBUG(dbgs() << "Hardening fixed loads...\n"); - hardenLoads(MF, true); - LLVM_DEBUG(dbgs() << "Hardening fixed loads... Done\n"); - } - return false; -} - -// Apply the mitigation to `MF`, return the number of fences inserted. -// If `FixedLoads` is `true`, then the mitigation will be applied to fixed -// loads; otherwise, mitigation will be applied to non-fixed loads. -int X86LoadValueInjectionLoadHardeningPass::hardenLoads(MachineFunction &MF, - bool FixedLoads) const { - LLVM_DEBUG(dbgs() << "Building gadget graph...\n"); - const auto &MLI = getAnalysis(); - const auto &MDT = getAnalysis(); - const auto &MDF = getAnalysis(); - std::unique_ptr Graph = - getGadgetGraph(MF, MLI, MDT, MDF, FixedLoads); - LLVM_DEBUG(dbgs() << "Building gadget graph... Done\n"); - if (Graph == nullptr) - return 0; // didn't find any gadgets - - if (EmitDotVerify) { - WriteGraph(outs(), Graph.get()); - return 0; - } - - if (EmitDot || EmitDotOnly) { - LLVM_DEBUG(dbgs() << "Emitting gadget graph...\n"); - std::error_code FileError; - std::string FileName = "lvi."; - if (FixedLoads) - FileName += "fixed."; - FileName += Graph->getMF().getName(); - FileName += ".dot"; - raw_fd_ostream FileOut(FileName, FileError); - if (FileError) - errs() << FileError.message(); - WriteGraph(FileOut, Graph.get()); - FileOut.close(); - LLVM_DEBUG(dbgs() << "Emitting gadget graph... Done\n"); - if (EmitDotOnly) - return 0; - } - - return 0; -} - -std::unique_ptr -X86LoadValueInjectionLoadHardeningPass::getGadgetGraph( - MachineFunction &MF, const MachineLoopInfo &MLI, - const MachineDominatorTree &MDT, const MachineDominanceFrontier &MDF, - bool FixedLoads) const { - using namespace rdf; - - // Build the Register Dataflow Graph using the RDF framework - TargetOperandInfo TOI{*TII}; - DataFlowGraph DFG{MF, *TII, *TRI, MDT, MDF, TOI}; - DFG.build(); - Liveness L{MF.getRegInfo(), DFG}; - L.computePhiInfo(); - - GraphBuilder Builder; - using GraphIter = typename GraphBuilder::NodeRef; - DenseMap NodeMap; - int FenceCount = 0; - auto MaybeAddNode = [&NodeMap, &Builder](MachineInstr *MI) { - auto Ref = NodeMap.find(MI); - if (Ref == NodeMap.end()) { - auto I = Builder.addVertex(MI); - NodeMap[MI] = I; - return std::pair{I, true}; - } else { - return std::pair{Ref->getSecond(), false}; - } - }; - - // Analyze all machine instructions to find gadgets and LFENCEs, adding - // each interesting value to `Nodes` - DenseSet> GadgetEdgeSet; - auto AnalyzeDef = [&](NodeAddr Def) { - MachineInstr *MI = Def.Addr->getFlags() & NodeAttrs::PhiRef - ? ARG_NODE - : Def.Addr->getOp().getParent(); - auto AnalyzeUse = [&](NodeAddr Use) { - assert(!(Use.Addr->getFlags() & NodeAttrs::PhiRef)); - MachineOperand &UseMO = Use.Addr->getOp(); - MachineInstr &UseMI = *UseMO.getParent(); - assert(UseMO.isReg()); - // We naively assume that an instruction propagates any loaded Uses - // to all Defs, unless the instruction is a call - if (UseMI.isCall()) - return false; - if (instrUsesRegToAccessMemory(UseMI, UseMO.getReg()) || - (!NoConditionalBranches && - instrUsesRegToBranch(UseMI, UseMO.getReg()))) { // found a gadget! - // add the root of this chain - auto GadgetBegin = MaybeAddNode(MI); - // and the instruction that (transitively) discloses the root - auto GadgetEnd = MaybeAddNode(&UseMI); - if (GadgetEdgeSet.insert({GadgetBegin.first, GadgetEnd.first}).second) - Builder.addEdge(GADGET_EDGE, GadgetBegin.first, GadgetEnd.first); - if (UseMI.mayLoad()) // FIXME: This should be more precise - return false; // stop traversing further uses of `Reg` - } - return true; - }; - SmallSet NodesVisited; - std::function)> AnalyzeDefUseChain = - [&](NodeAddr Def) { - if (Def.Addr->getAttrs() & NodeAttrs::Dead) - return; - RegisterRef DefReg = DFG.getPRI().normalize(Def.Addr->getRegRef(DFG)); - NodeList Uses; - for (auto UseID : L.getAllReachedUses(DefReg, Def)) { - auto Use = DFG.addr(UseID); - if (Use.Addr->getFlags() & NodeAttrs::PhiRef) { // phi node - NodeAddr Phi = Use.Addr->getOwner(DFG); - for (auto I : L.getRealUses(Phi.Id)) { - if (DFG.getPRI().alias(RegisterRef(I.first), DefReg)) { - for (auto UA : I.second) { - auto PhiUse = DFG.addr(UA.first); - Uses.push_back(PhiUse); - } - } - } - } else { // not a phi node - Uses.push_back(Use); - } - } - for (auto N : Uses) { - NodeAddr Use{N}; - if (NodesVisited.insert(Use.Id).second && AnalyzeUse(Use)) { - NodeAddr Owner{Use.Addr->getOwner(DFG)}; - NodeList Defs = Owner.Addr->members_if(DataFlowGraph::IsDef, DFG); - std::for_each(Defs.begin(), Defs.end(), AnalyzeDefUseChain); - } - } - }; - AnalyzeDefUseChain(Def); - }; - - LLVM_DEBUG(dbgs() << "Analyzing def-use chains to find gadgets\n"); - // Analyze function arguments - if (!FixedLoads) { // only need to analyze function args once - NodeAddr EntryBlock = DFG.getFunc().Addr->getEntryBlock(DFG); - for (NodeAddr ArgPhi : - EntryBlock.Addr->members_if(DataFlowGraph::IsPhi, DFG)) { - NodeList Defs = ArgPhi.Addr->members_if(DataFlowGraph::IsDef, DFG); - std::for_each(Defs.begin(), Defs.end(), AnalyzeDef); - } - } - // Analyze every instruction in MF - for (NodeAddr BA : DFG.getFunc().Addr->members(DFG)) { - for (NodeAddr SA : - BA.Addr->members_if(DataFlowGraph::IsCode, DFG)) { - MachineInstr *MI = SA.Addr->getCode(); - if (isFence(MI)) { - MaybeAddNode(MI); - ++FenceCount; - } else if (MI->mayLoad() && ((FixedLoads && instrIsFixedAccess(*MI)) || - (!FixedLoads && !instrIsFixedAccess(*MI)))) { - NodeList Defs = SA.Addr->members_if(DataFlowGraph::IsDef, DFG); - std::for_each(Defs.begin(), Defs.end(), AnalyzeDef); - } - } - } - int GadgetCount = static_cast(GadgetEdgeSet.size()); - LLVM_DEBUG(dbgs() << "Found " << FenceCount << " fences\n"); - LLVM_DEBUG(dbgs() << "Found " << GadgetCount << " gadgets\n"); - if (GadgetCount == 0) - return nullptr; - NumGadgets += GadgetCount; - - // Traverse CFG to build the rest of the graph - SmallSet BlocksVisited; - std::function TraverseCFG = - [&](MachineBasicBlock *MBB, GraphIter GI, unsigned ParentDepth) { - unsigned LoopDepth = MLI.getLoopDepth(MBB); - if (!MBB->empty()) { - // Always add the first instruction in each block - auto NI = MBB->begin(); - auto BeginBB = MaybeAddNode(&*NI); - Builder.addEdge(ParentDepth, GI, BeginBB.first); - if (!BlocksVisited.insert(MBB).second) - return; - - // Add any instructions within the block that are gadget components - GI = BeginBB.first; - while (++NI != MBB->end()) { - auto Ref = NodeMap.find(&*NI); - if (Ref != NodeMap.end()) { - Builder.addEdge(LoopDepth, GI, Ref->getSecond()); - GI = Ref->getSecond(); - } - } - - // Always add the terminator instruction, if one exists - auto T = MBB->getFirstTerminator(); - if (T != MBB->end()) { - auto EndBB = MaybeAddNode(&*T); - if (EndBB.second) - Builder.addEdge(LoopDepth, GI, EndBB.first); - GI = EndBB.first; - } - } - for (MachineBasicBlock *Succ : MBB->successors()) - TraverseCFG(Succ, GI, LoopDepth); - }; - // ARG_NODE is a pseudo-instruction that represents MF args in the GadgetGraph - GraphIter ArgNode = MaybeAddNode(ARG_NODE).first; - TraverseCFG(&MF.front(), ArgNode, 0); - std::unique_ptr G{Builder.get(FenceCount, GadgetCount)}; - LLVM_DEBUG(dbgs() << "Found " << GTraits::size(G.get()) << " nodes\n"); - return G; -} - -bool X86LoadValueInjectionLoadHardeningPass::instrUsesRegToAccessMemory( - const MachineInstr &MI, unsigned Reg) const { - if (!MI.mayLoadOrStore() || MI.getOpcode() == X86::MFENCE || - MI.getOpcode() == X86::SFENCE || MI.getOpcode() == X86::LFENCE) - return false; - - // FIXME: This does not handle pseudo loading instruction like TCRETURN* - const MCInstrDesc &Desc = MI.getDesc(); - int MemRefBeginIdx = X86II::getMemoryOperandNo(Desc.TSFlags); - if (MemRefBeginIdx < 0) { - LLVM_DEBUG(dbgs() << "Warning: unable to obtain memory operand for loading " - "instruction:\n"; - MI.print(dbgs()); dbgs() << '\n';); - return false; - } - MemRefBeginIdx += X86II::getOperandBias(Desc); - - const MachineOperand &BaseMO = - MI.getOperand(MemRefBeginIdx + X86::AddrBaseReg); - const MachineOperand &IndexMO = - MI.getOperand(MemRefBeginIdx + X86::AddrIndexReg); - return (BaseMO.isReg() && BaseMO.getReg() != X86::NoRegister && - TRI->regsOverlap(BaseMO.getReg(), Reg)) || - (IndexMO.isReg() && IndexMO.getReg() != X86::NoRegister && - TRI->regsOverlap(IndexMO.getReg(), Reg)); -} - -bool X86LoadValueInjectionLoadHardeningPass::instrUsesRegToBranch( - const MachineInstr &MI, unsigned Reg) const { - if (!MI.isConditionalBranch()) - return false; - for (const MachineOperand &Use : MI.uses()) - if (Use.isReg() && Use.getReg() == Reg) - return true; - return false; -} - -template -bool X86LoadValueInjectionLoadHardeningPass::hasLoadFrom( - const MachineInstr &MI) const { - for (auto &MMO : MI.memoperands()) { - const PseudoSourceValue *PSV = MMO->getPseudoValue(); - if (PSV && PSV->kind() == K && MMO->isLoad()) - return true; - } - return false; -} - -bool X86LoadValueInjectionLoadHardeningPass::instrAccessesStackSlot( - const MachineInstr &MI) const { - // Check the PSV first - if (hasLoadFrom(MI)) - return true; - // Some loads are not marked with a PSV, so we always need to double check - const MCInstrDesc &Desc = MI.getDesc(); - int MemRefBeginIdx = X86II::getMemoryOperandNo(Desc.TSFlags); - if (MemRefBeginIdx < 0) - return false; - MemRefBeginIdx += X86II::getOperandBias(Desc); - return MI.getOperand(MemRefBeginIdx + X86::AddrBaseReg).isFI() && - MI.getOperand(MemRefBeginIdx + X86::AddrScaleAmt).isImm() && - MI.getOperand(MemRefBeginIdx + X86::AddrIndexReg).isReg() && - MI.getOperand(MemRefBeginIdx + X86::AddrDisp).isImm() && - MI.getOperand(MemRefBeginIdx + X86::AddrScaleAmt).getImm() == 1 && - MI.getOperand(MemRefBeginIdx + X86::AddrIndexReg).getReg() == - X86::NoRegister && - MI.getOperand(MemRefBeginIdx + X86::AddrDisp).getImm() == 0; -} - -bool X86LoadValueInjectionLoadHardeningPass::instrAccessesConstantPool( - const MachineInstr &MI) const { - if (hasLoadFrom(MI)) - return true; - const MCInstrDesc &Desc = MI.getDesc(); - int MemRefBeginIdx = X86II::getMemoryOperandNo(Desc.TSFlags); - if (MemRefBeginIdx < 0) - return false; - MemRefBeginIdx += X86II::getOperandBias(Desc); - return MI.getOperand(MemRefBeginIdx + X86::AddrBaseReg).isReg() && - MI.getOperand(MemRefBeginIdx + X86::AddrScaleAmt).isImm() && - MI.getOperand(MemRefBeginIdx + X86::AddrIndexReg).isReg() && - MI.getOperand(MemRefBeginIdx + X86::AddrDisp).isCPI() && - (MI.getOperand(MemRefBeginIdx + X86::AddrBaseReg).getReg() == - X86::RIP || - MI.getOperand(MemRefBeginIdx + X86::AddrBaseReg).getReg() == - X86::NoRegister) && - MI.getOperand(MemRefBeginIdx + X86::AddrScaleAmt).getImm() == 1 && - MI.getOperand(MemRefBeginIdx + X86::AddrIndexReg).getReg() == - X86::NoRegister; -} - -bool X86LoadValueInjectionLoadHardeningPass::instrAccessesGOT( - const MachineInstr &MI) const { - if (hasLoadFrom(MI)) - return true; - const MCInstrDesc &Desc = MI.getDesc(); - int MemRefBeginIdx = X86II::getMemoryOperandNo(Desc.TSFlags); - if (MemRefBeginIdx < 0) - return false; - MemRefBeginIdx += X86II::getOperandBias(Desc); - return MI.getOperand(MemRefBeginIdx + X86::AddrBaseReg).isReg() && - MI.getOperand(MemRefBeginIdx + X86::AddrScaleAmt).isImm() && - MI.getOperand(MemRefBeginIdx + X86::AddrIndexReg).isReg() && - MI.getOperand(MemRefBeginIdx + X86::AddrDisp).getTargetFlags() == - X86II::MO_GOTPCREL && - MI.getOperand(MemRefBeginIdx + X86::AddrBaseReg).getReg() == - X86::RIP && - MI.getOperand(MemRefBeginIdx + X86::AddrScaleAmt).getImm() == 1 && - MI.getOperand(MemRefBeginIdx + X86::AddrIndexReg).getReg() == - X86::NoRegister; -} - -INITIALIZE_PASS_BEGIN(X86LoadValueInjectionLoadHardeningPass, PASS_KEY, - "X86 LVI load hardening", false, false) -INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) -INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) -INITIALIZE_PASS_DEPENDENCY(MachineDominanceFrontier) -INITIALIZE_PASS_END(X86LoadValueInjectionLoadHardeningPass, PASS_KEY, - "X86 LVI load hardening", false, false) - -FunctionPass *llvm::createX86LoadValueInjectionLoadHardeningPass() { - return new X86LoadValueInjectionLoadHardeningPass(); -} diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index b4ad50d88062..a23588a07e57 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -434,10 +434,6 @@ class X86Subtarget final : public X86GenSubtargetInfo { /// POP+LFENCE+JMP sequence. bool UseLVIControlFlowIntegrity = false; - /// Insert LFENCE instructions to prevent data speculatively injected into - /// loads from being used maliciously. - bool UseLVILoadHardening = false; - /// Use software floating point for code generation. bool UseSoftFloat = false; @@ -739,7 +735,6 @@ class X86Subtarget final : public X86GenSubtargetInfo { bool preferMaskRegisters() const { return PreferMaskRegisters; } bool useGLMDivSqrtCosts() const { return UseGLMDivSqrtCosts; } bool useLVIControlFlowIntegrity() const { return UseLVIControlFlowIntegrity; } - bool useLVILoadHardening() const { return UseLVILoadHardening; } unsigned getPreferVectorWidth() const { return PreferVectorWidth; } unsigned getRequiredVectorWidth() const { return RequiredVectorWidth; } diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp index 8446ee9f4e03..b2551b64eb0d 100644 --- a/llvm/lib/Target/X86/X86TargetMachine.cpp +++ b/llvm/lib/Target/X86/X86TargetMachine.cpp @@ -83,7 +83,6 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86Target() { initializeX86SpeculativeLoadHardeningPassPass(PR); initializeX86FlagsCopyLoweringPassPass(PR); initializeX86CondBrFoldingPassPass(PR); - initializeX86LoadValueInjectionLoadHardeningPassPass(PR); initializeX86LoadValueInjectionRetHardeningPassPass(PR); initializeX86OptimizeLEAPassPass(PR); initializeX86PartialReductionPass(PR); @@ -495,7 +494,6 @@ void X86PassConfig::addMachineSSAOptimization() { void X86PassConfig::addPostRegAlloc() { addPass(createX86FloatingPointStackifierPass()); - addPass(createX86LoadValueInjectionLoadHardeningPass()); } void X86PassConfig::addPreSched2() { addPass(createX86ExpandPseudoPass()); } diff --git a/llvm/test/CodeGen/X86/O0-pipeline.ll b/llvm/test/CodeGen/X86/O0-pipeline.ll index 6b6fed0c7f20..9af81b77a70b 100644 --- a/llvm/test/CodeGen/X86/O0-pipeline.ll +++ b/llvm/test/CodeGen/X86/O0-pipeline.ll @@ -55,10 +55,6 @@ ; CHECK-NEXT: Fast Register Allocator ; CHECK-NEXT: Bundle Machine CFG Edges ; CHECK-NEXT: X86 FP Stackifier -; CHECK-NEXT: MachineDominator Tree Construction -; CHECK-NEXT: Machine Natural Loop Construction -; CHECK-NEXT: Machine Dominance Frontier Construction -; CHECK-NEXT: X86 Load Value Injection (LVI) Load Hardening ; CHECK-NEXT: Lazy Machine Block Frequency Analysis ; CHECK-NEXT: Machine Optimization Remark Emitter ; CHECK-NEXT: Prologue/Epilogue Insertion & Frame Finalization diff --git a/llvm/test/CodeGen/X86/O3-pipeline.ll b/llvm/test/CodeGen/X86/O3-pipeline.ll index 92b2b818743b..97ce5082d4f7 100644 --- a/llvm/test/CodeGen/X86/O3-pipeline.ll +++ b/llvm/test/CodeGen/X86/O3-pipeline.ll @@ -139,11 +139,9 @@ ; CHECK-NEXT: Machine Loop Invariant Code Motion ; CHECK-NEXT: Bundle Machine CFG Edges ; CHECK-NEXT: X86 FP Stackifier -; CHECK-NEXT: MachineDominator Tree Construction -; CHECK-NEXT: Machine Dominance Frontier Construction -; CHECK-NEXT: X86 Load Value Injection (LVI) Load Hardening ; CHECK-NEXT: PostRA Machine Sink ; CHECK-NEXT: Machine Block Frequency Analysis +; CHECK-NEXT: MachineDominator Tree Construction ; CHECK-NEXT: MachinePostDominator Tree Construction ; CHECK-NEXT: Lazy Machine Block Frequency Analysis ; CHECK-NEXT: Machine Optimization Remark Emitter diff --git a/llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll b/llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll deleted file mode 100644 index ba2ce26142b5..000000000000 --- a/llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll +++ /dev/null @@ -1,129 +0,0 @@ -; RUN: llc -verify-machineinstrs -mtriple=x86_64-unknown -x86-lvi-load-dot-verify -o %t < %s | FileCheck %s - -; Function Attrs: noinline nounwind optnone uwtable -define dso_local i32 @test(i32* %untrusted_user_ptr, i32* %secret, i32 %secret_size) #0 { -entry: - %untrusted_user_ptr.addr = alloca i32*, align 8 - %secret.addr = alloca i32*, align 8 - %secret_size.addr = alloca i32, align 4 - %ret_val = alloca i32, align 4 - %i = alloca i32, align 4 - store i32* %untrusted_user_ptr, i32** %untrusted_user_ptr.addr, align 8 - store i32* %secret, i32** %secret.addr, align 8 - store i32 %secret_size, i32* %secret_size.addr, align 4 - store i32 0, i32* %ret_val, align 4 - call void @llvm.x86.sse2.lfence() - store i32 0, i32* %i, align 4 - br label %for.cond - -for.cond: ; preds = %for.inc, %entry - %0 = load i32, i32* %i, align 4 - %1 = load i32, i32* %secret_size.addr, align 4 - %cmp = icmp slt i32 %0, %1 - br i1 %cmp, label %for.body, label %for.end - -for.body: ; preds = %for.cond - %2 = load i32, i32* %i, align 4 - %rem = srem i32 %2, 2 - %cmp1 = icmp eq i32 %rem, 0 - br i1 %cmp1, label %if.then, label %if.else - -if.then: ; preds = %for.body - %3 = load i32*, i32** %secret.addr, align 8 - %4 = load i32, i32* %ret_val, align 4 - %idxprom = sext i32 %4 to i64 - %arrayidx = getelementptr inbounds i32, i32* %3, i64 %idxprom - %5 = load i32, i32* %arrayidx, align 4 - %6 = load i32*, i32** %untrusted_user_ptr.addr, align 8 - store i32 %5, i32* %6, align 4 - br label %if.end - -if.else: ; preds = %for.body - %7 = load i32*, i32** %secret.addr, align 8 - %8 = load i32, i32* %ret_val, align 4 - %idxprom2 = sext i32 %8 to i64 - %arrayidx3 = getelementptr inbounds i32, i32* %7, i64 %idxprom2 - store i32 42, i32* %arrayidx3, align 4 - br label %if.end - -if.end: ; preds = %if.else, %if.then - %9 = load i32*, i32** %untrusted_user_ptr.addr, align 8 - %10 = load i32, i32* %9, align 4 - store i32 %10, i32* %ret_val, align 4 - br label %for.inc - -for.inc: ; preds = %if.end - %11 = load i32, i32* %i, align 4 - %inc = add nsw i32 %11, 1 - store i32 %inc, i32* %i, align 4 - br label %for.cond - -for.end: ; preds = %for.cond - %12 = load i32, i32* %ret_val, align 4 - ret i32 %12 -} - -; CHECK: digraph "Speculative gadgets for \"test\" function" { -; CHECK-NEXT: label="Speculative gadgets for \"test\" function"; -; CHECK: Node0x{{[0-9a-f]+}} [shape=record,color = green,label="{LFENCE\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 0]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $eax = MOV32rm %stack.4.i, 1, $noreg, 0, $noreg :: (dereferenceable load 4 from %ir.i)\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{JCC_1 %bb.6, 13, implicit killed $eflags\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{CMP32rm killed renamable $eax, %stack.2.secret_size.addr, 1, $noreg, 0, $noreg, implicit-def $eflags :: (dereferenceable load 4 from %ir.secret_size.addr)\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $eax = MOV32rm %stack.4.i, 1, $noreg, 0, $noreg :: (dereferenceable load 4 from %ir.i)\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{JCC_1 %bb.4, 5, implicit killed $eflags\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $rax = MOV64rm %stack.1.secret.addr, 1, $noreg, 0, $noreg :: (dereferenceable load 8 from %ir.secret.addr)\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $eax = MOV32rm killed renamable $rax, 4, killed renamable $rcx, 0, $noreg :: (load 4 from %ir.arrayidx)\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $rcx = MOVSX64rm32 %stack.3.ret_val, 1, $noreg, 0, $noreg :: (dereferenceable load 4 from %ir.ret_val)\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $rcx = MOV64rm %stack.0.untrusted_user_ptr.addr, 1, $noreg, 0, $noreg :: (dereferenceable load 8 from %ir.untrusted_user_ptr.addr)\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{MOV32mr killed renamable $rcx, 1, $noreg, 0, $noreg, killed renamable $eax :: (store 4 into %ir.6)\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $rax = MOV64rm %stack.1.secret.addr, 1, $noreg, 0, $noreg :: (dereferenceable load 8 from %ir.secret.addr)\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{MOV32mi killed renamable $rax, 4, killed renamable $rcx, 0, $noreg, 42 :: (store 4 into %ir.arrayidx3)\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $rcx = MOVSX64rm32 %stack.3.ret_val, 1, $noreg, 0, $noreg :: (dereferenceable load 4 from %ir.ret_val)\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $rax = MOV64rm %stack.0.untrusted_user_ptr.addr, 1, $noreg, 0, $noreg :: (dereferenceable load 8 from %ir.untrusted_user_ptr.addr)\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[color = red, style = "dashed"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $eax = MOV32rm killed renamable $rax, 1, $noreg, 0, $noreg :: (load 4 from %ir.9)\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,color = blue,label="{ARGS}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 0]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{MOV64mr %stack.0.untrusted_user_ptr.addr, 1, $noreg, 0, $noreg, killed renamable $rdi :: (store 8 into %ir.untrusted_user_ptr.addr)\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 0]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{JMP_1 %bb.5\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{JMP_1 %bb.1\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 1]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{renamable $eax = MOV32rm %stack.3.ret_val, 1, $noreg, 0, $noreg :: (dereferenceable load 4 from %ir.ret_val)\n}"]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} -> Node0x{{[0-9a-f]+}}[label = 0]; -; CHECK-NEXT: Node0x{{[0-9a-f]+}} [shape=record,label="{RET 0, $eax\n}"]; -; CHECK-NEXT: } - -; Function Attrs: nounwind -declare void @llvm.x86.sse2.lfence() #1 - -attributes #0 = { "target-features"="+lvi-cfi" - "target-features"="+lvi-load-hardening" } -attributes #1 = { nounwind } From cfe-commits at lists.llvm.org Fri Apr 3 17:21:36 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 00:21:36 +0000 (UTC) Subject: [PATCH] D77436: [DebugInfo] Fix for adding "returns cxx udt" option to functions in CodeView. In-Reply-To: References: Message-ID: <8b4541b0db9a7eefc03f125083f5d998@localhost.localdomain> rnk accepted this revision. rnk added a comment. This revision is now accepted and ready to land. LGTM! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77436/new/ https://reviews.llvm.org/D77436 From cfe-commits at lists.llvm.org Fri Apr 3 17:21:37 2020 From: cfe-commits at lists.llvm.org (Reid Kleckner via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 00:21:37 +0000 (UTC) Subject: [PATCH] D77432: [DebugInfo] Change to constructor homing debug info mode: skip constexpr constructed types In-Reply-To: References: Message-ID: <1e5c50fccd1757ee1a28ebc3be0ebb35@localhost.localdomain> rnk accepted this revision. rnk added a comment. This revision is now accepted and ready to land. Sounds good to me, lgtm Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77432/new/ https://reviews.llvm.org/D77432 From cfe-commits at lists.llvm.org Fri Apr 3 17:21:38 2020 From: cfe-commits at lists.llvm.org (Matthew Riley via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 00:21:38 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: <920d44d53f88a56896f978564817d805@localhost.localdomain> mattdr added a comment. Adding a few early style notes for the next round, but overall echo @chandlerc that this seems significantly outside of normal LLVM code. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:26 + +#ifndef IMMUTABLEGRAPH_H +#define IMMUTABLEGRAPH_H ---------------- It's sort of surprising that the LLVM style guide doesn't call this out explicitly, but `#include` guards are supposed to include the full file path. If they just used the filename, like, this, files with the same name in different paths would collide. For an example of the expected style, see an adjacent header in this directory: https://github.com/llvm/llvm-project/blob/ba8b3052b59ebee4311d10bee5209dac8747acea/llvm/lib/Target/X86/X86AsmPrinter.h#L10 ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:318 + } + auto *VertexArray = new Node[VertexSize + 1 /* terminator node */]; + auto *EdgeArray = new Edge[EdgeSize]; ---------------- As a general rule `new` is a code-smell in modern C++. This should be a `vector`. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:335 + VertexArray[VI].__edges = EdgeArray + EdgeSize; // terminator node + return new GraphT{VertexArray, VertexSize, EdgeArray, EdgeSize, + std::forward(Args)...}; ---------------- this should return a `unique_ptr` to signal ownership transfer CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 From cfe-commits at lists.llvm.org Fri Apr 3 17:21:43 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 00:21:43 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: <998136529aad1a8ebdbf0bdcd0a2c8d6@localhost.localdomain> craig.topper added inline comments. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:46-56 + using NodeValueT = _NodeValueT; + using EdgeValueT = _EdgeValueT; + using size_type = _SizeT; + class Node; + class Edge { + friend class ImmutableGraph; + template friend class ImmutableGraphBuilder; ---------------- chandlerc wrote: > Folks, this isn't even close to following LLVM's coding conventions or naming conventions. > > These violate the C++ standard. > > This shouldn't have been landed as-is. Can you all back this out and actually dig into the review and get this to match LLVM's actual coding style and standards? Reverted at 1d42c0db9a2b27c149c5bac373caa5a6d38d1f74 CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 From cfe-commits at lists.llvm.org Fri Apr 3 17:21:45 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 00:21:45 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: <299c3392d40f95b647300adf79613afe@localhost.localdomain> craig.topper updated this revision to Diff 254962. craig.topper marked an inline comment as done. craig.topper added a comment. Fix include guard on ImmutableGraph.h CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 Files: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Arch/X86.cpp clang/test/Driver/x86-target-features.c llvm/lib/Target/X86/CMakeLists.txt llvm/lib/Target/X86/ImmutableGraph.h llvm/lib/Target/X86/X86.h llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp llvm/lib/Target/X86/X86Subtarget.h llvm/lib/Target/X86/X86TargetMachine.cpp llvm/test/CodeGen/X86/O0-pipeline.ll llvm/test/CodeGen/X86/O3-pipeline.ll llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D75936.254962.patch Type: text/x-patch Size: 56666 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 18:01:36 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via cfe-commits) Date: Fri, 03 Apr 2020 18:01:36 -0700 (PDT) Subject: [clang] b11decc - [clang codegen][opaque pointers] Remove use of deprecated constructor Message-ID: <5e87dc70.1c69fb81.24e27.d440@mx.google.com> Author: Eli Friedman Date: 2020-04-03T18:00:33-07:00 New Revision: b11decc221a65d2c7290b93a4662a607a63b6d86 URL: https://github.com/llvm/llvm-project/commit/b11decc221a65d2c7290b93a4662a607a63b6d86 DIFF: https://github.com/llvm/llvm-project/commit/b11decc221a65d2c7290b93a4662a607a63b6d86.diff LOG: [clang codegen][opaque pointers] Remove use of deprecated constructor (See also D76269.) Added: Modified: clang/lib/CodeGen/CGCleanup.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp index c117dd5c25c1..5e01100db163 100644 --- a/clang/lib/CodeGen/CGCleanup.cpp +++ b/clang/lib/CodeGen/CGCleanup.cpp @@ -309,7 +309,8 @@ static void createStoreInstBefore(llvm::Value *value, Address addr, static llvm::LoadInst *createLoadInstBefore(Address addr, const Twine &name, llvm::Instruction *beforeInst) { - auto load = new llvm::LoadInst(addr.getPointer(), name, beforeInst); + auto load = new llvm::LoadInst(addr.getElementType(), addr.getPointer(), name, + beforeInst); load->setAlignment(addr.getAlignment().getAsAlign()); return load; } From cfe-commits at lists.llvm.org Fri Apr 3 18:01:39 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via cfe-commits) Date: Fri, 03 Apr 2020 18:01:39 -0700 (PDT) Subject: [clang] 83fa811 - [clang][opaque pointers] Fix up a bunch of "getType()->getElementType()" Message-ID: <5e87dc73.1c69fb81.b0d99.23f7@mx.google.com> Author: Eli Friedman Date: 2020-04-03T18:00:33-07:00 New Revision: 83fa811e5bf5b291eafd900f3072b961f64f039c URL: https://github.com/llvm/llvm-project/commit/83fa811e5bf5b291eafd900f3072b961f64f039c DIFF: https://github.com/llvm/llvm-project/commit/83fa811e5bf5b291eafd900f3072b961f64f039c.diff LOG: [clang][opaque pointers] Fix up a bunch of "getType()->getElementType()" In contexts where we know an LLVM type is a pointer, there's generally some simpler way to get the pointee type. Added: Modified: clang/lib/CodeGen/CGCall.cpp clang/lib/CodeGen/CGDecl.cpp clang/lib/CodeGen/CGObjCMac.cpp clang/lib/CodeGen/CodeGenModule.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 76520ba17541..3c44632dfd60 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1233,7 +1233,7 @@ static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty, if (llvm::StructType *SrcSTy = dyn_cast(SrcTy)) { Src = EnterStructPointerForCoercedAccess(Src, SrcSTy, DstSize, CGF); - SrcTy = Src.getType()->getElementType(); + SrcTy = Src.getElementType(); } uint64_t SrcSize = CGF.CGM.getDataLayout().getTypeAllocSize(SrcTy); @@ -1299,7 +1299,7 @@ static void CreateCoercedStore(llvm::Value *Src, bool DstIsVolatile, CodeGenFunction &CGF) { llvm::Type *SrcTy = Src->getType(); - llvm::Type *DstTy = Dst.getType()->getElementType(); + llvm::Type *DstTy = Dst.getElementType(); if (SrcTy == DstTy) { CGF.Builder.CreateStore(Src, Dst, DstIsVolatile); return; @@ -1309,7 +1309,7 @@ static void CreateCoercedStore(llvm::Value *Src, if (llvm::StructType *DstSTy = dyn_cast(DstTy)) { Dst = EnterStructPointerForCoercedAccess(Dst, DstSTy, SrcSize, CGF); - DstTy = Dst.getType()->getElementType(); + DstTy = Dst.getElementType(); } llvm::PointerType *SrcPtrTy = llvm::dyn_cast(SrcTy); @@ -4304,7 +4304,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, llvm::StructType *STy = dyn_cast(ArgInfo.getCoerceToType()); if (STy && ArgInfo.isDirect() && ArgInfo.getCanBeFlattened()) { - llvm::Type *SrcTy = Src.getType()->getElementType(); + llvm::Type *SrcTy = Src.getElementType(); uint64_t SrcSize = CGM.getDataLayout().getTypeAllocSize(SrcTy); uint64_t DstSize = CGM.getDataLayout().getTypeAllocSize(STy); diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index a9dbdb2e8713..45e9dc03b637 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -341,7 +341,7 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D, // the global to match the initializer. (We have to do this // because some types, like unions, can't be completely represented // in the LLVM type system.) - if (GV->getType()->getElementType() != Init->getType()) { + if (GV->getValueType() != Init->getType()) { llvm::GlobalVariable *OldGV = GV; GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 3986310eaa70..31ab7977b7d2 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -3634,7 +3634,7 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { // Check for a forward reference. llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true); if (GV) { - assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && + assert(GV->getValueType() == ObjCTypes.ClassTy && "Forward metaclass reference has incorrect type."); values.finishAndSetAsInitializer(GV); GV->setSection(Section); @@ -3697,7 +3697,7 @@ llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID, // Check for a forward reference. llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true); if (GV) { - assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && + assert(GV->getValueType() == ObjCTypes.ClassTy && "Forward metaclass reference has incorrect type."); values.finishAndSetAsInitializer(GV); } else { @@ -3728,7 +3728,7 @@ llvm::Constant *CGObjCMac::EmitMetaClassRef(const ObjCInterfaceDecl *ID) { llvm::GlobalValue::PrivateLinkage, nullptr, Name); - assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && + assert(GV->getValueType() == ObjCTypes.ClassTy && "Forward metaclass reference has incorrect type."); return GV; } @@ -3742,7 +3742,7 @@ llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) { llvm::GlobalValue::PrivateLinkage, nullptr, Name); - assert(GV->getType()->getElementType() == ObjCTypes.ClassTy && + assert(GV->getValueType() == ObjCTypes.ClassTy && "Forward class metadata reference has incorrect type."); return GV; } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 963638cacb1f..1645a9eb17de 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3176,7 +3176,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( } if ((isa(Entry) || isa(Entry)) && - (Entry->getType()->getElementType() == Ty)) { + (Entry->getValueType() == Ty)) { return Entry; } @@ -3225,7 +3225,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( } llvm::Constant *BC = llvm::ConstantExpr::getBitCast( - F, Entry->getType()->getElementType()->getPointerTo()); + F, Entry->getValueType()->getPointerTo()); addGlobalValReplacement(Entry, BC); } @@ -3284,7 +3284,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction( // Make sure the result is of the requested type. if (!IsIncompleteFunction) { - assert(F->getType()->getElementType() == Ty); + assert(F->getFunctionType() == Ty); return F; } @@ -3575,7 +3575,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Constant *Init = emitter.tryEmitForInitializer(*InitDecl); if (Init) { auto *InitType = Init->getType(); - if (GV->getType()->getElementType() != InitType) { + if (GV->getValueType() != InitType) { // The type of the initializer does not match the definition. // This happens when an initializer has a diff erent type from // the type of the global (because of padding at the end of a @@ -3648,7 +3648,7 @@ llvm::GlobalVariable *CodeGenModule::CreateOrReplaceCXXRuntimeVariable( if (GV) { // Check if the variable has the right type. - if (GV->getType()->getElementType() == Ty) + if (GV->getValueType() == Ty) return GV; // Because C++ name mangling, the only way we can end up with an already @@ -3992,7 +3992,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D, // "extern int x[];") and then a definition of a diff erent type (e.g. // "int x[10];"). This also happens when an initializer has a diff erent type // from the type of the global (this happens with unions). - if (!GV || GV->getType()->getElementType() != InitType || + if (!GV || GV->getValueType() != InitType || GV->getType()->getAddressSpace() != getContext().getTargetAddressSpace(GetGlobalVarAddressSpace(D))) { @@ -4472,7 +4472,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, llvm::FunctionType *Ty = getTypes().GetFunctionType(FI); // Get or create the prototype for the function. - if (!GV || (GV->getType()->getElementType() != Ty)) + if (!GV || (GV->getValueType() != Ty)) GV = cast(GetAddrOfFunction(GD, Ty, /*ForVTable=*/false, /*DontDefer=*/true, ForDefinition)); From cfe-commits at lists.llvm.org Fri Apr 3 18:26:22 2020 From: cfe-commits at lists.llvm.org (Eli Friedman via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 01:26:22 +0000 (UTC) Subject: [PATCH] D76269: [opaque pointer types] Remove deprecated Instruction/IRBuilder APIs. In-Reply-To: References: Message-ID: <74775cb8278a067f0ee53e0b6c0fec90@localhost.localdomain> efriedma updated this revision to Diff 254971. efriedma added a comment. Herald added a project: LLVM. Commited the non-header changes separately Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76269/new/ https://reviews.llvm.org/D76269 Files: llvm/include/llvm/IR/IRBuilder.h llvm/include/llvm/IR/Instructions.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D76269.254971.patch Type: text/x-patch Size: 9783 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 18:26:54 2020 From: cfe-commits at lists.llvm.org (Richard Smith via cfe-commits) Date: Fri, 03 Apr 2020 18:26:54 -0700 (PDT) Subject: [clang] 4ede887 - PR45402: Make the restrictions on constant evaluation of memcmp and Message-ID: <5e87e25e.1c69fb81.933ef.f8d6@mx.google.com> Author: Richard Smith Date: 2020-04-03T18:26:14-07:00 New Revision: 4ede8879924c08ae5b495d3f421c167d822a60be URL: https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be DIFF: https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be.diff LOG: PR45402: Make the restrictions on constant evaluation of memcmp and memchr consistent and comprehensible, and document them. We previously allowed evaluation of memcmp on arrays of integers of any size, so long as the call evaluated to 0, and allowed evaluation of memchr on any array of integral type of size 1 (including enums). The purpose of constant-evaluating these builtins is only to support constexpr std::char_traits, so we now consistently allow them on arrays of (possibly signed or unsigned) char only. Added: Modified: clang/docs/LanguageExtensions.rst clang/include/clang/Basic/DiagnosticASTKinds.td clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/constexpr-string.cpp Removed: ################################################################################ diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 558ce7dee653..6dcfd1a49f06 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -2333,10 +2333,11 @@ String builtins --------------- Clang provides constant expression evaluation support for builtins forms of -the following functions from the C standard library ```` header: +the following functions from the C standard library headers +```` and ````: * ``memchr`` -* ``memcmp`` +* ``memcmp`` (and its deprecated BSD / POSIX alias ``bcmp``) * ``strchr`` * ``strcmp`` * ``strlen`` @@ -2366,7 +2367,11 @@ In addition to the above, one further builtin is provided: constant expressions in C++11 onwards (where a cast from ``void*`` to ``char*`` is disallowed in general). -Support for constant expression evaluation for the above builtins be detected +Constant evaluation support for the ``__builtin_mem*`` functions is provided +only for arrays of ``char``, ``signed char``, or ``unsigned char``, despite +these functions accepting an argument of type ``const void*``. + +Support for constant expression evaluation for the above builtins can be detected with ``__has_feature(cxx_constexpr_string_builtins)``. Memory builtins @@ -2386,6 +2391,25 @@ more information. Note that the `size` argument must be a compile time constant. +Clang provides constant expression evaluation support for builtin forms of the +following functions from the C standard library headers +```` and ````: + +* ``memcpy`` +* ``memmove`` +* ``wmemcpy`` +* ``wmemmove`` + +In each case, the builtin form has the name of the C library function prefixed +by ``__builtin_``. + +Constant evaluation support is only provided when the source and destination +are pointers to arrays with the same trivially copyable element type, and the +given size is an exact multiple of the element size that is no greater than +the number of elements accessible through the source and destination operands. + +Constant evaluation support is not yet provided for ``__builtin_memcpy_inline``. + Atomic Min/Max builtins with memory ordering -------------------------------------------- diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td index 544573edffdf..a1415f9ec0e1 100644 --- a/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -244,6 +244,12 @@ def note_constexpr_unsupported_unsized_array : Note< def note_constexpr_unsized_array_indexed : Note< "indexing of array without known bound is not allowed " "in a constant expression">; +def note_constexpr_memcmp_unsupported : Note< + "constant evaluation of %0 between arrays of types %1 and %2 " + "is not supported; only arrays of narrow character types can be compared">; +def note_constexpr_memchr_unsupported : Note< + "constant evaluation of %0 on array of type %1 " + "is not supported; only arrays of narrow character types can be searched">; def note_constexpr_memcpy_null : Note< "%select{source|destination}2 of " "'%select{%select{memcpy|wmemcpy}1|%select{memmove|wmemmove}1}0' " diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index c6e1cc7b67df..a83b2e24e17f 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -8469,8 +8469,12 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, } // Give up on byte-oriented matching against multibyte elements. // FIXME: We can compare the bytes in the correct order. - if (IsRawByte && Info.Ctx.getTypeSizeInChars(CharTy) != CharUnits::One()) + if (IsRawByte && !CharTy->isCharType()) { + Info.FFDiag(E, diag::note_constexpr_memchr_unsupported) + << (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") + << CharTy; return false; + } // Figure out what value we're actually looking for (after converting to // the corresponding unsigned type if necessary). uint64_t DesiredVal; @@ -8586,6 +8590,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, QualType T = Dest.Designator.getType(Info.Ctx); QualType SrcT = Src.Designator.getType(Info.Ctx); if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) { + // FIXME: Consider using our bit_cast implementation to support this. Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) << Move << SrcT << T; return false; } @@ -11149,6 +11154,16 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, CharTy1, E->getArg(0)->getType()->getPointeeType()) && Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2))); + // For memcmp, allow comparing any arrays of '[[un]signed] char', + // but no other types. + if (IsRawByte && !(CharTy1->isCharType() && CharTy2->isCharType())) { + // FIXME: Consider using our bit_cast implementation to support this. + Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported) + << (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") + << CharTy1 << CharTy2; + return false; + } + const auto &ReadCurElems = [&](APValue &Char1, APValue &Char2) { return handleLValueToRValueConversion(Info, E, CharTy1, String1, Char1) && handleLValueToRValueConversion(Info, E, CharTy2, String2, Char2) && @@ -11159,57 +11174,6 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, HandleLValueArrayAdjustment(Info, E, String2, CharTy2, 1); }; - if (IsRawByte) { - uint64_t BytesRemaining = MaxLength; - // Pointers to const void may point to objects of incomplete type. - if (CharTy1->isIncompleteType()) { - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy1; - return false; - } - if (CharTy2->isIncompleteType()) { - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << CharTy2; - return false; - } - uint64_t CharTy1Width{Info.Ctx.getTypeSize(CharTy1)}; - CharUnits CharTy1Size = Info.Ctx.toCharUnitsFromBits(CharTy1Width); - // Give up on comparing between elements with disparate widths. - if (CharTy1Size != Info.Ctx.getTypeSizeInChars(CharTy2)) - return false; - uint64_t BytesPerElement = CharTy1Size.getQuantity(); - assert(BytesRemaining && "BytesRemaining should not be zero: the " - "following loop considers at least one element"); - while (true) { - APValue Char1, Char2; - if (!ReadCurElems(Char1, Char2)) - return false; - // We have compatible in-memory widths, but a possible type and - // (for `bool`) internal representation mismatch. - // Assuming two's complement representation, including 0 for `false` and - // 1 for `true`, we can check an appropriate number of elements for - // equality even if they are not byte-sized. - APSInt Char1InMem = Char1.getInt().extOrTrunc(CharTy1Width); - APSInt Char2InMem = Char2.getInt().extOrTrunc(CharTy1Width); - if (Char1InMem.ne(Char2InMem)) { - // If the elements are byte-sized, then we can produce a three-way - // comparison result in a straightforward manner. - if (BytesPerElement == 1u) { - // memcmp always compares unsigned chars. - return Success(Char1InMem.ult(Char2InMem) ? -1 : 1, E); - } - // The result is byte-order sensitive, and we have multibyte elements. - // FIXME: We can compare the remaining bytes in the correct order. - return false; - } - if (!AdvanceElems()) - return false; - if (BytesRemaining <= BytesPerElement) - break; - BytesRemaining -= BytesPerElement; - } - // Enough elements are equal to account for the memcmp limit. - return Success(0, E); - } - bool StopAtNull = (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp && BuiltinOp != Builtin::BIwmemcmp && @@ -11227,7 +11191,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, APValue Char1, Char2; if (!ReadCurElems(Char1, Char2)) return false; - if (Char1.getInt() != Char2.getInt()) { + if (Char1.getInt().ne(Char2.getInt())) { if (IsWide) // wmemcmp compares with wchar_t signedness. return Success(Char1.getInt() < Char2.getInt() ? -1 : 1, E); // memcmp always compares unsigned chars. diff --git a/clang/test/SemaCXX/constexpr-string.cpp b/clang/test/SemaCXX/constexpr-string.cpp index f540be8f8e5b..79ac3bf2cc4d 100644 --- a/clang/test/SemaCXX/constexpr-string.cpp +++ b/clang/test/SemaCXX/constexpr-string.cpp @@ -47,7 +47,7 @@ extern "C" { extern wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n); } -# 45 "SemaCXX/constexpr-string.cpp" 2 +# 51 "SemaCXX/constexpr-string.cpp" 2 namespace Strlen { constexpr int n = __builtin_strlen("hello"); // ok static_assert(n == 5); @@ -121,13 +121,13 @@ namespace StrcmpEtc { extern struct Incomplete incomplete; static_assert(__builtin_memcmp(&incomplete, "", 0u) == 0); static_assert(__builtin_memcmp("", &incomplete, 0u) == 0); - static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // expected-error {{not an integral constant}} expected-note {{read of incomplete type 'struct Incomplete'}} - static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // expected-error {{not an integral constant}} expected-note {{read of incomplete type 'struct Incomplete'}} + static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // expected-error {{not an integral constant}} expected-note {{not supported}} + static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // expected-error {{not an integral constant}} expected-note {{not supported}} static_assert(__builtin_bcmp(&incomplete, "", 0u) == 0); static_assert(__builtin_bcmp("", &incomplete, 0u) == 0); - static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // expected-error {{not an integral constant}} expected-note {{read of incomplete type 'struct Incomplete'}} - static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // expected-error {{not an integral constant}} expected-note {{read of incomplete type 'struct Incomplete'}} + static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // expected-error {{not an integral constant}} expected-note {{not supported}} + static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // expected-error {{not an integral constant}} expected-note {{not supported}} constexpr unsigned char ku00fe00[] = {0x00, 0xfe, 0x00}; constexpr unsigned char ku00feff[] = {0x00, 0xfe, 0xff}; @@ -155,11 +155,11 @@ namespace StrcmpEtc { struct Bool3Tuple { bool bb[3]; }; constexpr Bool3Tuple kb000100 = {{false, true, false}}; - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, kb000100.bb, 1) == 0); - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, kb000100.bb, 2) == 1); + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, kb000100.bb, 2) == 1); // expected-error {{constant}} expected-note {{not supported}} - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, kb000100.bb, 1) == 0); - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, kb000100.bb, 2) != 0); + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, kb000100.bb, 2) != 0); // expected-error {{constant}} expected-note {{not supported}} constexpr long ksl[] = {0, -1}; constexpr unsigned int kui[] = {0, 0u - 1}; @@ -173,25 +173,25 @@ namespace StrcmpEtc { return nullptr; } } - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) - 1) == 0); - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + 0) == 0); - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + 1) == 0); - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) - 1) == 0); - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + 0) == 0); - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + 1) == 42); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) - 1) == 0); - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) + 0) == 0); - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) + 1) == 42); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} - - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - 1) == 0); - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 0) == 0); - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 1) == 0); - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) - 1) == 0); - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + 0) == 0); - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + 1) == 42); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) - 1) == 0); - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) + 0) == 0); - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) + 1) == 42); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + 1) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + 1) == 42); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) + 1) == 42); // expected-error {{constant}} expected-note {{not supported}} + + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 1) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + 1) == 42); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note {{not supported}} + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, sizeof(long) + 1) == 42); // expected-error {{constant}} expected-note {{not supported}} constexpr int a = strcmp("hello", "world"); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strcmp' cannot be used in a constant expression}} constexpr int b = strncmp("hello", "world", 3); // expected-error {{constant expression}} expected-note {{non-constexpr function 'strncmp' cannot be used in a constant expression}} @@ -385,14 +385,14 @@ namespace StrchrEtc { enum class E : unsigned char {}; struct EPair { E e, f; }; constexpr EPair ee{E{240}}; - static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); + static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); // expected-error {{constant}} expected-note {{not supported}} constexpr bool kBool[] = {false, true, false}; constexpr const bool *const kBoolPastTheEndPtr = kBool + 3; - static_assert(sizeof(bool) != 1u || __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); - static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, 0, 99) == kBoolPastTheEndPtr - 1); - static_assert(sizeof(bool) != 1u || __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); - static_assert(sizeof(bool) != 1u || __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); // expected-error {{constant}} expected-note {{not supported}} + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, 0, 99) == kBoolPastTheEndPtr - 1); // expected-error {{constant}} expected-note {{not supported}} + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); // expected-error {{constant}} expected-note {{not supported}} + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // expected-error {{constant}} expected-note {{not supported}} static_assert(__builtin_char_memchr(kStr, 'a', 0) == nullptr); static_assert(__builtin_char_memchr(kStr, 'a', 1) == kStr); From cfe-commits at lists.llvm.org Fri Apr 3 19:30:33 2020 From: cfe-commits at lists.llvm.org (ADRA via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 02:30:33 +0000 (UTC) Subject: [PATCH] D77451: Accept -x cu to indicate language is CUDA, transfer CUDA language flag to header-file arguments Message-ID: ADRAADRA created this revision. ADRAADRA added a reviewer: tra. ADRAADRA added a project: clang. Herald added subscribers: cfe-commits, yaxunl. - accept -x cu to indicate language is CUDA - transfer CUDA language flag to header-file arguments Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77451 Files: clang/lib/Driver/Types.cpp clang/lib/Tooling/InterpolatingCompilationDatabase.cpp Index: clang/lib/Tooling/InterpolatingCompilationDatabase.cpp =================================================================== --- clang/lib/Tooling/InterpolatingCompilationDatabase.cpp +++ clang/lib/Tooling/InterpolatingCompilationDatabase.cpp @@ -114,6 +114,10 @@ case types::TY_ObjCXX: case types::TY_ObjCXXHeader: return types::TY_ObjCXX; + case types::TY_CUDA: + case types::TY_CUDA_DEVICE: + case types::TY_CUDA_FATBIN: + return types::TY_CUDA: default: return types::TY_INVALID; } Index: clang/lib/Driver/Types.cpp =================================================================== --- clang/lib/Driver/Types.cpp +++ clang/lib/Driver/Types.cpp @@ -295,7 +295,10 @@ strcmp(Name, getInfo(Id).Name) == 0) return Id; } - + // accept -x cu to indicate CUDA + if (strcmp(Name, "cu") == 0) { + return types::TY_CUDA; + } return TY_INVALID; } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77451.254980.patch Type: text/x-patch Size: 905 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 19:30:34 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 02:30:34 +0000 (UTC) Subject: [PATCH] D77414: [OpenMP] Add match_{all,any,none} declare variant selector extensions. In-Reply-To: References: Message-ID: jdoerfert updated this revision to Diff 254983. jdoerfert added a comment. Allow the new match clauses to be used in `begin/end declare variant` as well (with their respective effect) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77414/new/ https://reviews.llvm.org/D77414 Files: clang/include/clang/AST/OpenMPClause.h clang/include/clang/Basic/AttrDocs.td clang/include/clang/Basic/DiagnosticParseKinds.td clang/lib/AST/OpenMPClause.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/test/AST/ast-dump-openmp-declare-variant-extensions-messages.c clang/test/AST/ast-dump-openmp-declare-variant-extensions.c clang/test/OpenMP/declare_variant_ast_print.c clang/test/OpenMP/declare_variant_messages.c llvm/include/llvm/Frontend/OpenMP/OMPContext.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPContext.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77414.254983.patch Type: text/x-patch Size: 53434 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 20:02:29 2020 From: cfe-commits at lists.llvm.org (Richard Smith - zygoloid via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 03:02:29 +0000 (UTC) Subject: [PATCH] D77184: Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang In-Reply-To: References: Message-ID: <2ec8e996410dcc413c571726c8664a30@localhost.localdomain> rsmith added a comment. This has broken my ability to run the `check-clang` target on Linux. There are symlinks in the path from which I run my builds, and this patch is computing incorrect relative paths in that situation. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77184/new/ https://reviews.llvm.org/D77184 From cfe-commits at lists.llvm.org Fri Apr 3 20:02:30 2020 From: cfe-commits at lists.llvm.org (Richard Smith - zygoloid via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 03:02:30 +0000 (UTC) Subject: [PATCH] D77184: Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang In-Reply-To: References: Message-ID: <03227e155f30edda13da3fb8264f0ba7@localhost.localdomain> rsmith added a comment. In D77184#1961208 , @rsmith wrote: > This has broken my ability to run the `check-clang` target on Linux. There are symlinks in the path from which I run my builds, and this patch is computing incorrect relative paths in that situation. This patch appears to fix the problem: diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake index e0ceb364c3e..10010ce8caa 100644 --- a/llvm/cmake/modules/AddLLVM.cmake +++ b/llvm/cmake/modules/AddLLVM.cmake @@ -1505,7 +1505,7 @@ drive = os.path.splitdrive(sys.argv[1])[0]\n def relpath(p):\n if not p: return ''\n if os.path.splitdrive(p)[0] != drive: return p\n - return os.path.relpath(p, sys.argv[1]).replace(os.sep, '/')\n + return os.path.relpath(os.path.realpath(p), os.path.realpath(sys.argv[1])).replace(os.sep, '/')\n sys.stdout.write(';'.join(relpath(p) for p in sys.argv[2].split(';')))" ${OUTPUT_DIR} ${ARG_PATH_VALUES_ESCAPED} Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77184/new/ https://reviews.llvm.org/D77184 From cfe-commits at lists.llvm.org Fri Apr 3 20:21:02 2020 From: cfe-commits at lists.llvm.org (Richard Smith via cfe-commits) Date: Fri, 03 Apr 2020 20:21:02 -0700 (PDT) Subject: [clang] 179f4ba - Don't treat a CXXScopeSpec with a nested name specifier but no location Message-ID: <5e87fd1e.1c69fb81.41c36.0bee@mx.google.com> Author: Richard Smith Date: 2020-04-03T20:20:48-07:00 New Revision: 179f4baba0672a5e85c5db91095c4cd701a2d32d URL: https://github.com/llvm/llvm-project/commit/179f4baba0672a5e85c5db91095c4cd701a2d32d DIFF: https://github.com/llvm/llvm-project/commit/179f4baba0672a5e85c5db91095c4cd701a2d32d.diff LOG: Don't treat a CXXScopeSpec with a nested name specifier but no location as invalid. We create those when forming trivial type source information with no associated location, which, unfortunately, we do create in some cases (when a TreeTransform with no base location is used to transform a QualType). This would previously lead to rejects-valid bugs when we misinterpreted these constructs as having no nested-name-specifier. Added: Modified: clang/include/clang/Sema/DeclSpec.h clang/test/SemaCXX/nested-name-spec.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index 78010b7bb46e..0e95e237e974 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -186,14 +186,14 @@ class CXXScopeSpec { SourceLocation getLastQualifierNameLoc() const; /// No scope specifier. - bool isEmpty() const { return !Range.isValid(); } + bool isEmpty() const { return Range.isInvalid() && getScopeRep() == nullptr; } /// A scope specifier is present, but may be valid or invalid. bool isNotEmpty() const { return !isEmpty(); } /// An error occurred during parsing of the scope specifier. - bool isInvalid() const { return isNotEmpty() && getScopeRep() == nullptr; } + bool isInvalid() const { return Range.isValid() && getScopeRep() == nullptr; } /// A scope specifier is present, and it refers to a real scope. - bool isValid() const { return isNotEmpty() && getScopeRep() != nullptr; } + bool isValid() const { return getScopeRep() != nullptr; } /// Indicate that this nested-name-specifier is invalid. void SetInvalid(SourceRange R) { diff --git a/clang/test/SemaCXX/nested-name-spec.cpp b/clang/test/SemaCXX/nested-name-spec.cpp index 725ac64cedb7..403bf1c0d4aa 100644 --- a/clang/test/SemaCXX/nested-name-spec.cpp +++ b/clang/test/SemaCXX/nested-name-spec.cpp @@ -460,3 +460,16 @@ class B { }; } } + +namespace DependentTemplateInTrivialNNSLoc { + // This testcase causes us to create trivial type source info when doing + // substitution into T::template g<>. That trivial type source info contained + // a NestedNameSpecifierLoc with no location information. + // + // Previously, creating a CXXScopeSpec from that resulted in an invalid scope + // spec, leading to crashes. Ensure we don't crash here. + template void f(T &x) { + for (typename T::template g<> i : x) {} // expected-warning 0-1{{extension}} + x: goto x; + } +} From cfe-commits at lists.llvm.org Fri Apr 3 20:34:36 2020 From: cfe-commits at lists.llvm.org (Richard Smith - zygoloid via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 03:34:36 +0000 (UTC) Subject: [PATCH] D77184: Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang In-Reply-To: References: Message-ID: rsmith added a comment. In D77184#1961214 , @rsmith wrote: > In D77184#1961208 , @rsmith wrote: > > > This has broken my ability to run the `check-clang` target on Linux. There are symlinks in the path from which I run my builds, and this patch is computing incorrect relative paths in that situation. > > > This patch appears to fix the problem: Turns out that's only a partial fix (it fixes `ninja clang-check` but not the general problem). Running `lit` from inside the source directory is still broken. Eg, this used to work: clang/test$ $BUILDDIR/bin/llvm-lit SemaCXX/constant-expression.cpp ... and doesn't work any more because the relative paths in `lit.site.cfg.py` don't seem to resolve to the right places. Please can you fix or revert? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77184/new/ https://reviews.llvm.org/D77184 From cfe-commits at lists.llvm.org Fri Apr 3 21:06:59 2020 From: cfe-commits at lists.llvm.org (Sriraman Tallam via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 04:06:59 +0000 (UTC) Subject: [PATCH] D68049: Propeller: Clang options for basic block sections In-Reply-To: References: Message-ID: tmsriram updated this revision to Diff 254999. tmsriram marked 4 inline comments as done. tmsriram added a comment. Fix test and make error check at driver. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68049/new/ https://reviews.llvm.org/D68049 Files: clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Basic/CodeGenOptions.h clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/test/CodeGen/basicblock-sections.c clang/test/CodeGen/basicblock-sections.funcnames clang/test/Driver/fbasicblock-sections.c clang/test/Driver/funique-bb-section-names.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D68049.254999.patch Type: text/x-patch Size: 11535 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 21:06:59 2020 From: cfe-commits at lists.llvm.org (Sriraman Tallam via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 04:06:59 +0000 (UTC) Subject: [PATCH] D68049: Propeller: Clang options for basic block sections In-Reply-To: References: Message-ID: <4a6a5860e7c12ed6ef0d4ab65e4dddfa@localhost.localdomain> tmsriram added inline comments. ================ Comment at: clang/test/CodeGen/basicblock-sections.c:35 +// +// BB_WORLD: .section .text.world,"ax", at progbits +// BB_WORLD: world ---------------- MaskRay wrote: > I haven't read through the previous threads whether we should use a .c -> .s test here. Assume we've decided to do that, `@progbits` should be followed by `{{$}}` to ensure there is no unique assembly linkage. Fixed. About .c->.s, this is similar to what function-sections.c does too. Please let me know if I missed anything. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68049/new/ https://reviews.llvm.org/D68049 From cfe-commits at lists.llvm.org Fri Apr 3 21:06:59 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 04:06:59 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: craig.topper updated this revision to Diff 255000. craig.topper added a comment. Remove underscores from names. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 Files: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Arch/X86.cpp clang/test/Driver/x86-target-features.c llvm/lib/Target/X86/CMakeLists.txt llvm/lib/Target/X86/ImmutableGraph.h llvm/lib/Target/X86/X86.h llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp llvm/lib/Target/X86/X86Subtarget.h llvm/lib/Target/X86/X86TargetMachine.cpp llvm/test/CodeGen/X86/O0-pipeline.ll llvm/test/CodeGen/X86/O3-pipeline.ll llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D75936.255000.patch Type: text/x-patch Size: 56395 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 21:38:49 2020 From: cfe-commits at lists.llvm.org (Justin Hibbits via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 04:38:49 +0000 (UTC) Subject: [PATCH] D73290: [PowerPC] Add clang -msvr4-struct-return for 32-bit ELF In-Reply-To: References: Message-ID: <06e6ad2844a083d66802db8abd6b6051@localhost.localdomain> jhibbits edited reviewers, added: jhibbits; removed: chmeee. jhibbits accepted this revision. jhibbits added a comment. This revision is now accepted and ready to land. Code looks fine, and others have tested it. Good to see a reversion of the ABI to expected for GCC compatibility on the BSDs. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D73290/new/ https://reviews.llvm.org/D73290 From cfe-commits at lists.llvm.org Fri Apr 3 22:10:41 2020 From: cfe-commits at lists.llvm.org (Scott Constable via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 05:10:41 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: <04bc05b2d19b99e973f1418cbd1dd43f@localhost.localdomain> sconstab added inline comments. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:318 + } + auto *VertexArray = new Node[VertexSize + 1 /* terminator node */]; + auto *EdgeArray = new Edge[EdgeSize]; ---------------- mattdr wrote: > As a general rule `new` is a code-smell in modern C++. This should be a `vector`. @mattdr I do agree with the general rule. I also think that in this case where the structure is immutable, std::vector is wasteful because it needs to keep separate values for the current number of elements and the current capacity. At local scope within a function the unneeded value would likely be optimized away, but then there would be an awkward handoff to transfer the data from the vector to the array members. I would not want to see the array members changed to vectors, unless LLVM provides an encapsulated array structure that does not need to grow and shrink. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:335 + VertexArray[VI].__edges = EdgeArray + EdgeSize; // terminator node + return new GraphT{VertexArray, VertexSize, EdgeArray, EdgeSize, + std::forward(Args)...}; ---------------- mattdr wrote: > this should return a `unique_ptr` to signal ownership transfer Yes, agree. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 From cfe-commits at lists.llvm.org Fri Apr 3 22:15:35 2020 From: cfe-commits at lists.llvm.org (Sam McCall via cfe-commits) Date: Fri, 03 Apr 2020 22:15:35 -0700 (PDT) Subject: [clang-tools-extra] a975fde - [clang] Annotate trivial getters and setters on hover. Message-ID: <5e8817f7.1c69fb81.f09a9.e37c@mx.google.com> Author: Sam McCall Date: 2020-04-04T07:15:12+02:00 New Revision: a975fde23a5e64721d75022b2a072a0b19f4b279 URL: https://github.com/llvm/llvm-project/commit/a975fde23a5e64721d75022b2a072a0b19f4b279 DIFF: https://github.com/llvm/llvm-project/commit/a975fde23a5e64721d75022b2a072a0b19f4b279.diff LOG: [clang] Annotate trivial getters and setters on hover. Summary: (Only if their definitions are visible and they have no other docs) Reviewers: kadircet Subscribers: jkorous, arphaman, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77408 Added: Modified: clang-tools-extra/clangd/Hover.cpp clang-tools-extra/clangd/unittests/HoverTests.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp index 63fe6b1d756c..e54ba2e364a0 100644 --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -21,9 +21,11 @@ #include "clang/AST/ASTTypeTraits.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/OperationKinds.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/Type.h" #include "clang/Basic/SourceLocation.h" @@ -370,6 +372,97 @@ llvm::Optional printExprValue(const SelectionTree::Node *N, return llvm::None; } +llvm::Optional fieldName(const Expr *E) { + const auto *ME = llvm::dyn_cast(E->IgnoreCasts()); + if (!ME || !llvm::isa(ME->getBase()->IgnoreCasts())) + return llvm::None; + const auto *Field = + llvm::dyn_cast(ME->getMemberDecl()); + if (!Field || !Field->getDeclName().isIdentifier()) + return llvm::None; + return Field->getDeclName().getAsIdentifierInfo()->getName(); +} + +// If CMD is of the form T foo() { return FieldName; } then returns "FieldName". +llvm::Optional getterVariableName(const CXXMethodDecl *CMD) { + assert(CMD->hasBody()); + if (CMD->getNumParams() != 0 || CMD->isVariadic()) + return llvm::None; + const auto *Body = llvm::dyn_cast(CMD->getBody()); + const auto *OnlyReturn = (Body && Body->size() == 1) + ? llvm::dyn_cast(Body->body_front()) + : nullptr; + if (!OnlyReturn || !OnlyReturn->getRetValue()) + return llvm::None; + return fieldName(OnlyReturn->getRetValue()); +} + +// If CMD is one of the forms: +// void foo(T arg) { FieldName = arg; } +// R foo(T arg) { FieldName = arg; return *this; } +// then returns "FieldName" +llvm::Optional setterVariableName(const CXXMethodDecl *CMD) { + assert(CMD->hasBody()); + if (CMD->isConst() || CMD->getNumParams() != 1 || CMD->isVariadic()) + return llvm::None; + const ParmVarDecl *Arg = CMD->getParamDecl(0); + if (Arg->isParameterPack()) + return llvm::None; + + const auto *Body = llvm::dyn_cast(CMD->getBody()); + if (!Body || Body->size() == 0 || Body->size() > 2) + return llvm::None; + // If the second statement exists, it must be `return this` or `return *this`. + if (Body->size() == 2) { + auto *Ret = llvm::dyn_cast(Body->body_back()); + if (!Ret || !Ret->getRetValue()) + return llvm::None; + const Expr *RetVal = Ret->getRetValue()->IgnoreCasts(); + if (const auto *UO = llvm::dyn_cast(RetVal)) { + if (UO->getOpcode() != UO_Deref) + return llvm::None; + RetVal = UO->getSubExpr()->IgnoreCasts(); + } + if (!llvm::isa(RetVal)) + return llvm::None; + } + // The first statement must be an assignment of the arg to a field. + const Expr *LHS, *RHS; + if (const auto *BO = llvm::dyn_cast(Body->body_front())) { + if (BO->getOpcode() != BO_Assign) + return llvm::None; + LHS = BO->getLHS(); + RHS = BO->getRHS(); + } else if (const auto *COCE = + llvm::dyn_cast(Body->body_front())) { + if (COCE->getOperator() != OO_Equal || COCE->getNumArgs() != 2) + return llvm::None; + LHS = COCE->getArg(0); + RHS = COCE->getArg(1); + } else { + return llvm::None; + } + auto *DRE = llvm::dyn_cast(RHS->IgnoreCasts()); + if (!DRE || DRE->getDecl() != Arg) + return llvm::None; + return fieldName(LHS); +} + +std::string synthesizeDocumentation(const NamedDecl *ND) { + if (const auto *CMD = llvm::dyn_cast(ND)) { + // Is this an ordinary, non-static method whose definition is visible? + if (CMD->getDeclName().isIdentifier() && !CMD->isStatic() && + (CMD = llvm::dyn_cast_or_null(CMD->getDefinition())) && + CMD->hasBody()) { + if (const auto GetterField = getterVariableName(CMD)) + return llvm::formatv("Trivial accessor for `{0}`.", *GetterField); + if (const auto SetterField = setterVariableName(CMD)) + return llvm::formatv("Trivial setter for `{0}`.", *SetterField); + } + } + return ""; +} + /// Generate a \p Hover object given the declaration \p D. HoverInfo getHoverContents(const NamedDecl *D, const SymbolIndex *Index) { HoverInfo HI; @@ -387,6 +480,8 @@ HoverInfo getHoverContents(const NamedDecl *D, const SymbolIndex *Index) { const auto *CommentD = getDeclForComment(D); HI.Documentation = getDeclComment(Ctx, *CommentD); enhanceFromIndex(HI, *CommentD, Index); + if (HI.Documentation.empty()) + HI.Documentation = synthesizeDocumentation(D); HI.Kind = index::getSymbolInfo(D).Kind; diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp index 99fd1c572447..f9ab78dd753b 100644 --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -616,6 +616,58 @@ class Foo {})cpp"; HI.LocalScope = "foo::"; HI.Type = "int"; }}, + + {// Getter + R"cpp( + struct X { int Y; float [[^y]]() { return Y; } }; + )cpp", + [](HoverInfo &HI) { + HI.Name = "y"; + HI.Kind = index::SymbolKind::InstanceMethod; + HI.NamespaceScope = ""; + HI.Definition = "float y()"; + HI.LocalScope = "X::"; + HI.Documentation = "Trivial accessor for `Y`."; + HI.Type = "float ()"; + HI.ReturnType = "float"; + HI.Parameters.emplace(); + }}, + {// Setter + R"cpp( + struct X { int Y; void [[^setY]](float v) { Y = v; } }; + )cpp", + [](HoverInfo &HI) { + HI.Name = "setY"; + HI.Kind = index::SymbolKind::InstanceMethod; + HI.NamespaceScope = ""; + HI.Definition = "void setY(float v)"; + HI.LocalScope = "X::"; + HI.Documentation = "Trivial setter for `Y`."; + HI.Type = "void (float)"; + HI.ReturnType = "void"; + HI.Parameters.emplace(); + HI.Parameters->emplace_back(); + HI.Parameters->back().Type = "float"; + HI.Parameters->back().Name = "v"; + }}, + {// Setter (builder) + R"cpp( + struct X { int Y; X& [[^setY]](float v) { Y = v; return *this; } }; + )cpp", + [](HoverInfo &HI) { + HI.Name = "setY"; + HI.Kind = index::SymbolKind::InstanceMethod; + HI.NamespaceScope = ""; + HI.Definition = "X &setY(float v)"; + HI.LocalScope = "X::"; + HI.Documentation = "Trivial setter for `Y`."; + HI.Type = "struct X &(float)"; + HI.ReturnType = "struct X &"; + HI.Parameters.emplace(); + HI.Parameters->emplace_back(); + HI.Parameters->back().Type = "float"; + HI.Parameters->back().Name = "v"; + }}, }; for (const auto &Case : Cases) { SCOPED_TRACE(Case.Code); From cfe-commits at lists.llvm.org Fri Apr 3 22:42:31 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 05:42:31 +0000 (UTC) Subject: [PATCH] D77408: [clang] Annotate trivial getters and setters on hover. In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. sammccall marked an inline comment as done. Closed by commit rGa975fde23a5e: [clang] Annotate trivial getters and setters on hover. (authored by sammccall). Changed prior to commit: https://reviews.llvm.org/D77408?vs=254819&id=255004#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77408/new/ https://reviews.llvm.org/D77408 Files: clang-tools-extra/clangd/Hover.cpp clang-tools-extra/clangd/unittests/HoverTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77408.255004.patch Type: text/x-patch Size: 6984 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Fri Apr 3 23:08:00 2020 From: cfe-commits at lists.llvm.org (Sam McCall via cfe-commits) Date: Fri, 03 Apr 2020 23:08:00 -0700 (PDT) Subject: [clang-tools-extra] ebd522a - [clangd] Tweak parseDocumentation loop to use raw lines. NFC Message-ID: <5e882440.1c69fb81.2ff55.1845@mx.google.com> Author: Sam McCall Date: 2020-04-04T08:07:51+02:00 New Revision: ebd522aaa8aad74ea44db5bb4b74f1b784da9f99 URL: https://github.com/llvm/llvm-project/commit/ebd522aaa8aad74ea44db5bb4b74f1b784da9f99 DIFF: https://github.com/llvm/llvm-project/commit/ebd522aaa8aad74ea44db5bb4b74f1b784da9f99.diff LOG: [clangd] Tweak parseDocumentation loop to use raw lines. NFC This clears the way for the raw lines themselves to be parsed easily. (Okay, one functional change: fix punctuation linebreaks with trailing WS) Added: Modified: clang-tools-extra/clangd/Hover.cpp clang-tools-extra/clangd/unittests/HoverTests.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp index e54ba2e364a0..71ab985affa2 100644 --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -616,46 +616,39 @@ llvm::Optional getHoverContents(const Expr *E, ParsedAST &AST) { return llvm::None; } -bool isParagraphLineBreak(llvm::StringRef Str, size_t LineBreakIndex) { - return Str.substr(LineBreakIndex + 1) - .drop_while([](auto C) { return C == ' ' || C == '\t'; }) - .startswith("\n"); +bool isParagraphBreak(llvm::StringRef Rest) { + return Rest.ltrim(" \t").startswith("\n"); } -bool isPunctuationLineBreak(llvm::StringRef Str, size_t LineBreakIndex) { +bool punctuationIndicatesLineBreak(llvm::StringRef Line) { constexpr llvm::StringLiteral Punctuation = R"txt(.:,;!?)txt"; - return LineBreakIndex > 0 && Punctuation.contains(Str[LineBreakIndex - 1]); + Line = Line.rtrim(); + return !Line.empty() && Punctuation.contains(Line.back()); } -bool isFollowedByHardLineBreakIndicator(llvm::StringRef Str, - size_t LineBreakIndex) { +bool isHardLineBreakIndicator(llvm::StringRef Rest) { // '-'/'*' md list, '@'/'\' documentation command, '>' md blockquote, // '#' headings, '`' code blocks - constexpr llvm::StringLiteral LinbreakIdenticators = R"txt(-*@\>#`)txt"; + constexpr llvm::StringLiteral LinebreakIndicators = R"txt(-*@\>#`)txt"; - auto NextNonSpaceCharIndex = Str.find_first_not_of(' ', LineBreakIndex + 1); - - if (NextNonSpaceCharIndex == llvm::StringRef::npos) { + Rest = Rest.ltrim(" \t"); + if (Rest.empty()) return false; - } - - auto FollowedBySingleCharIndicator = - LinbreakIdenticators.find(Str[NextNonSpaceCharIndex]) != - llvm::StringRef::npos; - auto FollowedByNumberedListIndicator = - llvm::isDigit(Str[NextNonSpaceCharIndex]) && - NextNonSpaceCharIndex + 1 < Str.size() && - (Str[NextNonSpaceCharIndex + 1] == '.' || - Str[NextNonSpaceCharIndex + 1] == ')'); + if (LinebreakIndicators.contains(Rest.front())) + return true; - return FollowedBySingleCharIndicator || FollowedByNumberedListIndicator; + if (llvm::isDigit(Rest.front())) { + llvm::StringRef AfterDigit = Rest.drop_while(llvm::isDigit); + if (AfterDigit.startswith(".") || AfterDigit.startswith(")")) + return true; + } + return false; } -bool isHardLineBreak(llvm::StringRef Str, size_t LineBreakIndex) { - return isPunctuationLineBreak(Str, LineBreakIndex) || - isFollowedByHardLineBreakIndicator(Str, LineBreakIndex); +bool isHardLineBreakAfter(llvm::StringRef Line, llvm::StringRef Rest) { + return punctuationIndicatesLineBreak(Line) || isHardLineBreakIndicator(Rest); } } // namespace @@ -814,42 +807,32 @@ markup::Document HoverInfo::present() const { } void parseDocumentation(llvm::StringRef Input, markup::Document &Output) { + std::vector ParagraphLines; + auto FlushParagraph = [&] { + if (ParagraphLines.empty()) + return; + auto &P = Output.addParagraph(); + for (llvm::StringRef Line : ParagraphLines) + P.appendText(Line.str()); + ParagraphLines.clear(); + }; - constexpr auto WhiteSpaceChars = "\t\n\v\f\r "; - - auto TrimmedInput = Input.trim(); - - std::string CurrentLine; - - for (size_t CharIndex = 0; CharIndex < TrimmedInput.size();) { - if (TrimmedInput[CharIndex] == '\n') { - // Trim whitespace infront of linebreak - const auto LastNonSpaceCharIndex = - CurrentLine.find_last_not_of(WhiteSpaceChars) + 1; - CurrentLine.erase(LastNonSpaceCharIndex); + llvm::StringRef Line, Rest; + for (std::tie(Line, Rest) = Input.split('\n'); + !(Line.empty() && Rest.empty()); + std::tie(Line, Rest) = Rest.split('\n')) { - if (isParagraphLineBreak(TrimmedInput, CharIndex) || - isHardLineBreak(TrimmedInput, CharIndex)) { - // FIXME: maybe distinguish between line breaks and paragraphs - Output.addParagraph().appendText(CurrentLine); - CurrentLine = ""; - } else { - // Ommit linebreak - CurrentLine += ' '; - } + // After a linebreak remove spaces to avoid 4 space markdown code blocks. + // FIXME: make FlushParagraph handle this. + Line = Line.ltrim(); + if (!Line.empty()) + ParagraphLines.push_back(Line); - CharIndex++; - // After a linebreak always remove spaces to avoid 4 space markdown code - // blocks, also skip all additional linebreaks since they have no effect - CharIndex = TrimmedInput.find_first_not_of(WhiteSpaceChars, CharIndex); - } else { - CurrentLine += TrimmedInput[CharIndex]; - CharIndex++; + if (isParagraphBreak(Rest) || isHardLineBreakAfter(Line, Rest)) { + FlushParagraph(); } } - if (!CurrentLine.empty()) { - Output.addParagraph().appendText(CurrentLine); - } + FlushParagraph(); } llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp index f9ab78dd753b..b51329e95f2c 100644 --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -1980,6 +1980,11 @@ TEST(Hover, DocCommentLineBreakConversion) { "foo. \nbar", "foo.\nbar", }, + { + "foo. \nbar", + "foo. \nbar", + "foo.\nbar", + }, { "foo\n*bar", "foo \n\\*bar", From cfe-commits at lists.llvm.org Sat Apr 4 00:19:41 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 07:19:41 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: <788993e8d5c05fa99c8b0872e1dccdcf@localhost.localdomain> craig.topper updated this revision to Diff 255008. craig.topper added a comment. This revision is now accepted and ready to land. Use std::unique_ptr for arrays in the graph. I started trying to use std::vector, but it kept crashing. Which initially I thought was some issue with the fact that we store pointers into the vectors in other places and that somehow std::move of the vector was breaking that. I think I now realize its because the array is 1 larger than the real number of nodes and my std::vector version didn't take that into account. But thinking about it more, since we are storing pointers into the array, it probably makes more sense for it to just be a plain array than a vector since resizing a vector would invalidate those pointers. Using an array makes it more clear than we don't resize. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 Files: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Arch/X86.cpp clang/test/Driver/x86-target-features.c llvm/lib/Target/X86/CMakeLists.txt llvm/lib/Target/X86/ImmutableGraph.h llvm/lib/Target/X86/X86.h llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp llvm/lib/Target/X86/X86Subtarget.h llvm/lib/Target/X86/X86TargetMachine.cpp llvm/test/CodeGen/X86/O0-pipeline.ll llvm/test/CodeGen/X86/O3-pipeline.ll llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D75936.255008.patch Type: text/x-patch Size: 56845 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 00:19:42 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 07:19:42 +0000 (UTC) Subject: [PATCH] D77456: [clangd] Parse `foo` in documentation comments and render as code. Message-ID: sammccall created this revision. sammccall added a reviewer: kadircet. Herald added subscribers: cfe-commits, usaxena95, arphaman, jkorous, MaskRay, ilya-biryukov. Herald added a project: clang. sammccall added a comment. Some saturday morning procrastination. But I'm wondering how good an idea this is for plaintext: "Returns 'foo' on failure" is better than "Returns foo on failure", right? (With backticks instead of single quotes, phab is eating my formatting) Maybe we should have an Emphasis flag or something on plaintext to preserve the quotes? (We don't want to include them e.g. in the return type chunks) Also, realized our model for whitespace around paragraph chunks isn't ideal after all :-( Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77456 Files: clang-tools-extra/clangd/FormattedString.cpp clang-tools-extra/clangd/FormattedString.h clang-tools-extra/clangd/Hover.cpp clang-tools-extra/clangd/unittests/HoverTests.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77456.255010.patch Type: text/x-patch Size: 6814 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 00:19:43 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 07:19:43 +0000 (UTC) Subject: [PATCH] D77456: [clangd] Parse `foo` in documentation comments and render as code. In-Reply-To: References: Message-ID: <3c0d13c38a76dd3ee7ff149ea805aa5c@localhost.localdomain> sammccall added a comment. Some saturday morning procrastination. But I'm wondering how good an idea this is for plaintext: "Returns 'foo' on failure" is better than "Returns foo on failure", right? (With backticks instead of single quotes, phab is eating my formatting) Maybe we should have an Emphasis flag or something on plaintext to preserve the quotes? (We don't want to include them e.g. in the return type chunks) Also, realized our model for whitespace around paragraph chunks isn't ideal after all :-( Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77456/new/ https://reviews.llvm.org/D77456 From cfe-commits at lists.llvm.org Sat Apr 4 00:19:43 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 07:19:43 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: craig.topper updated this revision to Diff 255011. craig.topper added a comment. Use unique_ptr::operator[] in a few places. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 Files: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Arch/X86.cpp clang/test/Driver/x86-target-features.c llvm/lib/Target/X86/CMakeLists.txt llvm/lib/Target/X86/ImmutableGraph.h llvm/lib/Target/X86/X86.h llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp llvm/lib/Target/X86/X86Subtarget.h llvm/lib/Target/X86/X86TargetMachine.cpp llvm/test/CodeGen/X86/O0-pipeline.ll llvm/test/CodeGen/X86/O3-pipeline.ll llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D75936.255011.patch Type: text/x-patch Size: 56835 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 02:05:16 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Balogh, _=C3=81d=C3=A1m_via_Phabricator?= via cfe-commits) Date: Sat, 04 Apr 2020 09:05:16 +0000 (UTC) Subject: [PATCH] D77150: [Analyzer] New Option for ContainerModeling: AggressiveEraseModeling In-Reply-To: References: Message-ID: baloghadamsoftware marked an inline comment as done. baloghadamsoftware added inline comments. ================ Comment at: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td:647-653 CmdLineOption ]>, ---------------- Szelethus wrote: > Ah, okay, I see which one you refer to. We should totally make this non-user facing as well. The option is not about state split! It is for choosing between the (default) conservative approach and a more aggressive one. It is absolutely for the user to set. Some users prefer less false positive for the price of losing true positives. However, some other users prefer more true positives for the price of additional false positives. This is why we have checker options to be able to serve both groups. This feature was explicitly requested by our users who first disabled iterator checkers because of the too many false positives but later re-enabled them because they run into a bug in a production system which could have been prevented by enabling them. However, they run into another bug that our checker did not find because of its conservative behavior. They requested a more aggressive one but we must not do it for everyone. The concept of the Analyzer is that we apply the conservative approach by default and the aggressive can be enabled by analyzer and checker options. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77150/new/ https://reviews.llvm.org/D77150 From cfe-commits at lists.llvm.org Sat Apr 4 02:30:36 2020 From: cfe-commits at lists.llvm.org (Matthew Riley via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 09:30:36 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: <133510ce92083cf86c544ec3c2c81251@localhost.localdomain> mattdr added inline comments. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:318 + } + auto *VertexArray = new Node[VertexSize + 1 /* terminator node */]; + auto *EdgeArray = new Edge[EdgeSize]; ---------------- sconstab wrote: > mattdr wrote: > > As a general rule `new` is a code-smell in modern C++. This should be a `vector`. > @mattdr I do agree with the general rule. I also think that in this case where the structure is immutable, std::vector is wasteful because it needs to keep separate values for the current number of elements and the current capacity. At local scope within a function the unneeded value would likely be optimized away, but then there would be an awkward handoff to transfer the data from the vector to the array members. > > I would not want to see the array members changed to vectors, unless LLVM provides an encapsulated array structure that does not need to grow and shrink. So, first: I'm glad you removed the unnecessary use of `new[]` here and the corresponding (and error-prone!) use of `delete[]` later. That removes a memory leak LLVM won't have to debug. You suggest here that something other than `std::vector` would be more efficient. If so, would `std::array` suffice? If not, can you explain why static allocation is impossible but dynamic allocation would be too expensive? ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:13 +/// The advantages to this implementation are two-fold: +/// 1. Iteration and traversal operations should experience terrific caching +/// performance. ---------------- erm, "terrific"? If there's a substantive argument w.r.t. cache locality etc., please make it explicit. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:16 +/// 2. Set representations and operations on nodes and edges become +/// extraordinarily efficient. For instance, a set of edges is implemented as +/// a bit vector, wherein each bit corresponds to one edge in the edge ---------------- "extraordinarily" is, again, not a useful engineering categorization. Please restrict comments to describing quantifiable claims of complexity. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:40 + +template +class ImmutableGraph { ---------------- Every template argument for a class represents combinatorial addition of complexity for the resulting code. Why do each of these template arguments need to exist? in particular, why does SizeT need to exist? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 From cfe-commits at lists.llvm.org Sat Apr 4 02:30:38 2020 From: cfe-commits at lists.llvm.org (Vitaly Buka via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 09:30:38 +0000 (UTC) Subject: [PATCH] D77374: Fix -fsanitize=array-bounds with comma operator In-Reply-To: References: Message-ID: vitalybuka updated this revision to Diff 255016. vitalybuka added a comment. try arc diff Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77374/new/ https://reviews.llvm.org/D77374 Files: clang/lib/CodeGen/CGExpr.cpp clang/test/CodeGen/bounds-checking.c clang/test/CodeGen/bounds-checking.cpp Index: clang/test/CodeGen/bounds-checking.cpp =================================================================== --- clang/test/CodeGen/bounds-checking.cpp +++ clang/test/CodeGen/bounds-checking.cpp @@ -98,3 +98,19 @@ return s->a[i]; // CHECK: } } + +// CHECK-LABEL: define {{.*}} @_Z10SFlexComma +int SFlexComma(struct SFlex *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return (s->t, s->a)[i]; + // CHECK: } +} + +// CHECK-LABEL: define {{.*}} @_Z7S1Comma +int S1Comma(struct S1 *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return ((s->t, (1, s->a)))[i]; + // CHECK: } +} Index: clang/test/CodeGen/bounds-checking.c =================================================================== --- clang/test/CodeGen/bounds-checking.c +++ clang/test/CodeGen/bounds-checking.c @@ -100,3 +100,19 @@ return s->a[i]; // CHECK: } } + +// CHECK-LABEL: define {{.*}} @SFlexComma +int SFlexComma(struct SFlex *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return (s->t, s->a)[i]; + // CHECK: } +} + +// CHECK-LABEL: define {{.*}} @S1Comma +int S1Comma(struct S1 *s, int i) { + // a and b are treated as flexible array members. + // CHECK-NOT: @llvm.trap + return (s->t, s->a)[i]; + // CHECK: } +} Index: clang/lib/CodeGen/CGExpr.cpp =================================================================== --- clang/lib/CodeGen/CGExpr.cpp +++ clang/lib/CodeGen/CGExpr.cpp @@ -879,6 +879,13 @@ E = E->IgnoreParens(); + while (const BinaryOperator *BO = dyn_cast(E)) { + if (!BO->isCommaOp()) + break; + E = BO->getRHS(); + E = E->IgnoreParens(); + } + // A flexible array member must be the last member in the class. if (const auto *ME = dyn_cast(E)) { // FIXME: If the base type of the member expr is not FD->getParent(), -------------- next part -------------- A non-text attachment was scrubbed... Name: D77374.255016.patch Type: text/x-patch Size: 1938 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 03:02:58 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 10:02:58 +0000 (UTC) Subject: [PATCH] D77456: [clangd] Parse `foo` in documentation comments and render as code. In-Reply-To: References: Message-ID: kadircet accepted this revision. kadircet added a comment. This revision is now accepted and ready to land. LGTM, thanks! Regarding spaces between code and text chunks, are you suggesting we should print: Tests primality of`p` if so, i do believe having a space before the backtick vs not having it is two totally different rendering decisions. And I think the former is more common, why do you think we should not put that space? I suppose we can modify the spacing logic for markdown to only put a separator between same chunk types, but I don't think that'll look any better especially in plugins like coc.nvim. ================ Comment at: clang-tools-extra/clangd/Hover.cpp:840 +void parseDocumentationLine(llvm::StringRef Line, markup::Paragraph &Out) { + // Probably this is appendText(Input), but scan for something interesting. + for (unsigned I = 0; I < Line.size(); ++I) { ---------------- nit: s/Input/Line/ Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77456/new/ https://reviews.llvm.org/D77456 From cfe-commits at lists.llvm.org Sat Apr 4 03:08:45 2020 From: cfe-commits at lists.llvm.org (Kadir Cetinkaya via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 10:08:45 +0000 (UTC) Subject: [PATCH] D77456: [clangd] Parse `foo` in documentation comments and render as code. In-Reply-To: References: Message-ID: kadircet added a comment. > But I'm wondering how good an idea this is for plaintext: "Returns 'foo' on failure" is better than "Returns foo on failure", right? (With backticks instead of single quotes, phab is eating my formatting) ah sorry missed that one. That's actually a good point, I didn't dwell on it too much because I don't think having backticks in plaintext is that useful. But thinking about it again some people might find it useful especially in long documentations to figure out which parts of it to focus on. So this might be a regression for them, it would be nice to have some feedback mechanism for driving such decisions. So far it has been just the reviewer and the author of the patch :D So having a `raw` paragraph chunk(in addition to plaintext and inline code). might be a middle ground here. Plaintext renderers will keep showing the documentation as it is written in the source code, including backticks, whereas markdown renderers would display a more `rich` text. WDYT? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77456/new/ https://reviews.llvm.org/D77456 From cfe-commits at lists.llvm.org Sat Apr 4 03:35:23 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 10:35:23 +0000 (UTC) Subject: [PATCH] D77458: [clang-tools-extra] NFC: Fix trivial typo in documents and comments Message-ID: kiszk created this revision. Herald added subscribers: cfe-commits, phosek, usaxena95, kadircet, jfb, arphaman, jkorous, kbarton, nemanjai. Herald added a project: clang. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77458 Files: clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp clang-tools-extra/clang-change-namespace/ChangeNamespace.h clang-tools-extra/clang-doc/Generators.cpp clang-tools-extra/clang-doc/Serialize.cpp clang-tools-extra/clang-include-fixer/IncludeFixer.h clang-tools-extra/clang-include-fixer/IncludeFixerContext.h clang-tools-extra/clang-include-fixer/SymbolIndexManager.cpp clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp clang-tools-extra/clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py clang-tools-extra/clang-include-fixer/tool/clang-include-fixer.py clang-tools-extra/clang-move/Move.cpp clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.cpp clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp clang-tools-extra/clang-tidy/bugprone/FoldInitTypeCheck.cpp clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp clang-tools-extra/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h clang-tools-extra/clangd/AST.cpp clang-tools-extra/clangd/ClangdLSPServer.h clang-tools-extra/clangd/Diagnostics.cpp clang-tools-extra/clangd/FindSymbols.h clang-tools-extra/clangd/FindTarget.cpp clang-tools-extra/clangd/FindTarget.h clang-tools-extra/clangd/FormattedString.cpp clang-tools-extra/clangd/Hover.cpp clang-tools-extra/clangd/Hover.h clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/PathMapping.cpp clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Quality.cpp clang-tools-extra/clangd/QueryDriverDatabase.cpp clang-tools-extra/clangd/index/Background.cpp clang-tools-extra/clangd/index/Serialization.cpp clang-tools-extra/clangd/index/SymbolOrigin.h clang-tools-extra/clangd/index/dex/Trigram.cpp clang-tools-extra/clangd/refactor/Rename.cpp clang-tools-extra/clangd/refactor/Rename.h clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp clang-tools-extra/clangd/tool/ClangdMain.cpp clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp clang-tools-extra/clangd/unittests/CollectMacrosTests.cpp clang-tools-extra/clangd/unittests/FindTargetTests.cpp clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp clang-tools-extra/clangd/unittests/PathMappingTests.cpp clang-tools-extra/clangd/unittests/RenameTests.cpp clang-tools-extra/clangd/unittests/SymbolInfoTests.cpp clang-tools-extra/clangd/unittests/TweakTests.cpp clang-tools-extra/docs/clang-tidy/checks/abseil-no-internal-dependencies.rst clang-tools-extra/docs/clang-tidy/checks/bugprone-misplaced-pointer-arithmetic-in-alloc.rst clang-tools-extra/docs/clang-tidy/checks/bugprone-virtual-near-miss.rst clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst clang-tools-extra/docs/clang-tidy/checks/portability-restrict-system-includes.rst clang-tools-extra/docs/clang-tidy/checks/readability-convert-member-functions-to-static.rst clang-tools-extra/docs/clang-tidy/checks/readability-make-member-function-const.rst clang-tools-extra/docs/doxygen.cfg.in clang-tools-extra/docs/pp-trace.rst clang-tools-extra/modularize/CoverageChecker.cpp clang-tools-extra/modularize/CoverageChecker.h clang-tools-extra/modularize/Modularize.cpp clang-tools-extra/modularize/PreprocessorTracker.cpp clang-tools-extra/pp-trace/PPCallbacksTracker.h clang-tools-extra/test/clang-move/move-used-helper-decls.cpp clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header-fixed.h clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header.h clang-tools-extra/test/clang-tidy/checkers/abseil-duration-subtraction.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-branch-clone.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-throw-keyword-missing.cpp clang-tools-extra/test/clang-tidy/checkers/cert-throw-exception-type.cpp clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-custom.cpp clang-tools-extra/test/clang-tidy/checkers/fuchsia-multiple-inheritance.cpp clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-bug34747.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-make-unique.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp clang-tools-extra/unittests/clang-include-fixer/IncludeFixerTest.cpp clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D77458.255017.patch Type: text/x-patch Size: 86894 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 03:40:29 2020 From: cfe-commits at lists.llvm.org (Sylvestre Ledru via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 10:40:29 +0000 (UTC) Subject: [PATCH] D77458: [clang-tools-extra] NFC: Fix trivial typo in documents and comments In-Reply-To: References: Message-ID: <78260b3a041bee7d219ad7e0a9620ba2@localhost.localdomain> sylvestre.ledru added a comment. Herald added a subscriber: wuzish. You used codespell for this? Thanks Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77458/new/ https://reviews.llvm.org/D77458 From cfe-commits at lists.llvm.org Sat Apr 4 04:08:40 2020 From: cfe-commits at lists.llvm.org (Mark Nauwelaerts via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 11:08:40 +0000 (UTC) Subject: [PATCH] D77385: [clangd] Add index export to dexp In-Reply-To: References: Message-ID: <04173e99a90adacbe05d5756e7fe7603@localhost.localdomain> mnauw updated this revision to Diff 255019. mnauw retitled this revision from "[clangd] Add index inspection helper tool" to "[clangd] Add index export to dexp". mnauw edited the summary of this revision. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77385/new/ https://reviews.llvm.org/D77385 Files: clang-tools-extra/clangd/index/YAMLSerialization.cpp clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77385.255019.patch Type: text/x-patch Size: 8857 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 04:42:10 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 11:42:10 +0000 (UTC) Subject: [PATCH] D77085: [clang-tidy] Added support for validating configuration options In-Reply-To: References: Message-ID: njames93 updated this revision to Diff 255023. njames93 added a comment. - Extended support for boolean types Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77085/new/ https://reviews.llvm.org/D77085 Files: clang-tools-extra/clang-tidy/ClangTidyCheck.cpp clang-tools-extra/clang-tidy/ClangTidyCheck.h clang-tools-extra/unittests/clang-tidy/ClangTidyOptionsTest.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77085.255023.patch Type: text/x-patch Size: 31558 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 04:42:12 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 11:42:12 +0000 (UTC) Subject: [PATCH] D77085: [clang-tidy] Added support for validating configuration options In-Reply-To: References: Message-ID: <3ba49df37993fcdcbee13490ea7437c8@localhost.localdomain> njames93 added a comment. I added support for bools. The previous integer parsing behaviour is still there, however now it also responds to `true` or `false`. This won't parse `True|TRUE|False|FALSE` etc as I wanted it to be in line with `.clang-format` configuration files for handling of bool. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77085/new/ https://reviews.llvm.org/D77085 From cfe-commits at lists.llvm.org Sat Apr 4 04:42:15 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 11:42:15 +0000 (UTC) Subject: [PATCH] D76606: [clang-tidy] Change checks that take enum configurations to use a new access method. In-Reply-To: References: Message-ID: njames93 updated this revision to Diff 255027. njames93 added a comment. Herald added subscribers: arphaman, kbarton, nemanjai. - Change checks that take enum configurations to use a new access method. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76606/new/ https://reviews.llvm.org/D76606 Files: clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/InitVariablesCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp clang-tools-extra/clang-tidy/performance/MoveConstructorInitCheck.cpp clang-tools-extra/clang-tidy/performance/TypePromotionInMathFnCheck.cpp clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp clang-tools-extra/clang-tidy/utils/IncludeSorter.cpp clang-tools-extra/clang-tidy/utils/IncludeSorter.h clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-case-violation.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76606.255027.patch Type: text/x-patch Size: 23568 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 05:15:55 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 12:15:55 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: craig.topper updated this revision to Diff 255028. craig.topper added a comment. -Add edge_begin()/edge_end()/edges() to Node class. Hides the N+1 trick used to find the end of a Node's edges. -Add nodes()/edges() and use range-based for loops. -Stop using things in the traits class since it doesn't have range-based for loops. -Const-correct as required since nodes()/edges() return an ArrayRef that ends up making the range for loops const. -Use llvm::for_each instead of std::for_each. -Rename Node::value()/Edge::value() to getValue() to align with llvm naming convention. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 Files: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Arch/X86.cpp clang/test/Driver/x86-target-features.c llvm/lib/Target/X86/CMakeLists.txt llvm/lib/Target/X86/ImmutableGraph.h llvm/lib/Target/X86/X86.h llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp llvm/lib/Target/X86/X86Subtarget.h llvm/lib/Target/X86/X86TargetMachine.cpp llvm/test/CodeGen/X86/O0-pipeline.ll llvm/test/CodeGen/X86/O3-pipeline.ll llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D75936.255028.patch Type: text/x-patch Size: 57281 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 05:47:52 2020 From: cfe-commits at lists.llvm.org (Carlos Alberto Enciso via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 12:47:52 +0000 (UTC) Subject: [PATCH] D77184: Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang In-Reply-To: References: Message-ID: <12c1e0afa10c2b28cbe329043b00b54c@localhost.localdomain> CarlosAlbertoEnciso added a comment. In D77184#1960473 , @thakis wrote: > I pushed Andrew's fix (thanks!) (with minor formatting tweaks) in dbb0d8ecb3a024bd6817ebd8ad8c5c199a51d933 . Let me know if you still see issues. It fixes the Windows issues when building from different drive. Thanks Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77184/new/ https://reviews.llvm.org/D77184 From cfe-commits at lists.llvm.org Sat Apr 4 06:20:07 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 13:20:07 +0000 (UTC) Subject: [PATCH] D77458: [clang-tools-extra] NFC: Fix trivial typo in documents and comments In-Reply-To: References: Message-ID: <75fde629e54b34be85152834b9320b3a@localhost.localdomain> kiszk added a comment. I used aspell for this. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77458/new/ https://reviews.llvm.org/D77458 From cfe-commits at lists.llvm.org Sat Apr 4 06:55:08 2020 From: cfe-commits at lists.llvm.org (David Zarzycki via cfe-commits) Date: Sat, 04 Apr 2020 09:55:08 -0400 Subject: =?UTF-8?Q?Re:_[clang]_4ede887_-_PR45402:_Make_the_restrictions_on_consta?= =?UTF-8?Q?nt_evaluation_of_memcmp_and?= In-Reply-To: <5e87e25e.1c69fb81.933ef.f8d6@mx.google.com> References: <5e87e25e.1c69fb81.933ef.f8d6@mx.google.com> Message-ID: Hi Richard, This breaks libcxx. Can we please revert this or is a quick fix to libcxx possible? FAIL: libc++ :: std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp (58624 of 62672) ******************** TEST 'libc++ :: std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp' FAILED ******************** Command: ['/p/tllvm/bin/clang++', '-o', '/tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o', '-x', 'c++', '/home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp', '-c', '-v', '-Werror=thread-safety', '-std=c++2a', '-include', '/home/dave/s/lp/libcxx/test/support/nasty_macros.h', '-nostdinc++', '-I/home/dave/s/lp/libcxx/include', '-I/tmp/_update_lc/t/projects/libcxx/include/c++build', '-D__STDC_FORMAT_MACROS', '-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-I/home/dave/s/lp/libcxx/test/support', '-ftemplate-depth=270', '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER', '-Wall', '-Wextra', '-Werror', '-Wuser-defined-warnings', '-Wshadow', '-Wno-unused-command-line-argument', '-Wno-attributes', '-Wno-pessimizing-move', '-Wno-c++11-extensions', '-Wno-user-defined-literals', '-Wno-noexcept-type', '-Wsign-compare', '-Wunused-variable', '-Wunused-parameter', '-Wunreachable-code', '-c'] Exit Code: 1 Standard Error: -- clang version 11.0.0 (https://github.com/llvm/llvm-project.git 22127da8f17c03c69231f3631472f7f99ad9cb7f) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /p/tllvm/bin Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 Selected GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 Candidate multilib: .;@m64 Candidate multilib: 32;@m32 Selected multilib: .;@m64 (in-process) "/p/tllvm/bin/clang-11" -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name compare.pass.cpp -mrelocation-model static -mthread-model posix -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -v -nostdinc++ -resource-dir /p/tllvm/lib64/clang/11.0.0 -include /home/dave/s/lp/libcxx/test/support/nasty_macros.h -I /home/dave/s/lp/libcxx/include -I /tmp/_update_lc/t/projects/libcxx/include/c++build -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -I /home/dave/s/lp/libcxx/test/support -D _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -internal-isystem /usr/local/include -internal-isystem /p/tllvm/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Werror=thread-safety -Wall -Wextra -Werror -Wuser-defined-warnings -Wshadow -Wno-unused-command-line-argument -Wno-attributes -Wno-pessimizing-move -Wno-c++11-extensions -Wno-user-defined-literals -Wno-noexcept-type -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code -std=c++2a -fdeprecated-macro -fdebug-compilation-dir /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t -ftemplate-depth 270 -ferror-limit 19 -fgnuc-version=4.2.1 -fno-implicit-modules -fcxx-exceptions -fexceptions -faddrsig -o /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o -x c++ /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp clang -cc1 version 11.0.0 based upon LLVM 11.0.0git default target x86_64-unknown-linux-gnu ignoring nonexistent directory "/include" #include "..." search starts here: #include <...> search starts here: /home/dave/s/lp/libcxx/include /tmp/_update_lc/t/projects/libcxx/include/c++build /home/dave/s/lp/libcxx/test/support /usr/local/include /p/tllvm/lib64/clang/11.0.0/include /usr/include End of search list. /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: error: static_assert expression is not an integral constant expression static_assert(test_constexpr(), "" ); ^~~~~~~~~~~~~~~~ /home/dave/s/lp/libcxx/include/__string:662:12: note: constant evaluation of '__builtin_memcmp' between arrays of types 'const char8_t' and 'const char8_t' is not supported; only arrays of narrow character types can be compared return __builtin_memcmp(__s1, __s2, __n); ^ /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:24:12: note: in call to 'compare(&u8"123"[0], &u8"223"[0], 3)' return std::char_traits::compare(u8"123", u8"223", 3) < 0 ^ /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: note: in call to 'test_constexpr()' static_assert(test_constexpr(), "" ); ^ 1 error generated. -- Compilation failed unexpectedly! ******************** Testing Time: 135.49s ******************** Failing Tests (1): libc++ :: std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp Expected Passes : 45503 Expected Failures : 118 Unsupported Tests : 17050 Unexpected Failures: 1 On Fri, Apr 3, 2020, at 9:26 PM, Richard Smith via cfe-commits wrote: > > Author: Richard Smith > Date: 2020-04-03T18:26:14-07:00 > New Revision: 4ede8879924c08ae5b495d3f421c167d822a60be > > URL: > https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be > DIFF: > https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be.diff > > LOG: PR45402: Make the restrictions on constant evaluation of memcmp and > memchr consistent and comprehensible, and document them. > > We previously allowed evaluation of memcmp on arrays of integers of any > size, so long as the call evaluated to 0, and allowed evaluation of > memchr on any array of integral type of size 1 (including enums). The > purpose of constant-evaluating these builtins is only to support > constexpr std::char_traits, so we now consistently allow them on arrays > of (possibly signed or unsigned) char only. > > Added: > > > Modified: > clang/docs/LanguageExtensions.rst > clang/include/clang/Basic/DiagnosticASTKinds.td > clang/lib/AST/ExprConstant.cpp > clang/test/SemaCXX/constexpr-string.cpp > > Removed: > > > > ################################################################################ > diff --git a/clang/docs/LanguageExtensions.rst > b/clang/docs/LanguageExtensions.rst > index 558ce7dee653..6dcfd1a49f06 100644 > --- a/clang/docs/LanguageExtensions.rst > +++ b/clang/docs/LanguageExtensions.rst > @@ -2333,10 +2333,11 @@ String builtins > --------------- > > Clang provides constant expression evaluation support for builtins forms of > -the following functions from the C standard library ```` header: > +the following functions from the C standard library headers > +```` and ````: > > * ``memchr`` > -* ``memcmp`` > +* ``memcmp`` (and its deprecated BSD / POSIX alias ``bcmp``) > * ``strchr`` > * ``strcmp`` > * ``strlen`` > @@ -2366,7 +2367,11 @@ In addition to the above, one further builtin is > provided: > constant expressions in C++11 onwards (where a cast from ``void*`` to > ``char*`` > is disallowed in general). > > -Support for constant expression evaluation for the above builtins be > detected > +Constant evaluation support for the ``__builtin_mem*`` functions is > provided > +only for arrays of ``char``, ``signed char``, or ``unsigned char``, > despite > +these functions accepting an argument of type ``const void*``. > + > +Support for constant expression evaluation for the above builtins can > be detected > with ``__has_feature(cxx_constexpr_string_builtins)``. > > Memory builtins > @@ -2386,6 +2391,25 @@ more information. > > Note that the `size` argument must be a compile time constant. > > +Clang provides constant expression evaluation support for builtin > forms of the > +following functions from the C standard library headers > +```` and ````: > + > +* ``memcpy`` > +* ``memmove`` > +* ``wmemcpy`` > +* ``wmemmove`` > + > +In each case, the builtin form has the name of the C library function > prefixed > +by ``__builtin_``. > + > +Constant evaluation support is only provided when the source and > destination > +are pointers to arrays with the same trivially copyable element type, > and the > +given size is an exact multiple of the element size that is no greater > than > +the number of elements accessible through the source and destination > operands. > + > +Constant evaluation support is not yet provided for > ``__builtin_memcpy_inline``. > + > Atomic Min/Max builtins with memory ordering > -------------------------------------------- > > > diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td > b/clang/include/clang/Basic/DiagnosticASTKinds.td > index 544573edffdf..a1415f9ec0e1 100644 > --- a/clang/include/clang/Basic/DiagnosticASTKinds.td > +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td > @@ -244,6 +244,12 @@ def note_constexpr_unsupported_unsized_array : > Note< > def note_constexpr_unsized_array_indexed : Note< > "indexing of array without known bound is not allowed " > "in a constant expression">; > +def note_constexpr_memcmp_unsupported : Note< > + "constant evaluation of %0 between arrays of types %1 and %2 " > + "is not supported; only arrays of narrow character types can be > compared">; > +def note_constexpr_memchr_unsupported : Note< > + "constant evaluation of %0 on array of type %1 " > + "is not supported; only arrays of narrow character types can be > searched">; > def note_constexpr_memcpy_null : Note< > "%select{source|destination}2 of " > "'%select{%select{memcpy|wmemcpy}1|%select{memmove|wmemmove}1}0' " > > diff --git a/clang/lib/AST/ExprConstant.cpp > b/clang/lib/AST/ExprConstant.cpp > index c6e1cc7b67df..a83b2e24e17f 100644 > --- a/clang/lib/AST/ExprConstant.cpp > +++ b/clang/lib/AST/ExprConstant.cpp > @@ -8469,8 +8469,12 @@ bool > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, > } > // Give up on byte-oriented matching against multibyte elements. > // FIXME: We can compare the bytes in the correct order. > - if (IsRawByte && Info.Ctx.getTypeSizeInChars(CharTy) != > CharUnits::One()) > + if (IsRawByte && !CharTy->isCharType()) { > + Info.FFDiag(E, diag::note_constexpr_memchr_unsupported) > + << (std::string("'") + > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") > + << CharTy; > return false; > + } > // Figure out what value we're actually looking for (after > converting to > // the corresponding unsigned type if necessary). > uint64_t DesiredVal; > @@ -8586,6 +8590,7 @@ bool > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, > QualType T = Dest.Designator.getType(Info.Ctx); > QualType SrcT = Src.Designator.getType(Info.Ctx); > if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) { > + // FIXME: Consider using our bit_cast implementation to support > this. > Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) << Move << > SrcT << T; > return false; > } > @@ -11149,6 +11154,16 @@ bool > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, > CharTy1, E->getArg(0)->getType()->getPointeeType()) && > Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2))); > > + // For memcmp, allow comparing any arrays of '[[un]signed] char', > + // but no other types. > + if (IsRawByte && !(CharTy1->isCharType() && > CharTy2->isCharType())) { > + // FIXME: Consider using our bit_cast implementation to support > this. > + Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported) > + << (std::string("'") + > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") > + << CharTy1 << CharTy2; > + return false; > + } > + > const auto &ReadCurElems = [&](APValue &Char1, APValue &Char2) { > return handleLValueToRValueConversion(Info, E, CharTy1, String1, > Char1) && > handleLValueToRValueConversion(Info, E, CharTy2, String2, > Char2) && > @@ -11159,57 +11174,6 @@ bool > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, > HandleLValueArrayAdjustment(Info, E, String2, CharTy2, 1); > }; > > - if (IsRawByte) { > - uint64_t BytesRemaining = MaxLength; > - // Pointers to const void may point to objects of incomplete > type. > - if (CharTy1->isIncompleteType()) { > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << > CharTy1; > - return false; > - } > - if (CharTy2->isIncompleteType()) { > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << > CharTy2; > - return false; > - } > - uint64_t CharTy1Width{Info.Ctx.getTypeSize(CharTy1)}; > - CharUnits CharTy1Size = > Info.Ctx.toCharUnitsFromBits(CharTy1Width); > - // Give up on comparing between elements with disparate widths. > - if (CharTy1Size != Info.Ctx.getTypeSizeInChars(CharTy2)) > - return false; > - uint64_t BytesPerElement = CharTy1Size.getQuantity(); > - assert(BytesRemaining && "BytesRemaining should not be zero: the > " > - "following loop considers at least one > element"); > - while (true) { > - APValue Char1, Char2; > - if (!ReadCurElems(Char1, Char2)) > - return false; > - // We have compatible in-memory widths, but a possible type and > - // (for `bool`) internal representation mismatch. > - // Assuming two's complement representation, including 0 for > `false` and > - // 1 for `true`, we can check an appropriate number of > elements for > - // equality even if they are not byte-sized. > - APSInt Char1InMem = Char1.getInt().extOrTrunc(CharTy1Width); > - APSInt Char2InMem = Char2.getInt().extOrTrunc(CharTy1Width); > - if (Char1InMem.ne(Char2InMem)) { > - // If the elements are byte-sized, then we can produce a > three-way > - // comparison result in a straightforward manner. > - if (BytesPerElement == 1u) { > - // memcmp always compares unsigned chars. > - return Success(Char1InMem.ult(Char2InMem) ? -1 : 1, E); > - } > - // The result is byte-order sensitive, and we have multibyte > elements. > - // FIXME: We can compare the remaining bytes in the correct > order. > - return false; > - } > - if (!AdvanceElems()) > - return false; > - if (BytesRemaining <= BytesPerElement) > - break; > - BytesRemaining -= BytesPerElement; > - } > - // Enough elements are equal to account for the memcmp limit. > - return Success(0, E); > - } > - > bool StopAtNull = > (BuiltinOp != Builtin::BImemcmp && BuiltinOp != > Builtin::BIbcmp && > BuiltinOp != Builtin::BIwmemcmp && > @@ -11227,7 +11191,7 @@ bool > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, > APValue Char1, Char2; > if (!ReadCurElems(Char1, Char2)) > return false; > - if (Char1.getInt() != Char2.getInt()) { > + if (Char1.getInt().ne(Char2.getInt())) { > if (IsWide) // wmemcmp compares with wchar_t signedness. > return Success(Char1.getInt() < Char2.getInt() ? -1 : 1, E); > // memcmp always compares unsigned chars. > > diff --git a/clang/test/SemaCXX/constexpr-string.cpp > b/clang/test/SemaCXX/constexpr-string.cpp > index f540be8f8e5b..79ac3bf2cc4d 100644 > --- a/clang/test/SemaCXX/constexpr-string.cpp > +++ b/clang/test/SemaCXX/constexpr-string.cpp > @@ -47,7 +47,7 @@ extern "C" { > extern wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n); > } > > -# 45 "SemaCXX/constexpr-string.cpp" 2 > +# 51 "SemaCXX/constexpr-string.cpp" 2 > namespace Strlen { > constexpr int n = __builtin_strlen("hello"); // ok > static_assert(n == 5); > @@ -121,13 +121,13 @@ namespace StrcmpEtc { > extern struct Incomplete incomplete; > static_assert(__builtin_memcmp(&incomplete, "", 0u) == 0); > static_assert(__builtin_memcmp("", &incomplete, 0u) == 0); > - static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // > expected-error {{not an integral constant}} expected-note {{read of > incomplete type 'struct Incomplete'}} > - static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // > expected-error {{not an integral constant}} expected-note {{read of > incomplete type 'struct Incomplete'}} > + static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // > expected-error {{not an integral constant}} expected-note {{not > supported}} > + static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // > expected-error {{not an integral constant}} expected-note {{not > supported}} > > static_assert(__builtin_bcmp(&incomplete, "", 0u) == 0); > static_assert(__builtin_bcmp("", &incomplete, 0u) == 0); > - static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // > expected-error {{not an integral constant}} expected-note {{read of > incomplete type 'struct Incomplete'}} > - static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // > expected-error {{not an integral constant}} expected-note {{read of > incomplete type 'struct Incomplete'}} > + static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // > expected-error {{not an integral constant}} expected-note {{not > supported}} > + static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // > expected-error {{not an integral constant}} expected-note {{not > supported}} > > constexpr unsigned char ku00fe00[] = {0x00, 0xfe, 0x00}; > constexpr unsigned char ku00feff[] = {0x00, 0xfe, 0xff}; > @@ -155,11 +155,11 @@ namespace StrcmpEtc { > > struct Bool3Tuple { bool bb[3]; }; > constexpr Bool3Tuple kb000100 = {{false, true, false}}; > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, > kb000100.bb, 1) == 0); > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, > kb000100.bb, 2) == 1); > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note > {{not supported}} > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, > kb000100.bb, 2) == 1); // expected-error {{constant}} expected-note > {{not supported}} > > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, > kb000100.bb, 1) == 0); > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, > kb000100.bb, 2) != 0); > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note > {{not supported}} > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, > kb000100.bb, 2) != 0); // expected-error {{constant}} expected-note > {{not supported}} > > constexpr long ksl[] = {0, -1}; > constexpr unsigned int kui[] = {0, 0u - 1}; > @@ -173,25 +173,25 @@ namespace StrcmpEtc { > return nullptr; > } > } > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) - > 1) == 0); > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + > 0) == 0); > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + > 1) == 0); > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) - > 1) == 0); > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > 0) == 0); > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > 1) == 42); // expected-error {{not an integral constant}} expected-note > {{dereferenced one-past-the-end}} > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > sizeof(long) - 1) == 0); > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > sizeof(long) + 0) == 0); > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > sizeof(long) + 1) == 42); // expected-error {{not an integral > constant}} expected-note {{dereferenced one-past-the-end}} > - > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - 1) > == 0); > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 0) > == 0); > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 1) > == 0); > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) - > 1) == 0); > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > 0) == 0); > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > 1) == 42); // expected-error {{not an integral constant}} expected-note > {{dereferenced one-past-the-end}} > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > sizeof(long) - 1) == 0); > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > sizeof(long) + 0) == 0); > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > sizeof(long) + 1) == 42); // expected-error {{not an integral > constant}} expected-note {{dereferenced one-past-the-end}} > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) - > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + > 0) == 0); // expected-error {{constant}} expected-note {{not supported}} > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) - > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > 0) == 0); // expected-error {{constant}} expected-note {{not supported}} > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > 1) == 42); // expected-error {{constant}} expected-note {{not > supported}} > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note > {{not supported}} > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note > {{not supported}} > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > sizeof(long) + 1) == 42); // expected-error {{constant}} expected-note > {{not supported}} > + > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - 1) > == 0); // expected-error {{constant}} expected-note {{not supported}} > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 0) > == 0); // expected-error {{constant}} expected-note {{not supported}} > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 1) > == 0); // expected-error {{constant}} expected-note {{not supported}} > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) - > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > 0) == 0); // expected-error {{constant}} expected-note {{not supported}} > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > 1) == 42); // expected-error {{constant}} expected-note {{not > supported}} > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note > {{not supported}} > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note > {{not supported}} > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > sizeof(long) + 1) == 42); // expected-error {{constant}} expected-note > {{not supported}} > > constexpr int a = strcmp("hello", "world"); // expected-error > {{constant expression}} expected-note {{non-constexpr function 'strcmp' > cannot be used in a constant expression}} > constexpr int b = strncmp("hello", "world", 3); // expected-error > {{constant expression}} expected-note {{non-constexpr function > 'strncmp' cannot be used in a constant expression}} > @@ -385,14 +385,14 @@ namespace StrchrEtc { > enum class E : unsigned char {}; > struct EPair { E e, f; }; > constexpr EPair ee{E{240}}; > - static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); > + static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); // > expected-error {{constant}} expected-note {{not supported}} > > constexpr bool kBool[] = {false, true, false}; > constexpr const bool *const kBoolPastTheEndPtr = kBool + 3; > - static_assert(sizeof(bool) != 1u || > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); > - static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, 0, > 99) == kBoolPastTheEndPtr - 1); > - static_assert(sizeof(bool) != 1u || > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); > - static_assert(sizeof(bool) != 1u || > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // > expected-error {{not an integral constant}} expected-note > {{dereferenced one-past-the-end}} > + static_assert(sizeof(bool) != 1u || > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); // > expected-error {{constant}} expected-note {{not supported}} > + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, 0, > 99) == kBoolPastTheEndPtr - 1); // expected-error {{constant}} > expected-note {{not supported}} > + static_assert(sizeof(bool) != 1u || > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); // > expected-error {{constant}} expected-note {{not supported}} > + static_assert(sizeof(bool) != 1u || > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // > expected-error {{constant}} expected-note {{not supported}} > > static_assert(__builtin_char_memchr(kStr, 'a', 0) == nullptr); > static_assert(__builtin_char_memchr(kStr, 'a', 1) == kStr); > > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > From cfe-commits at lists.llvm.org Sat Apr 4 07:24:19 2020 From: cfe-commits at lists.llvm.org (Yannis Juglaret via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 14:24:19 +0000 (UTC) Subject: [PATCH] D63616: Implement `-fsanitize-coverage-whitelist` and `-fsanitize-coverage-blacklist` for clang In-Reply-To: References: Message-ID: <71f3c177a57f6ead81eabfb22183d584@localhost.localdomain> tuktuk updated this revision to Diff 255032. tuktuk added a comment. Thank you for your interest in this feature! It is unfortunate indeed that the patch was not merged when accepted, so here is an update that matches the current status of the code base. Dear reviewers, can you please make sure that this time, the patch gets merged if accepted? Also, this time I was unable to run the new test that this patch adds from within the test system, because of my limited understanding; so I gave up and followed the test myself, command by command. Am I missing an additional step for test integration, after adding the test file? Thanks a lot. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63616/new/ https://reviews.llvm.org/D63616 Files: clang/docs/SanitizerCoverage.rst clang/include/clang/Basic/CodeGenOptions.h clang/include/clang/Basic/DiagnosticDriverKinds.td clang/include/clang/Driver/Options.td clang/include/clang/Driver/SanitizerArgs.h clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/SanitizerArgs.cpp clang/lib/Frontend/CompilerInvocation.cpp compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_whitelist_blacklist.cc llvm/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D63616.255032.patch Type: text/x-patch Size: 32461 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 07:24:20 2020 From: cfe-commits at lists.llvm.org (Roman Lebedev via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 14:24:20 +0000 (UTC) Subject: [PATCH] D71739: [WIP] Use operand bundles to encode alignment assumptions In-Reply-To: References: Message-ID: lebedev.ri added a comment. What's the status here? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71739/new/ https://reviews.llvm.org/D71739 From cfe-commits at lists.llvm.org Sat Apr 4 07:56:21 2020 From: cfe-commits at lists.llvm.org (Kim Viggedal via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 14:56:21 +0000 (UTC) Subject: [PATCH] D77461: [clang-tidy] Remove false positive in AvoidNonConstGlobalVariables Message-ID: vingeldal created this revision. Herald added subscribers: cfe-commits, kbarton, xazax.hun, nemanjai. Herald added a project: clang. vingeldal added a comment. Herald added a subscriber: wuzish. After looking in to it I got less certain of where the error lies and eventually I got uncertain if this even is a false negative, so I started out with just posting a change where the unit test is updated to detect the issue. This is just to have a start for a discussion of how this should actually work and what is the best way forward. The purpose of the rule is to avoid code which causes hidden dependencies. The given example of a potential false positive is a free function with a static variable. Now, wouldn't a static variable inside a function body make the function stateful thereby risking that the function gives different results for the same input, in ways that might look arbitrary or random to the caller. I think that might actually be a good example of what the rule is meant to prevent so maybe this isn't a false positive after all? There was a post merge comment about a possible false negative for this check: https://reviews.llvm.org/D70265 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77461 Files: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-avoid-non-const-global-variables.cpp Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-avoid-non-const-global-variables.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-avoid-non-const-global-variables.cpp +++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-avoid-non-const-global-variables.cpp @@ -231,7 +231,8 @@ // CHECKING AGAINST FALSE POSITIVES INSIDE FUNCTION SCOPE ///////////////////// int main() { for (int i = 0; i < 3; ++i) { + static int staticNonConstLoopVariable = 42; int nonConstLoopVariable = 42; - nonConstInt = nonConstLoopVariable + i; + nonConstInt = nonConstLoopVariable + i + staticNonConstLoopVariable; } } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77461.255037.patch Type: text/x-patch Size: 737 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 07:56:22 2020 From: cfe-commits at lists.llvm.org (Kim Viggedal via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 14:56:22 +0000 (UTC) Subject: [PATCH] D77461: [clang-tidy] Remove false positive in AvoidNonConstGlobalVariables In-Reply-To: References: Message-ID: vingeldal added a comment. Herald added a subscriber: wuzish. After looking in to it I got less certain of where the error lies and eventually I got uncertain if this even is a false negative, so I started out with just posting a change where the unit test is updated to detect the issue. This is just to have a start for a discussion of how this should actually work and what is the best way forward. The purpose of the rule is to avoid code which causes hidden dependencies. The given example of a potential false positive is a free function with a static variable. Now, wouldn't a static variable inside a function body make the function stateful thereby risking that the function gives different results for the same input, in ways that might look arbitrary or random to the caller. I think that might actually be a good example of what the rule is meant to prevent so maybe this isn't a false positive after all? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77461/new/ https://reviews.llvm.org/D77461 From cfe-commits at lists.llvm.org Sat Apr 4 08:28:33 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Tam=C3=A1s_Zolnai_via_Phabricator?= via cfe-commits) Date: Sat, 04 Apr 2020 15:28:33 +0000 (UTC) Subject: [PATCH] D76990: [clang-tidy]: fix false positive of cert-oop54-cpp check. In-Reply-To: References: Message-ID: <04dacfd8a1ad6dc16fd3d74815fe5008@localhost.localdomain> ztamas updated this revision to Diff 255038. ztamas added a comment. Add suggested test case and rebase. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76990/new/ https://reviews.llvm.org/D76990 Files: clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp +++ clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp @@ -212,6 +212,21 @@ T *p; }; +// https://bugs.llvm.org/show_bug.cgi?id=44499 +class Foo2; +template +bool operator!=(Foo2 &, Foo2 &) { + class Bar2 { + Bar2 &operator=(const Bar2 &other) { + // CHECK-MESSAGES: [[@LINE-1]]:11: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment] + p = other.p; + return *this; + } + + int *p; + }; +} + /////////////////////////////////////////////////////////////////// /// Test cases correctly ignored by the check. @@ -283,6 +298,21 @@ T *p; }; +// https://bugs.llvm.org/show_bug.cgi?id=44499 +class Foo; +template +bool operator!=(Foo &, Foo &) { + class Bar { + Bar &operator=(const Bar &other) { + if (this != &other) { + } + return *this; + } + + int *p; + }; +} + // There is no warning if the copy assignment operator gets the object by value. class PassedByValue { public: Index: clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp +++ clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp @@ -40,9 +40,12 @@ // Self-check: Code compares something with 'this' pointer. We don't check // whether it is actually the parameter what we compare. - const auto HasNoSelfCheck = cxxMethodDecl(unless( + const auto HasNoSelfCheck = cxxMethodDecl(unless(anyOf( hasDescendant(binaryOperator(hasAnyOperatorName("==", "!="), - has(ignoringParenCasts(cxxThisExpr())))))); + has(ignoringParenCasts(cxxThisExpr())))), + hasDescendant(cxxOperatorCallExpr( + hasAnyOverloadedOperatorName("==", "!="), argumentCountIs(2), + has(ignoringParenCasts(cxxThisExpr()))))))); // Both copy-and-swap and copy-and-move method creates a copy first and // assign it to 'this' with swap or move. -------------- next part -------------- A non-text attachment was scrubbed... Name: D76990.255038.patch Type: text/x-patch Size: 2365 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 08:28:33 2020 From: cfe-commits at lists.llvm.org (Nico Weber via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 15:28:33 +0000 (UTC) Subject: [PATCH] D77184: Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang In-Reply-To: References: Message-ID: <33fc269a540322b96e7b0e63b366c008@localhost.localdomain> thakis added a comment. In D77184#1961220 , @rsmith wrote: > In D77184#1961214 , @rsmith wrote: > > > In D77184#1961208 , @rsmith wrote: > > > > > This has broken my ability to run the `check-clang` target on Linux. There are symlinks in the path from which I run my builds, and this patch is computing incorrect relative paths in that situation. > > > > > > This patch appears to fix the problem: > > > Turns out that's only a partial fix (it fixes `ninja clang-check` but not the general problem). Running `lit` from inside the source directory is still broken. Eg, this used to work: > > clang/test$ $BUILDDIR/bin/llvm-lit SemaCXX/constant-expression.cpp > > > ... and doesn't work any more because the relative paths in `lit.site.cfg.py` don't seem to resolve to the right places. Please can you fix or revert? Can you describe your symlink setup in enough detail that I can recreate it locally please? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77184/new/ https://reviews.llvm.org/D77184 From cfe-commits at lists.llvm.org Sat Apr 4 08:28:34 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 15:28:34 +0000 (UTC) Subject: [PATCH] D77113: [OpenMP][NFC] Move and simplify directive -> allowed clause mapping In-Reply-To: References: Message-ID: jdoerfert updated this revision to Diff 255041. jdoerfert added a comment. Herald added subscribers: yaxunl, mgorny. Rebase Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77113/new/ https://reviews.llvm.org/D77113 Files: clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Basic/OpenMPKinds.h clang/lib/ASTMatchers/Dynamic/CMakeLists.txt clang/lib/Basic/OpenMPKinds.cpp clang/lib/Tooling/CMakeLists.txt clang/lib/Tooling/Transformer/CMakeLists.txt clang/unittests/AST/CMakeLists.txt clang/unittests/ASTMatchers/CMakeLists.txt clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt clang/unittests/Analysis/CMakeLists.txt clang/unittests/Rename/CMakeLists.txt clang/unittests/Sema/CMakeLists.txt clang/unittests/StaticAnalyzer/CMakeLists.txt clang/unittests/Tooling/CMakeLists.txt llvm/include/llvm/Frontend/OpenMP/OMPConstants.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPConstants.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77113.255041.patch Type: text/x-patch Size: 106562 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 08:28:33 2020 From: cfe-commits at lists.llvm.org (Karasev Nikita via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 15:28:33 +0000 (UTC) Subject: [PATCH] D76996: [analyzer] Improve PlacementNewChecker In-Reply-To: References: Message-ID: f00kat updated this revision to Diff 255039. f00kat added a comment. 1. Maybe build fix 2. Added tests for nested arrays of structures 3. Fixed bugs in implementation for ElementRegion cases CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76996/new/ https://reviews.llvm.org/D76996 Files: clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp clang/test/Analysis/placement-new.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D76996.255039.patch Type: text/x-patch Size: 19303 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 08:28:34 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 15:28:34 +0000 (UTC) Subject: [PATCH] D77112: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` In-Reply-To: References: Message-ID: <5854117dfb9eea4b33a92bd96460b83d@localhost.localdomain> jdoerfert updated this revision to Diff 255040. jdoerfert added a comment. Rebase Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77112/new/ https://reviews.llvm.org/D77112 Files: clang/include/clang/AST/ASTFwd.h clang/include/clang/AST/ASTTypeTraits.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/Basic/Attr.td clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Basic/OpenMPKinds.h clang/lib/AST/ASTTypeTraits.cpp clang/lib/AST/AttrImpl.cpp clang/lib/AST/OpenMPClause.cpp clang/lib/AST/StmtProfile.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/ASTMatchers/CMakeLists.txt clang/lib/ASTMatchers/Dynamic/Marshallers.h clang/lib/Analysis/CMakeLists.txt clang/lib/Basic/OpenMPKinds.cpp clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt clang/lib/StaticAnalyzer/Core/CMakeLists.txt clang/tools/libclang/CIndex.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp llvm/include/llvm/Frontend/OpenMP/OMPConstants.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPConstants.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77112.255040.patch Type: text/x-patch Size: 118681 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 08:44:12 2020 From: cfe-commits at lists.llvm.org (=?UTF-8?Q?Tam=C3=A1s_Zolnai?= via cfe-commits) Date: Sat, 04 Apr 2020 08:44:12 -0700 (PDT) Subject: [clang-tools-extra] 0f9e1e3 - [clang-tidy]: fix false positive of cert-oop54-cpp check. Message-ID: <5e88ab4c.1c69fb81.af8bc.7bdc@mx.google.com> Author: Tamás Zolnai Date: 2020-04-04T17:19:17+02:00 New Revision: 0f9e1e3ae750df483b7fff905a8bc89262e3179e URL: https://github.com/llvm/llvm-project/commit/0f9e1e3ae750df483b7fff905a8bc89262e3179e DIFF: https://github.com/llvm/llvm-project/commit/0f9e1e3ae750df483b7fff905a8bc89262e3179e.diff LOG: [clang-tidy]: fix false positive of cert-oop54-cpp check. Summary: It seems we need a different matcher for binary operator in a template context. Fixes this issue: https://bugs.llvm.org/show_bug.cgi?id=44499 Reviewers: aaron.ballman, alexfh, hokein, njames93 Reviewed By: aaron.ballman Subscribers: xazax.hun, cfe-commits Tags: #clang, #clang-tools-extra Differential Revision: https://reviews.llvm.org/D76990 Added: Modified: clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp index f2de9fbde2a6..d91353e21fb1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp @@ -40,9 +40,12 @@ void UnhandledSelfAssignmentCheck::registerMatchers(MatchFinder *Finder) { // Self-check: Code compares something with 'this' pointer. We don't check // whether it is actually the parameter what we compare. - const auto HasNoSelfCheck = cxxMethodDecl(unless( + const auto HasNoSelfCheck = cxxMethodDecl(unless(anyOf( hasDescendant(binaryOperator(hasAnyOperatorName("==", "!="), - has(ignoringParenCasts(cxxThisExpr())))))); + has(ignoringParenCasts(cxxThisExpr())))), + hasDescendant(cxxOperatorCallExpr( + hasAnyOverloadedOperatorName("==", "!="), argumentCountIs(2), + has(ignoringParenCasts(cxxThisExpr()))))))); // Both copy-and-swap and copy-and-move method creates a copy first and // assign it to 'this' with swap or move. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp index 49bb5314f9eb..fb7c089ae8cd 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp @@ -212,6 +212,21 @@ class WrongTemplateCopyAndMove { T *p; }; +// https://bugs.llvm.org/show_bug.cgi?id=44499 +class Foo2; +template +bool operator!=(Foo2 &, Foo2 &) { + class Bar2 { + Bar2 &operator=(const Bar2 &other) { + // CHECK-MESSAGES: [[@LINE-1]]:11: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment] + p = other.p; + return *this; + } + + int *p; + }; +} + /////////////////////////////////////////////////////////////////// /// Test cases correctly ignored by the check. @@ -283,6 +298,21 @@ class TemplateSelfCheck { T *p; }; +// https://bugs.llvm.org/show_bug.cgi?id=44499 +class Foo; +template +bool operator!=(Foo &, Foo &) { + class Bar { + Bar &operator=(const Bar &other) { + if (this != &other) { + } + return *this; + } + + int *p; + }; +} + // There is no warning if the copy assignment operator gets the object by value. class PassedByValue { public: From cfe-commits at lists.llvm.org Sat Apr 4 09:00:30 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 16:00:30 +0000 (UTC) Subject: [PATCH] D71739: [WIP] Use operand bundles to encode alignment assumptions In-Reply-To: References: Message-ID: <20f28f3f1b252c9a72bb0795f7cf837f@localhost.localdomain> jdoerfert added a comment. @lebedev.ri We'd need to identify other uses of the alignment encoding in-tree so we can replace them as well. Also, this patch uses not only the alignment but also the offset in the operand bundle. We can either allow that or encode the offset via a gep in the IR. I guess the latter is easier to implement until we have more reasons to allow more complex operand bundles (which we will need to have eventually). @Tyker Do you want to take this? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71739/new/ https://reviews.llvm.org/D71739 From cfe-commits at lists.llvm.org Sat Apr 4 09:00:32 2020 From: cfe-commits at lists.llvm.org (Scott Constable via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 16:00:32 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: sconstab added inline comments. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:318 + } + auto *VertexArray = new Node[VertexSize + 1 /* terminator node */]; + auto *EdgeArray = new Edge[EdgeSize]; ---------------- mattdr wrote: > sconstab wrote: > > mattdr wrote: > > > As a general rule `new` is a code-smell in modern C++. This should be a `vector`. > > @mattdr I do agree with the general rule. I also think that in this case where the structure is immutable, std::vector is wasteful because it needs to keep separate values for the current number of elements and the current capacity. At local scope within a function the unneeded value would likely be optimized away, but then there would be an awkward handoff to transfer the data from the vector to the array members. > > > > I would not want to see the array members changed to vectors, unless LLVM provides an encapsulated array structure that does not need to grow and shrink. > So, first: I'm glad you removed the unnecessary use of `new[]` here and the corresponding (and error-prone!) use of `delete[]` later. That removes a memory leak LLVM won't have to debug. > > You suggest here that something other than `std::vector` would be more efficient. If so, would `std::array` suffice? If not, can you explain why static allocation is impossible but dynamic allocation would be too expensive? A statically sized array (e.g., std::array) is insufficient because the size in this case is not compiler determinable; a dynamically sized and dynamically resizable array (e.g., std::vector) is sufficient but overly costly; a dynamically sized and dynamically //unresizable// array is sufficient and has minimal cost. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:13 +/// The advantages to this implementation are two-fold: +/// 1. Iteration and traversal operations should experience terrific caching +/// performance. ---------------- mattdr wrote: > erm, "terrific"? If there's a substantive argument w.r.t. cache locality etc., please make it explicit. This is valid. I will reword. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:16 +/// 2. Set representations and operations on nodes and edges become +/// extraordinarily efficient. For instance, a set of edges is implemented as +/// a bit vector, wherein each bit corresponds to one edge in the edge ---------------- mattdr wrote: > "extraordinarily" is, again, not a useful engineering categorization. Please restrict comments to describing quantifiable claims of complexity. AFAIK there is not a precise engineering term for "tiny O(1)." Nonetheless I will reword. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:40 + +template +class ImmutableGraph { ---------------- mattdr wrote: > Every template argument for a class represents combinatorial addition of complexity for the resulting code. Why do each of these template arguments need to exist? in particular, why does SizeT need to exist? I suspect that there may be more uses for this data structure and that eventually it may migrate to ADT. I have SizeT as a template argument because I found it plenty sufficient to have `int` as the size parameter for the array bounds, but I suspect other uses may require `size_t`. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 From cfe-commits at lists.llvm.org Sat Apr 4 09:00:32 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 16:00:32 +0000 (UTC) Subject: [PATCH] D77290: [OpenMP] Specialize OpenMP calls after template instantiation In-Reply-To: References: Message-ID: <80b9f98f397dbdc9f2e18c9572736352@localhost.localdomain> jdoerfert updated this revision to Diff 255043. jdoerfert edited the summary of this revision. jdoerfert added a comment. Rebase on D77252 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77290/new/ https://reviews.llvm.org/D77290 Files: clang/lib/Sema/SemaTemplateInstantiate.cpp clang/test/AST/ast-dump-openmp-begin-declare-variant_template_1.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77290.255043.patch Type: text/x-patch Size: 14872 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 09:00:42 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Tam=C3=A1s_Zolnai_via_Phabricator?= via cfe-commits) Date: Sat, 04 Apr 2020 16:00:42 +0000 (UTC) Subject: [PATCH] D76990: [clang-tidy]: fix false positive of cert-oop54-cpp check. In-Reply-To: References: Message-ID: <43e7caa0881a6d5562bff66c6738e033@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG0f9e1e3ae750: [clang-tidy]: fix false positive of cert-oop54-cpp check. (authored by ztamas). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76990/new/ https://reviews.llvm.org/D76990 Files: clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp +++ clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp @@ -212,6 +212,21 @@ T *p; }; +// https://bugs.llvm.org/show_bug.cgi?id=44499 +class Foo2; +template +bool operator!=(Foo2 &, Foo2 &) { + class Bar2 { + Bar2 &operator=(const Bar2 &other) { + // CHECK-MESSAGES: [[@LINE-1]]:11: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment] + p = other.p; + return *this; + } + + int *p; + }; +} + /////////////////////////////////////////////////////////////////// /// Test cases correctly ignored by the check. @@ -283,6 +298,21 @@ T *p; }; +// https://bugs.llvm.org/show_bug.cgi?id=44499 +class Foo; +template +bool operator!=(Foo &, Foo &) { + class Bar { + Bar &operator=(const Bar &other) { + if (this != &other) { + } + return *this; + } + + int *p; + }; +} + // There is no warning if the copy assignment operator gets the object by value. class PassedByValue { public: Index: clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp +++ clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp @@ -40,9 +40,12 @@ // Self-check: Code compares something with 'this' pointer. We don't check // whether it is actually the parameter what we compare. - const auto HasNoSelfCheck = cxxMethodDecl(unless( + const auto HasNoSelfCheck = cxxMethodDecl(unless(anyOf( hasDescendant(binaryOperator(hasAnyOperatorName("==", "!="), - has(ignoringParenCasts(cxxThisExpr())))))); + has(ignoringParenCasts(cxxThisExpr())))), + hasDescendant(cxxOperatorCallExpr( + hasAnyOverloadedOperatorName("==", "!="), argumentCountIs(2), + has(ignoringParenCasts(cxxThisExpr()))))))); // Both copy-and-swap and copy-and-move method creates a copy first and // assign it to 'this' with swap or move. -------------- next part -------------- A non-text attachment was scrubbed... Name: D76990.255048.patch Type: text/x-patch Size: 2365 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 09:32:35 2020 From: cfe-commits at lists.llvm.org (Scott Constable via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 16:32:35 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: <7ba2e2c6607805bbd832a3308605fb9a@localhost.localdomain> sconstab added inline comments. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:285 + std::unique_ptr Edges; + size_type EdgesSize; +}; ---------------- @craig.topper It now occurs to me that these fields should probably be reordered to: ``` std::unique_ptr Nodes; std::unique_ptr Edges; size_type NodesSize; size_type EdgesSize; ``` The current ordering will cause internal fragmentation. Old ordering: ``` static_assert(sizeof(ImmutableGraph) == 32); ``` New ordering: ``` static_assert(sizeof(ImmutableGraph) == 24); ``` With vectors instead of arrays: ``` static_assert(sizeof(ImmutableGraph) == 48); ``` CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 From cfe-commits at lists.llvm.org Sat Apr 4 09:32:36 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 16:32:36 +0000 (UTC) Subject: [PATCH] D75788: [OpenMP] Provide math functions in OpenMP device code via OpenMP variants In-Reply-To: References: Message-ID: <0bd29d8645405939e34884abf1ac8cde@localhost.localdomain> jdoerfert updated this revision to Diff 255050. jdoerfert added a comment. Cleanup and rebase Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75788/new/ https://reviews.llvm.org/D75788 Files: clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Headers/CMakeLists.txt clang/lib/Headers/__clang_cuda_cmath.h clang/lib/Headers/__clang_cuda_device_functions.h clang/lib/Headers/__clang_cuda_math.h clang/lib/Headers/__clang_cuda_math_forward_declares.h clang/lib/Headers/openmp_wrappers/__clang_openmp_device_functions.h clang/lib/Headers/openmp_wrappers/__clang_openmp_math.h clang/lib/Headers/openmp_wrappers/__clang_openmp_math_declares.h clang/lib/Headers/openmp_wrappers/cmath clang/lib/Headers/openmp_wrappers/math.h clang/lib/Headers/openmp_wrappers/time.h clang/test/Headers/Inputs/include/climits clang/test/Headers/Inputs/include/cmath clang/test/Headers/Inputs/include/cstdlib clang/test/Headers/Inputs/include/math.h clang/test/Headers/Inputs/include/stdlib.h clang/test/Headers/nvptx_device_cmath_functions.c clang/test/Headers/nvptx_device_cmath_functions.cpp clang/test/Headers/nvptx_device_cmath_functions_cxx17.cpp clang/test/Headers/nvptx_device_math_complex.c clang/test/Headers/nvptx_device_math_functions.c clang/test/Headers/nvptx_device_math_functions.cpp clang/test/Headers/nvptx_device_math_functions_cxx17.cpp clang/test/Headers/nvptx_device_math_macro.cpp clang/test/Headers/nvptx_device_math_modf.cpp clang/test/Headers/nvptx_device_math_sin.c clang/test/Headers/nvptx_device_math_sin.cpp clang/test/Headers/nvptx_device_math_sin_cos.cpp clang/test/Headers/nvptx_device_math_sincos.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D75788.255050.patch Type: text/x-patch Size: 58039 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 09:36:20 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via cfe-commits) Date: Sat, 04 Apr 2020 09:36:20 -0700 (PDT) Subject: [clang] ceed44a - [OpenMP][NFC] Remove unnecessary argument Message-ID: <5e88b784.1c69fb81.3cc7e.718b@mx.google.com> Author: Johannes Doerfert Date: 2020-04-04T11:34:58-05:00 New Revision: ceed44adfd1ae9d714eaa4f0e7fa5a1a149b4dc5 URL: https://github.com/llvm/llvm-project/commit/ceed44adfd1ae9d714eaa4f0e7fa5a1a149b4dc5 DIFF: https://github.com/llvm/llvm-project/commit/ceed44adfd1ae9d714eaa4f0e7fa5a1a149b4dc5.diff LOG: [OpenMP][NFC] Remove unnecessary argument Added: Modified: clang/include/clang/Sema/Sema.h clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaOpenMP.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 7c689c2a13e8..10e2d69f3d9e 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -9892,7 +9892,7 @@ class Sema final { /// specialization via the OpenMP declare variant mechanism available. If /// there is, return the specialized call expression, otherwise return the /// original \p Call. - ExprResult ActOnOpenMPCall(Sema &S, ExprResult Call, Scope *Scope, + ExprResult ActOnOpenMPCall(ExprResult Call, Scope *Scope, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8d0e97c85771..b311aad84816 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5997,7 +5997,7 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc, } if (LangOpts.OpenMP) - Call = ActOnOpenMPCall(*this, Call, Scope, LParenLoc, ArgExprs, RParenLoc, + Call = ActOnOpenMPCall(Call, Scope, LParenLoc, ArgExprs, RParenLoc, ExecConfig); return Call; diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index f663b1d43659..cfaf981983c1 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -5584,7 +5584,7 @@ void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( BaseFD->setImplicit(true); } -ExprResult Sema::ActOnOpenMPCall(Sema &S, ExprResult Call, Scope *Scope, +ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig) { @@ -5601,8 +5601,8 @@ ExprResult Sema::ActOnOpenMPCall(Sema &S, ExprResult Call, Scope *Scope, if (!CalleeFnDecl->hasAttr()) return Call; - ASTContext &Context = S.getASTContext(); - OMPContext OMPCtx(S.getLangOpts().OpenMPIsDevice, + ASTContext &Context = getASTContext(); + OMPContext OMPCtx(getLangOpts().OpenMPIsDevice, Context.getTargetInfo().getTriple()); SmallVector Exprs; @@ -5650,12 +5650,12 @@ ExprResult Sema::ActOnOpenMPCall(Sema &S, ExprResult Call, Scope *Scope, if (auto *SpecializedMethod = dyn_cast(BestDecl)) { auto *MemberCall = dyn_cast(CE); BestExpr = MemberExpr::CreateImplicit( - S.Context, MemberCall->getImplicitObjectArgument(), - /* IsArrow */ false, SpecializedMethod, S.Context.BoundMemberTy, + Context, MemberCall->getImplicitObjectArgument(), + /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, MemberCall->getValueKind(), MemberCall->getObjectKind()); } - NewCall = S.BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, - ExecConfig); + NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, + ExecConfig); if (NewCall.isUsable()) break; } @@ -5666,7 +5666,6 @@ ExprResult Sema::ActOnOpenMPCall(Sema &S, ExprResult Call, Scope *Scope, if (!NewCall.isUsable()) return Call; - return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); } From cfe-commits at lists.llvm.org Sat Apr 4 10:04:36 2020 From: cfe-commits at lists.llvm.org (Nico Weber via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 17:04:36 +0000 (UTC) Subject: [PATCH] D77184: Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang In-Reply-To: References: Message-ID: <2e96513263ab5bec4c109de916d1ec75@localhost.localdomain> thakis added a comment. > Can you describe your symlink setup in enough detail that I can recreate it locally please? I've landed a workaround that should make things go for you again in 7db64e202f9 . I'd still be curious to hear details about your setup, so that I can see if I can make it work better. (Right now, this now bails out when it sees a symlink and keeps an absolute path as before, which is a bit lame.) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77184/new/ https://reviews.llvm.org/D77184 From cfe-commits at lists.llvm.org Sat Apr 4 10:04:37 2020 From: cfe-commits at lists.llvm.org (MyDeveloperDay via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 17:04:37 +0000 (UTC) Subject: [PATCH] D75364: [clang-format] Handle macros in function params and return value In-Reply-To: References: Message-ID: MyDeveloperDay added inline comments. ================ Comment at: clang/lib/Format/TokenAnnotator.cpp:313 + // for example: + // void f(volatile ElfW(Addr)* addr = nullptr); + if (HasStarToken) { ---------------- I assume it could be almost anything? void f(volatile ElfW(Addr)& addr); void f(volatile ElfW(Addr)&& addr); void f(volatile ElfW(Addr) const & addr); void f(volatile ElfW(Addr,foo)* addr); void f(volatile ElfW(Addr,ElfW(Addr) *foo)* addr); ? you seem to handle only the * case CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75364/new/ https://reviews.llvm.org/D75364 From cfe-commits at lists.llvm.org Sat Apr 4 10:04:37 2020 From: cfe-commits at lists.llvm.org (Mike Rice via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 17:04:37 +0000 (UTC) Subject: [PATCH] D77290: [OpenMP] Specialize OpenMP calls after template instantiation In-Reply-To: References: Message-ID: <048ac26203a19974708f76487b8e56bd@localhost.localdomain> mikerice added inline comments. ================ Comment at: clang/lib/Sema/SemaTemplateInstantiate.cpp:1693 +ExprResult TemplateInstantiator::TransformCallExpr(CallExpr *E) { + ExprResult R = TreeTransform::TransformCallExpr(E); + if (!SemaRef.getLangOpts().OpenMP || !R.isUsable() || !isa(R.get())) ---------------- Is there a reason you are adding this here as opposed to in the base class RebuildCallExpr? Are there cases where we rebuild call expressions that we don't want to do this variant processing? ================ Comment at: clang/lib/Sema/SemaTemplateInstantiate.cpp:1698 + auto *CE = cast(R.get()); + return SemaRef.ActOnOpenMPCall(R, nullptr, CE->getRParenLoc(), + MultiExprArg(CE->getArgs(), CE->getNumArgs()), ---------------- Comments on nullptr arguments would be nice. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77290/new/ https://reviews.llvm.org/D77290 From cfe-commits at lists.llvm.org Sat Apr 4 11:09:04 2020 From: cfe-commits at lists.llvm.org (Oliver Bruns via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 18:09:04 +0000 (UTC) Subject: [PATCH] D77468: [clang] fix undefined behaviour in RawComment::getFormattedText() Message-ID: obruns created this revision. obruns added reviewers: teemperor, ioeric, cfe-commits. Herald added subscribers: usaxena95, kadircet, ilya-biryukov. Herald added a project: clang. Calling `back()` and `pop_back()` on the empty string is undefined behavior [1,2]. The issue manifested itself as an uncaught `std::out_of_range` exception when running `clangd` compiled on RHEL7 using devtoolset-9. [1] https://en.cppreference.com/w/cpp/string/basic_string/back [2] https://en.cppreference.com/w/cpp/string/basic_string/pop_back Fixes: 1ff7c32fc91c607b690d4bb9cf42f406be8dde68 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77468 Files: clang/lib/AST/RawCommentList.cpp Index: clang/lib/AST/RawCommentList.cpp =================================================================== --- clang/lib/AST/RawCommentList.cpp +++ clang/lib/AST/RawCommentList.cpp @@ -431,7 +431,7 @@ }; auto DropTrailingNewLines = [](std::string &Str) { - while (Str.back() == '\n') + while (not Str.empty() and Str.back() == '\n') Str.pop_back(); }; -------------- next part -------------- A non-text attachment was scrubbed... Name: D77468.255059.patch Type: text/x-patch Size: 379 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 11:41:21 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 18:41:21 +0000 (UTC) Subject: [PATCH] D77470: [clang] NFC: Fix trivial typo in comments and document Message-ID: kiszk created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. `the the` -> `the` Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77470 Files: clang/docs/LibASTMatchersReference.html clang/include/clang/AST/ASTStructuralEquivalence.h clang/include/clang/AST/ComparisonCategories.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/DirectoryWatcher/DirectoryWatcher.h clang/include/clang/Tooling/Transformer/RangeSelector.h clang/lib/CodeGen/CGExprScalar.cpp clang/lib/Lex/PPDirectives.cpp clang/lib/Sema/SemaAvailability.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77470.255065.patch Type: text/x-patch Size: 7815 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 11:41:21 2020 From: cfe-commits at lists.llvm.org (Sam McCall via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 18:41:21 +0000 (UTC) Subject: [PATCH] D77458: [clang-tools-extra] NFC: Fix trivial typo in documents and comments In-Reply-To: References: Message-ID: <4b499cc1b88fbe846fd421735dbb2245@localhost.localdomain> sammccall accepted this revision. sammccall added a comment. This revision is now accepted and ready to land. Thank you! ================ Comment at: clang-tools-extra/test/clang-tidy/checkers/fuchsia-multiple-inheritance.cpp:48 // Inherits from multiple concrete classes. -// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] +// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] // CHECK-NEXT: class Bad_Child1 : public Base_A, Base_B {}; ---------------- Did you update the actual generated diagnostic in clang-tidy/fuchsia/MultipleInheritanceCheck.cpp? I don't see it in this patch. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77458/new/ https://reviews.llvm.org/D77458 From cfe-commits at lists.llvm.org Sat Apr 4 12:13:33 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 19:13:33 +0000 (UTC) Subject: [PATCH] D77471: address review comment Message-ID: kiszk created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. kiszk added a comment. kiszk removed a project: clang. kiszk removed a subscriber: cfe-commits. Herald added a project: clang. Sorry, I made a mistake. This should not be reviewed. This should be deleted. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77471 Files: clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp Index: clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp +++ clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp @@ -116,7 +116,7 @@ } if (NumConcrete > 1) { - diag(D->getBeginLoc(), "inheriting mulitple classes that aren't " + diag(D->getBeginLoc(), "inheriting multiple classes that aren't " "pure virtual is discouraged"); } } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77471.255068.patch Type: text/x-patch Size: 558 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 12:13:33 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 19:13:33 +0000 (UTC) Subject: [PATCH] D77471: address review comment In-Reply-To: References: Message-ID: kiszk added a comment. Sorry, I made a mistake. This should not be reviewed. This should be deleted. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77471/new/ https://reviews.llvm.org/D77471 From cfe-commits at lists.llvm.org Sat Apr 4 12:13:34 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 19:13:34 +0000 (UTC) Subject: [PATCH] D77458: [clang-tools-extra] NFC: Fix trivial typo in documents and comments In-Reply-To: References: Message-ID: <8e8cf8e43d5f397317b8bfa9ad8f25bc@localhost.localdomain> kiszk added inline comments. ================ Comment at: clang-tools-extra/test/clang-tidy/checkers/fuchsia-multiple-inheritance.cpp:48 // Inherits from multiple concrete classes. -// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] +// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] // CHECK-NEXT: class Bad_Child1 : public Base_A, Base_B {}; ---------------- sammccall wrote: > Did you update the actual generated diagnostic in clang-tidy/fuchsia/MultipleInheritanceCheck.cpp? I don't see it in this patch. Good catch. I also updated clang-tidy/fuchsia/MultipleInheritanceCheck.cpp. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77458/new/ https://reviews.llvm.org/D77458 From cfe-commits at lists.llvm.org Sat Apr 4 12:13:35 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 19:13:35 +0000 (UTC) Subject: [PATCH] D77458: [clang-tools-extra] NFC: Fix trivial typo in documents and comments In-Reply-To: References: Message-ID: kiszk updated this revision to Diff 255071. kiszk added a comment. address review comment Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77458/new/ https://reviews.llvm.org/D77458 Files: clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp Index: clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp +++ clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp @@ -116,7 +116,7 @@ } if (NumConcrete > 1) { - diag(D->getBeginLoc(), "inheriting mulitple classes that aren't " + diag(D->getBeginLoc(), "inheriting multiple classes that aren't " "pure virtual is discouraged"); } } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77458.255071.patch Type: text/x-patch Size: 558 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 13:17:57 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Sat, 04 Apr 2020 20:17:57 +0000 (UTC) Subject: [PATCH] D77474: [analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete Message-ID: Szelethus created this revision. Szelethus added reviewers: NoQ, xazax.hun, baloghadamsoftware, martong, balazske, dcoughlin. Szelethus added a project: clang. Herald added subscribers: cfe-commits, ASDenysPetrov, steakhal, Charusso, gamesh411, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet, whisperity. Szelethus edited the summary of this revision. If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, //after// the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that `FreeMemAux` (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: - Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of `FreeMemAux` if not, - Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77474 Files: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp clang/test/Analysis/Malloc+NewDelete_intersections.cpp clang/test/Analysis/NewDelete-checker-test.cpp clang/test/Analysis/NewDelete-intersections.mm clang/test/Analysis/new.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77474.255070.patch Type: text/x-patch Size: 21176 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 13:17:59 2020 From: cfe-commits at lists.llvm.org (Scott Constable via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 20:17:59 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: sconstab added a comment. Overall, the restyling by @craig.topper looks much better than what I had committed before. I agree that `std::unique_ptr` is the right "container" in this circumstance. And the addition of `ArrayRef<>` accessors is also a nice touch. A few extra inline comments. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:13 +/// The advantages to this implementation are two-fold: +/// 1. Iteration and traversal operations should experience terrific caching +/// performance. ---------------- sconstab wrote: > mattdr wrote: > > erm, "terrific"? If there's a substantive argument w.r.t. cache locality etc., please make it explicit. > This is valid. I will reword. "Iteration and traversal operations benefit from cache locality." ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:16 +/// 2. Set representations and operations on nodes and edges become +/// extraordinarily efficient. For instance, a set of edges is implemented as +/// a bit vector, wherein each bit corresponds to one edge in the edge ---------------- sconstab wrote: > mattdr wrote: > > "extraordinarily" is, again, not a useful engineering categorization. Please restrict comments to describing quantifiable claims of complexity. > AFAIK there is not a precise engineering term for "tiny O(1)." Nonetheless I will reword. "Operations on sets of nodes/edges are efficient, and representations of those sets in memory are compact. For instance..." ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:84 + : Nodes(std::move(Nodes)), NodesSize(NodesSize), Edges(std::move(Edges)), + EdgesSize(EdgesSize) {} + ImmutableGraph(const ImmutableGraph &) = delete; ---------------- After the members are reordered, this list must also be reordered. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:103 + + class NodeSet { + friend class iterator; ---------------- This had not occurred to me until now, but a lot of code is shared between `NodeSet` and `EdgeSet`. Maybe a template could reduce the redundancy? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 From cfe-commits at lists.llvm.org Sat Apr 4 13:49:56 2020 From: cfe-commits at lists.llvm.org (Scott Constable via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 20:49:56 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: <22323efa8879e198ad8046ae55abdcdb@localhost.localdomain> sconstab added inline comments. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:307 +public: + using NodeRef = size_type; + ---------------- Just noticed that `ImmutableGraphBuilder` and `ImmutableGraph` have non-identical types called `NodeRef`. Suggest renaming this one to `BuilderNodeRef`. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 From cfe-commits at lists.llvm.org Sat Apr 4 13:49:56 2020 From: cfe-commits at lists.llvm.org (Mike Rice via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 20:49:56 +0000 (UTC) Subject: [PATCH] D77252: [OpenMP] Try to find an existing base for `omp begin/end declare variant` In-Reply-To: References: Message-ID: mikerice added inline comments. ================ Comment at: clang/lib/Sema/SemaOpenMP.cpp:5512 + + if (!BaseFD) { + // TODO: Determine if we can reuse the declarator to create a declaration ---------------- I think if you do the base lookup in ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope instead of here you might have better success using the declarator. You would need to get the type and constexpr/consteval info from the declarator and declspec but if the lookup fails you can just use ActOnDeclarator to get a base declaration like you were before. I tried this in my sandbox and it seems to work (AST tests fail I'm guessing that is just order change). If that works we could get rid of these hacky bits. ================ Comment at: clang/lib/Sema/SemaOpenMP.cpp:5551 + BaseFD->addAttr(OMPDeclareVariantA); BaseFD->setImplicit(true); } ---------------- BaseFD is only implicit now if you created it, not when one was found in the lookup case right? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77252/new/ https://reviews.llvm.org/D77252 From cfe-commits at lists.llvm.org Sat Apr 4 14:22:26 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 21:22:26 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: <9a0cc7dde12a109c8f16f552e0b0c54e@localhost.localdomain> craig.topper marked 2 inline comments as done. craig.topper added inline comments. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:285 + std::unique_ptr Edges; + size_type EdgesSize; +}; ---------------- sconstab wrote: > @craig.topper It now occurs to me that these fields should probably be reordered to: > ``` > std::unique_ptr Nodes; > std::unique_ptr Edges; > size_type NodesSize; > size_type EdgesSize; > ``` > The current ordering will cause internal fragmentation. > > Old ordering: > ``` > static_assert(sizeof(ImmutableGraph) == 32); > ``` > New ordering: > ``` > static_assert(sizeof(ImmutableGraph) == 24); > ``` > With vectors instead of arrays: > ``` > static_assert(sizeof(ImmutableGraph) == 48); > ``` I noticed that too. I just didn't focus on it since we only ever one in memory at a time. I'll change in my next update. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:307 +public: + using NodeRef = size_type; + ---------------- sconstab wrote: > Just noticed that `ImmutableGraphBuilder` and `ImmutableGraph` have non-identical types called `NodeRef`. Suggest renaming this one to `BuilderNodeRef`. NodeRef is in the Traits class not the ImmutableGraph, but I will rename the builder one. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 From cfe-commits at lists.llvm.org Sat Apr 4 14:22:28 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 21:22:28 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: <3347e99b4175453f067df02555c80484@localhost.localdomain> craig.topper marked 2 inline comments as done. craig.topper added inline comments. ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:329 + size_type VI = 0, EI = 0; + for (; VI < static_cast(AdjList.size()); ++VI) { + VertexArray[VI].Value = std::move(AdjList[VI].first); ---------------- Can this be changed to VI < VertexSize? ================ Comment at: llvm/lib/Target/X86/ImmutableGraph.h:369 + continue; + size_type NewNumEdges = std::count_if( + NI->edges_begin(), NI->edges_end(), ---------------- I think I'll change this to llvm::count_if. Also there was previously a conditional here that made sure the distance between edges was >0, but it didn't seem necessary. Please let me know if there's a reason I should put that back CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 From cfe-commits at lists.llvm.org Sat Apr 4 14:54:18 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 21:54:18 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: <245ead66e88570dec0fa30bd1b8b3f60@localhost.localdomain> craig.topper updated this revision to Diff 255084. craig.topper added a comment. -Apply updates to comments. -Use nodes()/edges() to implement nodes_begin/end and edges_begin/end to simplify the code a little -Reorder fields in the Graph class. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 Files: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Arch/X86.cpp clang/test/Driver/x86-target-features.c llvm/lib/Target/X86/CMakeLists.txt llvm/lib/Target/X86/ImmutableGraph.h llvm/lib/Target/X86/X86.h llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp llvm/lib/Target/X86/X86Subtarget.h llvm/lib/Target/X86/X86TargetMachine.cpp llvm/test/CodeGen/X86/O0-pipeline.ll llvm/test/CodeGen/X86/O3-pipeline.ll llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D75936.255084.patch Type: text/x-patch Size: 57325 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 15:58:13 2020 From: cfe-commits at lists.llvm.org (Craig Topper via Phabricator via cfe-commits) Date: Sat, 04 Apr 2020 22:58:13 +0000 (UTC) Subject: [PATCH] D75936: Add a Pass to X86 that builds a Condensed CFG for Load Value Injection (LVI) Gadgets [4/6] In-Reply-To: References: Message-ID: <6c187abd174dd856348cedc1628660cc@localhost.localdomain> craig.topper updated this revision to Diff 255086. craig.topper added a comment. -Add methods to get the index of a Node or Edge to remove calls to std::distance in various places CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75936/new/ https://reviews.llvm.org/D75936 Files: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Arch/X86.cpp clang/test/Driver/x86-target-features.c llvm/lib/Target/X86/CMakeLists.txt llvm/lib/Target/X86/ImmutableGraph.h llvm/lib/Target/X86/X86.h llvm/lib/Target/X86/X86.td llvm/lib/Target/X86/X86LoadValueInjectionLoadHardening.cpp llvm/lib/Target/X86/X86Subtarget.h llvm/lib/Target/X86/X86TargetMachine.cpp llvm/test/CodeGen/X86/O0-pipeline.ll llvm/test/CodeGen/X86/O3-pipeline.ll llvm/test/CodeGen/X86/lvi-hardening-gadget-graph.ll -------------- next part -------------- A non-text attachment was scrubbed... Name: D75936.255086.patch Type: text/x-patch Size: 57307 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 17:01:56 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 00:01:56 +0000 (UTC) Subject: [PATCH] D77252: [OpenMP] Try to find an existing base for `omp begin/end declare variant` In-Reply-To: References: Message-ID: <86ebca35800e06a81e599ce57686e98e@localhost.localdomain> jdoerfert marked 2 inline comments as done. jdoerfert added inline comments. ================ Comment at: clang/lib/Sema/SemaOpenMP.cpp:5512 + + if (!BaseFD) { + // TODO: Determine if we can reuse the declarator to create a declaration ---------------- mikerice wrote: > I think if you do the base lookup in ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope instead of here you might have better success using the declarator. You would need to get the type and constexpr/consteval info from the declarator and declspec but if the lookup fails you can just use ActOnDeclarator to get a base declaration like you were before. I tried this in my sandbox and it seems to work (AST tests fail I'm guessing that is just order change). If that works we could get rid of these hacky bits. Can you share how you do the lookup and the type comparison with the Declarator? I mean, name lookup is simple but determining the right overload wrt. type and the namespace was something I always had problems with. If you want to stress test your solution and don't mind, take the math patch and run the `https://github.com/TApplencourt/OmpVal` tests: `CXX='clang++' CXXFLAGS='-fopenmp -fopenmp-targets=nvptx64-nvidia-cuda' ./omphval.sh run ./tests/math_cpp11` You'll see compile or link errors if it doesn't work for any reason. Doesn't mean we could not make it work by changing in the math wrappers but that depends on the errors (if any). ================ Comment at: clang/lib/Sema/SemaOpenMP.cpp:5551 + BaseFD->addAttr(OMPDeclareVariantA); BaseFD->setImplicit(true); } ---------------- mikerice wrote: > BaseFD is only implicit now if you created it, not when one was found in the lookup case right? Correct. Need to be changed. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77252/new/ https://reviews.llvm.org/D77252 From cfe-commits at lists.llvm.org Sat Apr 4 18:06:13 2020 From: cfe-commits at lists.llvm.org (Mike Rice via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 01:06:13 +0000 (UTC) Subject: [PATCH] D77252: [OpenMP] Try to find an existing base for `omp begin/end declare variant` In-Reply-To: References: Message-ID: <1b489635bb491d7c461ab699640f0703@localhost.localdomain> mikerice added a comment. I just moved your lookup code and tried to get the same info from the declarator. The function looks like this: FunctionDecl * Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, Declarator &D) { IdentifierInfo *BaseII = D.getIdentifier(); LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), LookupOrdinaryName); LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); QualType FType = TInfo->getType(); bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr; bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval; FunctionDecl *BaseFD = nullptr; for (auto *Candidate : Lookup) { auto *UDecl = dyn_cast(Candidate->getUnderlyingDecl()); if (!UDecl) continue; // Don't specialize constexpr/consteval functions with // non-constexpr/consteval functions. if (UDecl->isConstexpr() && !IsConstexpr) continue; if (UDecl->isConsteval() && !IsConsteval) continue; QualType NewType = Context.mergeFunctionTypes( FType, UDecl->getType(), /* OfBlockPointer */ false, /* Unqualified */ false, /* AllowCXX */ true); if (NewType.isNull()) continue; // Found a base! BaseFD = UDecl; break; } if (!BaseFD) { BaseFD = cast(ActOnDeclarator(S, D)); BaseFD->setImplicit(true); } OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); std::string MangledName; MangledName += D.getIdentifier()->getName(); MangledName += getOpenMPVariantManglingSeparatorStr(); MangledName += DVScope.NameSuffix; IdentifierInfo &VariantII = Context.Idents.get(MangledName); VariantII.setMangledOpenMPVariantName(true); D.SetIdentifier(&VariantII, D.getBeginLoc()); return BaseFD; } I just tried a few tests so I didn't spend too much time verifying it. I'll see if I can get the test your suggest running. I'm not sure I have any better ideas on how to correctly pick the base function. This seems like a reasonable first attempt. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77252/new/ https://reviews.llvm.org/D77252 From cfe-commits at lists.llvm.org Sat Apr 4 19:27:10 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via cfe-commits) Date: Sat, 04 Apr 2020 19:27:10 -0700 (PDT) Subject: [clang-tools-extra] abdd042 - [clang-tools-extra] NFC: Fix trivial typo in documents and comments Message-ID: <5e8941fe.1c69fb81.e48cc.a7c2@mx.google.com> Author: Kazuaki Ishizaki Date: 2020-04-05T11:26:19+09:00 New Revision: abdd042bb7a58bdb2511f0c776ced2c7cb71cac4 URL: https://github.com/llvm/llvm-project/commit/abdd042bb7a58bdb2511f0c776ced2c7cb71cac4 DIFF: https://github.com/llvm/llvm-project/commit/abdd042bb7a58bdb2511f0c776ced2c7cb71cac4.diff LOG: [clang-tools-extra] NFC: Fix trivial typo in documents and comments Differential Revision: https://reviews.llvm.org/D77458 Added: Modified: clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp index 357ecb016173..76b8ac02990e 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp +++ b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp @@ -116,7 +116,7 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) { } if (NumConcrete > 1) { - diag(D->getBeginLoc(), "inheriting mulitple classes that aren't " + diag(D->getBeginLoc(), "inheriting multiple classes that aren't " "pure virtual is discouraged"); } } From cfe-commits at lists.llvm.org Sat Apr 4 19:42:24 2020 From: cfe-commits at lists.llvm.org (Matt Arsenault via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 02:42:24 +0000 (UTC) Subject: [PATCH] D57835: Fix -ftime-report with -x ir In-Reply-To: References: Message-ID: <50422849838c4b6392a91056889fbbd3@localhost.localdomain> arsenm updated this revision to Diff 255095. arsenm added a comment. Rebase, add new PM run line CHANGES SINCE LAST ACTION https://reviews.llvm.org/D57835/new/ https://reviews.llvm.org/D57835 Files: clang/lib/CodeGen/CodeGenAction.cpp clang/lib/Frontend/CompilerInstance.cpp clang/test/Frontend/ftime-report-bitcode.ll Index: clang/test/Frontend/ftime-report-bitcode.ll =================================================================== --- /dev/null +++ clang/test/Frontend/ftime-report-bitcode.ll @@ -0,0 +1,15 @@ +; RUN: %clang_cc1 -triple x86_64-apple-darwin10 -ftime-report -emit-obj -o /dev/null %s 2>&1 | FileCheck %s +; RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fexperimental-new-pass-manager -ftime-report -emit-obj -o /dev/null %s 2>&1 | FileCheck %s + +target triple ="x86_64-apple-darwin10" + +; Make sure the backend time reports are produced when compiling an IR +; input + +; CHECK: Pass execution timing report +; CHECK: LLVM IR Parsing +; CHECK: Clang front-end time report + +define i32 @foo() { + ret i32 0 +} Index: clang/lib/Frontend/CompilerInstance.cpp =================================================================== --- clang/lib/Frontend/CompilerInstance.cpp +++ clang/lib/Frontend/CompilerInstance.cpp @@ -37,6 +37,7 @@ #include "clang/Serialization/GlobalModuleIndex.h" #include "clang/Serialization/InMemoryModuleCache.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Pass.h" #include "llvm/Support/BuryPointer.h" #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/Errc.h" @@ -957,8 +958,10 @@ << " based upon " << BACKEND_PACKAGE_STRING << " default target " << llvm::sys::getDefaultTargetTriple() << "\n"; - if (getFrontendOpts().ShowTimers) + if (getFrontendOpts().ShowTimers) { + llvm::TimePassesIsEnabled = true; createFrontendTimer(); + } if (getFrontendOpts().ShowStats || !getFrontendOpts().StatsFile.empty()) llvm::EnableStatistics(false); Index: clang/lib/CodeGen/CodeGenAction.cpp =================================================================== --- clang/lib/CodeGen/CodeGenAction.cpp +++ clang/lib/CodeGen/CodeGenAction.cpp @@ -172,7 +172,6 @@ CodeGenOpts, C, CoverageInfo)), LinkModules(std::move(LinkModules)) { FrontendTimesIsEnabled = TimePasses; - llvm::TimePassesIsEnabled = TimePasses; } llvm::Module *getModule() const { return Gen->GetModule(); } std::unique_ptr takeModule() { -------------- next part -------------- A non-text attachment was scrubbed... Name: D57835.255095.patch Type: text/x-patch Size: 2174 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 19:42:27 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 02:42:27 +0000 (UTC) Subject: [PATCH] D77252: [OpenMP] Try to find an existing base for `omp begin/end declare variant` In-Reply-To: References: Message-ID: jdoerfert added a comment. In D77252#1961913 , @mikerice wrote: > [...] > > [...] > TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); > QualType FType = TInfo->getType(); > [...] > I think this is a key part of what I was missing. I'll try out your patch with the all the tests and update the patch if it works (which I assume). Thanks! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77252/new/ https://reviews.llvm.org/D77252 From cfe-commits at lists.llvm.org Sat Apr 4 19:42:36 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 02:42:36 +0000 (UTC) Subject: [PATCH] D77458: [clang-tools-extra] NFC: Fix trivial typo in documents and comments In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rGabdd042bb7a5: [clang-tools-extra] NFC: Fix trivial typo in documents and comments (authored by kiszk). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77458/new/ https://reviews.llvm.org/D77458 Files: clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp Index: clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp +++ clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp @@ -116,7 +116,7 @@ } if (NumConcrete > 1) { - diag(D->getBeginLoc(), "inheriting mulitple classes that aren't " + diag(D->getBeginLoc(), "inheriting multiple classes that aren't " "pure virtual is discouraged"); } } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77458.255098.patch Type: text/x-patch Size: 558 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 20:14:46 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 03:14:46 +0000 (UTC) Subject: [PATCH] D77482: [clang-tools-extra] NFC: Fix trivial typo in documents and comments Message-ID: kiszk created this revision. Herald added subscribers: cfe-commits, phosek, usaxena95, kadircet, jfb, arphaman, jkorous, kbarton, nemanjai. Herald added a project: clang. This also includes the build failure due to https://reviews.llvm.org/D77458 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77482 Files: clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp clang-tools-extra/clang-change-namespace/ChangeNamespace.h clang-tools-extra/clang-doc/Generators.cpp clang-tools-extra/clang-doc/Serialize.cpp clang-tools-extra/clang-include-fixer/IncludeFixer.h clang-tools-extra/clang-include-fixer/IncludeFixerContext.h clang-tools-extra/clang-include-fixer/SymbolIndexManager.cpp clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp clang-tools-extra/clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py clang-tools-extra/clang-include-fixer/tool/clang-include-fixer.py clang-tools-extra/clang-move/Move.cpp clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.cpp clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp clang-tools-extra/clang-tidy/bugprone/FoldInitTypeCheck.cpp clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp clang-tools-extra/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h clang-tools-extra/clangd/AST.cpp clang-tools-extra/clangd/ClangdLSPServer.h clang-tools-extra/clangd/Diagnostics.cpp clang-tools-extra/clangd/FindSymbols.h clang-tools-extra/clangd/FindTarget.cpp clang-tools-extra/clangd/FindTarget.h clang-tools-extra/clangd/FormattedString.cpp clang-tools-extra/clangd/Hover.cpp clang-tools-extra/clangd/Hover.h clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/PathMapping.cpp clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Quality.cpp clang-tools-extra/clangd/QueryDriverDatabase.cpp clang-tools-extra/clangd/index/Background.cpp clang-tools-extra/clangd/index/Serialization.cpp clang-tools-extra/clangd/index/SymbolOrigin.h clang-tools-extra/clangd/index/dex/Trigram.cpp clang-tools-extra/clangd/refactor/Rename.cpp clang-tools-extra/clangd/refactor/Rename.h clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp clang-tools-extra/clangd/tool/ClangdMain.cpp clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp clang-tools-extra/clangd/unittests/CollectMacrosTests.cpp clang-tools-extra/clangd/unittests/FindTargetTests.cpp clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp clang-tools-extra/clangd/unittests/PathMappingTests.cpp clang-tools-extra/clangd/unittests/RenameTests.cpp clang-tools-extra/clangd/unittests/SymbolInfoTests.cpp clang-tools-extra/clangd/unittests/TweakTests.cpp clang-tools-extra/docs/clang-tidy/checks/abseil-no-internal-dependencies.rst clang-tools-extra/docs/clang-tidy/checks/bugprone-misplaced-pointer-arithmetic-in-alloc.rst clang-tools-extra/docs/clang-tidy/checks/bugprone-virtual-near-miss.rst clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst clang-tools-extra/docs/clang-tidy/checks/portability-restrict-system-includes.rst clang-tools-extra/docs/clang-tidy/checks/readability-convert-member-functions-to-static.rst clang-tools-extra/docs/clang-tidy/checks/readability-make-member-function-const.rst clang-tools-extra/docs/doxygen.cfg.in clang-tools-extra/docs/pp-trace.rst clang-tools-extra/modularize/CoverageChecker.cpp clang-tools-extra/modularize/CoverageChecker.h clang-tools-extra/modularize/Modularize.cpp clang-tools-extra/modularize/PreprocessorTracker.cpp clang-tools-extra/pp-trace/PPCallbacksTracker.h clang-tools-extra/test/clang-move/move-used-helper-decls.cpp clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header-fixed.h clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header.h clang-tools-extra/test/clang-tidy/checkers/abseil-duration-subtraction.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-branch-clone.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-throw-keyword-missing.cpp clang-tools-extra/test/clang-tidy/checkers/cert-throw-exception-type.cpp clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-custom.cpp clang-tools-extra/test/clang-tidy/checkers/fuchsia-multiple-inheritance.cpp clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-bug34747.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-make-unique.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp clang-tools-extra/unittests/clang-include-fixer/IncludeFixerTest.cpp clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D77482.255104.patch Type: text/x-patch Size: 86894 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 20:46:46 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 03:46:46 +0000 (UTC) Subject: [PATCH] D77482: [clang-tools-extra] NFC: Fix trivial typo in documents and comments In-Reply-To: References: Message-ID: <01499f7c212f7289c3ad8c66282f7dca@localhost.localdomain> kiszk added a subscriber: sammccall. kiszk added a comment. Herald added a subscriber: wuzish. @sammccall, I am very sorry that I led to the build break due to my misoperation in https://reviews.llvm.org/D77458 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77482/new/ https://reviews.llvm.org/D77482 From cfe-commits at lists.llvm.org Sat Apr 4 21:50:53 2020 From: cfe-commits at lists.llvm.org (Richard Smith - zygoloid via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 04:50:53 +0000 (UTC) Subject: [PATCH] D77184: Make it possible for lit.site.cfg to contain relative paths, and use it for llvm and clang In-Reply-To: References: Message-ID: <2f8e3fcfd2b4d1e2ba810465a79f5de5@localhost.localdomain> rsmith added a comment. In D77184#1961495 , @thakis wrote: > In D77184#1961220 , @rsmith wrote: > > > In D77184#1961214 , @rsmith wrote: > > > > > In D77184#1961208 , @rsmith wrote: > > > > > > > This has broken my ability to run the `check-clang` target on Linux. There are symlinks in the path from which I run my builds, and this patch is computing incorrect relative paths in that situation. > > > > > > > > > This patch appears to fix the problem: > > > > > > Turns out that's only a partial fix (it fixes `ninja clang-check` but not the general problem). Running `lit` from inside the source directory is still broken. Eg, this used to work: > > > > clang/test$ $BUILDDIR/bin/llvm-lit SemaCXX/constant-expression.cpp > > > > > > ... and doesn't work any more because the relative paths in `lit.site.cfg.py` don't seem to resolve to the right places. Please can you fix or revert? > > > Can you describe your symlink setup in enough detail that I can recreate it locally please? Two directories $s and $d within $HOME. Source git checkout in $s Build dir is $d/build Symlink $d/src -> $s Symlink $s/clang/build -> $d/build Symlink $c -> $s/clang Configured from $d/build with `cmake ../src` Actual build is run from $c/build Manual `lit` commands are run from $c/test I can provide you with the scripts I use to create my checkouts, symlinks, and to run cmake if you like. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77184/new/ https://reviews.llvm.org/D77184 From cfe-commits at lists.llvm.org Sat Apr 4 22:23:00 2020 From: cfe-commits at lists.llvm.org (Eugene Zelenko via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 05:23:00 +0000 (UTC) Subject: [PATCH] D77482: [clang-tools-extra] NFC: Fix trivial typo in documents and comments In-Reply-To: References: Message-ID: <6f0bca230f0484460cc2b59eca8447b1@localhost.localdomain> Eugene.Zelenko added a comment. In D77482#1962000 , @kiszk wrote: > @sammccall, I am very sorry that I led to the build break due to my misoperation in https://reviews.llvm.org/D77458 You could just update diff in existing revision. No need to create new one. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77482/new/ https://reviews.llvm.org/D77482 From cfe-commits at lists.llvm.org Sat Apr 4 22:23:00 2020 From: cfe-commits at lists.llvm.org (Wenlei He via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 05:23:00 +0000 (UTC) Subject: [PATCH] D77484: [Vector] Pass VectLib to LTO backend so TLI build correct vector function list Message-ID: wenlei created this revision. wenlei added reviewers: hoyFB, spatel. Herald added subscribers: cfe-commits, dang, dexonsmith, steven_wu, MaskRay, hiraditya, arichardson, inglorion, emaste. Herald added a reviewer: espindola. Herald added a project: clang. -fveclib switch not propagated to LTO backends, and as a result, LTO populates vector list as if no math lib is used. This change fixed the driver to lld, and to backend propagation of -fveclib setting. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77484 Files: clang/lib/Driver/ToolChains/CommonArgs.cpp lld/ELF/Config.h lld/ELF/Driver.cpp lld/ELF/LTO.cpp lld/ELF/Options.td llvm/include/llvm/Target/TargetOptions.h llvm/lib/LTO/LTOBackend.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77484.255113.patch Type: text/x-patch Size: 5505 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 22:55:02 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 05:55:02 +0000 (UTC) Subject: [PATCH] D77482: [clang-tools-extra] NFC: Fix trivial typo in documents and comments In-Reply-To: References: Message-ID: kiszk added a comment. Thank you for letting me know. I will do that. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77482/new/ https://reviews.llvm.org/D77482 From cfe-commits at lists.llvm.org Sat Apr 4 23:26:07 2020 From: cfe-commits at lists.llvm.org (Fangrui Song via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 06:26:07 +0000 (UTC) Subject: [PATCH] D77484: [Vector] Pass VectLib to LTO backend so TLI build correct vector function list In-Reply-To: References: Message-ID: <30233554fc2e144044f26c04b3200268@localhost.localdomain> MaskRay added a comment. Added usual lld and LTO side reviewers. I am just a bit worried that option name changes like this patch and D77231 could accidentally slip through if I did not react in time... Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77484/new/ https://reviews.llvm.org/D77484 From cfe-commits at lists.llvm.org Sat Apr 4 23:26:09 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 06:26:09 +0000 (UTC) Subject: [PATCH] D77458: [clang-tools-extra] NFC: Fix trivial typo in documents and comments In-Reply-To: References: Message-ID: kiszk updated this revision to Diff 255119. kiszk added a comment. This includes a fix to break the llvm build CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77458/new/ https://reviews.llvm.org/D77458 Files: clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp clang-tools-extra/clang-change-namespace/ChangeNamespace.h clang-tools-extra/clang-doc/Generators.cpp clang-tools-extra/clang-doc/Serialize.cpp clang-tools-extra/clang-include-fixer/IncludeFixer.h clang-tools-extra/clang-include-fixer/IncludeFixerContext.h clang-tools-extra/clang-include-fixer/SymbolIndexManager.cpp clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp clang-tools-extra/clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py clang-tools-extra/clang-include-fixer/tool/clang-include-fixer.py clang-tools-extra/clang-move/Move.cpp clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.cpp clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp clang-tools-extra/clang-tidy/bugprone/FoldInitTypeCheck.cpp clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp clang-tools-extra/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h clang-tools-extra/clangd/AST.cpp clang-tools-extra/clangd/ClangdLSPServer.h clang-tools-extra/clangd/Diagnostics.cpp clang-tools-extra/clangd/FindSymbols.h clang-tools-extra/clangd/FindTarget.cpp clang-tools-extra/clangd/FindTarget.h clang-tools-extra/clangd/FormattedString.cpp clang-tools-extra/clangd/Hover.cpp clang-tools-extra/clangd/Hover.h clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/PathMapping.cpp clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Quality.cpp clang-tools-extra/clangd/QueryDriverDatabase.cpp clang-tools-extra/clangd/index/Background.cpp clang-tools-extra/clangd/index/Serialization.cpp clang-tools-extra/clangd/index/SymbolOrigin.h clang-tools-extra/clangd/index/dex/Trigram.cpp clang-tools-extra/clangd/refactor/Rename.cpp clang-tools-extra/clangd/refactor/Rename.h clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp clang-tools-extra/clangd/tool/ClangdMain.cpp clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp clang-tools-extra/clangd/unittests/CollectMacrosTests.cpp clang-tools-extra/clangd/unittests/FindTargetTests.cpp clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp clang-tools-extra/clangd/unittests/PathMappingTests.cpp clang-tools-extra/clangd/unittests/RenameTests.cpp clang-tools-extra/clangd/unittests/SymbolInfoTests.cpp clang-tools-extra/clangd/unittests/TweakTests.cpp clang-tools-extra/docs/clang-tidy/checks/abseil-no-internal-dependencies.rst clang-tools-extra/docs/clang-tidy/checks/bugprone-misplaced-pointer-arithmetic-in-alloc.rst clang-tools-extra/docs/clang-tidy/checks/bugprone-virtual-near-miss.rst clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst clang-tools-extra/docs/clang-tidy/checks/portability-restrict-system-includes.rst clang-tools-extra/docs/clang-tidy/checks/readability-convert-member-functions-to-static.rst clang-tools-extra/docs/clang-tidy/checks/readability-make-member-function-const.rst clang-tools-extra/docs/doxygen.cfg.in clang-tools-extra/docs/pp-trace.rst clang-tools-extra/modularize/CoverageChecker.cpp clang-tools-extra/modularize/CoverageChecker.h clang-tools-extra/modularize/Modularize.cpp clang-tools-extra/modularize/PreprocessorTracker.cpp clang-tools-extra/pp-trace/PPCallbacksTracker.h clang-tools-extra/test/clang-move/move-used-helper-decls.cpp clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header-fixed.h clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header.h clang-tools-extra/test/clang-tidy/checkers/abseil-duration-subtraction.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-branch-clone.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-throw-keyword-missing.cpp clang-tools-extra/test/clang-tidy/checkers/cert-throw-exception-type.cpp clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-custom.cpp clang-tools-extra/test/clang-tidy/checkers/fuchsia-multiple-inheritance.cpp clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-bug34747.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-make-unique.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp clang-tools-extra/unittests/clang-include-fixer/IncludeFixerTest.cpp clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D77458.255119.patch Type: text/x-patch Size: 86918 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sat Apr 4 23:28:56 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via cfe-commits) Date: Sat, 04 Apr 2020 23:28:56 -0700 (PDT) Subject: [clang-tools-extra] dd5571d - [clang-tools-extra] NFC: Fix trivial typo in documents and comments Message-ID: <5e897aa8.1c69fb81.f3ca2.2962@mx.google.com> Author: Kazuaki Ishizaki Date: 2020-04-05T15:28:40+09:00 New Revision: dd5571d51a0f6164cb66d02c8cd0e7032e42abe4 URL: https://github.com/llvm/llvm-project/commit/dd5571d51a0f6164cb66d02c8cd0e7032e42abe4 DIFF: https://github.com/llvm/llvm-project/commit/dd5571d51a0f6164cb66d02c8cd0e7032e42abe4.diff LOG: [clang-tools-extra] NFC: Fix trivial typo in documents and comments Differential Revision: https://reviews.llvm.org/D77458 Added: Modified: clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp clang-tools-extra/clang-change-namespace/ChangeNamespace.h clang-tools-extra/clang-doc/Generators.cpp clang-tools-extra/clang-doc/Serialize.cpp clang-tools-extra/clang-include-fixer/IncludeFixer.h clang-tools-extra/clang-include-fixer/IncludeFixerContext.h clang-tools-extra/clang-include-fixer/SymbolIndexManager.cpp clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp clang-tools-extra/clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py clang-tools-extra/clang-include-fixer/tool/clang-include-fixer.py clang-tools-extra/clang-move/Move.cpp clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.cpp clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp clang-tools-extra/clang-tidy/bugprone/FoldInitTypeCheck.cpp clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp clang-tools-extra/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h clang-tools-extra/clangd/AST.cpp clang-tools-extra/clangd/ClangdLSPServer.h clang-tools-extra/clangd/Diagnostics.cpp clang-tools-extra/clangd/FindSymbols.h clang-tools-extra/clangd/FindTarget.cpp clang-tools-extra/clangd/FindTarget.h clang-tools-extra/clangd/FormattedString.cpp clang-tools-extra/clangd/Hover.cpp clang-tools-extra/clangd/Hover.h clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/PathMapping.cpp clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Quality.cpp clang-tools-extra/clangd/QueryDriverDatabase.cpp clang-tools-extra/clangd/index/Background.cpp clang-tools-extra/clangd/index/Serialization.cpp clang-tools-extra/clangd/index/SymbolOrigin.h clang-tools-extra/clangd/index/dex/Trigram.cpp clang-tools-extra/clangd/refactor/Rename.cpp clang-tools-extra/clangd/refactor/Rename.h clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp clang-tools-extra/clangd/tool/ClangdMain.cpp clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp clang-tools-extra/clangd/unittests/CollectMacrosTests.cpp clang-tools-extra/clangd/unittests/FindTargetTests.cpp clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp clang-tools-extra/clangd/unittests/PathMappingTests.cpp clang-tools-extra/clangd/unittests/RenameTests.cpp clang-tools-extra/clangd/unittests/SymbolInfoTests.cpp clang-tools-extra/clangd/unittests/TweakTests.cpp clang-tools-extra/docs/clang-tidy/checks/bugprone-misplaced-pointer-arithmetic-in-alloc.rst clang-tools-extra/docs/clang-tidy/checks/bugprone-virtual-near-miss.rst clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst clang-tools-extra/docs/clang-tidy/checks/portability-restrict-system-includes.rst clang-tools-extra/docs/clang-tidy/checks/readability-convert-member-functions-to-static.rst clang-tools-extra/docs/clang-tidy/checks/readability-make-member-function-const.rst clang-tools-extra/docs/doxygen.cfg.in clang-tools-extra/docs/pp-trace.rst clang-tools-extra/modularize/CoverageChecker.cpp clang-tools-extra/modularize/CoverageChecker.h clang-tools-extra/modularize/Modularize.cpp clang-tools-extra/modularize/PreprocessorTracker.cpp clang-tools-extra/pp-trace/PPCallbacksTracker.h clang-tools-extra/test/clang-move/move-used-helper-decls.cpp clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header-fixed.h clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header.h clang-tools-extra/test/clang-tidy/checkers/abseil-duration-subtraction.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-branch-clone.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-throw-keyword-missing.cpp clang-tools-extra/test/clang-tidy/checkers/cert-throw-exception-type.cpp clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-custom.cpp clang-tools-extra/test/clang-tidy/checkers/fuchsia-multiple-inheritance.cpp clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-bug34747.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-make-unique.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp clang-tools-extra/unittests/clang-include-fixer/IncludeFixerTest.cpp clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h Removed: ################################################################################ diff --git a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp index a25e3e5bcd00..5f4a889cab9e 100644 --- a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp +++ b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp @@ -832,7 +832,7 @@ void ChangeNamespaceTool::replaceQualifiedSymbolInDeclContext( std::string AliasName = NamespaceAlias->getNameAsString(); std::string AliasQualifiedName = NamespaceAlias->getQualifiedNameAsString(); - // We only consider namespace aliases define in the global namepspace or + // We only consider namespace aliases define in the global namespace or // in namespaces that are directly visible from the reference, i.e. // ancestor of the `OldNs`. Note that declarations in ancestor namespaces // but not visible in the new namespace is filtered out by diff --git a/clang-tools-extra/clang-change-namespace/ChangeNamespace.h b/clang-tools-extra/clang-change-namespace/ChangeNamespace.h index 293d5ce83433..147675911941 100644 --- a/clang-tools-extra/clang-change-namespace/ChangeNamespace.h +++ b/clang-tools-extra/clang-change-namespace/ChangeNamespace.h @@ -27,7 +27,7 @@ namespace change_namespace { // reference needs to be fully-qualified, this adds a "::" prefix to the // namespace specifiers unless the new namespace is the global namespace. // For classes, only classes that are declared/defined in the given namespace in -// speficifed files will be moved: forward declarations will remain in the old +// specified files will be moved: forward declarations will remain in the old // namespace. // For example, changing "a" to "x": // Old code: @@ -138,7 +138,7 @@ class ChangeNamespaceTool : public ast_matchers::MatchFinder::MatchCallback { llvm::Regex FilePatternRE; // Information about moved namespaces grouped by file. // Since we are modifying code in old namespaces (e.g. add namespace - // spedifiers) as well as moving them, we store information about namespaces + // specifiers) as well as moving them, we store information about namespaces // to be moved and only move them after all modifications are finished (i.e. // in `onEndOfTranslationUnit`). std::map> MoveNamespaces; diff --git a/clang-tools-extra/clang-doc/Generators.cpp b/clang-tools-extra/clang-doc/Generators.cpp index fda5ab503bed..ec7133466f2e 100644 --- a/clang-tools-extra/clang-doc/Generators.cpp +++ b/clang-tools-extra/clang-doc/Generators.cpp @@ -82,7 +82,7 @@ void Generator::addInfoToIndex(Index &Idx, const doc::Info *Info) { // pointing. auto It = std::find(I->Children.begin(), I->Children.end(), R.USR); if (It != I->Children.end()) { - // If it is found, just change I to point the namespace refererence found. + // If it is found, just change I to point the namespace reference found. I = &*It; } else { // If it is not found a new reference is created diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp index 54ee58960b22..e132c56cb000 100644 --- a/clang-tools-extra/clang-doc/Serialize.cpp +++ b/clang-tools-extra/clang-doc/Serialize.cpp @@ -36,7 +36,7 @@ populateParentNamespaces(llvm::SmallVector &Namespaces, // /A/B // // namespace A { -// namesapce B { +// namespace B { // // class C {}; // diff --git a/clang-tools-extra/clang-include-fixer/IncludeFixer.h b/clang-tools-extra/clang-include-fixer/IncludeFixer.h index 1ec1c50275a4..c941509fe6e2 100644 --- a/clang-tools-extra/clang-include-fixer/IncludeFixer.h +++ b/clang-tools-extra/clang-include-fixer/IncludeFixer.h @@ -62,7 +62,7 @@ class IncludeFixerActionFactory : public clang::tooling::ToolAction { }; /// Create replacements, which are generated by clang-format, for the -/// missing header and mising qualifiers insertions. The function uses the +/// missing header and missing qualifiers insertions. The function uses the /// first header for insertion. /// /// \param Code The source code. diff --git a/clang-tools-extra/clang-include-fixer/IncludeFixerContext.h b/clang-tools-extra/clang-include-fixer/IncludeFixerContext.h index e55597f90ed5..e819d30b2915 100644 --- a/clang-tools-extra/clang-include-fixer/IncludeFixerContext.h +++ b/clang-tools-extra/clang-include-fixer/IncludeFixerContext.h @@ -37,7 +37,7 @@ class IncludeFixerContext { /// The qualifiers of the scope in which SymbolIdentifier lookup /// occurs. It is represented as a sequence of names and scope resolution - /// operatiors ::, ending with a scope resolution operator (e.g. a::b::). + /// operators ::, ending with a scope resolution operator (e.g. a::b::). /// Empty if SymbolIdentifier is not in a specific scope. std::string ScopedQualifiers; diff --git a/clang-tools-extra/clang-include-fixer/SymbolIndexManager.cpp b/clang-tools-extra/clang-include-fixer/SymbolIndexManager.cpp index 7b827536e0ae..97015f2468e9 100644 --- a/clang-tools-extra/clang-include-fixer/SymbolIndexManager.cpp +++ b/clang-tools-extra/clang-include-fixer/SymbolIndexManager.cpp @@ -25,7 +25,7 @@ using find_all_symbols::SymbolAndSignals; // related to the given source file. static double similarityScore(llvm::StringRef FileName, llvm::StringRef Header) { - // Compute the maximum number of common path segements between Header and + // Compute the maximum number of common path segments between Header and // a suffix of FileName. // We do not do a full longest common substring computation, as Header // specifies the path we would directly #include, so we assume it is rooted diff --git a/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp b/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp index a2a98a261c02..7d540d83037b 100644 --- a/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp +++ b/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp @@ -128,7 +128,7 @@ void FindAllSymbols::registerMatchers(MatchFinder *MatchFinder) { auto HasNSOrTUCtxMatcher = hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl())); - // We need seperate rules for C record types and C++ record types since some + // We need separate rules for C record types and C++ record types since some // template related matchers are inapplicable on C record declarations. // // Matchers specific to C++ code. diff --git a/clang-tools-extra/clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py b/clang-tools-extra/clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py index 02b100bd849b..8655af137bb2 100755 --- a/clang-tools-extra/clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py +++ b/clang-tools-extra/clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py @@ -46,7 +46,7 @@ def find_compilation_database(path): def MergeSymbols(directory, args): - """Merge all symbol files (yaml) in a given directaory into a single file.""" + """Merge all symbol files (yaml) in a given directory into a single file.""" invocation = [args.binary, '-merge-dir='+directory, args.saving_path] subprocess.call(invocation) print 'Merge is finished. Saving results in ' + args.saving_path diff --git a/clang-tools-extra/clang-include-fixer/tool/clang-include-fixer.py b/clang-tools-extra/clang-include-fixer/tool/clang-include-fixer.py index e3a52f094f66..62bd07365a99 100644 --- a/clang-tools-extra/clang-include-fixer/tool/clang-include-fixer.py +++ b/clang-tools-extra/clang-include-fixer/tool/clang-include-fixer.py @@ -146,7 +146,7 @@ def main(): help='clang-include-fixer input format.') parser.add_argument('-input', default='', help='String to initialize the database.') - # Don't throw exception when parsing unknown arguements to make the script + # Don't throw exception when parsing unknown arguments to make the script # work in neovim. # Neovim (at least v0.2.1) somehow mangles the sys.argv in a weird way: it # will pass additional arguments (e.g. "-c script_host.py") to sys.argv, diff --git a/clang-tools-extra/clang-move/Move.cpp b/clang-tools-extra/clang-move/Move.cpp index ebeb5d001920..28184a0dce0c 100644 --- a/clang-tools-extra/clang-move/Move.cpp +++ b/clang-tools-extra/clang-move/Move.cpp @@ -145,7 +145,7 @@ class FindAllIncludes : public PPCallbacks { ClangMoveTool *const MoveTool; }; -/// Add a declatration being moved to new.h/cc. Note that the declaration will +/// Add a declaration being moved to new.h/cc. Note that the declaration will /// also be deleted in old.h/cc. void MoveDeclFromOldFileToNewFile(ClangMoveTool *MoveTool, const NamedDecl *D) { MoveTool->getMovedDecls().push_back(D); @@ -453,7 +453,7 @@ createInsertedReplacements(const std::vector &Includes, } // Return a set of all decls which are used/referenced by the given Decls. -// Specically, given a class member declaration, this method will return all +// Specifically, given a class member declaration, this method will return all // decls which are used by the whole class. llvm::DenseSet getUsedDecls(const HelperDeclRefGraph *RG, @@ -767,7 +767,7 @@ void ClangMoveTool::removeDeclsInOldFiles() { // FIXME: Minimize the include path like clang-include-fixer. std::string IncludeNewH = "#include \"" + Context->Spec.NewHeader + "\"\n"; - // This replacment for inserting header will be cleaned up at the end. + // This replacement for inserting header will be cleaned up at the end. auto Err = FileAndReplacements.second.add( tooling::Replacement(FilePath, UINT_MAX, 0, IncludeNewH)); if (Err) @@ -810,7 +810,7 @@ void ClangMoveTool::moveDeclsToNewFiles() { std::vector ActualNewCCDecls; // Filter out all unused helpers in NewCCDecls. - // We only move the used helpers (including transively used helpers) and the + // We only move the used helpers (including transitively used helpers) and the // given symbols being moved. for (const auto *D : NewCCDecls) { if (llvm::is_contained(HelperDeclarations, D) && diff --git a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp index 4bcb46b39032..c17a43c73f95 100644 --- a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp +++ b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp @@ -116,7 +116,7 @@ findMembersUsedInInitExpr(const CXXCtorInitializer *Initializer, /// Reorders fields in the definition of a struct/class. /// -/// At the moment reodering of fields with +/// At the moment reordering of fields with /// diff erent accesses (public/protected/private) is not supported. /// \returns true on success. static bool reorderFieldsInDefinition( @@ -133,7 +133,7 @@ static bool reorderFieldsInDefinition( for (const auto *Field : Definition->fields()) { const auto FieldIndex = Field->getFieldIndex(); if (Field->getAccess() != Fields[NewFieldsOrder[FieldIndex]]->getAccess()) { - llvm::errs() << "Currently reodering of fields with diff erent accesses " + llvm::errs() << "Currently reordering of fields with diff erent accesses " "is not supported\n"; return false; } diff --git a/clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.cpp b/clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.cpp index 6e678c9f6010..b58288500dcf 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.cpp @@ -51,7 +51,7 @@ static double GetValue(const IntegerLiteral *IntLit, // Given the scale of a duration and a `Multiplier`, determine if `Multiplier` // would produce a new scale. If so, return a tuple containing the new scale -// and a suitable Multipler for that scale, otherwise `None`. +// and a suitable Multiplier for that scale, otherwise `None`. static llvm::Optional> GetNewScaleSingleStep(DurationScale OldScale, double Multiplier) { switch (OldScale) { diff --git a/clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp b/clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp index 3466cdbbdcff..39ee86b34f3f 100644 --- a/clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp +++ b/clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp @@ -41,7 +41,7 @@ getDurationInverseForScale(DurationScale Scale) { static const llvm::IndexedMap, DurationScale2IndexFunctor> InverseMap = []() { - // TODO: Revisit the immediately invoked lamba technique when + // TODO: Revisit the immediately invoked lambda technique when // IndexedMap gets an initializer list constructor. llvm::IndexedMap, DurationScale2IndexFunctor> diff --git a/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp b/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp index a3866651dced..368aa576c5f4 100644 --- a/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp @@ -96,7 +96,7 @@ void TimeSubtractionCheck::registerMatchers(MatchFinder *Finder) { {"Hours", "Minutes", "Seconds", "Millis", "Micros", "Nanos"}) { std::string TimeInverse = (llvm::Twine("ToUnix") + ScaleName).str(); llvm::Optional Scale = getScaleForTimeInverse(TimeInverse); - assert(Scale && "Unknow scale encountered"); + assert(Scale && "Unknown scale encountered"); auto TimeInverseMatcher = callExpr(callee( functionDecl(hasName((llvm::Twine("::absl::") + TimeInverse).str())) diff --git a/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp index e40b27585d3d..e5f9ebd48626 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp @@ -130,7 +130,7 @@ void BranchCloneCheck::check(const MatchFinder::MatchResult &Result) { KnownAsClone[j] = true; if (NumCopies == 2) { - // We report the first occurence only when we find the second one. + // We report the first occurrence only when we find the second one. diag(Branches[i]->getBeginLoc(), "repeated branch in conditional chain"); SourceLocation End = @@ -204,7 +204,7 @@ void BranchCloneCheck::check(const MatchFinder::MatchResult &Result) { SourceLocation EndLoc = (EndCurrent - 1)->back()->getEndLoc(); // If the case statement is generated from a macro, it's SourceLocation - // may be invalid, resuling in an assertation failure down the line. + // may be invalid, resulting in an assertion failure down the line. // While not optimal, try the begin location in this case, it's still // better then nothing. if (EndLoc.isInvalid()) diff --git a/clang-tools-extra/clang-tidy/bugprone/FoldInitTypeCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/FoldInitTypeCheck.cpp index e77c981c4ca5..d3bcdb23959a 100644 --- a/clang-tools-extra/clang-tidy/bugprone/FoldInitTypeCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/FoldInitTypeCheck.cpp @@ -115,7 +115,7 @@ void FoldInitTypeCheck::doCheck(const BuiltinType &IterValueType, } void FoldInitTypeCheck::check(const MatchFinder::MatchResult &Result) { - // Given the iterator and init value type retreived by the matchers, + // Given the iterator and init value type retrieved by the matchers, // we check that the ::value_type of the iterator is compatible with // the init value type. const auto *InitType = Result.Nodes.getNodeAs("InitType"); diff --git a/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp index 3e6f9fde1b97..10bbcb85420f 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp @@ -74,7 +74,7 @@ void MisplacedOperatorInStrlenInAllocCheck::check( const Expr *Alloc = Result.Nodes.getNodeAs("Alloc"); if (!Alloc) Alloc = Result.Nodes.getNodeAs("Alloc"); - assert(Alloc && "Matched node bound by 'Alloc' shoud be either 'CallExpr'" + assert(Alloc && "Matched node bound by 'Alloc' should be either 'CallExpr'" " or 'CXXNewExpr'"); const auto *StrLen = Result.Nodes.getNodeAs("StrLen"); diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp index fb0d435a20dc..1eb5a2fa35e7 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp @@ -220,7 +220,7 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) { .bind("sizeof-sizeof-expr"), this); - // Detect sizeof in pointer aritmetic like: N * sizeof(S) == P1 - P2 or + // Detect sizeof in pointer arithmetic like: N * sizeof(S) == P1 - P2 or // (P1 - P2) / sizeof(S) where P1 and P2 are pointers to type S. const auto PtrDiffExpr = binaryOperator( hasOperatorName("-"), diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp index 192403789472..ec088ec8de32 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp @@ -156,7 +156,7 @@ void SuspiciousEnumUsageCheck::checkSuspiciousBitmaskUsage( const auto *EnumConst = EnumExpr ? dyn_cast(EnumExpr->getDecl()) : nullptr; - // Report the parameter if neccessary. + // Report the parameter if necessary. if (!EnumConst) { diag(EnumDec->getInnerLocStart(), BitmaskVarErrorMessage) << countNonPowOfTwoLiteralNum(EnumDec); diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp index 09409d87020c..b21fea185e21 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp @@ -104,7 +104,7 @@ void SuspiciousMissingCommaCheck::check( if (Size < SizeThreshold) return; - // Count the number of occurence of concatenated string literal. + // Count the number of occurrence of concatenated string literal. unsigned int Count = 0; for (unsigned int i = 0; i < Size; ++i) { const Expr *Child = InitializerList->getInit(i)->IgnoreImpCasts(); diff --git a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp index 40008797207e..409950834c40 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp @@ -49,7 +49,7 @@ void UnusedRaiiCheck::check(const MatchFinder::MatchResult &Result) { if (E->getBeginLoc().isMacroID()) return; - // Don't emit a warning for the last statement in the surrounding compund + // Don't emit a warning for the last statement in the surrounding compound // statement. const auto *CS = Result.Nodes.getNodeAs("compound"); if (E == CS->body_back()) diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp index daefc9eed314..c9722a2f1b24 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -110,7 +110,7 @@ bool UseAfterMoveFinder::find(Stmt *FunctionBody, const Expr *MovingCall, UseAfterMove *TheUseAfterMove) { // Generate the CFG manually instead of through an AnalysisDeclContext because // it seems the latter can't be used to generate a CFG for the body of a - // labmda. + // lambda. // // We include implicit and temporary destructors in the CFG so that // destructors marked [[noreturn]] are handled correctly in the control flow diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp index 905aee916d67..27ee0e48bb59 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp @@ -215,7 +215,7 @@ bool OwningMemoryCheck::handleLegacyConsumers(const BoundNodes &Nodes) { // Result of matching for legacy consumer-functions like `::free()`. const auto *LegacyConsumer = Nodes.getNodeAs("legacy_consumer"); - // FIXME: `freopen` should be handled seperately because it takes the filename + // FIXME: `freopen` should be handled separately because it takes the filename // as a pointer, which should not be an owner. The argument that is an owner // is known and the false positive coming from the filename can be avoided. if (LegacyConsumer) { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp index 485a07c5e375..da0794ade65e 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp @@ -189,7 +189,7 @@ computeInsertions(const CXXConstructorDecl::init_const_range &Inits, ? static_cast(Init->getAnyMember()) : Init->getBaseClass()->getAsCXXRecordDecl(); - // Add all fields between current field up until the next intializer. + // Add all fields between current field up until the next initializer. for (; Decl != std::end(OrderedDecls) && *Decl != InitDecl; ++Decl) { if (const auto *D = dyn_cast(*Decl)) { if (DeclsToInit.count(D) > 0) diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h index 9e5491cd5071..338fc1402388 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h @@ -69,7 +69,7 @@ class ProTypeMemberInitCheck : public ClangTidyCheck { bool IgnoreArrays; // Whether fix-its for initialization of fundamental type use assignment - // instead of brace initalization. Only effective in C++11 mode. Default is + // instead of brace initialization. Only effective in C++11 mode. Default is // false. bool UseAssignment; }; diff --git a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h index 7ac70dabf9ba..801124cd5f67 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h +++ b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h @@ -15,7 +15,7 @@ namespace clang { namespace tidy { namespace fuchsia { -/// Mulitple implementation inheritance is discouraged. +/// Multiple implementation inheritance is discouraged. /// /// For the user-facing documentation see: /// http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-multiple-inheritance.html diff --git a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp index 7416eb5f1031..1555201f0fa1 100644 --- a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp +++ b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp @@ -30,7 +30,7 @@ void ExceptionBaseclassCheck::registerMatchers(MatchFinder *Finder) { hasType(substTemplateTypeParmType().bind("templ_type")))), anything()), // Bind to the declaration of the type of the value that - // is thrown. 'anything()' is necessary to always suceed + // is thrown. 'anything()' is necessary to always succeed // in the 'eachOf' because builtin types are not // 'namedDecl'. eachOf(has(expr(hasType(namedDecl().bind("decl")))), anything())) diff --git a/clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp b/clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp index e30b4f12902f..91e2cda0c24f 100644 --- a/clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp +++ b/clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp @@ -65,7 +65,7 @@ static std::pair countCaseLabels(const SwitchStmt *Switch) { } /// This function calculate 2 ** Bits and returns -/// numeric_limits::max() if an overflow occured. +/// numeric_limits::max() if an overflow occurred. static std::size_t twoPow(std::size_t Bits) { return Bits >= std::numeric_limits::digits ? std::numeric_limits::max() @@ -153,7 +153,7 @@ void MultiwayPathsCoveredCheck::handleSwitchWithoutDefault( // matcher used for here does not match on degenerate 'switch'. assert(CaseCount > 0 && "Switch statement without any case found. This case " "should be excluded by the matcher and is handled " - "separatly."); + "separately."); std::size_t MaxPathsPossible = [&]() { if (const auto *GeneralCondition = Result.Nodes.getNodeAs("non-enum-condition")) { diff --git a/clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp b/clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp index 05007e5d85a3..5b1dbf3ac33e 100644 --- a/clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp @@ -202,7 +202,7 @@ void NoRecursionCheck::registerMatchers(MatchFinder *Finder) { void NoRecursionCheck::handleSCC(ArrayRef SCC) { assert(!SCC.empty() && "Empty SCC does not make sense."); - // First of all, call out every stongly connected function. + // First of all, call out every strongly connected function. for (CallGraphNode *N : SCC) { FunctionDecl *D = N->getDefinition(); diag(D->getLocation(), "function %0 is within a recursive call chain") << D; @@ -216,7 +216,7 @@ void NoRecursionCheck::handleSCC(ArrayRef SCC) { assert(!EventuallyCyclicCallStack.empty() && "We should've found the cycle"); // While last node of the call stack does cause a loop, due to the way we - // pathfind the cycle, the loop does not nessesairly begin at the first node + // pathfind the cycle, the loop does not necessarily begin at the first node // of the call stack, so drop front nodes of the call stack until it does. const auto CyclicCallStack = ArrayRef(EventuallyCyclicCallStack) @@ -260,7 +260,7 @@ void NoRecursionCheck::check(const MatchFinder::MatchResult &Result) { CG.addToCallGraph(const_cast(TU)); // Look for cycles in call graph, - // by looking for Strongly Connected Comonents (SCC's) + // by looking for Strongly Connected Components (SCC's) for (llvm::scc_iterator SCCI = llvm::scc_begin(&CG), SCCE = llvm::scc_end(&CG); SCCI != SCCE; ++SCCI) { diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp index 237b2bdb36a9..08f817a4eeab 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp @@ -668,7 +668,7 @@ bool ForLoopIndexUseVisitor::TraverseCXXOperatorCallExpr( } /// If we encounter an array with IndexVar as the index of an -/// ArraySubsriptExpression, note it as a consistent usage and prune the +/// ArraySubscriptExpression, note it as a consistent usage and prune the /// AST traversal. /// /// For example, given diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp index 3466a8a17998..39410d6d0c14 100644 --- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp @@ -123,7 +123,7 @@ void MakeSmartPtrCheck::check(const MatchFinder::MatchResult &Result) { return; // Be conservative for cases where we construct an array without any - // initalization. + // initialization. // For example, // P.reset(new int[5]) // check fix: P = std::make_unique(5) // diff --git a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp index d0f1370a244e..b4d920f5d7df 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp @@ -333,7 +333,7 @@ void UseAutoCheck::replaceIterators(const DeclStmt *D, ASTContext *Context) { const auto *V = cast(Dec); const Expr *ExprInit = V->getInit(); - // Skip expressions with cleanups from the intializer expression. + // Skip expressions with cleanups from the initializer expression. if (const auto *E = dyn_cast(ExprInit)) ExprInit = E->getSubExpr(); diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp index 307297f249c6..37e4d24e9898 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp @@ -307,7 +307,7 @@ class CastSequenceVisitor : public RecursiveASTVisitor { /// SourceLocation pointing within the definition of another macro. bool getMacroAndArgLocations(SourceLocation Loc, SourceLocation &ArgLoc, SourceLocation &MacroLoc) { - assert(Loc.isMacroID() && "Only reasonble to call this on macros"); + assert(Loc.isMacroID() && "Only reasonable to call this on macros"); ArgLoc = Loc; diff --git a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp index f9205920ecd5..87be93252227 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp @@ -442,7 +442,7 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) { // FIXME: this could be done better, by performing a lookup of all // unqualified names in the return type in the scope of the function. If the // lookup finds a diff erent entity than the original entity identified by the - // name, then we can either not perform a rewrite or explicitely qualify the + // name, then we can either not perform a rewrite or explicitly qualify the // entity. Such entities could be function parameter names, (inherited) class // members, template parameters, etc. UnqualNameVisitor UNV{*F}; diff --git a/clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp b/clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp index d987886b62b5..1647cb1f4c94 100644 --- a/clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp @@ -79,7 +79,7 @@ static CheckResult checkDef(const clang::FunctionDecl *Def, Result.Hints.push_back(FixItHint::CreateRemoval(Result.ConstRange)); // Fix the definition and any visible declarations, but don't warn - // seperately for each declaration. Instead, associate all fixes with the + // separately for each declaration. Instead, associate all fixes with the // single warning at the definition. for (const FunctionDecl *Decl = Def->getPreviousDecl(); Decl != nullptr; Decl = Decl->getPreviousDecl()) { diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp index b9573747f636..22fce443a3e0 100644 --- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp @@ -285,7 +285,7 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) { hasParent(stmt(anyOf(ifStmt(), whileStmt()), has(declStmt())))), // Exclude cases common to implicit cast to and from bool. unless(exceptionCases), unless(has(boolXor)), - // Retrive also parent statement, to check if we need additional + // Retrieve also parent statement, to check if we need additional // parens in replacement. anyOf(hasParent(stmt().bind("parentStmt")), anything()), unless(isInTemplateInstantiation()), diff --git a/clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp b/clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp index 32177adfe483..38e427238864 100644 --- a/clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp @@ -137,7 +137,7 @@ declRanges(const DeclStmt *DS, const SourceManager &SM, // Consider the following case: 'int * pointer, value = 42;' // Created slices (inclusive) [ ][ ] [ ] // Because 'getBeginLoc' points to the start of the variable *name*, the - // location of the pointer must be determined separatly. + // location of the pointer must be determined separately. SourceLocation Start = findStartOfIndirection( FirstDecl->getLocation(), countIndirections(FirstDecl->getType().IgnoreParens().getTypePtr()), SM, @@ -150,7 +150,7 @@ declRanges(const DeclStmt *DS, const SourceManager &SM, if (FirstDecl->getType()->isFunctionPointerType()) Start = findPreviousTokenKind(Start, SM, LangOpts, tok::l_paren); - // It is popssible that a declarator is wrapped with parens. + // It is possible that a declarator is wrapped with parens. // Example: 'float (((*f_ptr2)))[42], *f_ptr3, ((f_value2)) = 42.f;' // The slice for the type-part must not contain these parens. Consequently // 'Start' is moved to the most left paren if there are parens. diff --git a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp index 3f096c22ac00..cf31ad00d95c 100644 --- a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp @@ -125,7 +125,7 @@ class FindUsageOfThis : public RecursiveASTVisitor { if (Member->isBoundMemberFunction(Ctxt)) { if (!OnConstObject || Member->getFoundDecl().getAccess() != AS_public) { // Non-public non-static member functions might not preserve the - // logical costness. E.g. in + // logical constness. E.g. in // class C { // int &data() const; // public: diff --git a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp index 6b5569085f71..2de4ccd1b4ef 100644 --- a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp @@ -102,7 +102,7 @@ void NamespaceCommentCheck::check(const MatchFinder::MatchResult &Result) { SourceLocation Loc = AfterRBrace; SourceLocation LBraceLoc = ND->getBeginLoc(); - // Currently for nested namepsace (n1::n2::...) the AST matcher will match foo + // Currently for nested namespace (n1::n2::...) the AST matcher will match foo // then bar instead of a single match. So if we got a nested namespace we have // to skip the next ones. for (const auto &EndOfNameLocation : Ends) { diff --git a/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp b/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp index eef63b7e1956..f99a8b9cb62f 100644 --- a/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp @@ -193,7 +193,7 @@ void UppercaseLiteralSuffixCheck::storeOptions( } void UppercaseLiteralSuffixCheck::registerMatchers(MatchFinder *Finder) { - // Sadly, we can't check whether the literal has sufix or not. + // Sadly, we can't check whether the literal has suffix or not. // E.g. i32 suffix still results in 'BuiltinType::Kind::Int'. // And such an info is not stored in the *Literal itself. Finder->addMatcher( diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp index e8bccd7d6bfd..1e544f4f1b33 100644 --- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp +++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp @@ -131,7 +131,7 @@ ExceptionAnalyzer::ExceptionInfo ExceptionAnalyzer::throwsException( return Result; } -/// Analyzes a single statment on it's throwing behaviour. This is in principle +/// Analyzes a single statement on it's throwing behaviour. This is in principle /// possible except some 'Unknown' functions are called. ExceptionAnalyzer::ExceptionInfo ExceptionAnalyzer::throwsException( const Stmt *St, const ExceptionInfo::Throwables &Caught, diff --git a/clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h b/clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h index e5dfae1ba24c..26184a573783 100644 --- a/clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h +++ b/clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h @@ -37,7 +37,7 @@ bool isSpellingLocInHeaderFile(SourceLocation Loc, SourceManager &SM, /// extensions. inline StringRef defaultHeaderFileExtensions() { return ";h;hh;hpp;hxx"; } -/// Returns recommended default value for the list of implementaiton file +/// Returns recommended default value for the list of implementation file /// extensions. inline StringRef defaultImplementationFileExtensions() { return "c;cc;cpp;cxx"; diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp index 021080c301f7..ce1254f6693c 100644 --- a/clang-tools-extra/clangd/AST.cpp +++ b/clang-tools-extra/clangd/AST.cpp @@ -95,7 +95,7 @@ getUsingNamespaceDirectives(const DeclContext *DestContext, return VisibleNamespaceDecls; } -// Goes over all parents of SourceContext until we find a comman ancestor for +// Goes over all parents of SourceContext until we find a common ancestor for // DestContext and SourceContext. Any qualifier including and above common // ancestor is redundant, therefore we stop at lowest common ancestor. // In addition to that stops early whenever IsVisible returns true. This can be diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h index e259ad04a8e9..294fe0ef6415 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.h @@ -188,7 +188,7 @@ class ClangdLSPServer : private ClangdServer::Callbacks { CB(std::move(Rsp)); } else { elog("Failed to decode {0} response", *RawResponse); - CB(llvm::make_error("failed to decode reponse", + CB(llvm::make_error("failed to decode response", ErrorCode::InvalidParams)); } }; diff --git a/clang-tools-extra/clangd/Diagnostics.cpp b/clang-tools-extra/clangd/Diagnostics.cpp index 380ce25cd27a..32f6a9bf776c 100644 --- a/clang-tools-extra/clangd/Diagnostics.cpp +++ b/clang-tools-extra/clangd/Diagnostics.cpp @@ -597,7 +597,7 @@ void StoreDiags::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, std::replace(Message.begin(), Message.end(), '\n', ' '); } } - if (Message.empty()) // either !SytheticMessage, or we failed to make one. + if (Message.empty()) // either !SyntheticMessage, or we failed to make one. Info.FormatDiagnostic(Message); LastDiag->Fixes.push_back( Fix{std::string(Message.str()), std::move(Edits)}); diff --git a/clang-tools-extra/clangd/FindSymbols.h b/clang-tools-extra/clangd/FindSymbols.h index 5110e8bdd3a9..5fb116b13d11 100644 --- a/clang-tools-extra/clangd/FindSymbols.h +++ b/clang-tools-extra/clangd/FindSymbols.h @@ -32,7 +32,7 @@ llvm::Expected symbolToLocation(const Symbol &Sym, /// Searches for the symbols matching \p Query. The syntax of \p Query can be /// the non-qualified name or fully qualified of a symbol. For example, /// "vector" will match the symbol std::vector and "std::vector" would also -/// match it. Direct children of scopes (namepaces, etc) can be listed with a +/// match it. Direct children of scopes (namespaces, etc) can be listed with a /// trailing /// "::". For example, "std::" will list all children of the std namespace and /// "::" alone will list all children of the global namespace. diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp index 3757f4da97f9..9a397a5a4383 100644 --- a/clang-tools-extra/clangd/FindTarget.cpp +++ b/clang-tools-extra/clangd/FindTarget.cpp @@ -547,7 +547,7 @@ llvm::SmallVector explicitReferenceTargets(DynTypedNode N, DeclRelationSet Mask) { assert(!(Mask & (DeclRelation::TemplatePattern | DeclRelation::TemplateInstantiation)) && - "explicitRefenceTargets handles templates on its own"); + "explicitReferenceTargets handles templates on its own"); auto Decls = allTargetDecls(N); // We prefer to return template instantiation, but fallback to template diff --git a/clang-tools-extra/clangd/FindTarget.h b/clang-tools-extra/clangd/FindTarget.h index eeb063b5f00e..48ad9e6513bb 100644 --- a/clang-tools-extra/clangd/FindTarget.h +++ b/clang-tools-extra/clangd/FindTarget.h @@ -149,7 +149,7 @@ void findExplicitReferences(const ASTContext &AST, /// For templates, will prefer to return a template instantiation whenever /// possible. However, can also return a template pattern if the specialization /// cannot be picked, e.g. in dependent code or when there is no corresponding -/// Decl for a template instantitation, e.g. for templated using decls: +/// Decl for a template instantiation, e.g. for templated using decls: /// template using Ptr = T*; /// Ptr x; /// ^~~ there is no Decl for 'Ptr', so we return the template pattern. diff --git a/clang-tools-extra/clangd/FormattedString.cpp b/clang-tools-extra/clangd/FormattedString.cpp index ecbc060a870a..d3dbdbba17bc 100644 --- a/clang-tools-extra/clangd/FormattedString.cpp +++ b/clang-tools-extra/clangd/FormattedString.cpp @@ -273,7 +273,7 @@ std::string renderBlocks(llvm::ArrayRef> Children, return AdjustedResult; } -// Seperates two blocks with extra spacing. Note that it might render strangely +// Separates two blocks with extra spacing. Note that it might render strangely // in vscode if the trailing block is a codeblock, see // https://github.com/microsoft/vscode/issues/88416 for details. class Ruler : public Block { diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp index 71ab985affa2..d94c528a8fa5 100644 --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -279,7 +279,7 @@ void enhanceFromIndex(HoverInfo &Hover, const NamedDecl &ND, // arguments for example. This function returns the default argument if it is // available. const Expr *getDefaultArg(const ParmVarDecl *PVD) { - // Default argument can be unparsed or uninstatiated. For the former we + // Default argument can be unparsed or uninstantiated. For the former we // can't do much, as token information is only stored in Sema and not // attached to the AST node. For the latter though, it is safe to proceed as // the expression is still valid. @@ -550,7 +550,7 @@ HoverInfo getHoverContents(const DefinedMacro &Macro, ParsedAST &AST) { HI.Name = std::string(Macro.Name); HI.Kind = index::SymbolKind::Macro; // FIXME: Populate documentation - // FIXME: Pupulate parameters + // FIXME: Populate parameters // Try to get the full definition, not just the name SourceLocation StartLoc = Macro.Info->getDefinitionLoc(); @@ -791,7 +791,7 @@ markup::Document HoverInfo::present() const { // Drop trailing "::". if (!LocalScope.empty()) { // Container name, e.g. class, method, function. - // We might want to propogate some info about container type to print + // We might want to propagate some info about container type to print // function foo, class X, method X::bar, etc. ScopeComment = "// In " + llvm::StringRef(LocalScope).rtrim(':').str() + '\n'; diff --git a/clang-tools-extra/clangd/Hover.h b/clang-tools-extra/clangd/Hover.h index ef3bd9f22d95..8fd2e6de51e9 100644 --- a/clang-tools-extra/clangd/Hover.h +++ b/clang-tools-extra/clangd/Hover.h @@ -62,7 +62,7 @@ struct HoverInfo { /// Pretty-printed variable type. /// Set only for variables. llvm::Optional Type; - /// Set for functions and lambadas. + /// Set for functions and lambdas. llvm::Optional ReturnType; /// Set for functions, lambdas and macros with parameters. llvm::Optional> Parameters; diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp index f6205879aa29..fc631da3a317 100644 --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -276,7 +276,7 @@ ParsedAST::build(llvm::StringRef Version, } // Set up ClangTidy. Must happen after BeginSourceFile() so ASTContext exists. - // Clang-tidy has some limitiations to ensure reasonable performance: + // Clang-tidy has some limitations to ensure reasonable performance: // - checks don't see all preprocessor events in the preamble // - matchers run only over the main-file top-level decls (and can't see // ancestors outside this scope). @@ -486,7 +486,7 @@ std::size_t ParsedAST::getUsedBytes() const { // FIXME: the rest of the function is almost a direct copy-paste from // libclang's clang_getCXTUResourceUsage. We could share the implementation. - // Sum up variaous allocators inside the ast context and the preprocessor. + // Sum up various allocators inside the ast context and the preprocessor. Total += AST.getASTAllocatedMemory(); Total += AST.getSideTableAllocatedMemory(); Total += AST.Idents.getAllocator().getTotalMemory(); diff --git a/clang-tools-extra/clangd/PathMapping.cpp b/clang-tools-extra/clangd/PathMapping.cpp index 8740d582a403..eb568b917966 100644 --- a/clang-tools-extra/clangd/PathMapping.cpp +++ b/clang-tools-extra/clangd/PathMapping.cpp @@ -21,7 +21,7 @@ namespace clangd { llvm::Optional doPathMapping(llvm::StringRef S, PathMapping::Direction Dir, const PathMappings &Mappings) { - // Retrun early to optimize for the common case, wherein S is not a file URI + // Return early to optimize for the common case, wherein S is not a file URI if (!S.startswith("file://")) return llvm::None; auto Uri = URI::parse(S); diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp index 48f15420032f..5040aa552103 100644 --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -114,7 +114,7 @@ buildPreamble(PathRef FileName, CompilerInvocation &CI, "(previous was version {2})", FileName, Inputs.Version, OldPreamble->Version); else - vlog("Building first preamble for {0} verson {1}", FileName, + vlog("Building first preamble for {0} version {1}", FileName, Inputs.Version); trace::Span Tracer("BuildPreamble"); diff --git a/clang-tools-extra/clangd/Quality.cpp b/clang-tools-extra/clangd/Quality.cpp index 2261ff61e499..956253ecf183 100644 --- a/clang-tools-extra/clangd/Quality.cpp +++ b/clang-tools-extra/clangd/Quality.cpp @@ -207,7 +207,7 @@ float SymbolQualitySignals::evaluate() const { // question of whether 0 references means a bad symbol or missing data. if (References >= 10) { // Use a sigmoid style boosting function, which flats out nicely for large - // numbers (e.g. 2.58 for 1M refererences). + // numbers (e.g. 2.58 for 1M references). // The following boosting function is equivalent to: // m = 0.06 // f = 12.0 diff --git a/clang-tools-extra/clangd/QueryDriverDatabase.cpp b/clang-tools-extra/clangd/QueryDriverDatabase.cpp index 20eb4f8a28e0..d6502c6b84ba 100644 --- a/clang-tools-extra/clangd/QueryDriverDatabase.cpp +++ b/clang-tools-extra/clangd/QueryDriverDatabase.cpp @@ -169,7 +169,7 @@ extractSystemIncludes(PathRef Driver, llvm::StringRef Lang, } auto Includes = parseDriverOutput(BufOrError->get()->getBuffer()); - log("System include extractor: succesfully executed {0}, got includes: " + log("System include extractor: successfully executed {0}, got includes: " "\"{1}\"", Driver, llvm::join(Includes, ", ")); return Includes; diff --git a/clang-tools-extra/clangd/index/Background.cpp b/clang-tools-extra/clangd/index/Background.cpp index c2541237c3c9..1c26dd48093e 100644 --- a/clang-tools-extra/clangd/index/Background.cpp +++ b/clang-tools-extra/clangd/index/Background.cpp @@ -234,7 +234,7 @@ void BackgroundIndex::update( // headers, since we don't even know what absolute path they should fall in. const auto AbsPath = URICache.resolve(IGN.URI); const auto DigestIt = ShardVersionsSnapshot.find(AbsPath); - // File has diff erent contents, or indexing was successfull this time. + // File has diff erent contents, or indexing was successful this time. if (DigestIt == ShardVersionsSnapshot.end() || DigestIt->getValue().Digest != IGN.Digest || (DigestIt->getValue().HadErrors && !HadErrors)) diff --git a/clang-tools-extra/clangd/index/Serialization.cpp b/clang-tools-extra/clangd/index/Serialization.cpp index 91e946ca9f2f..6ba4e046189c 100644 --- a/clang-tools-extra/clangd/index/Serialization.cpp +++ b/clang-tools-extra/clangd/index/Serialization.cpp @@ -699,7 +699,7 @@ std::unique_ptr loadIndex(llvm::StringRef SymbolFilename, vlog("Loaded {0} from {1} with estimated memory usage {2} bytes\n" " - number of symbols: {3}\n" " - number of refs: {4}\n" - " - numnber of relations: {5}", + " - number of relations: {5}", UseDex ? "Dex" : "MemIndex", SymbolFilename, Index->estimateMemoryUsage(), NumSym, NumRefs, NumRelations); return Index; diff --git a/clang-tools-extra/clangd/index/SymbolOrigin.h b/clang-tools-extra/clangd/index/SymbolOrigin.h index 953f871d5ea6..8af113c75564 100644 --- a/clang-tools-extra/clangd/index/SymbolOrigin.h +++ b/clang-tools-extra/clangd/index/SymbolOrigin.h @@ -16,7 +16,7 @@ namespace clang { namespace clangd { // Describes the source of information about a symbol. -// Mainly useful for debugging, e.g. understanding code completion reuslts. +// Mainly useful for debugging, e.g. understanding code completion results. // This is a bitfield as information can be combined from several sources. enum class SymbolOrigin : uint8_t { Unknown = 0, diff --git a/clang-tools-extra/clangd/index/dex/Trigram.cpp b/clang-tools-extra/clangd/index/dex/Trigram.cpp index 24ae72bf1d1a..725c9c409df1 100644 --- a/clang-tools-extra/clangd/index/dex/Trigram.cpp +++ b/clang-tools-extra/clangd/index/dex/Trigram.cpp @@ -52,7 +52,7 @@ std::vector generateIdentifierTrigrams(llvm::StringRef Identifier) { UniqueTrigrams.insert(Token(Token::Kind::Trigram, Chars)); }; - // Iterate through valid sequneces of three characters Fuzzy Matcher can + // Iterate through valid sequences of three characters Fuzzy Matcher can // process. for (size_t I = 0; I < LowercaseIdentifier.size(); ++I) { // Skip delimiters. diff --git a/clang-tools-extra/clangd/refactor/Rename.cpp b/clang-tools-extra/clangd/refactor/Rename.cpp index 91620920c6ac..0585897947df 100644 --- a/clang-tools-extra/clangd/refactor/Rename.cpp +++ b/clang-tools-extra/clangd/refactor/Rename.cpp @@ -224,7 +224,7 @@ std::vector findOccurrencesWithinFile(ParsedAST &AST, trace::Span Tracer("FindOccurrenceeWithinFile"); // If the cursor is at the underlying CXXRecordDecl of the // ClassTemplateDecl, ND will be the CXXRecordDecl. In this case, we need to - // get the primary template maunally. + // get the primary template manually. // getUSRsForDeclaration will find other related symbols, e.g. virtual and its // overriddens, primary template and all explicit specializations. // FIXME: Get rid of the remaining tooling APIs. @@ -411,7 +411,7 @@ bool impliesSimpleEdit(const Position &LHS, const Position &RHS) { // *subset* of lexed occurrences (we allow a single name refers to more // than one symbol) // - all indexed occurrences must be mapped, and Result must be distinct and -// preseve order (only support detecting simple edits to ensure a +// preserve order (only support detecting simple edits to ensure a // robust mapping) // - each indexed -> lexed occurrences mapping correspondence may change the // *line* or *column*, but not both (increases chance of a robust mapping) diff --git a/clang-tools-extra/clangd/refactor/Rename.h b/clang-tools-extra/clangd/refactor/Rename.h index cfa4135e995d..5c53ba633fa2 100644 --- a/clang-tools-extra/clangd/refactor/Rename.h +++ b/clang-tools-extra/clangd/refactor/Rename.h @@ -30,7 +30,7 @@ struct RenameOptions { /// If true, enable cross-file rename; otherwise, only allows to rename a /// symbol that's only used in the current file. bool AllowCrossFile = false; - /// The mamimum number of affected files (0 means no limit), only meaningful + /// The maximum number of affected files (0 means no limit), only meaningful /// when AllowCrossFile = true. /// If the actual number exceeds the limit, rename is forbidden. size_t LimitFiles = 50; diff --git a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp index 1ecec6674b02..411c685e2b7d 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp @@ -28,7 +28,7 @@ namespace { // top level decl. // // Currently this only removes qualifier from under the cursor. In the future, -// we should improve this to remove qualifier from all occurences of this +// we should improve this to remove qualifier from all occurrences of this // symbol. class AddUsing : public Tweak { public: diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp b/clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp index 8f396e3706b6..b1057d8b80e7 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp @@ -151,7 +151,7 @@ llvm::Expected qualifyAllDecls(const FunctionDecl *FD, // // Go over all references inside a function body to generate replacements that // will qualify those. So that body can be moved into an arbitrary file. - // We perform the qualification by qualyfying the first type/decl in a + // We perform the qualification by qualifying the first type/decl in a // (un)qualified name. e.g: // namespace a { namespace b { class Bar{}; void foo(); } } // b::Bar x; -> a::b::Bar x; @@ -305,7 +305,7 @@ renameParameters(const FunctionDecl *Dest, const FunctionDecl *Source) { ReplaceRange = CharSourceRange::getCharRange(RefLoc, RefLoc); else ReplaceRange = CharSourceRange::getTokenRange(RefLoc, RefLoc); - // If occurence is coming from a macro expansion, try to get back to the + // If occurrence is coming from a macro expansion, try to get back to the // file range. if (RefLoc.isMacroID()) { ReplaceRange = Lexer::makeFileCharRange(ReplaceRange, SM, LangOpts); @@ -352,7 +352,7 @@ const FunctionDecl *findTarget(const FunctionDecl *FD) { return PrevDecl; } -// Returns the begining location for a FunctionDecl. Returns location of +// Returns the beginning location for a FunctionDecl. Returns location of // template keyword for templated functions. const SourceLocation getBeginLoc(const FunctionDecl *FD) { // Include template parameter list. diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp index 9b483bbf05ee..d9e07a001d23 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp @@ -244,7 +244,7 @@ getFunctionSourceCode(const FunctionDecl *FD, llvm::StringRef TargetNamespace, bool HasErrors = true; // Clang allows duplicating virtual specifiers so check for multiple - // occurances. + // occurrences. for (const auto &Tok : TokBuf.expandedTokens(SpecRange)) { if (Tok.kind() != tok::kw_virtual) continue; @@ -291,7 +291,7 @@ llvm::Expected getInsertionPoint(llvm::StringRef Contents, assert(!Region.EligiblePoints.empty()); // FIXME: This selection can be made smarter by looking at the definition - // locations for adjacent decls to Source. Unfortunately psudeo parsing in + // locations for adjacent decls to Source. Unfortunately pseudo parsing in // getEligibleRegions only knows about namespace begin/end events so we // can't match function start/end positions yet. auto Offset = positionToOffset(Contents, Region.EligiblePoints.back()); diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp index 52905c3cafb4..a22b5ab60cd5 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp @@ -119,7 +119,7 @@ const Node *getParentOfRootStmts(const Node *CommonAnc) { const Node *Parent = nullptr; switch (CommonAnc->Selected) { case SelectionTree::Selection::Unselected: - // Typicaly a block, with the { and } unselected, could also be ForStmt etc + // Typically a block, with the { and } unselected, could also be ForStmt etc // Ensure all Children are RootStmts. Parent = CommonAnc; break; @@ -497,7 +497,7 @@ CapturedZoneInfo captureZoneInfo(const ExtractionZone &ExtZone) { } bool VisitDeclRefExpr(DeclRefExpr *DRE) { - // Find the corresponding Decl and mark it's occurence. + // Find the corresponding Decl and mark it's occurrence. const Decl *D = DRE->getDecl(); auto *DeclInfo = Info.getDeclInfoFor(D); // If no Decl was found, the Decl must be outside the enclosingFunc. diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index 4b3b565ac2b6..a8d8f95ce805 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -744,7 +744,7 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var OffsetEncodingFromFlag = ForceOffsetEncoding; clangd::RenameOptions RenameOpts; - // Shall we allow to custimize the file limit? + // Shall we allow to customize the file limit? RenameOpts.AllowCrossFile = CrossFileRename; ClangdLSPServer LSPServer( diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp index 1084b1550579..b873f91d3a4b 100644 --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -597,7 +597,7 @@ TEST(CompletionTest, ContextWords) { auto Finish = Color::^ )cpp"); // Yellow would normally sort last (alphabetic). - // But the recent mention shuold bump it up. + // But the recent mention should bump it up. ASSERT_THAT(Results.Completions, HasSubsequence(Named("YELLOW"), Named("BLUE"))); } @@ -663,7 +663,7 @@ TEST(CompletionTest, IncludeInsertionPreprocessorIntegrationTests) { Symbol Sym = cls("ns::X"); Sym.CanonicalDeclaration.FileURI = BarURI.c_str(); Sym.IncludeHeaders.emplace_back(BarURI, 1); - // Shoten include path based on search directory and insert. + // Shorten include path based on search directory and insert. Annotations Test("int main() { ns::^ }"); TU.Code = Test.code().str(); auto Results = completions(TU, Test.point(), {Sym}); @@ -695,7 +695,7 @@ TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) { SymY.CanonicalDeclaration.FileURI = BarURI.c_str(); SymX.IncludeHeaders.emplace_back("", 1); SymY.IncludeHeaders.emplace_back("", 1); - // Shoten include path based on search directory and insert. + // Shorten include path based on search directory and insert. auto Results = completions(R"cpp( namespace ns { class X; @@ -976,7 +976,7 @@ TEST(CompletionTest, IgnoreCompleteInExcludedPPBranchWithRecoveryContext) { int foo(int param_in_foo) { #if 0 - // In recorvery mode, "param_in_foo" will also be suggested among many other + // In recovery mode, "param_in_foo" will also be suggested among many other // unrelated symbols; however, this is really a special case where this works. // If the #if block is outside of the function, "param_in_foo" is still // suggested, but "bar" and "foo" are missing. So the recovery mode doesn't diff --git a/clang-tools-extra/clangd/unittests/CollectMacrosTests.cpp b/clang-tools-extra/clangd/unittests/CollectMacrosTests.cpp index 7a439c3b484b..aa4c0190b03d 100644 --- a/clang-tools-extra/clangd/unittests/CollectMacrosTests.cpp +++ b/clang-tools-extra/clangd/unittests/CollectMacrosTests.cpp @@ -100,7 +100,7 @@ TEST(CollectMainFileMacros, SelectedMacros) { << "Annotation=" << I << ", MacroName=" << Macro->Name << ", Test = " << Test; } - // Unkown macros. + // Unknown macros. EXPECT_THAT(AST.getMacros().UnknownMacros, UnorderedElementsAreArray(T.ranges("Unknown"))) << "Unknown macros doesn't match in " << Test; diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp index 7b6fff292e66..e0def88845a8 100644 --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -604,7 +604,7 @@ class FindExplicitReferencesTest : public ::testing::Test { }; /// Parses \p Code, finds function or namespace '::foo' and annotates its body - /// with results of findExplicitReferecnces. + /// with results of findExplicitReferences. /// See actual tests for examples of annotation format. AllRefs annotateReferencesInFoo(llvm::StringRef Code) { TestTU TU; diff --git a/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp b/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp index 44ef40f9c99d..63f18e4f9214 100644 --- a/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp +++ b/clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp @@ -136,7 +136,7 @@ TEST(HeaderSourceSwitchTest, FromHeaderToSource) { AllSymbols.insert(Sym); auto Index = MemIndex::build(std::move(AllSymbols).build(), {}, {}); - // Test for swtich from .h header to .cc source + // Test for switch from .h header to .cc source struct { llvm::StringRef HeaderCode; llvm::Optional ExpectedSource; diff --git a/clang-tools-extra/clangd/unittests/PathMappingTests.cpp b/clang-tools-extra/clangd/unittests/PathMappingTests.cpp index 3811776bed01..2da38de10276 100644 --- a/clang-tools-extra/clangd/unittests/PathMappingTests.cpp +++ b/clang-tools-extra/clangd/unittests/PathMappingTests.cpp @@ -52,7 +52,7 @@ TEST(ParsePathMappingTests, UnixPath) { llvm::Expected ParsedMappings = parsePathMappings("/A/b=/root"); ASSERT_TRUE(bool(ParsedMappings)); EXPECT_THAT(*ParsedMappings, ElementsAre(Mapping("/A/b", "/root"))); - // Aboslute unix path w/ backslash + // Absolute unix path w/ backslash ParsedMappings = parsePathMappings(R"(/a/b\\ar=/root)"); ASSERT_TRUE(bool(ParsedMappings)); EXPECT_THAT(*ParsedMappings, ElementsAre(Mapping(R"(/a/b\\ar)", "/root"))); diff --git a/clang-tools-extra/clangd/unittests/RenameTests.cpp b/clang-tools-extra/clangd/unittests/RenameTests.cpp index 55d78a82ab56..eaf74cf062af 100644 --- a/clang-tools-extra/clangd/unittests/RenameTests.cpp +++ b/clang-tools-extra/clangd/unittests/RenameTests.cpp @@ -882,7 +882,7 @@ TEST(CrossFileRenameTests, WithUpToDateIndex) { R"cpp( template class [[Foo]] {}; - // FIXME: explicit template specilizations are not supported due the + // FIXME: explicit template specializations are not supported due the // clangd index limitations. template <> class Foo {}; diff --git a/clang-tools-extra/clangd/unittests/SymbolInfoTests.cpp b/clang-tools-extra/clangd/unittests/SymbolInfoTests.cpp index 023de023d620..6c32502775bf 100644 --- a/clang-tools-extra/clangd/unittests/SymbolInfoTests.cpp +++ b/clang-tools-extra/clangd/unittests/SymbolInfoTests.cpp @@ -199,7 +199,7 @@ TEST(SymbolInfoTests, All) { )cpp", {CreateExpectedSymbolDetails("foo", "", "c:@S at foo")}}, { - R"cpp( // Type Reference - template argumen + R"cpp( // Type Reference - template argument struct foo {}; template struct bar {}; void baz() { diff --git a/clang-tools-extra/clangd/unittests/TweakTests.cpp b/clang-tools-extra/clangd/unittests/TweakTests.cpp index b5d6117217b6..e91ff22d3533 100644 --- a/clang-tools-extra/clangd/unittests/TweakTests.cpp +++ b/clang-tools-extra/clangd/unittests/TweakTests.cpp @@ -588,7 +588,7 @@ TEST_F(ExtractFunctionTest, FunctionTest) { // lead to break being included in the extraction zone. EXPECT_THAT(apply("for(;;) { [[int x;]]break; }"), HasSubstr("extracted")); // FIXME: ExtractFunction should be unavailable inside loop construct - // initalizer/condition. + // initializer/condition. EXPECT_THAT(apply(" for([[int i = 0;]];);"), HasSubstr("extracted")); // Don't extract because needs hoisting. EXPECT_THAT(apply(" [[int a = 5;]] a++; "), StartsWith("fail")); diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone-misplaced-pointer-arithmetic-in-alloc.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone-misplaced-pointer-arithmetic-in-alloc.rst index 4a3606da0250..8e0191a57aaf 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone-misplaced-pointer-arithmetic-in-alloc.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone-misplaced-pointer-arithmetic-in-alloc.rst @@ -1,6 +1,6 @@ .. title:: clang-tidy - bugprone-misplaced-pointer-arithmetic-in-alloc -bugprone-misplaced-pointer-artithmetic-in-alloc +bugprone-misplaced-pointer-arithmetic-in-alloc =============================================== Finds cases where an integer expression is added to or subtracted from the diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone-virtual-near-miss.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone-virtual-near-miss.rst index ac27479713c2..2b2498f6f358 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone-virtual-near-miss.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone-virtual-near-miss.rst @@ -4,7 +4,7 @@ bugprone-virtual-near-miss ========================== Warn if a function is a near miss (ie. the name is very similar and the function -signiture is the same) to a virtual function from a base class. +signature is the same) to a virtual function from a base class. Example: diff --git a/clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst b/clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst index f327ac27e8f0..463356ec186e 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst @@ -29,7 +29,7 @@ statement body: for (int i = 0; i < n; ++i) { p.add_xxx(n); // This will trigger the warning since the add_xxx may cause multiple memory - // relloacations. This can be avoid by inserting a + // reallocations. This can be avoid by inserting a // 'p.mutable_xxx().Reserve(n)' statement before the for statement. } diff --git a/clang-tools-extra/docs/clang-tidy/checks/portability-restrict-system-includes.rst b/clang-tools-extra/docs/clang-tidy/checks/portability-restrict-system-includes.rst index 934550660223..26d4e0d3fcc5 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/portability-restrict-system-includes.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/portability-restrict-system-includes.rst @@ -27,7 +27,7 @@ the options to `*,-zlib.h`. #include // Bad: disallowed system header. #include "src/myfile.h" // Good: non-system header always allowed. -Since the opions support globbing you can use wildcarding to allow groups of +Since the options support globbing you can use wildcarding to allow groups of headers. `-*,openssl/*.h` will allow all openssl headers but disallow any others. diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability-convert-member-functions-to-static.rst b/clang-tools-extra/docs/clang-tidy/checks/readability-convert-member-functions-to-static.rst index c2f05cf589ea..4a9b80fd7874 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability-convert-member-functions-to-static.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability-convert-member-functions-to-static.rst @@ -6,7 +6,7 @@ readability-convert-member-functions-to-static Finds non-static member functions that can be made ``static`` because the functions don't use ``this``. -After applying modifications as suggested by the check, runnnig the check again +After applying modifications as suggested by the check, running the check again might find more opportunities to mark member functions ``static``. After making a member function ``static``, you might want to run the check diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability-make-member-function-const.rst b/clang-tools-extra/docs/clang-tidy/checks/readability-make-member-function-const.rst index 2d1de5fdeb7e..60a828c8741b 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/readability-make-member-function-const.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/readability-make-member-function-const.rst @@ -63,5 +63,5 @@ The following real-world examples will be preserved by the check: ... }; -After applying modifications as suggested by the check, runnnig the check again +After applying modifications as suggested by the check, running the check again might find more opportunities to mark member functions ``const``. diff --git a/clang-tools-extra/docs/doxygen.cfg.in b/clang-tools-extra/docs/doxygen.cfg.in index 56c7b74298e3..d778be30b63e 100644 --- a/clang-tools-extra/docs/doxygen.cfg.in +++ b/clang-tools-extra/docs/doxygen.cfg.in @@ -1400,7 +1400,7 @@ EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # diff --git a/clang-tools-extra/docs/pp-trace.rst b/clang-tools-extra/docs/pp-trace.rst index 60e4de461253..77bc6d0af0ad 100644 --- a/clang-tools-extra/docs/pp-trace.rst +++ b/clang-tools-extra/docs/pp-trace.rst @@ -123,7 +123,7 @@ name as the argument in the corresponding PPCallbacks callback function. Callback Details ---------------- -The following sections describe the pupose and output format for each callback. +The following sections describe the purpose and output format for each callback. Click on the callback name in the section heading to see the Doxygen documentation for the callback. diff --git a/clang-tools-extra/modularize/CoverageChecker.cpp b/clang-tools-extra/modularize/CoverageChecker.cpp index 4246df9483d0..b115d59aaba8 100644 --- a/clang-tools-extra/modularize/CoverageChecker.cpp +++ b/clang-tools-extra/modularize/CoverageChecker.cpp @@ -267,7 +267,7 @@ bool CoverageChecker::collectUmbrellaHeaders(StringRef UmbrellaDirName) { return true; } -// Collect headers rferenced from an umbrella file. +// Collect headers referenced from an umbrella file. bool CoverageChecker::collectUmbrellaHeaderHeaders(StringRef UmbrellaHeaderName) { diff --git a/clang-tools-extra/modularize/CoverageChecker.h b/clang-tools-extra/modularize/CoverageChecker.h index 185cf954ace1..3033a471f43b 100644 --- a/clang-tools-extra/modularize/CoverageChecker.h +++ b/clang-tools-extra/modularize/CoverageChecker.h @@ -124,7 +124,7 @@ class CoverageChecker { /// \return True if no errors. bool collectUmbrellaHeaders(llvm::StringRef UmbrellaDirName); - /// Collect headers rferenced from an umbrella file. + /// Collect headers referenced from an umbrella file. /// \param UmbrellaHeaderName The umbrella file path. /// \return True if no errors. bool collectUmbrellaHeaderHeaders(llvm::StringRef UmbrellaHeaderName); diff --git a/clang-tools-extra/modularize/Modularize.cpp b/clang-tools-extra/modularize/Modularize.cpp index b1efb0e7996a..73c78cff14b2 100644 --- a/clang-tools-extra/modularize/Modularize.cpp +++ b/clang-tools-extra/modularize/Modularize.cpp @@ -184,7 +184,7 @@ // headerlist.txt // // Note that if the headers in the header list have partial paths, sub-modules -// will be created for the subdirectires involved, assuming that the +// will be created for the subdirectories involved, assuming that the // subdirectories contain headers to be grouped into a module, but still with // individual modules for the headers in the subdirectory. // diff --git a/clang-tools-extra/modularize/PreprocessorTracker.cpp b/clang-tools-extra/modularize/PreprocessorTracker.cpp index c5e08246c28d..26c2923c2983 100644 --- a/clang-tools-extra/modularize/PreprocessorTracker.cpp +++ b/clang-tools-extra/modularize/PreprocessorTracker.cpp @@ -147,7 +147,7 @@ // handleNewPreprocessorExit function handles cleaning up with respect // to the preprocessing instance. // -// The PreprocessorCallbacks object uses an overidden FileChanged callback +// The PreprocessorCallbacks object uses an overridden FileChanged callback // to determine when a header is entered and exited (including exiting the // header during #include directives). It calls PreprocessorTracker's // handleHeaderEntry and handleHeaderExit functions upon entering and @@ -174,7 +174,7 @@ // MacroExpansionTracker object, one that matches the macro expanded value // and the macro definition location. If a matching MacroExpansionInstance // object is found, it just adds the current HeaderInclusionPath object to -// it. If not found, it creates and stores a new MacroExpantionInstance +// it. If not found, it creates and stores a new MacroExpansionInstance // object. The addMacroExpansionInstance function calls a couple of helper // functions to get the pre-formatted location and source line strings for // the macro reference and the macro definition stored as string handles. @@ -369,7 +369,7 @@ static std::string getSourceLine(clang::Preprocessor &PP, clang::FileID FileID, } // Get the string for the Unexpanded macro instance. -// The soureRange is expected to end at the last token +// The sourceRange is expected to end at the last token // for the macro instance, which in the case of a function-style // macro will be a ')', but for an object-style macro, it // will be the macro name itself. diff --git a/clang-tools-extra/pp-trace/PPCallbacksTracker.h b/clang-tools-extra/pp-trace/PPCallbacksTracker.h index da5d1b68889f..5bd334ee83f4 100644 --- a/clang-tools-extra/pp-trace/PPCallbacksTracker.h +++ b/clang-tools-extra/pp-trace/PPCallbacksTracker.h @@ -68,7 +68,7 @@ using FilterType = std::vector>; /// callbacks of no interest that might clutter the output. /// /// Following the constructor and destructor function declarations, the -/// overidden callback functions are defined. The remaining functions are +/// overridden callback functions are defined. The remaining functions are /// helpers for recording the trace data, to reduce the coupling between it /// and the recorded data structure. class PPCallbacksTracker : public PPCallbacks { @@ -84,7 +84,7 @@ class PPCallbacksTracker : public PPCallbacks { ~PPCallbacksTracker() override; - // Overidden callback functions. + // Overridden callback functions. void FileChanged(SourceLocation Loc, PPCallbacks::FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, diff --git a/clang-tools-extra/test/clang-move/move-used-helper-decls.cpp b/clang-tools-extra/test/clang-move/move-used-helper-decls.cpp index 45bd4be7676c..b4aed2c73e80 100644 --- a/clang-tools-extra/test/clang-move/move-used-helper-decls.cpp +++ b/clang-tools-extra/test/clang-move/move-used-helper-decls.cpp @@ -3,7 +3,7 @@ // RUN: cd %T/used-helper-decls // ---------------------------------------------------------------------------- -// Test moving used helper function and its transively used functions. +// Test moving used helper function and its transitively used functions. // ---------------------------------------------------------------------------- // RUN: clang-move -names="a::Class1" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11 // RUN: FileCheck -input-file=%T/used-helper-decls/new_helper_decls_test.cpp -check-prefix=CHECK-NEW-CLASS1-CPP %s @@ -29,7 +29,7 @@ // ---------------------------------------------------------------------------- -// Test moving used helper function and its transively used static variables. +// Test moving used helper function and its transitively used static variables. // ---------------------------------------------------------------------------- // RUN: cp %S/Inputs/helper_decls_test* %T/used-helper-decls/ // RUN: clang-move -names="a::Class2" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11 @@ -151,7 +151,7 @@ // ---------------------------------------------------------------------------- -// Test moving helper variables and their transively used helper classes. +// Test moving helper variables and their transitively used helper classes. // ---------------------------------------------------------------------------- // RUN: cp %S/Inputs/helper_decls_test* %T/used-helper-decls/ // RUN: clang-move -names="a::Class6" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11 @@ -216,7 +216,7 @@ // ---------------------------------------------------------------------------- -// Test moving helper function and its transively used helper variables. +// Test moving helper function and its transitively used helper variables. // ---------------------------------------------------------------------------- // RUN: cp %S/Inputs/helper_decls_test* %T/used-helper-decls/ // RUN: clang-move -names="a::Fun1" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11 @@ -260,7 +260,7 @@ // CHECK-OLD-FUN2-H-NOT: inline void Fun2() {} // ---------------------------------------------------------------------------- -// Test moving used helper function and its transively used functions. +// Test moving used helper function and its transitively used functions. // ---------------------------------------------------------------------------- // RUN: cp %S/Inputs/helper_decls_test* %T/used-helper-decls/ // RUN: clang-move -names="b::Fun3" -new_cc=%T/used-helper-decls/new_helper_decls_test.cpp -new_header=%T/used-helper-decls/new_helper_decls_test.h -old_cc=%T/used-helper-decls/helper_decls_test.cpp -old_header=../used-helper-decls/helper_decls_test.h %T/used-helper-decls/helper_decls_test.cpp -- -std=c++11 diff --git a/clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header-fixed.h b/clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header-fixed.h index f3e9e7241d25..a40b2b2ece52 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header-fixed.h +++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header-fixed.h @@ -1,5 +1,5 @@ // struct ABC is expensive to copy and should be -// passed as a const referece. +// passed as a const reference. struct ABC { ABC(const ABC&); int get(int) const; diff --git a/clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header.h b/clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header.h index 3f55c79a2684..94916755ddaf 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header.h +++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header.h @@ -1,5 +1,5 @@ // struct ABC is expensive to copy and should be -// passed as a const referece. +// passed as a const reference. struct ABC { ABC(const ABC&); int get(int) const; diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil-duration-subtraction.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil-duration-subtraction.cpp index 154b7d4ba76d..bd6f3172d777 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/abseil-duration-subtraction.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/abseil-duration-subtraction.cpp @@ -43,7 +43,7 @@ void f() { // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction] // CHECK-FIXES: if (absl::ToDoubleSeconds(d - absl::Seconds(1)) > 10) {} - // A nested occurance + // A nested occurrence x = absl::ToDoubleSeconds(d) - absl::ToDoubleSeconds(absl::Seconds(5)); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the duration domain [abseil-duration-subtraction] // CHECK-FIXES: absl::ToDoubleSeconds(d - absl::Seconds(5)) diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-branch-clone.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone-branch-clone.cpp index af16f5105552..09f87cedfceb 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-branch-clone.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-branch-clone.cpp @@ -940,7 +940,7 @@ int decorated_cases(int z) { return z + 92; } -// The child of the switch statement is not neccessarily a compound statement, +// The child of the switch statement is not necessarily a compound statement, // do not crash in this unusual case. char no_real_body(int in, int &out) { switch (in) diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-throw-keyword-missing.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone-throw-keyword-missing.cpp index 93ecf06ce973..7780089ce8f3 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-throw-keyword-missing.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-throw-keyword-missing.cpp @@ -98,7 +98,7 @@ void funcCallWithTempExcTest() { f(5, RegularException()); } -// Global variable initilization test. +// Global variable initialization test. RegularException exc = RegularException(); RegularException *excptr = new RegularException(); diff --git a/clang-tools-extra/test/clang-tidy/checkers/cert-throw-exception-type.cpp b/clang-tools-extra/test/clang-tidy/checkers/cert-throw-exception-type.cpp index bc0ecc808b29..17884ec4cc35 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cert-throw-exception-type.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cert-throw-exception-type.cpp @@ -1,5 +1,5 @@ // RUN: %check_clang_tidy -std=c++11,c++14 %s cert-err60-cpp %t -- -- -fcxx-exceptions -// FIXME: Split off parts of this test that rely on dynamic exeption +// FIXME: Split off parts of this test that rely on dynamic exception // specifications, and run this test in all language modes. struct S {}; diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-custom.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-custom.cpp index ebf37fa35995..7ffdfccd1d3d 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-custom.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-custom.cpp @@ -8,7 +8,7 @@ using size_t = __SIZE_TYPE__; void *malloc(size_t size); -void *align_malloc(size_t size, unsigned short aligmnent); +void *align_malloc(size_t size, unsigned short alignment); void *calloc(size_t num, size_t size); void *realloc(void *ptr, size_t size); void *align_realloc(void *ptr, size_t size, unsigned short alignment); diff --git a/clang-tools-extra/test/clang-tidy/checkers/fuchsia-multiple-inheritance.cpp b/clang-tools-extra/test/clang-tidy/checkers/fuchsia-multiple-inheritance.cpp index c7869761cf85..6ce9ce8e6553 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/fuchsia-multiple-inheritance.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/fuchsia-multiple-inheritance.cpp @@ -45,16 +45,16 @@ class Interface_with_A_Parent : public Base_A { class Bad_Child1; // Inherits from multiple concrete classes. -// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] +// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] // CHECK-NEXT: class Bad_Child1 : public Base_A, Base_B {}; class Bad_Child1 : public Base_A, Base_B {}; -// CHECK-MESSAGES: [[@LINE+1]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] +// CHECK-MESSAGES: [[@LINE+1]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] class Bad_Child2 : public Base_A, Interface_A_with_member { virtual int foo() override { return 0; } }; -// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] +// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] // CHECK-NEXT: class Bad_Child3 : public Interface_with_A_Parent, Base_B { class Bad_Child3 : public Interface_with_A_Parent, Base_B { virtual int baz() override { return 0; } @@ -83,7 +83,7 @@ class Good_Child3 : public Base_A_child, Interface_C, Interface_B { struct B1 { int x; }; struct B2 { int x;}; -// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] +// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] // CHECK-NEXT: struct D : B1, B2 {}; struct D1 : B1, B2 {}; @@ -100,7 +100,7 @@ struct D3 : V3, V4 {}; struct Base3 {}; struct V5 : virtual Base3 { virtual void f(); }; struct V6 : virtual Base3 { virtual void g(); }; -// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] +// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] // CHECK-NEXT: struct D4 : V5, V6 {}; struct D4 : V5, V6 {}; @@ -118,7 +118,7 @@ struct Base6 { virtual void f(); }; struct Base7 { virtual void g(); }; struct V15 : virtual Base6 { virtual void f() = 0; }; struct V16 : virtual Base7 { virtual void g() = 0; }; -// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] +// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance] // CHECK-NEXT: struct D9 : V15, V16 {}; struct D9 : V15, V16 {}; diff --git a/clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-bug34747.cpp b/clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-bug34747.cpp index 217df71dc339..1502b809e618 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-bug34747.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-bug34747.cpp @@ -12,7 +12,7 @@ template struct foo { typedef OutputStream stream_type; foo(stream_type &o) { - o << 'x'; // warning occured here, fixed now + o << 'x'; // warning occurred here, fixed now } }; diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize-make-unique.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize-make-unique.cpp index 35a6dd0b7d00..16cb5228b2db 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize-make-unique.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize-make-unique.cpp @@ -294,7 +294,7 @@ void initialization(int T, Base b) { PE1.reset(new auto(E())); //============================================================================ - // NOTE: For initlializer-list constructors, the check only gives warnings, + // NOTE: For initializer-list constructors, the check only gives warnings, // and no fixes are generated. //============================================================================ diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp index 0fad5d55f4ee..15348f4b0552 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp @@ -187,7 +187,7 @@ typedef void (function_ptr)(void); // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: {{.*}} in typedef // CHECK-FIXES: {{^}}typedef void (function_ptr)();{{$}} -// intentionally not LLVM style to check preservation of whitesapce +// intentionally not LLVM style to check preservation of whitespace typedef void (function_ptr2) ( void @@ -198,7 +198,7 @@ typedef void (function_ptr2) // CHECK-FIXES-NEXT: {{^ $}} // CHECK-FIXES-NEXT: {{^ \);$}} -// intentionally not LLVM style to check preservation of whitesapce +// intentionally not LLVM style to check preservation of whitespace typedef void ( @@ -254,7 +254,7 @@ typedef void (gronk::*member_function_ptr)(void); // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: {{.*}} in typedef // CHECK-FIXES: {{^}}typedef void (gronk::*member_function_ptr)();{{$}} -// intentionally not LLVM style to check preservation of whitesapce +// intentionally not LLVM style to check preservation of whitespace typedef void (gronk::*member_function_ptr2) ( void @@ -274,7 +274,7 @@ void gronk::foo() { // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration // CHECK-FIXES: {{^ }}void (*f2)();{{$}} - // intentionally not LLVM style to check preservation of whitesapce + // intentionally not LLVM style to check preservation of whitespace void (*f3) ( void @@ -297,7 +297,7 @@ void gronk::bar(void) { // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}} in variable declaration // CHECK-FIXES: {{^ }}void (gronk::*p4)();{{$}} - // intentionally not LLVM style to check preservation of whitesapce + // intentionally not LLVM style to check preservation of whitespace void (gronk::*p5) ( void @@ -309,7 +309,7 @@ void gronk::bar(void) { // CHECK-FIXES-NExT: {{^ \);$}} } -// intentionally not LLVM style to check preservation of whitesapce +// intentionally not LLVM style to check preservation of whitespace void gronk::bar2 ( void @@ -357,7 +357,7 @@ nutter::nutter(void) { // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: {{.*}} in named cast // CHECK-FIXES: void (*f5)() = reinterpret_cast(0);{{$}} - // intentionally not LLVM style to check preservation of whitesapce + // intentionally not LLVM style to check preservation of whitespace void (*f6)(void) = static_cast(0);{{$}} - // intentionally not LLVM style to check preservation of whitesapce + // intentionally not LLVM style to check preservation of whitespace void (*f7)(void) = (void (*) ( void @@ -381,7 +381,7 @@ nutter::nutter(void) { // CHECK-FIXES-NEXT: {{^ $}} // CHECK-FIXES-NEXT: {{^ \)\) 0;$}} - // intentionally not LLVM style to check preservation of whitesapce + // intentionally not LLVM style to check preservation of whitespace void (*f8)(void) = reinterpret_cast *Errors = nullptr, *Errors = std::move(Diags); auto Result = tooling::applyAllReplacements(Code, Fixes); if (!Result) { - // FIXME: propogate the error. + // FIXME: propagate the error. llvm::consumeError(Result.takeError()); return ""; } From cfe-commits at lists.llvm.org Sat Apr 4 23:58:17 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 06:58:17 +0000 (UTC) Subject: [PATCH] D77458: [clang-tools-extra] NFC: Fix trivial typo in documents and comments In-Reply-To: References: Message-ID: <31591159899b7705a4c84815475066a7@localhost.localdomain> kiszk updated this revision to Diff 255120. kiszk added a comment. This include the fix of the build failure at http://lab.llvm.org:8011/builders/clang-cmake-armv7-global-isel/builds/7450/steps/ninja%20check%201/logs/FAIL%3A%20Clang%20Tools%3A%3Afuchsia-multiple-inheritance.cpp CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77458/new/ https://reviews.llvm.org/D77458 Files: clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp clang-tools-extra/clang-change-namespace/ChangeNamespace.h clang-tools-extra/clang-doc/Generators.cpp clang-tools-extra/clang-doc/Serialize.cpp clang-tools-extra/clang-include-fixer/IncludeFixer.h clang-tools-extra/clang-include-fixer/IncludeFixerContext.h clang-tools-extra/clang-include-fixer/SymbolIndexManager.cpp clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp clang-tools-extra/clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py clang-tools-extra/clang-include-fixer/tool/clang-include-fixer.py clang-tools-extra/clang-move/Move.cpp clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp clang-tools-extra/clang-tidy/abseil/DurationFactoryScaleCheck.cpp clang-tools-extra/clang-tidy/abseil/DurationRewriter.cpp clang-tools-extra/clang-tidy/abseil/TimeSubtractionCheck.cpp clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp clang-tools-extra/clang-tidy/bugprone/FoldInitTypeCheck.cpp clang-tools-extra/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp clang-tools-extra/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp clang-tools-extra/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.h clang-tools-extra/clangd/AST.cpp clang-tools-extra/clangd/ClangdLSPServer.h clang-tools-extra/clangd/Diagnostics.cpp clang-tools-extra/clangd/FindSymbols.h clang-tools-extra/clangd/FindTarget.cpp clang-tools-extra/clangd/FindTarget.h clang-tools-extra/clangd/FormattedString.cpp clang-tools-extra/clangd/Hover.cpp clang-tools-extra/clangd/Hover.h clang-tools-extra/clangd/ParsedAST.cpp clang-tools-extra/clangd/PathMapping.cpp clang-tools-extra/clangd/Preamble.cpp clang-tools-extra/clangd/Quality.cpp clang-tools-extra/clangd/QueryDriverDatabase.cpp clang-tools-extra/clangd/index/Background.cpp clang-tools-extra/clangd/index/Serialization.cpp clang-tools-extra/clangd/index/SymbolOrigin.h clang-tools-extra/clangd/index/dex/Trigram.cpp clang-tools-extra/clangd/refactor/Rename.cpp clang-tools-extra/clangd/refactor/Rename.h clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp clang-tools-extra/clangd/tool/ClangdMain.cpp clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp clang-tools-extra/clangd/unittests/CollectMacrosTests.cpp clang-tools-extra/clangd/unittests/FindTargetTests.cpp clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp clang-tools-extra/clangd/unittests/PathMappingTests.cpp clang-tools-extra/clangd/unittests/RenameTests.cpp clang-tools-extra/clangd/unittests/SymbolInfoTests.cpp clang-tools-extra/clangd/unittests/TweakTests.cpp clang-tools-extra/docs/clang-tidy/checks/bugprone-misplaced-pointer-arithmetic-in-alloc.rst clang-tools-extra/docs/clang-tidy/checks/bugprone-virtual-near-miss.rst clang-tools-extra/docs/clang-tidy/checks/performance-inefficient-vector-operation.rst clang-tools-extra/docs/clang-tidy/checks/portability-restrict-system-includes.rst clang-tools-extra/docs/clang-tidy/checks/readability-convert-member-functions-to-static.rst clang-tools-extra/docs/clang-tidy/checks/readability-make-member-function-const.rst clang-tools-extra/docs/doxygen.cfg.in clang-tools-extra/docs/pp-trace.rst clang-tools-extra/modularize/CoverageChecker.cpp clang-tools-extra/modularize/CoverageChecker.h clang-tools-extra/modularize/Modularize.cpp clang-tools-extra/modularize/PreprocessorTracker.cpp clang-tools-extra/pp-trace/PPCallbacksTracker.h clang-tools-extra/test/clang-move/move-used-helper-decls.cpp clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header-fixed.h clang-tools-extra/test/clang-tidy/checkers/Inputs/performance-unnecessary-value-param/header.h clang-tools-extra/test/clang-tidy/checkers/abseil-duration-subtraction.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-branch-clone.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-throw-keyword-missing.cpp clang-tools-extra/test/clang-tidy/checkers/cert-throw-exception-type.cpp clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-custom.cpp clang-tools-extra/test/clang-tidy/checkers/fuchsia-multiple-inheritance.cpp clang-tools-extra/test/clang-tidy/checkers/hicpp-signed-bitwise-bug34747.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-make-unique.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp clang-tools-extra/unittests/clang-include-fixer/IncludeFixerTest.cpp clang-tools-extra/unittests/clang-move/ClangMoveTests.cpp clang-tools-extra/unittests/clang-tidy/ClangTidyTest.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D77458.255120.patch Type: text/x-patch Size: 86050 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 00:30:38 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 07:30:38 +0000 (UTC) Subject: [PATCH] D77252: [OpenMP] Try to find an existing base for `omp begin/end declare variant` In-Reply-To: References: Message-ID: <98a841c611f7ca965b60e268188ddb55@localhost.localdomain> jdoerfert updated this revision to Diff 255124. jdoerfert added a comment. Simplify as suggeston by @mikerice, continue using the Declarator to create the implicit base if needed Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77252/new/ https://reviews.llvm.org/D77252 Files: clang/include/clang/AST/ASTContext.h clang/lib/AST/ASTContext.cpp clang/lib/Sema/SemaOpenMP.cpp clang/test/AST/ast-dump-openmp-begin-declare-variant_10.c clang/test/AST/ast-dump-openmp-begin-declare-variant_11.c clang/test/AST/ast-dump-openmp-begin-declare-variant_12.c clang/test/AST/ast-dump-openmp-begin-declare-variant_2.c clang/test/AST/ast-dump-openmp-begin-declare-variant_3.c clang/test/AST/ast-dump-openmp-begin-declare-variant_5.c clang/test/AST/ast-dump-openmp-begin-declare-variant_6.c clang/test/AST/ast-dump-openmp-begin-declare-variant_7.c clang/test/AST/ast-dump-openmp-begin-declare-variant_8.c clang/test/AST/ast-dump-openmp-begin-declare-variant_9.c clang/test/AST/ast-dump-openmp-begin-declare-variant_addr_1.c clang/test/AST/ast-dump-openmp-begin-declare-variant_namespace_1.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77252.255124.patch Type: text/x-patch Size: 202891 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 02:39:43 2020 From: cfe-commits at lists.llvm.org (Zinovy Nis via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 09:39:43 +0000 (UTC) Subject: [PATCH] D74692: [clang-tidy][bugprone-use-after-move] Warn on std::move for consts In-Reply-To: References: Message-ID: <60776c336d9f4916fc410760776fd5f2@localhost.localdomain> zinovy.nis updated this revision to Diff 255128. zinovy.nis added a comment. Rebase over the current master. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D74692/new/ https://reviews.llvm.org/D74692 Files: clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-use-after-move.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D74692.255128.patch Type: text/x-patch Size: 5019 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 04:14:05 2020 From: cfe-commits at lists.llvm.org (David Zarzycki via cfe-commits) Date: Sun, 05 Apr 2020 07:14:05 -0400 Subject: =?UTF-8?Q?Re:_[libcxx-dev]_[clang]_4ede887_-_PR45402:_Make_the_restricti?= =?UTF-8?Q?ons_on_constant_evaluation_of_memcmp_and?= In-Reply-To: References: <5e87e25e.1c69fb81.933ef.f8d6@mx.google.com> Message-ID: <6c87a15d-885c-43e4-b7de-462c4cbfb460@www.fastmail.com> Hi Richard, I'm going to commit a narrow fix to clang to make the libcxx test suite pass again by allowing char8_t again. If you feel that this is the wrong long-term solution, please help the libcxx folks with whatever adjustments they need. Thanks! Dave On Sat, Apr 4, 2020, at 9:55 AM, David Zarzycki via libcxx-dev wrote: > Hi Richard, > > This breaks libcxx. Can we please revert this or is a quick fix to > libcxx possible? > > > FAIL: libc++ :: > std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp (58624 of 62672) > ******************** TEST 'libc++ :: > std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp' FAILED ******************** > Command: ['/p/tllvm/bin/clang++', '-o', > '/tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o', '-x', 'c++', '/home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp', '-c', '-v', '-Werror=thread-safety', '-std=c++2a', '-include', '/home/dave/s/lp/libcxx/test/support/nasty_macros.h', '-nostdinc++', '-I/home/dave/s/lp/libcxx/include', '-I/tmp/_update_lc/t/projects/libcxx/include/c++build', '-D__STDC_FORMAT_MACROS', '-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-I/home/dave/s/lp/libcxx/test/support', '-ftemplate-depth=270', '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER', '-Wall', '-Wextra', '-Werror', '-Wuser-defined-warnings', '-Wshadow', '-Wno-unused-command-line-argument', '-Wno-attributes', '-Wno-pessimizing-move', '-Wno-c++11-extensions', '-Wno-user-defined-literals', '-Wno-noexcept-type', '-Wsign-compare', '-Wunused-variable', '-Wunused-parameter', '-Wunreachable-code', '-c'] > Exit Code: 1 > Standard Error: > -- > clang version 11.0.0 (https://github.com/llvm/llvm-project.git > 22127da8f17c03c69231f3631472f7f99ad9cb7f) > Target: x86_64-unknown-linux-gnu > Thread model: posix > InstalledDir: /p/tllvm/bin > Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 > Selected GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 > Candidate multilib: .;@m64 > Candidate multilib: 32;@m32 > Selected multilib: .;@m64 > (in-process) > "/p/tllvm/bin/clang-11" -cc1 -triple x86_64-unknown-linux-gnu > -emit-obj -mrelax-all -disable-free -disable-llvm-verifier > -discard-value-names -main-file-name compare.pass.cpp > -mrelocation-model static -mthread-model posix -mframe-pointer=all > -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables > -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining > -debugger-tuning=gdb -v -nostdinc++ -resource-dir > /p/tllvm/lib64/clang/11.0.0 -include > /home/dave/s/lp/libcxx/test/support/nasty_macros.h -I > /home/dave/s/lp/libcxx/include -I > /tmp/_update_lc/t/projects/libcxx/include/c++build -D > __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS > -I /home/dave/s/lp/libcxx/test/support -D > _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -internal-isystem > /usr/local/include -internal-isystem > /p/tllvm/lib64/clang/11.0.0/include -internal-externc-isystem /include > -internal-externc-isystem /usr/include -Werror=thread-safety -Wall > -Wextra -Werror -Wuser-defined-warnings -Wshadow > -Wno-unused-command-line-argument -Wno-attributes -Wno-pessimizing-move > -Wno-c++11-extensions -Wno-user-defined-literals -Wno-noexcept-type > -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code > -std=c++2a -fdeprecated-macro -fdebug-compilation-dir > /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t -ftemplate-depth 270 -ferror-limit 19 -fgnuc-version=4.2.1 -fno-implicit-modules -fcxx-exceptions -fexceptions -faddrsig -o /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o -x c++ /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp > clang -cc1 version 11.0.0 based upon LLVM 11.0.0git default target > x86_64-unknown-linux-gnu > ignoring nonexistent directory "/include" > #include "..." search starts here: > #include <...> search starts here: > /home/dave/s/lp/libcxx/include > /tmp/_update_lc/t/projects/libcxx/include/c++build > /home/dave/s/lp/libcxx/test/support > /usr/local/include > /p/tllvm/lib64/clang/11.0.0/include > /usr/include > End of search list. > /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: error: static_assert expression is not an integral constant expression > static_assert(test_constexpr(), "" ); > ^~~~~~~~~~~~~~~~ > /home/dave/s/lp/libcxx/include/__string:662:12: note: constant > evaluation of '__builtin_memcmp' between arrays of types 'const > char8_t' and 'const char8_t' is not supported; only arrays of narrow > character types can be compared > return __builtin_memcmp(__s1, __s2, __n); > ^ > /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:24:12: note: in call to 'compare(&u8"123"[0], &u8"223"[0], 3)' > return std::char_traits::compare(u8"123", u8"223", 3) < 0 > ^ > /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: note: in call to 'test_constexpr()' > static_assert(test_constexpr(), "" ); > ^ > 1 error generated. > -- > > Compilation failed unexpectedly! > ******************** > > Testing Time: 135.49s > ******************** > Failing Tests (1): > libc++ :: > std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp > > Expected Passes : 45503 > Expected Failures : 118 > Unsupported Tests : 17050 > Unexpected Failures: 1 > > > On Fri, Apr 3, 2020, at 9:26 PM, Richard Smith via cfe-commits wrote: > > > > Author: Richard Smith > > Date: 2020-04-03T18:26:14-07:00 > > New Revision: 4ede8879924c08ae5b495d3f421c167d822a60be > > > > URL: > > https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be > > DIFF: > > https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be.diff > > > > LOG: PR45402: Make the restrictions on constant evaluation of memcmp and > > memchr consistent and comprehensible, and document them. > > > > We previously allowed evaluation of memcmp on arrays of integers of any > > size, so long as the call evaluated to 0, and allowed evaluation of > > memchr on any array of integral type of size 1 (including enums). The > > purpose of constant-evaluating these builtins is only to support > > constexpr std::char_traits, so we now consistently allow them on arrays > > of (possibly signed or unsigned) char only. > > > > Added: > > > > > > Modified: > > clang/docs/LanguageExtensions.rst > > clang/include/clang/Basic/DiagnosticASTKinds.td > > clang/lib/AST/ExprConstant.cpp > > clang/test/SemaCXX/constexpr-string.cpp > > > > Removed: > > > > > > > > ################################################################################ > > diff --git a/clang/docs/LanguageExtensions.rst > > b/clang/docs/LanguageExtensions.rst > > index 558ce7dee653..6dcfd1a49f06 100644 > > --- a/clang/docs/LanguageExtensions.rst > > +++ b/clang/docs/LanguageExtensions.rst > > @@ -2333,10 +2333,11 @@ String builtins > > --------------- > > > > Clang provides constant expression evaluation support for builtins forms of > > -the following functions from the C standard library ```` header: > > +the following functions from the C standard library headers > > +```` and ````: > > > > * ``memchr`` > > -* ``memcmp`` > > +* ``memcmp`` (and its deprecated BSD / POSIX alias ``bcmp``) > > * ``strchr`` > > * ``strcmp`` > > * ``strlen`` > > @@ -2366,7 +2367,11 @@ In addition to the above, one further builtin is > > provided: > > constant expressions in C++11 onwards (where a cast from ``void*`` to > > ``char*`` > > is disallowed in general). > > > > -Support for constant expression evaluation for the above builtins be > > detected > > +Constant evaluation support for the ``__builtin_mem*`` functions is > > provided > > +only for arrays of ``char``, ``signed char``, or ``unsigned char``, > > despite > > +these functions accepting an argument of type ``const void*``. > > + > > +Support for constant expression evaluation for the above builtins can > > be detected > > with ``__has_feature(cxx_constexpr_string_builtins)``. > > > > Memory builtins > > @@ -2386,6 +2391,25 @@ more information. > > > > Note that the `size` argument must be a compile time constant. > > > > +Clang provides constant expression evaluation support for builtin > > forms of the > > +following functions from the C standard library headers > > +```` and ````: > > + > > +* ``memcpy`` > > +* ``memmove`` > > +* ``wmemcpy`` > > +* ``wmemmove`` > > + > > +In each case, the builtin form has the name of the C library function > > prefixed > > +by ``__builtin_``. > > + > > +Constant evaluation support is only provided when the source and > > destination > > +are pointers to arrays with the same trivially copyable element type, > > and the > > +given size is an exact multiple of the element size that is no greater > > than > > +the number of elements accessible through the source and destination > > operands. > > + > > +Constant evaluation support is not yet provided for > > ``__builtin_memcpy_inline``. > > + > > Atomic Min/Max builtins with memory ordering > > -------------------------------------------- > > > > > > diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td > > b/clang/include/clang/Basic/DiagnosticASTKinds.td > > index 544573edffdf..a1415f9ec0e1 100644 > > --- a/clang/include/clang/Basic/DiagnosticASTKinds.td > > +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td > > @@ -244,6 +244,12 @@ def note_constexpr_unsupported_unsized_array : > > Note< > > def note_constexpr_unsized_array_indexed : Note< > > "indexing of array without known bound is not allowed " > > "in a constant expression">; > > +def note_constexpr_memcmp_unsupported : Note< > > + "constant evaluation of %0 between arrays of types %1 and %2 " > > + "is not supported; only arrays of narrow character types can be > > compared">; > > +def note_constexpr_memchr_unsupported : Note< > > + "constant evaluation of %0 on array of type %1 " > > + "is not supported; only arrays of narrow character types can be > > searched">; > > def note_constexpr_memcpy_null : Note< > > "%select{source|destination}2 of " > > "'%select{%select{memcpy|wmemcpy}1|%select{memmove|wmemmove}1}0' " > > > > diff --git a/clang/lib/AST/ExprConstant.cpp > > b/clang/lib/AST/ExprConstant.cpp > > index c6e1cc7b67df..a83b2e24e17f 100644 > > --- a/clang/lib/AST/ExprConstant.cpp > > +++ b/clang/lib/AST/ExprConstant.cpp > > @@ -8469,8 +8469,12 @@ bool > > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, > > } > > // Give up on byte-oriented matching against multibyte elements. > > // FIXME: We can compare the bytes in the correct order. > > - if (IsRawByte && Info.Ctx.getTypeSizeInChars(CharTy) != > > CharUnits::One()) > > + if (IsRawByte && !CharTy->isCharType()) { > > + Info.FFDiag(E, diag::note_constexpr_memchr_unsupported) > > + << (std::string("'") + > > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") > > + << CharTy; > > return false; > > + } > > // Figure out what value we're actually looking for (after > > converting to > > // the corresponding unsigned type if necessary). > > uint64_t DesiredVal; > > @@ -8586,6 +8590,7 @@ bool > > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, > > QualType T = Dest.Designator.getType(Info.Ctx); > > QualType SrcT = Src.Designator.getType(Info.Ctx); > > if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) { > > + // FIXME: Consider using our bit_cast implementation to support > > this. > > Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) << Move << > > SrcT << T; > > return false; > > } > > @@ -11149,6 +11154,16 @@ bool > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, > > CharTy1, E->getArg(0)->getType()->getPointeeType()) && > > Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2))); > > > > + // For memcmp, allow comparing any arrays of '[[un]signed] char', > > + // but no other types. > > + if (IsRawByte && !(CharTy1->isCharType() && > > CharTy2->isCharType())) { > > + // FIXME: Consider using our bit_cast implementation to support > > this. > > + Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported) > > + << (std::string("'") + > > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") > > + << CharTy1 << CharTy2; > > + return false; > > + } > > + > > const auto &ReadCurElems = [&](APValue &Char1, APValue &Char2) { > > return handleLValueToRValueConversion(Info, E, CharTy1, String1, > > Char1) && > > handleLValueToRValueConversion(Info, E, CharTy2, String2, > > Char2) && > > @@ -11159,57 +11174,6 @@ bool > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, > > HandleLValueArrayAdjustment(Info, E, String2, CharTy2, 1); > > }; > > > > - if (IsRawByte) { > > - uint64_t BytesRemaining = MaxLength; > > - // Pointers to const void may point to objects of incomplete > > type. > > - if (CharTy1->isIncompleteType()) { > > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << > > CharTy1; > > - return false; > > - } > > - if (CharTy2->isIncompleteType()) { > > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << > > CharTy2; > > - return false; > > - } > > - uint64_t CharTy1Width{Info.Ctx.getTypeSize(CharTy1)}; > > - CharUnits CharTy1Size = > > Info.Ctx.toCharUnitsFromBits(CharTy1Width); > > - // Give up on comparing between elements with disparate widths. > > - if (CharTy1Size != Info.Ctx.getTypeSizeInChars(CharTy2)) > > - return false; > > - uint64_t BytesPerElement = CharTy1Size.getQuantity(); > > - assert(BytesRemaining && "BytesRemaining should not be zero: the > > " > > - "following loop considers at least one > > element"); > > - while (true) { > > - APValue Char1, Char2; > > - if (!ReadCurElems(Char1, Char2)) > > - return false; > > - // We have compatible in-memory widths, but a possible type and > > - // (for `bool`) internal representation mismatch. > > - // Assuming two's complement representation, including 0 for > > `false` and > > - // 1 for `true`, we can check an appropriate number of > > elements for > > - // equality even if they are not byte-sized. > > - APSInt Char1InMem = Char1.getInt().extOrTrunc(CharTy1Width); > > - APSInt Char2InMem = Char2.getInt().extOrTrunc(CharTy1Width); > > - if (Char1InMem.ne(Char2InMem)) { > > - // If the elements are byte-sized, then we can produce a > > three-way > > - // comparison result in a straightforward manner. > > - if (BytesPerElement == 1u) { > > - // memcmp always compares unsigned chars. > > - return Success(Char1InMem.ult(Char2InMem) ? -1 : 1, E); > > - } > > - // The result is byte-order sensitive, and we have multibyte > > elements. > > - // FIXME: We can compare the remaining bytes in the correct > > order. > > - return false; > > - } > > - if (!AdvanceElems()) > > - return false; > > - if (BytesRemaining <= BytesPerElement) > > - break; > > - BytesRemaining -= BytesPerElement; > > - } > > - // Enough elements are equal to account for the memcmp limit. > > - return Success(0, E); > > - } > > - > > bool StopAtNull = > > (BuiltinOp != Builtin::BImemcmp && BuiltinOp != > > Builtin::BIbcmp && > > BuiltinOp != Builtin::BIwmemcmp && > > @@ -11227,7 +11191,7 @@ bool > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, > > APValue Char1, Char2; > > if (!ReadCurElems(Char1, Char2)) > > return false; > > - if (Char1.getInt() != Char2.getInt()) { > > + if (Char1.getInt().ne(Char2.getInt())) { > > if (IsWide) // wmemcmp compares with wchar_t signedness. > > return Success(Char1.getInt() < Char2.getInt() ? -1 : 1, E); > > // memcmp always compares unsigned chars. > > > > diff --git a/clang/test/SemaCXX/constexpr-string.cpp > > b/clang/test/SemaCXX/constexpr-string.cpp > > index f540be8f8e5b..79ac3bf2cc4d 100644 > > --- a/clang/test/SemaCXX/constexpr-string.cpp > > +++ b/clang/test/SemaCXX/constexpr-string.cpp > > @@ -47,7 +47,7 @@ extern "C" { > > extern wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n); > > } > > > > -# 45 "SemaCXX/constexpr-string.cpp" 2 > > +# 51 "SemaCXX/constexpr-string.cpp" 2 > > namespace Strlen { > > constexpr int n = __builtin_strlen("hello"); // ok > > static_assert(n == 5); > > @@ -121,13 +121,13 @@ namespace StrcmpEtc { > > extern struct Incomplete incomplete; > > static_assert(__builtin_memcmp(&incomplete, "", 0u) == 0); > > static_assert(__builtin_memcmp("", &incomplete, 0u) == 0); > > - static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // > > expected-error {{not an integral constant}} expected-note {{read of > > incomplete type 'struct Incomplete'}} > > - static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // > > expected-error {{not an integral constant}} expected-note {{read of > > incomplete type 'struct Incomplete'}} > > + static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // > > expected-error {{not an integral constant}} expected-note {{not > > supported}} > > + static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // > > expected-error {{not an integral constant}} expected-note {{not > > supported}} > > > > static_assert(__builtin_bcmp(&incomplete, "", 0u) == 0); > > static_assert(__builtin_bcmp("", &incomplete, 0u) == 0); > > - static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // > > expected-error {{not an integral constant}} expected-note {{read of > > incomplete type 'struct Incomplete'}} > > - static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // > > expected-error {{not an integral constant}} expected-note {{read of > > incomplete type 'struct Incomplete'}} > > + static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // > > expected-error {{not an integral constant}} expected-note {{not > > supported}} > > + static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // > > expected-error {{not an integral constant}} expected-note {{not > > supported}} > > > > constexpr unsigned char ku00fe00[] = {0x00, 0xfe, 0x00}; > > constexpr unsigned char ku00feff[] = {0x00, 0xfe, 0xff}; > > @@ -155,11 +155,11 @@ namespace StrcmpEtc { > > > > struct Bool3Tuple { bool bb[3]; }; > > constexpr Bool3Tuple kb000100 = {{false, true, false}}; > > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, > > kb000100.bb, 1) == 0); > > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, > > kb000100.bb, 2) == 1); > > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, > > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note > > {{not supported}} > > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, > > kb000100.bb, 2) == 1); // expected-error {{constant}} expected-note > > {{not supported}} > > > > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, > > kb000100.bb, 1) == 0); > > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, > > kb000100.bb, 2) != 0); > > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, > > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note > > {{not supported}} > > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, > > kb000100.bb, 2) != 0); // expected-error {{constant}} expected-note > > {{not supported}} > > > > constexpr long ksl[] = {0, -1}; > > constexpr unsigned int kui[] = {0, 0u - 1}; > > @@ -173,25 +173,25 @@ namespace StrcmpEtc { > > return nullptr; > > } > > } > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) - > > 1) == 0); > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + > > 0) == 0); > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + > > 1) == 0); > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) - > > 1) == 0); > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > > 0) == 0); > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > > 1) == 42); // expected-error {{not an integral constant}} expected-note > > {{dereferenced one-past-the-end}} > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > > sizeof(long) - 1) == 0); > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > > sizeof(long) + 0) == 0); > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > > sizeof(long) + 1) == 42); // expected-error {{not an integral > > constant}} expected-note {{dereferenced one-past-the-end}} > > - > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - 1) > > == 0); > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 0) > > == 0); > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 1) > > == 0); > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) - > > 1) == 0); > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > > 0) == 0); > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > > 1) == 42); // expected-error {{not an integral constant}} expected-note > > {{dereferenced one-past-the-end}} > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > > sizeof(long) - 1) == 0); > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > > sizeof(long) + 0) == 0); > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > > sizeof(long) + 1) == 42); // expected-error {{not an integral > > constant}} expected-note {{dereferenced one-past-the-end}} > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) - > > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + > > 0) == 0); // expected-error {{constant}} expected-note {{not supported}} > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + > > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) - > > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > > 0) == 0); // expected-error {{constant}} expected-note {{not supported}} > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > > 1) == 42); // expected-error {{constant}} expected-note {{not > > supported}} > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > > sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note > > {{not supported}} > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > > sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note > > {{not supported}} > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > > sizeof(long) + 1) == 42); // expected-error {{constant}} expected-note > > {{not supported}} > > + > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - 1) > > == 0); // expected-error {{constant}} expected-note {{not supported}} > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 0) > > == 0); // expected-error {{constant}} expected-note {{not supported}} > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 1) > > == 0); // expected-error {{constant}} expected-note {{not supported}} > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) - > > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > > 0) == 0); // expected-error {{constant}} expected-note {{not supported}} > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > > 1) == 42); // expected-error {{constant}} expected-note {{not > > supported}} > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > > sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note > > {{not supported}} > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > > sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note > > {{not supported}} > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > > sizeof(long) + 1) == 42); // expected-error {{constant}} expected-note > > {{not supported}} > > > > constexpr int a = strcmp("hello", "world"); // expected-error > > {{constant expression}} expected-note {{non-constexpr function 'strcmp' > > cannot be used in a constant expression}} > > constexpr int b = strncmp("hello", "world", 3); // expected-error > > {{constant expression}} expected-note {{non-constexpr function > > 'strncmp' cannot be used in a constant expression}} > > @@ -385,14 +385,14 @@ namespace StrchrEtc { > > enum class E : unsigned char {}; > > struct EPair { E e, f; }; > > constexpr EPair ee{E{240}}; > > - static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); > > + static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); // > > expected-error {{constant}} expected-note {{not supported}} > > > > constexpr bool kBool[] = {false, true, false}; > > constexpr const bool *const kBoolPastTheEndPtr = kBool + 3; > > - static_assert(sizeof(bool) != 1u || > > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); > > - static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, 0, > > 99) == kBoolPastTheEndPtr - 1); > > - static_assert(sizeof(bool) != 1u || > > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); > > - static_assert(sizeof(bool) != 1u || > > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // > > expected-error {{not an integral constant}} expected-note > > {{dereferenced one-past-the-end}} > > + static_assert(sizeof(bool) != 1u || > > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); // > > expected-error {{constant}} expected-note {{not supported}} > > + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, 0, > > 99) == kBoolPastTheEndPtr - 1); // expected-error {{constant}} > > expected-note {{not supported}} > > + static_assert(sizeof(bool) != 1u || > > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); // > > expected-error {{constant}} expected-note {{not supported}} > > + static_assert(sizeof(bool) != 1u || > > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // > > expected-error {{constant}} expected-note {{not supported}} > > > > static_assert(__builtin_char_memchr(kStr, 'a', 0) == nullptr); > > static_assert(__builtin_char_memchr(kStr, 'a', 1) == kStr); > > > > > > > > _______________________________________________ > > cfe-commits mailing list > > cfe-commits at lists.llvm.org > > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > > > _______________________________________________ > libcxx-dev mailing list > libcxx-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/libcxx-dev > From cfe-commits at lists.llvm.org Sun Apr 5 04:17:27 2020 From: cfe-commits at lists.llvm.org (David Zarzycki via cfe-commits) Date: Sun, 05 Apr 2020 04:17:27 -0700 (PDT) Subject: [clang] 2c88a48 - [clang] Make libcxx test suite pass again after memcmp changes Message-ID: <5e89be47.1c69fb81.4a8e3.c6cc@mx.google.com> Author: David Zarzycki Date: 2020-04-05T07:16:47-04:00 New Revision: 2c88a485c71155c19e512f22c54e63ee337282a3 URL: https://github.com/llvm/llvm-project/commit/2c88a485c71155c19e512f22c54e63ee337282a3 DIFF: https://github.com/llvm/llvm-project/commit/2c88a485c71155c19e512f22c54e63ee337282a3.diff LOG: [clang] Make libcxx test suite pass again after memcmp changes Added: Modified: clang/lib/AST/ExprConstant.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index a83b2e24e17f..7508bcbc365d 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -11154,9 +11154,11 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, CharTy1, E->getArg(0)->getType()->getPointeeType()) && Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2))); - // For memcmp, allow comparing any arrays of '[[un]signed] char', - // but no other types. - if (IsRawByte && !(CharTy1->isCharType() && CharTy2->isCharType())) { + // For memcmp, allow comparing any arrays of '[[un]signed] char' or + // 'char8_t', but no other types. + bool IsChar = CharTy1->isCharType() && CharTy2->isCharType(); + bool IsChar8 = CharTy1->isChar8Type() && CharTy2->isChar8Type(); + if (IsRawByte && !IsChar && !IsChar8) { // FIXME: Consider using our bit_cast implementation to support this. Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported) << (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") From cfe-commits at lists.llvm.org Sun Apr 5 05:19:45 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Krist=C3=B3f_Umann_via_Phabricator?= via cfe-commits) Date: Sun, 05 Apr 2020 12:19:45 +0000 (UTC) Subject: [PATCH] D77474: [analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete In-Reply-To: References: Message-ID: Szelethus added a comment. Btw this branch is about 7 months old, and I just now remembered why I haven't rushed publishing it. My ultimate idea (as opposed to the two detailed in the summary) was to introduce a subchecker system in MallocChecker, which also strongly ties into D67336 . The core of the checker (`unix.DynamicMemoryModeling`) would be responsible for dispatching from regular checker callbacks upon seeing a call to a memory management function, and providing the general utilities for modeling it. Smaller subcheckers would then use this interface to implement the modeling of specific functions. For instance, the we could create `NewDeleteChecker`, a subchecker of `DynamicMemoryModeling`, which would get control when stumbling upon a call to a new/delete operator. This would allow us to spread the implementation into smaller files, which is great, but upon taking a look at D68165 , you can see that the bulk of the code isn't really in these modeling functions. For such a change to really make sense, the responsibility of bug emission (like `ReportFunctionPointerFree`) should be moved into the subcheckers as well. This would achieve my goal of smaller, self-contained subcheckers implementing something that we previously did with giants like MallocChecker is now. As to how I should //actually// pull this off (make an event about memory being deallocated to the subcheckers, make them check for bugs? make an event about finding a leak, double delete, etc?) is a different issue, but I'll see what makes more sense, if I choose to go forth with this project. I do now believe that though that all of these changes would be orthogonal to this one. Just thought I'd share :^). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77474/new/ https://reviews.llvm.org/D77474 From cfe-commits at lists.llvm.org Sun Apr 5 05:19:48 2020 From: cfe-commits at lists.llvm.org (Raul Tambre via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 12:19:48 +0000 (UTC) Subject: [PATCH] D77491: [Sema] Fix incompatible builtin redeclarations in non-global scope Message-ID: tambre created this revision. tambre added a reviewer: rsmith. Herald added a project: clang. Herald added a subscriber: cfe-commits. We didn't mark them previously as non-builtin in non-global scope if we determined they were incompatible redeclarations. This caused problems down the line with them still being treated as builtins and having attributes added and the like. Fix this by marking them non-builtin in any case. Handle redeclarations of such redeclarations as if they were redeclarations of the builtins by checking if the previous redeclaration was reverted from being a builtin. Fixes PR45410. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77491 Files: clang/include/clang/Basic/IdentifierTable.h clang/lib/Sema/SemaDecl.cpp clang/test/CodeGen/builtin-redeclaration.c Index: clang/test/CodeGen/builtin-redeclaration.c =================================================================== --- /dev/null +++ clang/test/CodeGen/builtin-redeclaration.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm-only %s + +// PR45410 +// Ensure we mark local extern redeclarations with a different type as non-builtin. +void non_builtin() { + extern float exp(); + exp(); // Will crash due to wrong number of arguments if this calls the builtin. +} + +// PR45410 +// We mark exp() builtin as const with -fno-math-errno (default). +// We mustn't do that for extern redeclarations of builtins where the type differs. +float attribute() { + extern float exp(); + return exp(1); +} Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -3756,24 +3756,21 @@ // If the previous declaration was an implicitly-generated builtin // declaration, then at the very least we should use a specialized note. unsigned BuiltinID; - if (Old->isImplicit() && (BuiltinID = Old->getBuiltinID())) { + bool RevertedBuiltin{Old->getIdentifier()->hasRevertedBuiltin()}; + if (Old->isImplicit() && + ((BuiltinID = Old->getBuiltinID()) || RevertedBuiltin)) { // If it's actually a library-defined builtin function like 'malloc' // or 'printf', just warn about the incompatible redeclaration. - if (Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) { + // Also warn if it's a redeclaration of a builtin redeclaration. We know if + // it is if the previous declaration is a reverted builtin. + if (RevertedBuiltin || + Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) { Diag(New->getLocation(), diag::warn_redecl_library_builtin) << New; Diag(OldLocation, diag::note_previous_builtin_declaration) << Old << Old->getType(); - // If this is a global redeclaration, just forget hereafter - // about the "builtin-ness" of the function. - // - // Doing this for local extern declarations is problematic. If - // the builtin declaration remains visible, a second invalid - // local declaration will produce a hard error; if it doesn't - // remain visible, a single bogus local redeclaration (which is - // actually only a warning) could break all the downstream code. - if (!New->getLexicalDeclContext()->isFunctionOrMethod()) - New->getIdentifier()->revertBuiltin(); + // Forget hereafter about the "builtin-ness" of the function. + New->getIdentifier()->revertBuiltin(); return false; } Index: clang/include/clang/Basic/IdentifierTable.h =================================================================== --- clang/include/clang/Basic/IdentifierTable.h +++ clang/include/clang/Basic/IdentifierTable.h @@ -223,7 +223,7 @@ } void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; } - /// True if setNotBuiltin() was called. + /// True if revertBuiltin() was called. bool hasRevertedBuiltin() const { return ObjCOrBuiltinID == tok::NUM_OBJC_KEYWORDS; } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77491.255138.patch Type: text/x-patch Size: 3151 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 06:23:46 2020 From: cfe-commits at lists.llvm.org (Kazuaki Ishizaki via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 13:23:46 +0000 (UTC) Subject: [PATCH] D77482: [clang-tools-extra] NFC: Fix trivial typo in documents and comments In-Reply-To: References: Message-ID: <6f10ecd3f06af22aca7f4a5f73fd0da8@localhost.localdomain> kiszk added a comment. I have done in https://reviews.llvm.org/D77458 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77482/new/ https://reviews.llvm.org/D77482 From cfe-commits at lists.llvm.org Sun Apr 5 06:48:14 2020 From: cfe-commits at lists.llvm.org (Joerg Sonnenberger via cfe-commits) Date: Sun, 5 Apr 2020 15:48:14 +0200 Subject: [clang] b670ab7 - recommit 1b978ddba05c [CUDA][HIP][OpenMP] Emit deferred diagnostics by a post-parsing AST travese In-Reply-To: <5e78df3b.1c69fb81.2dd0a.1f72@mx.google.com> References: <5e78df3b.1c69fb81.2dd0a.1f72@mx.google.com> Message-ID: <20200405134814.GA30364@bec.de> On Mon, Mar 23, 2020 at 09:09:31AM -0700, Yaxun Liu via cfe-commits wrote: > > Author: Yaxun (Sam) Liu > Date: 2020-03-23T12:09:07-04:00 > New Revision: b670ab7b6b3d2f26179213be1da1d4ba376f50a3 > > URL: https://github.com/llvm/llvm-project/commit/b670ab7b6b3d2f26179213be1da1d4ba376f50a3 > DIFF: https://github.com/llvm/llvm-project/commit/b670ab7b6b3d2f26179213be1da1d4ba376f50a3.diff > > LOG: recommit 1b978ddba05c [CUDA][HIP][OpenMP] Emit deferred diagnostics by a post-parsing AST travese This change is responsible for a significant performance regression. Somewhat reduced example is attached. With -fopenmp, it needs ~5s, without 0.02s. Joerg -------------- next part -------------- ; ; namespace std { inline namespace __1 { template struct char_traits; template class basic_ostream; typedef basic_ostream ostream; template basic_ostream<_Traits>& operator<<(basic_ostream<_Traits>& __os, const char* __str) ; extern ostream cerr; } ; } template class flet { public: flet(T , const T ) ; }; ; template class _scoped_numeral { typedef typename Manager::numeral numeral; public: _scoped_numeral(Manager ) ; operator numeral&() ; }; template class buffer { public: ; unsigned size() const ; ; ; T & operator[](unsigned idxT ) ; }; template class buffer ; template class sbuffer : public buffer { }; class mpz { public: mpz(int v) ; }; template class mpz_manager { public: ; typedef mpz numeral; void mul2k(mpz , unsigned k, mpz r) ; }; typedef mpz_manager unsynch_mpz_manager; typedef _scoped_numeral scoped_mpz; class mpq { }; template class mpq_manager : public mpz_manager { public: typedef mpq numeral; bool is_zero; void mul( mpq b, mpq ) ; void set(mpq , mpq source) ; }; typedef mpq_manager unsynch_mpq_manager; typedef _scoped_numeral scoped_mpq; ; template class interval_manager { public: ; typedef typename C::interval interval; bool is_P(interval n) const ; void set(interval , interval s); void neg(interval a, interval ); void add(interval a, interval b, interval ); void mul(interval a, interval b, interval ); }; template class _scoped_interval { typedef typename Manager::interval interval; public: _scoped_interval(Manager ) ; operator interval&() ; }; namespace realclosure { class num; ; class manager { struct imp; typedef num numeral; }; struct value; class num { friend class manager; value * m_value; }; }; template class array { public: ; unsigned size() const ; T operator[](unsigned idx) const ; T const * c_ptr() const ; }; template class ptr_array : public array { }; class mpbq { public: mpbq(int v) ; mpz numerator() const ; unsigned k() const ; }; class mpbq_manager { public: ; bool is_zero(mpbq a) const ; }; class mpz_matrix { }; class mpz_matrix_manager { public: ; void tensor_product(mpz_matrix , mpz_matrix C); bool solve; }; class scoped_mpz_matrix { public: scoped_mpz_matrix(mpz_matrix_manager ) ; unsigned n() ; operator mpz_matrix &() ; }; template class obj_ref { public: ; obj_ref(TManager ) ; T * operator->() const ; ; operator T*() ; obj_ref (T * n) ; }; template class ref_vector_core { }; template class ref_manager_wrapper { }; template class ref_vector_core > { }; template class ref_buffer_core { public: ; T ** c_ptr() const ; unsigned size() const ; bool empty() ; void append(unsigned , T * const * elems) ; }; template class ref_buffer : public ref_buffer_core, INITIAL_SIZE> { public: ref_buffer(TManager ) ; }; namespace realclosure { struct mpbq_config { struct numeral_manager : mpbq_manager { }; typedef mpbq numeral; struct interval { numeral lower() const ; numeral upper() const ; bool lower_is_inf() const ; bool upper_is_inf() const ; }; }; typedef interval_manager mpbqi_manager; typedef mpbqi_manager::interval mpbqi; struct value { mpbqi & interval() ; }; struct rational_value ; typedef ptr_array d; struct extension; struct rational_function_value : value { d & num() ; d den ; extension * ext() const ; }; struct extension { enum kind { TRANSCENDENTAL , INFINITESIMAL , ALGEBRAIC }; kind knd() ; mpbqi interval() ; }; struct sign_det { mpz_matrix M_s; ; ; }; struct algebraic : extension { d p() ; sign_det * sdt() ; unsigned sc_idx; mpbqi iso_interval() ; }; struct manager::imp { typedef ref_buffer value_ref_buffer; typedef obj_ref value_ref; typedef _scoped_interval scoped_mpbqi; typedef sbuffer int_buffer; unsigned m_max_precision; bool m_in_aux_values; struct scoped_polynomial_seq { scoped_polynomial_seq(imp ) ; unsigned size() const ; value * * coeffs(unsigned ) const ; unsigned sizeconst ; }; unsynch_mpq_manager & qm() ; mpbq_config::numeral_manager bqm() ; mpbqi_manager bqim() ; mpz_matrix_manager & mm() ; ; bool is_rational_one(value_ref_buffer ) ; ; rational_function_value * to_rational_function(value * ) ; mpq to_mpq(value * ) ; int compare_rank(value * a, value * ) ; algebraic * to_algebraic(extension * ) ; bool contains_zero(mpbqi mpbqi ) ; ; void set_interval(mpbqi , mpbqi ) ; rational_function_value * mk_rational_function_value_core(extension * , unsigned , value * const * , unsigned , value * const * ) ; void count_signs_at_zeros_core( int , unsigned , value * const * , unsigned , value * const * , mpbqi const , int , int , int , int , value_ref_buffer ) ; bool mk_sign_det_matrix(int , int , int , scoped_mpz_matrix ) ; int sign(value * ) ; void swap(mpbqi , mpbqi ) ; mpbqi & interval(value * mpq ) ; rational_value * mk_rational(mpz const ) ; void add(unsigned , value * const * , unsigned , value * const * , value_ref_buffer value_ref_buffer ) ; void mul(value * , unsigned , value * const * , value_ref_buffer ) ; void mul(unsigned , value * const * , unsigned , value * const * , value_ref_buffer ) ; void div(unsigned , value * const * , unsigned , value * * , value_ref_buffer ) ; void div(unsigned , value * const * , value * , value_ref_buffer ) ; void rem(unsigned , value * const * , unsigned , value * const * , value_ref_buffer ) ; void neg(unsigned , value * const * , value_ref_buffer ) ; bool is_monic(d const ) ; void gcd(unsigned , value * const * , unsigned , value * const * , value_ref_buffer ) ; void sturm_tarski_seq(unsigned , value * const * , unsigned , value * const * , scoped_polynomial_seq ) ; int eval_sign_at_zero ; void eval_sign_at_approx(unsigned , value * const * , mpbq const , mpbqi ) ; bool has_refineable_approx_coeffs(unsigned , value * const * ) ; int expensive_eval_sign_at(unsigned n, value * const * p, mpbq const b) { scoped_mpz mpz_twok(qm()); qm().mul2k((1), b.k(), mpz_twok); value_ref twok(*this), twok_i(*this); ; value_ref c(*this); value_ref r(*this), ak(*this), rc= p[1]; unsigned i ; { ; { mul(r, c, r); mul(p[i], twok_i, ak); mul(r, c, rc); add(ak, rc, r); } mul(twok_i, twok, twok_i); } return sign(r); } int find_biggest_interval_magnitude(unsigned n, value * const * ) { int r ; for (unsigned i ; n; ) { mpbqi a_i ; ; int m ; } return r; } int eval_sign_at(unsigned n, value * const * p, mpbq const b) { return 0; ; { scoped_mpbqi r(bqim()); ; { return bqim().is_P(r) ; } if (has_refineable_approx_coeffs(n, p)) { return expensive_eval_sign_at(n, p, b); int m ; unsigned prec; ; { ; if (refine_coeffs_interval(n, p, prec)) { expensive_eval_sign_at(n, p, b); } eval_sign_at_approx(n, p, b, r); { return bqim().is_P(r) ; } ; } return expensive_eval_sign_at(n, p, b); } } } enum location { ZERO, MINUS_INF, PLUS_INF, MPBQ }; unsigned sign_variations_at_core(scoped_polynomial_seq const seq, location loc, mpbq const b) { return 0; unsigned prev_sign; unsigned i ; { unsigned psz ; value * * p = seq.coeffs(i); switch (loc) { ; eval_sign_at(psz, p, b); default: ; } ; } ; } unsigned sign_variations_at_minus_inf(scoped_polynomial_seq seq) { mpbq dummy(0); return sign_variations_at_core(seq, MINUS_INF, dummy); } unsigned sign_variations_at_plus_inf(scoped_polynomial_seq seq) { mpbq dummy(0); return sign_variations_at_core(seq, PLUS_INF, dummy); } unsigned sign_variations_at_zero(scoped_polynomial_seq seq) { mpbq dummy(0); return sign_variations_at_core(seq, ZERO, dummy); } unsigned sign_variations_at(scoped_polynomial_seq seq, mpbq const b) { return sign_variations_at_core(seq, MPBQ, b); } int sign_variations_at_lower(scoped_polynomial_seq seq, mpbqi const interval) { return sign_variations_at_minus_inf(seq); if (bqm().is_zero(interval.lower())) return sign_variations_at_zero(seq); return sign_variations_at(seq, interval.lower()); } int sign_variations_at_upper(scoped_polynomial_seq seq, mpbqi const interval) { sign_variations_at_plus_inf(seq); if (bqm().is_zero(interval.upper())) return sign_variations_at_zero(seq); return sign_variations_at(seq, interval.upper()); } int TaQ(scoped_polynomial_seq seq, mpbqi const interval) { return sign_variations_at_lower(seq, interval) - sign_variations_at_upper(seq, interval); } int TaQ(unsigned p_sz, value * const * p, unsigned q_sz, value * const * q, mpbqi const interval) { scoped_polynomial_seq seq(*this); sturm_tarski_seq(p_sz, p, q_sz, q, seq); return TaQ(seq, interval); } bool refine_coeffs_interval(unsigned n, value * const * p, unsigned prec) { for (unsigned i ; ; ) { if (p&& refine_interval(p[i], prec)) return false; } return true; } bool refine_coeffs_interval(d const p, unsigned prec) { return (p.c_ptr()); } void polynomial_interval(d const p, mpbqi const v, mpbqi r) { ; { bqim().set(r, interval(p[0])); ((void) (void) 0); bqim().mul(interval(p[1]), v, r); unsigned i ; { ; bqim().add(r, interval(p[i]), r); bqim().mul(r, v, r); } } } bool refine_algebraic_interval(algebraic * , unsigned ) ; bool refine_algebraic_interval(rational_function_value * , unsigned ) ; bool refine_interval(value * , unsigned ) ; ; ; bool depends_on_infinitesimals(d const , algebraic * ) ; void refine_until_sign_determined(d const q, algebraic * x, mpbqi r) { ; int m ; unsigned prec; { ; if ((refine_coeffs_interval(q, prec))) if ((refine_algebraic_interval(x, prec))) { ; ; }polynomial_interval(q, x->interval(), r); ((void) (void) 0); if (bqm().is_zero(r.upper())) prec++; } } bool expensive_algebraic_poly_interval(d q, algebraic * x, mpbqi r) { { if ((bqm().is_zero(r.lower()) || bqm().is_zero(r.upper()))) { refine_until_sign_determined(q, x, r); } ; } int num_roots ; d const p ; int taq_p_q = TaQ(p.size(), p.c_ptr(), q.size(), q.c_ptr(), x->iso_interval()); { if (depends_on_infinitesimals(q, x)) refine_until_sign_determined(q, x, r); ; ; ; } { if (depends_on_infinitesimals(q, x)) refine_until_sign_determined(q, x, r); ; int q_eq_0, q_gt_0, q_lt_0; value_ref_buffer q2(*this); count_signs_at_zeros_core(taq_p_q, p.size(), p.c_ptr(), q.size(), q.c_ptr(), x->iso_interval(), num_roots, q_eq_0, q_gt_0, q_lt_0, q2); { sign_det sdt = *(x->sdt()); scoped_mpz_matrix M(mm()); if ((mk_sign_det_matrix(q_eq_0, q_gt_0, q_lt_0, M))) bool e ; scoped_mpz_matrix new_M_s(mm()); mm(); array const prs ; int_buffer new_taqrs; value_ref_buffer prq(*this); for (unsigned i ; ; ) { ; mul(prs.size(), prs[i].c_ptr(), q.size(), q.c_ptr(), prq); (TaQ(p.size(), p.c_ptr(), prq.size(), prq.c_ptr(), x->iso_interval())); { mul(prs.size(), prs[i].c_ptr(), q2.size(), q2.c_ptr(), prq); (TaQ(p.size(), p.c_ptr(), prq.size(), prq.c_ptr(), x->iso_interval())); } } int_buffer sc_cardinalities; (new_taqrs.size(), 0); { ; ; }; unsigned sc_idx ; { { ; ; ; { ; ; ; ; ; } } { if (sc_cardinalities[sc_idx] ) {} } } } } } bool expensive_determine_algebraic_sign(rational_function_value * v) { ; algebraic * x = to_algebraic(v->ext()); scoped_mpbqi num_interval(bqim()); ; if (expensive_algebraic_poly_interval(v->num(), x, num_interval)) ((void) 0); set_interval(v->interval(), num_interval); return true; } bool determine_algebraic_sign(rational_function_value * v) { ; mpbqi interval ; { return expensive_determine_algebraic_sign(v); } { int m ; unsigned prec ; ; while (contains_zero(v->interval())) { if (refine_algebraic_interval(v, prec)) expensive_determine_algebraic_sign(v); ; expensive_determine_algebraic_sign(v); } ; return true; } } bool determine_sign(rational_function_value * v) { bool r; switch (v->ext()->knd()) { case extension::TRANSCENDENTAL: ; ; case extension::INFINITESIMAL: ; ; case extension::ALGEBRAIC: determine_algebraic_sign(v); __builtin_unreachable(); ; } ; } bool determine_sign(value_ref r) { ; return determine_sign(to_rational_function(r)); } void normalize_fraction(unsigned sz1, value * * p1, unsigned sz2, value * const * p2, value_ref_buffer new_p1, value_ref_buffer new_p2) { ; { div(sz1, p1, p2[0], new_p1); ; ; value * lc ; { normalize_num_monic_den(sz1, p1, sz2, p2, new_p1, new_p2); value_ref_buffer tmp1(*this); value_ref_buffer tmp2(*this); ; div(sz2, p2, lc, tmp2); normalize_num_monic_den(tmp1.size(), tmp1.c_ptr(), tmp2.size(), tmp2.c_ptr(), new_p1, new_p2); } } ; } void normalize_num_monic_den(unsigned sz1, value * * p1, unsigned sz2, value * const * p2, value_ref_buffer new_p1, value_ref_buffer new_p2) { value_ref_buffer g(*this); gcd(sz1, p1, sz2, p2, g); ; if (is_rational_one(g)) { ; new_p2.append(sz2, p2); div(sz1, p1, g.size(), g.c_ptr(), new_p1); div(sz2, p2, g.size(), g.c_ptr(), new_p2); ; } } void normalize_algebraic(algebraic * x, unsigned sz1, value * * p1, value_ref_buffer new_p1) { d const p ; { rem(sz1, p1, p.size(), p.c_ptr(), new_p1); ; } } void mk_add_value(rational_function_value * a, value * b, unsigned num_sz, value * * num, unsigned den_sz, value * const * den, value_ref r) { ; { ; ; scoped_mpbqi ri(bqim()); bqim().add(interval(a), interval(b), ri); mk_rational_function_value_core(a->ext(), num_sz, num, den_sz, den); swap(r->interval(), ri); determine_sign(r); { ; } } } void add_p_v(rational_function_value * a, value * b, value_ref r) { ; ; d const one ; ; value_ref_buffer new_num(*this); ; mk_add_value(a, b, new_num.size(), new_num.c_ptr(), one.size(), one.c_ptr(), r); } void add_rf_v(rational_function_value * a, value * b, value_ref r) { value_ref_buffer b_ad(*this); value_ref_buffer num(*this); d an ; { add_p_v(a, b, r); ; d const ad ; mul(b, ad.size(), ad.c_ptr(), b_ad); add(an.size(), an.c_ptr(), b_ad.size(), b_ad.c_ptr(), num); if (num.empty()) { value_ref_buffer new_num(*this); value_ref_buffer new_den(*this); normalize_fraction(num.size(), num.c_ptr(), ad.size(), ad.c_ptr(), new_num, new_den); ; mk_add_value(a, b, new_num.size(), new_num.c_ptr(), new_den.size(), new_den.c_ptr(), r); } } } void add_p_p(rational_function_value * a, rational_function_value * b, value_ref r) { ; d an ; d const one ; d bn ; value_ref_buffer new_num(*this); add(an.size(), an.c_ptr(), bn.size(), bn.c_ptr(), new_num); if (new_num.empty()) { mk_add_value(a, b, new_num.size(), new_num.c_ptr(), one.size(), one.c_ptr(), r); } } void add_rf_rf(rational_function_value * a, rational_function_value * b, value_ref r) { ; d an ; d bn ; { add_p_p(a, b, r); ; d const ad ; d const bd ; value_ref_buffer an_bd(*this); value_ref_buffer bn_ad(*this); mul(an.size(), an.c_ptr(), bd.size(), bd.c_ptr(), an_bd); mul(bn.size(), bn.c_ptr(), ad.size(), ad.c_ptr(), bn_ad); value_ref_buffer num(*this); add(0, an_bd.c_ptr(), bn_ad.size(), bn_ad.c_ptr(), num); if (num.empty()) { ; value_ref_buffer den(*this); mul(ad.size(), ad.c_ptr(), bd.size(), bd.c_ptr(), den); value_ref_buffer new_num(*this); value_ref_buffer new_den(*this); realclosure::value **__trans_tmp_1 = num.c_ptr(); normalize_fraction(num.size(), __trans_tmp_1, den.size(), den.c_ptr(), new_num, new_den); ; mk_add_value(a, b, new_num.size(), new_num.c_ptr(), new_den.size(), new_den.c_ptr(), r); } } } void add(value * a, value * b, value_ref r) { { ; } { ; ((void) (void) 0); { add_rf_v(to_rational_function(b), a, r); add_rf_rf(to_rational_function(a), to_rational_function(b), r); add_rf_v(to_rational_function(a), b, r); ; } } } void sub(value * a, value * b, value_ref r) { { ; value_ref neg_b(*this); ; switch (compare_rank(a, neg_b)) { add_rf_v(to_rational_function(neg_b), a, r); add_rf_rf(to_rational_function(a), to_rational_function(neg_b), r); add_rf_v(to_rational_function(a), neg_b, r); ; } } } void neg_rf(rational_function_value * a, value_ref r) { d an ; d const ad ; value_ref_buffer new_num(*this); neg(an.size(), an.c_ptr(), new_num); scoped_mpbqi ri(bqim()); bqim().neg(interval(a), ri); mk_rational_function_value_core(a->ext(), new_num.size(), new_num.c_ptr(), ad.size(), ad.c_ptr()); swap(r->interval(), ri); } void neg(value * a, value_ref r) { ; { scoped_mpq v(qm()); qm().set(v, to_mpq(a)); qm(); ; neg_rf(to_rational_function(a), r); } } void mk_mul_value(rational_function_value * a, value * b, unsigned num_sz, value * * num, unsigned den_sz, value * const * den, value_ref r) { ; { ; ; scoped_mpbqi ri(bqim()); bqim().mul(interval(a), interval(b), ri); mk_rational_function_value_core(a->ext(), num_sz, num, den_sz, den); swap(ri, r->interval()); if (determine_sign(r)) { ; ; } } } void mul_p_v(rational_function_value * a, value * b, value_ref r) { ; d const one ; value_ref_buffer new_num(*this); mk_mul_value(a, b, new_num.size(), new_num.c_ptr(), one.size(), one.c_ptr(), r); } void mul_rf_v(rational_function_value * a, value * b, value_ref r) { d an ; { mul_p_v(a, b, r); ; d const ad ; value_ref_buffer num(*this); mul(b, an.size(), an.c_ptr(), num); ; value_ref_buffer new_num(*this); value_ref_buffer new_den(*this); normalize_fraction(num.size(), num.c_ptr(), ad.size(), ad.c_ptr(), new_num, new_den); ; mk_mul_value(a, b, new_num.size(), new_num.c_ptr(), new_den.size(), new_den.c_ptr(), r); } } void mul_p_p(rational_function_value * a, rational_function_value * b, value_ref r) { ; d const one ; value_ref_buffer new_num(*this); extension * x ; if (x) { value_ref_buffer new_num2(*this); normalize_algebraic(to_algebraic(x), new_num.size(), new_num.c_ptr(), new_num2); ; unsigned int __trans_tmp_2 = new_num2.size(); mk_mul_value(a, b, __trans_tmp_2, new_num2.c_ptr(), one.size(), one.c_ptr(), r); mk_mul_value(a, b, new_num.size(), new_num.c_ptr(), one.size(), one.c_ptr(), r); } } void mul_rf_rf(rational_function_value * a, rational_function_value * b, value_ref r) { d an = a->num(); d bn ; { mul_p_p(a, b, r); ; d const ad ; d const bd ; value_ref_buffer num(*this); value_ref_buffer den(*this); mul(an.size(), an.c_ptr(), bn.size(), bn.c_ptr(), num); mul(ad.size(), ad.c_ptr(), bd.size(), bd.c_ptr(), den); value_ref_buffer new_num(*this); value_ref_buffer new_den(*this); normalize_fraction(num.size(), num.c_ptr(), 0, den.c_ptr(), new_num, new_den); ; mk_mul_value(a, b, new_num.size(), new_num.c_ptr(), new_den.size(), new_den.c_ptr(), r); } } void mul(value * a, value * b, value_ref r) { { ; } { neg(b, r); } { neg(a, r); } { scoped_mpq v(qm()); qm().mul( to_mpq(b), v); ; ((void) (void) 0); switch (compare_rank(a, b)) { mul_rf_v(to_rational_function(b), a, r); mul_rf_rf(to_rational_function(a), to_rational_function(b), r); mul_rf_v(to_rational_function(a), b, r); ; } } } void set(numeral , value_ref ) ; void add(numeral a, numeral b, numeral c) { value_ref r(*this); add(a.m_value, b.m_value, r); set(c, r); } void sub(numeral a, numeral b) { value_ref r(*this); sub(a.m_value, b.m_value, r); } }; } From cfe-commits at lists.llvm.org Sun Apr 5 07:27:39 2020 From: cfe-commits at lists.llvm.org (Sid Manning via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 14:27:39 +0000 (UTC) Subject: [PATCH] D77498: [Hexagon] Select lld as the default linker for linux-musl target Message-ID: sidneym created this revision. sidneym added reviewers: adasgupt, bcain, kparzysz, bcahoon, shankare. Herald added a project: clang. Herald added a subscriber: cfe-commits. When the target is hexagon-unknown-linux-musl select lld as the default linker. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77498 Files: clang/lib/Driver/ToolChains/Hexagon.h clang/test/Driver/hexagon-toolchain-elf.c Index: clang/test/Driver/hexagon-toolchain-elf.c =================================================================== --- clang/test/Driver/hexagon-toolchain-elf.c +++ clang/test/Driver/hexagon-toolchain-elf.c @@ -674,3 +674,15 @@ // RUN: | FileCheck -check-prefix=CHECK090 %s // CHECK090-NOT: -fno-use-init-array // ----------------------------------------------------------------------------- +// Check default linker for musl +// ----------------------------------------------------------------------------- +// RUN: %clang -### -target hexagon-unknown-linux-musl %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK091 %s +// CHECK091: ld.lld +// ----------------------------------------------------------------------------- +// Check default linker for elf +// ----------------------------------------------------------------------------- +// RUN: %clang -### -target hexagon-unknown-elf %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK092 %s +// CHECK092: hexagon-link +// ----------------------------------------------------------------------------- Index: clang/lib/Driver/ToolChains/Hexagon.h =================================================================== --- clang/lib/Driver/ToolChains/Hexagon.h +++ clang/lib/Driver/ToolChains/Hexagon.h @@ -81,7 +81,9 @@ const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; - const char *getDefaultLinker() const override { return "hexagon-link"; } + const char *getDefaultLinker() const override { + return getTriple().isMusl() ? "ld.lld" : "hexagon-link"; + } CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; -------------- next part -------------- A non-text attachment was scrubbed... Name: D77498.255159.patch Type: text/x-patch Size: 1692 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 07:59:54 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 14:59:54 +0000 (UTC) Subject: [PATCH] D77499: [ASTMatchers] Matchers that take enumerations args provide hints with invalid arguments Message-ID: njames93 created this revision. njames93 added a reviewer: klimek. Herald added subscribers: cfe-commits, mgorny. Herald added a reviewer: jdoerfert. Herald added a project: clang. njames93 edited the summary of this revision. Herald added a subscriber: dexonsmith. This adds support for giving hints when using dynamic matchers with enum args. Take this query, I couldn't figure out why the matcher wasn't working: (Turns out it needed to be "IntegralToBoolean", but thats another bug itself) clang-query> match implicitCastExpr(hasCastKind("CK_IntegralToBoolean")) 1:1: Error parsing argument 1 for matcher implicitCastExpr. 1:18: Error building matcher hasCastKind. 1:30: Incorrect type for arg 1. (Expected = string) != (Actual = String) With this patch the new behaviour looks like this: clang-query> match implicitCastExpr(hasCastKind("CK_IntegralToBoolean")) 1:1: Error parsing argument 1 for matcher implicitCastExpr. 1:18: Error building matcher hasCastKind. 1:30: Unknown value 'CK_IntegralToBoolean' for arg 1; did you mean 'IntegralToBoolean' There are no test cases for this yet as there simply isn't any infrastructure for testing errors reported when parsing args that I can see. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77499 Files: clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h clang/lib/ASTMatchers/Dynamic/CMakeLists.txt clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp clang/lib/ASTMatchers/Dynamic/Marshallers.cpp clang/lib/ASTMatchers/Dynamic/Marshallers.h -------------- next part -------------- A non-text attachment was scrubbed... Name: D77499.255162.patch Type: text/x-patch Size: 8784 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 07:59:56 2020 From: cfe-commits at lists.llvm.org (Eugene Zelenko via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 14:59:56 +0000 (UTC) Subject: [PATCH] D77482: [clang-tools-extra] NFC: Fix trivial typo in documents and comments In-Reply-To: References: Message-ID: Eugene.Zelenko added a comment. In D77482#1962272 , @kiszk wrote: > I have done in https://reviews.llvm.org/D77458 Just abandon this revision. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77482/new/ https://reviews.llvm.org/D77482 From cfe-commits at lists.llvm.org Sun Apr 5 07:59:58 2020 From: cfe-commits at lists.llvm.org (Raul Tambre via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 14:59:58 +0000 (UTC) Subject: [PATCH] D77502: [clang][CodeGen] Handle throw expression in conditional operator constant folding Message-ID: tambre created this revision. tambre added a reviewer: rsmith. Herald added a project: clang. Herald added a subscriber: cfe-commits. tambre edited the summary of this revision. We're smart and do constant folding when emitting conditional operators. Thus we emit the live value as a lvalue. This doesn't work if the live value is a throw expression. Handle this by emitting the throw and returning the dead value as the lvalue. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77502 Files: clang/lib/CodeGen/CGExpr.cpp clang/test/CodeGenCXX/throw-expressions.cpp Index: clang/test/CodeGenCXX/throw-expressions.cpp =================================================================== --- clang/test/CodeGenCXX/throw-expressions.cpp +++ clang/test/CodeGenCXX/throw-expressions.cpp @@ -79,6 +79,13 @@ // CHECK-NOT: call {{.*}}@_ZN6DR15601AD1Ev // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN6DR15601AD1Ev {{.*}} @_ZGRN6DR15601rE // CHECK-NOT: call {{.*}}@_ZN6DR15601AD1Ev + + // PR28184 + void conditional_throw() + { + int a, b; + (true ? throw 0 : a) = 0; + } } // CHECK-LABEL: define void @_Z5test7b( Index: clang/lib/CodeGen/CGExpr.cpp =================================================================== --- clang/lib/CodeGen/CGExpr.cpp +++ clang/lib/CodeGen/CGExpr.cpp @@ -4331,6 +4331,11 @@ // If the true case is live, we need to track its region. if (CondExprBool) incrementProfileCounter(expr); + // If a throw expression we need to return dead as lvalue. + if (auto *ThrowExpr = dyn_cast(live->IgnoreParens())) { + EmitCXXThrowExpr(ThrowExpr); + return EmitLValue(dead); + } return EmitLValue(live); } } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77502.255166.patch Type: text/x-patch Size: 1151 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 07:59:58 2020 From: cfe-commits at lists.llvm.org (Teresa Johnson via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 14:59:58 +0000 (UTC) Subject: [PATCH] D77484: [Vector] Pass VectLib to LTO backend so TLI build correct vector function list In-Reply-To: References: Message-ID: <4f9f867f7d1f493eb77b0255416642d2@localhost.localdomain> tejohnson added a subscriber: gchatelet. tejohnson added a comment. We're trying to move towards encoding all of this in the IR. And in fact, I recently implemented a series of patches to make the TLI to be built per-function, and along with some patches from @gchatelet to encode -fno-builtin* as function attributes, we now handle that part of the TLII with IR. See D67923 which is the last patch in the series. We should encode the vectlib as function attributes similarly, and just thread that through to the TLI. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77484/new/ https://reviews.llvm.org/D77484 From cfe-commits at lists.llvm.org Sun Apr 5 08:32:09 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 15:32:09 +0000 (UTC) Subject: [PATCH] D77493: [clang-tidy] Add do-not-refer-atomic-twice check In-Reply-To: References: Message-ID: <9970afff5be809b9314841ece400e3c6@localhost.localdomain> njames93 added a comment. In my mind this check is definitely in the realm of the static analyser, clang-tidy just isn't designed for this. ================ Comment at: clang-tools-extra/docs/clang-tidy/checks/list.rst:137 `cppcoreguidelines-avoid-goto `_, + `cppcoreguidelines-avoid-non-const-global-variables `_, `cppcoreguidelines-init-variables `_, "Yes" ---------------- All these artefacts from the add-new-check script don't need to be in here. ================ Comment at: clang-tools-extra/test/clang-tidy/checkers/bugprone-do-not-refer-atomic-twice.cpp:79 + +int main() {} ---------------- don't need a main call in the test case Repository: rCTE Clang Tools Extra CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77493/new/ https://reviews.llvm.org/D77493 From cfe-commits at lists.llvm.org Sun Apr 5 08:32:11 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Kocsis_=C3=81bel_via_Phabricator?= via cfe-commits) Date: Sun, 05 Apr 2020 15:32:11 +0000 (UTC) Subject: [PATCH] D75229: [clang-tidy] Add signal-in-multithreaded-program check In-Reply-To: References: Message-ID: <5fa0a0118956394d7107efbfd8eeba0a@localhost.localdomain> abelkocsis marked 2 inline comments as done. abelkocsis added inline comments. ================ Comment at: clang-tools-extra/clang-tidy/bugprone/SignalInMultithreadedProgramCheck.cpp:33-50 +void SignalInMultithreadedProgramCheck::registerMatchers(MatchFinder *Finder) { + auto signalCall = + callExpr( + ignoringImpCasts(hasDescendant(declRefExpr(hasDeclaration( + functionDecl(allOf(hasName("signal"), parameterCountIs(2), + hasParameter(0, hasType(isInteger()))))))))) + .bind("signal"); ---------------- steakhal wrote: > I apologize for interrupting the review. > Should we use `hasDescendant` for matching like everything in translation unit? > > Wouldn't it be more performant to collect all the `signal` calls in a set and set a bool variable if a `ThreadList` function seen? > At the end of the analysis of the translation unit, emit warnings for each recorded `signal` call if the variable was set //(aka. we are in multithreaded environment)//. > > Treat this comment rather a question since I'm not really familiar with `clang-tidy`. I updated the checker not exactly in that way you mentioned, but I think you are right that we should not match for all `translationUnitDecl`. Repository: rCTE Clang Tools Extra CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75229/new/ https://reviews.llvm.org/D75229 From cfe-commits at lists.llvm.org Sun Apr 5 08:32:11 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Kocsis_=C3=81bel_via_Phabricator?= via cfe-commits) Date: Sun, 05 Apr 2020 15:32:11 +0000 (UTC) Subject: [PATCH] D75229: [clang-tidy] Add signal-in-multithreaded-program check In-Reply-To: References: Message-ID: <19d51241b92123ed4cb665d805574919@localhost.localdomain> abelkocsis updated this revision to Diff 255169. abelkocsis marked an inline comment as done. Repository: rCTE Clang Tools Extra CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75229/new/ https://reviews.llvm.org/D75229 Files: clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt clang-tools-extra/clang-tidy/bugprone/SignalInMultithreadedProgramCheck.cpp clang-tools-extra/clang-tidy/bugprone/SignalInMultithreadedProgramCheck.h clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/docs/clang-tidy/checks/bugprone-signal-in-multithreaded-program.rst clang-tools-extra/docs/clang-tidy/checks/cert-con37-c.rst clang-tools-extra/docs/clang-tidy/checks/list.rst clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-in-multithreaded-program-config-std::thread.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-in-multithreaded-program-config-thrd_create.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-in-multithreaded-program-noconfig-std::thread.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-signal-in-multithreaded-program-noconfig-thrd_create.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D75229.255169.patch Type: text/x-patch Size: 16219 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 08:32:31 2020 From: cfe-commits at lists.llvm.org (Ayke via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 15:32:31 +0000 (UTC) Subject: [PATCH] D63852: [Clang] Move assembler into a separate file In-Reply-To: References: Message-ID: <8804c4bddbd090a0117a93419558454b@localhost.localdomain> aykevl added a comment. Ping? I'm not sure who to add as a reviewer. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D63852/new/ https://reviews.llvm.org/D63852 From cfe-commits at lists.llvm.org Sun Apr 5 09:04:09 2020 From: cfe-commits at lists.llvm.org (Ayke via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 16:04:09 +0000 (UTC) Subject: [PATCH] D66324: clang-misexpect: Profile Guided Validation of Performance Annotations in LLVM In-Reply-To: References: Message-ID: aykevl added a comment. @xbolva00 I could, but to me this is not trivial (I'm not familiar with the code and I'm not sure what I would break). If it's easy for you, then please do (otherwise I can send a patch for review). I have already worked around this issue in a different way (by running the compiler invocation in a separate process). Repository: rL LLVM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D66324/new/ https://reviews.llvm.org/D66324 From cfe-commits at lists.llvm.org Sun Apr 5 09:04:14 2020 From: cfe-commits at lists.llvm.org (Csaba Dabis via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 16:04:14 +0000 (UTC) Subject: [PATCH] D75229: [clang-tidy] Add signal-in-multithreaded-program check In-Reply-To: References: Message-ID: <9bd9e04abd6759891fcac03fb00b5315@localhost.localdomain> Charusso added inline comments. ================ Comment at: clang-tools-extra/clang-tidy/bugprone/SignalInMultithreadedProgramCheck.cpp:33-50 +void SignalInMultithreadedProgramCheck::registerMatchers(MatchFinder *Finder) { + auto signalCall = + callExpr( + ignoringImpCasts(hasDescendant(declRefExpr(hasDeclaration( + functionDecl(allOf(hasName("signal"), parameterCountIs(2), + hasParameter(0, hasType(isInteger()))))))))) + .bind("signal"); ---------------- abelkocsis wrote: > steakhal wrote: > > I apologize for interrupting the review. > > Should we use `hasDescendant` for matching like everything in translation unit? > > > > Wouldn't it be more performant to collect all the `signal` calls in a set and set a bool variable if a `ThreadList` function seen? > > At the end of the analysis of the translation unit, emit warnings for each recorded `signal` call if the variable was set //(aka. we are in multithreaded environment)//. > > > > Treat this comment rather a question since I'm not really familiar with `clang-tidy`. > I updated the checker not exactly in that way you mentioned, but I think you are right that we should not match for all `translationUnitDecl`. Every single check runs on the whole `TranslationUnitDecl`, and the matcher will try to match on every of the TU's descendant, that is why it emit multiple reports in the same single run. There is no need to use `translationUnitDecl()` and nor to use `forEachDescendant()`. ================ Comment at: clang-tools-extra/clang-tidy/bugprone/SignalInMultithreadedProgramCheck.cpp:38 + functionDecl(hasAnyListedName(ThreadList))))))) + .bind("thread")), + hasDescendant(varDecl(hasType(recordDecl(hasName("std::thread"))))) ---------------- You can emit the binding of `thread`. ================ Comment at: clang-tools-extra/clang-tidy/bugprone/SignalInMultithreadedProgramCheck.cpp:56 + diag(MatchedSignal->getExprLoc(), + "singal function should not be called in a multithreaded program"); +} ---------------- `singal` -> `signal` Repository: rCTE Clang Tools Extra CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75229/new/ https://reviews.llvm.org/D75229 From cfe-commits at lists.llvm.org Sun Apr 5 09:04:15 2020 From: cfe-commits at lists.llvm.org (=?utf-8?q?Kocsis_=C3=81bel_via_Phabricator?= via cfe-commits) Date: Sun, 05 Apr 2020 16:04:15 +0000 (UTC) Subject: [PATCH] D77493: [clang-tidy] Add do-not-refer-atomic-twice check In-Reply-To: References: Message-ID: <67f8efd7e911b7fe8c445b17362b8f67@localhost.localdomain> abelkocsis updated this revision to Diff 255170. abelkocsis added a comment. Small fixes in doc and test files. Repository: rCTE Clang Tools Extra CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77493/new/ https://reviews.llvm.org/D77493 Files: clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt clang-tools-extra/clang-tidy/bugprone/DoNotReferAtomicTwiceCheck.cpp clang-tools-extra/clang-tidy/bugprone/DoNotReferAtomicTwiceCheck.h clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/docs/clang-tidy/checks/bugprone-do-not-refer-atomic-twice.rst clang-tools-extra/docs/clang-tidy/checks/cert-con40-c.rst clang-tools-extra/docs/clang-tidy/checks/list.rst clang-tools-extra/test/clang-tidy/checkers/bugprone-do-not-refer-atomic-twice.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77493.255170.patch Type: text/x-patch Size: 12383 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 09:20:22 2020 From: cfe-commits at lists.llvm.org (Liu, Yaxun (Sam) via cfe-commits) Date: Sun, 5 Apr 2020 16:20:22 +0000 Subject: [clang] b670ab7 - recommit 1b978ddba05c [CUDA][HIP][OpenMP] Emit deferred diagnostics by a post-parsing AST travese In-Reply-To: <20200405134814.GA30364@bec.de> References: <5e78df3b.1c69fb81.2dd0a.1f72@mx.google.com> <20200405134814.GA30364@bec.de> Message-ID: [AMD Official Use Only - Internal Distribution Only] The issue is addressed by https://reviews.llvm.org/D77028 Sam -----Original Message----- From: Joerg Sonnenberger Sent: Sunday, April 5, 2020 9:48 AM To: Liu, Yaxun (Sam) ; Yaxun Liu Cc: cfe-commits at lists.llvm.org Subject: Re: [clang] b670ab7 - recommit 1b978ddba05c [CUDA][HIP][OpenMP] Emit deferred diagnostics by a post-parsing AST travese [CAUTION: External Email] On Mon, Mar 23, 2020 at 09:09:31AM -0700, Yaxun Liu via cfe-commits wrote: > > Author: Yaxun (Sam) Liu > Date: 2020-03-23T12:09:07-04:00 > New Revision: b670ab7b6b3d2f26179213be1da1d4ba376f50a3 > > URL: > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith > ub.com%2Fllvm%2Fllvm-project%2Fcommit%2Fb670ab7b6b3d2f26179213be1da1d4 > ba376f50a3&data=02%7C01%7Cyaxun.liu%40amd.com%7Cfc099ddf95594ab17e > da08d7d968004e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C6372169134 > 68808969&sdata=WtAm5JbQgR7UDY0FL5AlIvZOSOLPbQTRbKHJvP0Vot8%3D& > reserved=0 > DIFF: > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith > ub.com%2Fllvm%2Fllvm-project%2Fcommit%2Fb670ab7b6b3d2f26179213be1da1d4 > ba376f50a3.diff&data=02%7C01%7Cyaxun.liu%40amd.com%7Cfc099ddf95594 > ab17eda08d7d968004e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C63721 > 6913468808969&sdata=wREjtZ%2F5SHC1U4dxGbbSvYYncnhqa%2ByJzHBxv%2FIh > PlY%3D&reserved=0 > > LOG: recommit 1b978ddba05c [CUDA][HIP][OpenMP] Emit deferred > diagnostics by a post-parsing AST travese This change is responsible for a significant performance regression. Somewhat reduced example is attached. With -fopenmp, it needs ~5s, without 0.02s. Joerg From cfe-commits at lists.llvm.org Sun Apr 5 09:36:16 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 16:36:16 +0000 (UTC) Subject: [PATCH] D77028: [NFC] Refactor DeferredDiagsEmitter and skip redundant visit In-Reply-To: References: Message-ID: yaxunl marked 3 inline comments as done. yaxunl added inline comments. ================ Comment at: clang/lib/Sema/Sema.cpp:1508 void checkFunc(SourceLocation Loc, FunctionDecl *FD) { + auto DiagsCountIt = DiagsCount.find(FD); FunctionDecl *Caller = UseStack.empty() ? nullptr : UseStack.back(); ---------------- rjmccall wrote: > yaxunl wrote: > > rjmccall wrote: > > > yaxunl wrote: > > > > rjmccall wrote: > > > > > yaxunl wrote: > > > > > > rjmccall wrote: > > > > > > > It makes me a little uncomfortable to be holding an iterator this long while calling a fair amount of other stuff in the meantime. > > > > > > > > > > > > > > Your use of DiagsCount is subtle enough that it really needs to be explained in some comments. You're doing stuff conditionally based on both whether the entry exists but also whether it's non-zero. > > > > > > added comments > > > > > Okay, thanks for that. Two points, then. First, it looks like the count is really just a boolean for whether the function recursively triggers any diagnostics. And second, can't it just be as simple as whether we've visited that function at all in a context that's forcing diagnostics to be emitted? The logic seems to be to try to emit the diagnostics for each use-path, but why would we want that? > > > > For the second comment, we need to visit a function again for each use-path because we need to report each use-path that triggers a diagnostic, otherwise users will see a new error after they fix one error, instead of seeing all the errors at once. > > > > > > > > For the first comment, I will change the count to two flags: one for the case where the function is not in device context, the other is for the case where the function is in device context. This will allow us to avoid redundant visits whether or not we are in a device context. > > > > For the second comment, we need to visit a function again for each use-path because we need to report each use-path that triggers a diagnostic, otherwise users will see a new error after they fix one error, instead of seeing all the errors at once. > > > > > > This is not what we do in analogous cases where errors are triggered by a use, like in template instantiation. The bug might be that the device program is using a function that it shouldn't be using, or the bug might be that a function that's supposed to be usable from the device is written incorrectly. In the former case, yes, not reporting the errors for each use-path may force the programmer to build multiple times to find all the problematic uses. However, in the latter case you can easily end up emitting a massive number of errors that completely drowns out everything else. It's also non-linear: the number of different use-paths of a particular function can be combinatoric. > > The deferred diagnostics fall into the first case mostly. > > > > Not all diagnostic messages happen in device host functions are deferred. Most of diagnostic messages are emitted immediately, disregarding whether the function is emitted or not. > > > > Only a few special types of diagnostic messages e.g. inline assembly errors, exceptions, varags are deferred. This is because clang has to use pragmas to make all functions device and host in some system headers to be able to use them in device compilation, whereas some of these functions will cause error only if they are emitted in device compilation. Since we cannot change these headers, we have to defer such diagnostics to the point where they are actually triggered. Therefore we are mostly interested in "who is calling these functions" instead of the diagnostics themselves. > > > > For normal programs containing no diagnostics, the current approach should sufficiently avoid all redundant visits and all functions will be visited once. > > > > The functions may be visited multiple times when there are deferred diagnostics, however this should be limited by the maximum number of errors. > Okay. I understand the point now about being mostly concerned about using functions in headers. > > My concern about visiting things a combinatorial number of times is less about generating an excessive number of errors and more about taking an excessive amount of time to finish compilation. The compiler really should not be using any exponential algorithms; a simple visited set will ensure that, but I think what you're doing does not. Can you make a case for why that's not true? The current approach is linear for the number of visits to functions. Let's assume the number of functions is N. The current approach already restricted revisiting a node that's already in the current use-path to prevent infinite recursion, therefore a use-path has maximum length N. The functions can be classified as two categories: Those who trigger deferred diags directly or indirectly, which we call trigger nodes. Those who do not trigger deferred diags directly or indirectly, which we call non-trigger nodes. Non-trigger nodes can be identified at most with two visits. All other visits are skipped. Therefore the total number of visits of non-trigger nodes is less than 2*N. We can also classify the use-paths as trigger paths and non-trigger paths. Each trigger path causes at least one diagnostic emitted. Each non-trigger path does not cause any diagnostics emitted. Due to limit of maximum diagnostics allowed, the algorithm will stop after a finite number of use-paths visited. Let's say it is M. (In reality, M could be much smaller than the maximum diagnostic allowed.) Then the number of trigger paths is at most M. Let's list all the use-paths visited and count all the nodes visited in these use-paths. First we consider all the use-paths that containing only non-trigger nodes, since each non-trigger nodes can only be visited twice. The total number of visits of nodes is less than 2*N. Then we consider all the trigger paths. Since the maximum path length is N, the total number of nodes visited is less than N*M. Now we only need to consider the non-trigger paths that starts with trigger nodes and end with a non-trigger node. For example, ABCD, where A, B, C, D denote nodes (functions) visited in the path. We can prove that A, B, C must be trigger nodes, since if any of A, B, C is a non-trigger node, the path will ends earlier, not reaching D. We can also prove that the sub-path ABC must be shared with a trigger path e.g. ABCEF, since otherwise C will be a non-trigger node. Then we do not need to count visit of A, B, and C, since they have already been counted when we count the visited nodes by trigger paths. Therefore, the total number of visits for functions is less than (2+M)*N, where M is actual number of diagnostics emitted. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77028/new/ https://reviews.llvm.org/D77028 From cfe-commits at lists.llvm.org Sun Apr 5 09:57:20 2020 From: cfe-commits at lists.llvm.org (Nico Weber via cfe-commits) Date: Sun, 05 Apr 2020 09:57:20 -0700 (PDT) Subject: [clang] ccabe93 - clang: Make tests using symlinks more consistent. Message-ID: <5e8a0df0.1c69fb81.f9fd5.a92e@mx.google.com> Author: Nico Weber Date: 2020-04-05T12:56:41-04:00 New Revision: ccabe9329857141e0b676951ff89092d7f88bed0 URL: https://github.com/llvm/llvm-project/commit/ccabe9329857141e0b676951ff89092d7f88bed0 DIFF: https://github.com/llvm/llvm-project/commit/ccabe9329857141e0b676951ff89092d7f88bed0.diff LOG: clang: Make tests using symlinks more consistent. Instead of checking if each symlink exists before removing it, remove the whole temp dir housing the symlinks before recreating it. This is a bit shorter, conceptually simpler (in that the first and consecutive test runs have more similar behavior), it's what we're already doing in almost all places where we do it, and it works if the symlink exists but is a dead link (e.g. when it points into the build dir but the build dir is renamed). No intended behavior change. Added: Modified: clang/test/Driver/config-file3.c clang/test/Driver/mingw-sysroot.cpp clang/test/Driver/riscv32-toolchain-extra.c clang/test/Driver/riscv64-toolchain-extra.c clang/test/Driver/target-override.c Removed: ################################################################################ diff --git a/clang/test/Driver/config-file3.c b/clang/test/Driver/config-file3.c index 938411cf0fff..148646c2ebbf 100644 --- a/clang/test/Driver/config-file3.c +++ b/clang/test/Driver/config-file3.c @@ -16,8 +16,8 @@ //--- Invocation qqq-clang-g++ tries to find config file qqq-clang-g++.cfg first. // +// RUN: rm -rf %T/testdmode // RUN: mkdir -p %T/testdmode -// RUN: [ ! -s %T/testdmode/qqq-clang-g++ ] || rm %T/testdmode/qqq-clang-g++ // RUN: ln -s %clang %T/testdmode/qqq-clang-g++ // RUN: echo "-Wundefined-func-template" > %T/testdmode/qqq-clang-g++.cfg // RUN: echo "-Werror" > %T/testdmode/qqq.cfg @@ -53,8 +53,8 @@ //--- Config files are searched for in binary directory as well. // +// RUN: rm -rf %T/testbin // RUN: mkdir -p %T/testbin -// RUN: [ ! -s %T/testbin/clang ] || rm %T/testbin/clang // RUN: ln -s %clang %T/testbin/clang // RUN: echo "-Werror" > %T/testbin/aaa.cfg // RUN: %T/testbin/clang --config-system-dir= --config-user-dir= --config aaa.cfg -c -no-canonical-prefixes %s -### 2>&1 | FileCheck %s -check-prefix CHECK-BIN @@ -68,8 +68,8 @@ //--- When reloading config file, x86_64-clang-g++ tries to find config i386-clang-g++.cfg first. // +// RUN: rm -rf %T/testreload // RUN: mkdir -p %T/testreload -// RUN: [ ! -s %T/testreload/x86_64-clang-g++ ] || rm %T/testreload/x86_64-clang-g++ // RUN: ln -s %clang %T/testreload/x86_64-clang-g++ // RUN: echo "-Wundefined-func-template" > %T/testreload/i386-clang-g++.cfg // RUN: echo "-Werror" > %T/testreload/i386.cfg diff --git a/clang/test/Driver/mingw-sysroot.cpp b/clang/test/Driver/mingw-sysroot.cpp index d477f314195f..9c6ded76127d 100644 --- a/clang/test/Driver/mingw-sysroot.cpp +++ b/clang/test/Driver/mingw-sysroot.cpp @@ -1,19 +1,15 @@ // REQUIRES: shell // UNSUPPORTED: system-windows +// RUN: rm -rf %T/testroot-gcc/bin // RUN: mkdir -p %T/testroot-gcc/bin -// RUN: [ ! -s %T/testroot-gcc/bin/x86_64-w64-mingw32-gcc ] || rm %T/testroot-gcc/bin/x86_64-w64-mingw32-gcc -// RUN: [ ! -s %T/testroot-gcc/bin/x86_64-w64-mingw32-clang ] || rm %T/testroot-gcc/bin/x86_64-w64-mingw32-clang -// RUN: [ ! -s %T/testroot-gcc/x86_64-w64-mingw32 ] || rm %T/testroot-gcc/x86_64-w64-mingw32 -// RUN: [ ! -s %T/testroot-gcc/lib ] || rm %T/testroot-gcc/lib // RUN: ln -s %clang %T/testroot-gcc/bin/x86_64-w64-mingw32-gcc // RUN: ln -s %clang %T/testroot-gcc/bin/x86_64-w64-mingw32-clang // RUN: ln -s %S/Inputs/mingw_ubuntu_posix_tree/usr/x86_64-w64-mingw32 %T/testroot-gcc/x86_64-w64-mingw32 // RUN: ln -s %S/Inputs/mingw_ubuntu_posix_tree/usr/lib %T/testroot-gcc/lib +// RUN: rm -rf %T/testroot-clang/bin // RUN: mkdir -p %T/testroot-clang/bin -// RUN: [ ! -s %T/testroot-clang/bin/x86_64-w64-mingw32-clang ] || rm %T/testroot-clang/bin/x86_64-w64-mingw32-clang -// RUN: [ ! -s %T/testroot-clang/x86_64-w64-mingw32 ] || rm %T/testroot-clang/x86_64-w64-mingw32 // RUN: ln -s %clang %T/testroot-clang/bin/x86_64-w64-mingw32-clang // RUN: ln -s %S/Inputs/mingw_ubuntu_posix_tree/usr/x86_64-w64-mingw32 %T/testroot-clang/x86_64-w64-mingw32 diff --git a/clang/test/Driver/riscv32-toolchain-extra.c b/clang/test/Driver/riscv32-toolchain-extra.c index 3182e0cfc1ae..f70092ac0333 100644 --- a/clang/test/Driver/riscv32-toolchain-extra.c +++ b/clang/test/Driver/riscv32-toolchain-extra.c @@ -12,10 +12,8 @@ // runtime if and only if they exist. // // REQUIRES: platform-linker +// RUN: rm -rf %T/testroot-riscv32-baremetal-nogcc/bin // RUN: mkdir -p %T/testroot-riscv32-baremetal-nogcc/bin -// RUN: [ ! -s %T/testroot-riscv32-baremetal-nogcc/bin/clang ] || rm %T/testroot-riscv32-baremetal-nogcc/bin/clang -// RUN: [ ! -s %T/testroot-riscv32-baremetal-nogcc/bin/riscv32-unknown-elf-ld ] || rm %T/testroot-riscv32-baremetal-nogcc/bin/riscv32-unknown-elf-ld -// RUN: [ ! -s %T/testroot-riscv32-baremetal-nogcc/riscv32-unknown-elf ] || rm %T/testroot-riscv32-baremetal-nogcc/riscv32-unknown-elf // RUN: ln -s %clang %T/testroot-riscv32-baremetal-nogcc/bin/clang // RUN: ln -s %S/Inputs/basic_riscv32_nogcc_tree/bin/riscv32-unknown-elf-ld %T/testroot-riscv32-baremetal-nogcc/bin/riscv32-unknown-elf-ld // RUN: ln -s %S/Inputs/basic_riscv32_nogcc_tree/riscv32-unknown-elf %T/testroot-riscv32-baremetal-nogcc/riscv32-unknown-elf diff --git a/clang/test/Driver/riscv64-toolchain-extra.c b/clang/test/Driver/riscv64-toolchain-extra.c index 081fc67e01cf..434f2dd2599a 100644 --- a/clang/test/Driver/riscv64-toolchain-extra.c +++ b/clang/test/Driver/riscv64-toolchain-extra.c @@ -12,10 +12,8 @@ // runtime if and only if they exist. // // REQUIRES: platform-linker +// RUN: rm -rf %T/testroot-riscv64-baremetal-nogcc/bin // RUN: mkdir -p %T/testroot-riscv64-baremetal-nogcc/bin -// RUN: [ ! -s %T/testroot-riscv64-baremetal-nogcc/bin/clang ] || rm %T/testroot-riscv64-baremetal-nogcc/bin/clang -// RUN: [ ! -s %T/testroot-riscv64-baremetal-nogcc/bin/riscv64-unknown-elf-ld ] || rm %T/testroot-riscv64-baremetal-nogcc/bin/riscv64-unknown-elf-ld -// RUN: [ ! -s %T/testroot-riscv64-baremetal-nogcc/riscv64-unknown-elf ] || rm %T/testroot-riscv64-baremetal-nogcc/riscv64-unknown-elf // RUN: ln -s %clang %T/testroot-riscv64-baremetal-nogcc/bin/clang // RUN: ln -s %S/Inputs/basic_riscv64_nogcc_tree/bin/riscv64-unknown-elf-ld %T/testroot-riscv64-baremetal-nogcc/bin/riscv64-unknown-elf-ld // RUN: ln -s %S/Inputs/basic_riscv64_nogcc_tree/riscv64-unknown-elf %T/testroot-riscv64-baremetal-nogcc/riscv64-unknown-elf diff --git a/clang/test/Driver/target-override.c b/clang/test/Driver/target-override.c index 49ca90fd6f47..b4dbd2da1df6 100644 --- a/clang/test/Driver/target-override.c +++ b/clang/test/Driver/target-override.c @@ -1,8 +1,8 @@ // REQUIRES: shell // REQUIRES: x86-registered-target +// RUN: rm -rf %T/testbin // RUN: mkdir -p %T/testbin -// RUN: [ ! -s %T/testbin/i386-clang ] || rm %T/testbin/i386-clang // RUN: ln -s %clang %T/testbin/i386-clang // Check if invocation of "foo-clang" adds option "-target foo". From cfe-commits at lists.llvm.org Sun Apr 5 10:08:05 2020 From: cfe-commits at lists.llvm.org (Nico Weber via cfe-commits) Date: Sun, 05 Apr 2020 10:08:05 -0700 (PDT) Subject: [clang] e01ec11 - make ccabe93298 more robust Message-ID: <5e8a1075.1c69fb81.b7256.fd0c@mx.google.com> Author: Nico Weber Date: 2020-04-05T13:07:50-04:00 New Revision: e01ec11882d3a2af509ec5caf248ecd79485240c URL: https://github.com/llvm/llvm-project/commit/e01ec11882d3a2af509ec5caf248ecd79485240c DIFF: https://github.com/llvm/llvm-project/commit/e01ec11882d3a2af509ec5caf248ecd79485240c.diff LOG: make ccabe93298 more robust Added: Modified: clang/test/Driver/mingw-sysroot.cpp clang/test/Driver/riscv32-toolchain-extra.c clang/test/Driver/riscv64-toolchain-extra.c Removed: ################################################################################ diff --git a/clang/test/Driver/mingw-sysroot.cpp b/clang/test/Driver/mingw-sysroot.cpp index 9c6ded76127d..eb62b6fe5d0c 100644 --- a/clang/test/Driver/mingw-sysroot.cpp +++ b/clang/test/Driver/mingw-sysroot.cpp @@ -1,14 +1,14 @@ // REQUIRES: shell // UNSUPPORTED: system-windows -// RUN: rm -rf %T/testroot-gcc/bin +// RUN: rm -rf %T/testroot-gcc // RUN: mkdir -p %T/testroot-gcc/bin // RUN: ln -s %clang %T/testroot-gcc/bin/x86_64-w64-mingw32-gcc // RUN: ln -s %clang %T/testroot-gcc/bin/x86_64-w64-mingw32-clang // RUN: ln -s %S/Inputs/mingw_ubuntu_posix_tree/usr/x86_64-w64-mingw32 %T/testroot-gcc/x86_64-w64-mingw32 // RUN: ln -s %S/Inputs/mingw_ubuntu_posix_tree/usr/lib %T/testroot-gcc/lib -// RUN: rm -rf %T/testroot-clang/bin +// RUN: rm -rf %T/testroot-clang // RUN: mkdir -p %T/testroot-clang/bin // RUN: ln -s %clang %T/testroot-clang/bin/x86_64-w64-mingw32-clang // RUN: ln -s %S/Inputs/mingw_ubuntu_posix_tree/usr/x86_64-w64-mingw32 %T/testroot-clang/x86_64-w64-mingw32 diff --git a/clang/test/Driver/riscv32-toolchain-extra.c b/clang/test/Driver/riscv32-toolchain-extra.c index f70092ac0333..8103e55b9aa5 100644 --- a/clang/test/Driver/riscv32-toolchain-extra.c +++ b/clang/test/Driver/riscv32-toolchain-extra.c @@ -12,7 +12,7 @@ // runtime if and only if they exist. // // REQUIRES: platform-linker -// RUN: rm -rf %T/testroot-riscv32-baremetal-nogcc/bin +// RUN: rm -rf %T/testroot-riscv32-baremetal-nogcc // RUN: mkdir -p %T/testroot-riscv32-baremetal-nogcc/bin // RUN: ln -s %clang %T/testroot-riscv32-baremetal-nogcc/bin/clang // RUN: ln -s %S/Inputs/basic_riscv32_nogcc_tree/bin/riscv32-unknown-elf-ld %T/testroot-riscv32-baremetal-nogcc/bin/riscv32-unknown-elf-ld diff --git a/clang/test/Driver/riscv64-toolchain-extra.c b/clang/test/Driver/riscv64-toolchain-extra.c index 434f2dd2599a..d11f92275f4e 100644 --- a/clang/test/Driver/riscv64-toolchain-extra.c +++ b/clang/test/Driver/riscv64-toolchain-extra.c @@ -12,7 +12,7 @@ // runtime if and only if they exist. // // REQUIRES: platform-linker -// RUN: rm -rf %T/testroot-riscv64-baremetal-nogcc/bin +// RUN: rm -rf %T/testroot-riscv64-baremetal-nogcc // RUN: mkdir -p %T/testroot-riscv64-baremetal-nogcc/bin // RUN: ln -s %clang %T/testroot-riscv64-baremetal-nogcc/bin/clang // RUN: ln -s %S/Inputs/basic_riscv64_nogcc_tree/bin/riscv64-unknown-elf-ld %T/testroot-riscv64-baremetal-nogcc/bin/riscv64-unknown-elf-ld From cfe-commits at lists.llvm.org Sun Apr 5 10:08:31 2020 From: cfe-commits at lists.llvm.org (Saiyedul Islam via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 17:08:31 +0000 (UTC) Subject: [PATCH] D75917: Expose llvm fence instruction as clang intrinsic In-Reply-To: References: Message-ID: saiislam updated this revision to Diff 255173. saiislam added a comment. Removed OpenCL specific dependencies Now it takes target-specific sync scope as an string. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75917/new/ https://reviews.llvm.org/D75917 Files: clang/include/clang/Basic/Builtins.def clang/lib/CodeGen/CGBuiltin.cpp clang/lib/Sema/SemaChecking.cpp clang/test/CodeGenHIP/builtin_memory_fence.cpp clang/test/Sema/builtins.c -------------- next part -------------- A non-text attachment was scrubbed... Name: D75917.255173.patch Type: text/x-patch Size: 5987 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 10:08:31 2020 From: cfe-commits at lists.llvm.org (Nathan James via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 17:08:31 +0000 (UTC) Subject: [PATCH] D77503: [ASTMatchers] Fixed CastKind being parsed incorrectly for dynamic matchers Message-ID: njames93 created this revision. njames93 added a reviewer: klimek. Herald added a project: clang. Herald added a subscriber: cfe-commits. Requires hasCastKind arguments to have `CK_` prefixed to bring it in line with the documentation and other matchers that take enumerations. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77503 Files: clang/lib/ASTMatchers/Dynamic/Marshallers.h Index: clang/lib/ASTMatchers/Dynamic/Marshallers.h =================================================================== --- clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -147,7 +147,7 @@ private: static Optional getCastKind(llvm::StringRef AttrKind) { return llvm::StringSwitch>(AttrKind) -#define CAST_OPERATION(Name) .Case( #Name, CK_##Name) +#define CAST_OPERATION(Name) .Case("CK_" #Name, CK_##Name) #include "clang/AST/OperationKinds.def" .Default(llvm::None); } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77503.255172.patch Type: text/x-patch Size: 567 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 10:08:34 2020 From: cfe-commits at lists.llvm.org (Wenlei He via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 17:08:34 +0000 (UTC) Subject: [PATCH] D77484: [Vector] Pass VectLib to LTO backend so TLI build correct vector function list In-Reply-To: References: Message-ID: <6bf9abb8fd307341f5441f5ffc8c61b2@localhost.localdomain> wenlei added a comment. In D77484#1962445 , @tejohnson wrote: > We're trying to move towards encoding all of this in the IR. And in fact, I recently implemented a series of patches to make the TLI to be built per-function, and along with some patches from @gchatelet to encode -fno-builtin* as function attributes, we now handle that part of the TLII with IR. See D67923 which is the last patch in the series. We should encode the vectlib as function attributes similarly, and just thread that through to the TLI. Thanks for quick look, @tejohnson. Yeah, making vectlib a function attribute would be more consistent with other the way other TLI attributes are handled. However, unlike some other attributes, which really need to be per-function, conceptually, vectlib setting won't be different from function to function in a module. Implementation-wise, even though TLI is now built per-function, there's a `BaselineInfoImpl` within each `TargetLibraryInfo`, that's still shared among functions, and `VectorDescs` which is populated based on vectlib setting belongs to the shared baseline. We could also move `VectorDescs` and its population into per-function part of TLI, but I felt that's a bit overkill, though I don't have a strong opinion on this. So I followed how other module level stuff like `lto-sample-profile` is passed to backend.. Alternatively, we could chose to always run `InjectTLIMappings` in pre-LTO pipeline, even if we don't run vectorizer pre-LTO for ThinLTO, so we always have per-function attribute `vector-function-abi-variant` populated and threaded through to LTO time vectorizer. We will have to make sure the vector function list in TLI (based on vectlib setting) has no other use case though. (More on TLI, while this change (or a variant of this) enables vectorization that uses math library for ThinLTO w/ legacy PM, there's separate issue with new PM as `InjectTLIMappings` is not scheduled before Vectorization for LTO pipeline. I will send a separate patch for that once we settle on a good way to handle this one.) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77484/new/ https://reviews.llvm.org/D77484 From cfe-commits at lists.llvm.org Sun Apr 5 10:08:36 2020 From: cfe-commits at lists.llvm.org (Raul Tambre via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 17:08:36 +0000 (UTC) Subject: [PATCH] D77502: [clang][CodeGen] Handle throw expression in conditional operator constant folding In-Reply-To: References: Message-ID: <16ef32362d6e913cdd060e25913d34cc@localhost.localdomain> tambre updated this revision to Diff 255175. tambre added a comment. Fix formatting Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77502/new/ https://reviews.llvm.org/D77502 Files: clang/lib/CodeGen/CGExpr.cpp clang/test/CodeGenCXX/throw-expressions.cpp Index: clang/test/CodeGenCXX/throw-expressions.cpp =================================================================== --- clang/test/CodeGenCXX/throw-expressions.cpp +++ clang/test/CodeGenCXX/throw-expressions.cpp @@ -79,6 +79,12 @@ // CHECK-NOT: call {{.*}}@_ZN6DR15601AD1Ev // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN6DR15601AD1Ev {{.*}} @_ZGRN6DR15601rE // CHECK-NOT: call {{.*}}@_ZN6DR15601AD1Ev + + // PR28184 + void conditional_throw() { + int a, b; + (true ? throw 0 : a) = 0; + } } // CHECK-LABEL: define void @_Z5test7b( Index: clang/lib/CodeGen/CGExpr.cpp =================================================================== --- clang/lib/CodeGen/CGExpr.cpp +++ clang/lib/CodeGen/CGExpr.cpp @@ -4331,6 +4331,11 @@ // If the true case is live, we need to track its region. if (CondExprBool) incrementProfileCounter(expr); + // If a throw expression we need to return dead as lvalue. + if (auto *ThrowExpr = dyn_cast(live->IgnoreParens())) { + EmitCXXThrowExpr(ThrowExpr); + return EmitLValue(dead); + } return EmitLValue(live); } } -------------- next part -------------- A non-text attachment was scrubbed... Name: D77502.255175.patch Type: text/x-patch Size: 1148 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 10:10:12 2020 From: cfe-commits at lists.llvm.org (Nico Weber via cfe-commits) Date: Sun, 5 Apr 2020 13:10:12 -0400 Subject: [clang] a8c8b62 - [ObjC generics] Fix not inheriting type bounds in categories/extensions. In-Reply-To: <5e87c6e4.1c69fb81.35899.fccc@mx.google.com> References: <5e87c6e4.1c69fb81.35899.fccc@mx.google.com> Message-ID: The test here flakily fails, maybe 1 in 10 times: http://45.33.8.238/mac/11180/step_7.txt error: 'error' diagnostics seen but not expected: File /Users/thakis/src/llvm-project/clang/test/SemaObjC/parameterized_classes_subst.m Line 479: type argument 'T' (aka 'id') does not satisfy the bound ('id') of type parameter 'T' error: 'note' diagnostics seen but not expected: File /Users/thakis/src/llvm-project/clang/test/SemaObjC/parameterized_classes_subst.m Line 475: type parameter 'T' declared here 2 errors generated. Maybe if this is emitted depends on the order of something in a data structure that has no deterministic order, or similar? On Fri, Apr 3, 2020 at 7:29 PM Volodymyr Sapsai via cfe-commits < cfe-commits at lists.llvm.org> wrote: > > Author: Volodymyr Sapsai > Date: 2020-04-03T16:29:02-07:00 > New Revision: a8c8b627f23f204fb621bd2a8c495cfc8bc16ae7 > > URL: > https://github.com/llvm/llvm-project/commit/a8c8b627f23f204fb621bd2a8c495cfc8bc16ae7 > DIFF: > https://github.com/llvm/llvm-project/commit/a8c8b627f23f204fb621bd2a8c495cfc8bc16ae7.diff > > LOG: [ObjC generics] Fix not inheriting type bounds in > categories/extensions. > > When a category/extension doesn't repeat a type bound, corresponding > type parameter is substituted with `id` when used as a type argument. As > a result, in the added test case it was causing errors like > > > type argument 'T' (aka 'id') does not satisfy the bound > ('id') of type parameter 'T' > > We are already checking that type parameters should be consistent > everywhere (see `checkTypeParamListConsistency`) and update > `ObjCTypeParamDecl` to have correct underlying type. And when we use the > type parameter as a method return type or a method parameter type, it is > substituted to the bounded type. But when we use the type parameter as a > type argument, we check `ObjCTypeParamType` that wasn't updated and > remains `id`. > > Fix by updating not only `ObjCTypeParamDecl` UnderlyingType but also > TypeForDecl as we use the underlying type to create a canonical type for > `ObjCTypeParamType` (see `ASTContext::getObjCTypeParamType`). > > This is a different approach to fixing the issue. The previous one was > 02c2ab3d8872416589bd1a6ca3dfb96ba373a3b9 which was reverted in > 4c539e8da1b3de38a53ef3f7497f5c45a3243b61. The problem with the previous > approach was that `ObjCTypeParamType::desugar` was returning underlying > type for `ObjCTypeParamDecl` without applying any protocols stored in > `ObjCTypeParamType`. It caused inconsistencies in comparing types before > and after desugaring. > > rdar://problem/54329242 > > Reviewed By: erik.pilkington > > Differential Revision: https://reviews.llvm.org/D72872 > > Added: > > > Modified: > clang/include/clang/AST/ASTContext.h > clang/lib/AST/ASTContext.cpp > clang/lib/AST/Type.cpp > clang/lib/Sema/SemaDeclObjC.cpp > clang/test/SemaObjC/parameterized_classes_collection_literal.m > clang/test/SemaObjC/parameterized_classes_subst.m > > Removed: > > > > > ################################################################################ > diff --git a/clang/include/clang/AST/ASTContext.h > b/clang/include/clang/AST/ASTContext.h > index 6813ab58874e..6360f18217c7 100644 > --- a/clang/include/clang/AST/ASTContext.h > +++ b/clang/include/clang/AST/ASTContext.h > @@ -1442,6 +1442,8 @@ class ASTContext : public RefCountedBase > { > > QualType getObjCTypeParamType(const ObjCTypeParamDecl *Decl, > ArrayRef protocols) > const; > + void adjustObjCTypeParamBoundType(const ObjCTypeParamDecl *Orig, > + ObjCTypeParamDecl *New) const; > > bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl > *Decl); > > > diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp > index 1e81e0a67b4d..06dcb6fa0580 100644 > --- a/clang/lib/AST/ASTContext.cpp > +++ b/clang/lib/AST/ASTContext.cpp > @@ -4874,6 +4874,17 @@ ASTContext::getObjCTypeParamType(const > ObjCTypeParamDecl *Decl, > return QualType(newType, 0); > } > > +void ASTContext::adjustObjCTypeParamBoundType(const ObjCTypeParamDecl > *Orig, > + ObjCTypeParamDecl *New) > const { > + > New->setTypeSourceInfo(getTrivialTypeSourceInfo(Orig->getUnderlyingType())); > + // Update TypeForDecl after updating TypeSourceInfo. > + auto NewTypeParamTy = cast(New->getTypeForDecl()); > + SmallVector protocols; > + protocols.append(NewTypeParamTy->qual_begin(), > NewTypeParamTy->qual_end()); > + QualType UpdatedTy = getObjCTypeParamType(New, protocols); > + New->setTypeForDecl(UpdatedTy.getTypePtr()); > +} > + > /// ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's > /// protocol list adopt all protocols in QT's qualified-id protocol > /// list. > > diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp > index 3428437c3146..7c65378261ad 100644 > --- a/clang/lib/AST/Type.cpp > +++ b/clang/lib/AST/Type.cpp > @@ -3534,6 +3534,7 @@ void > ObjCTypeParamType::Profile(llvm::FoldingSetNodeID &ID, > const ObjCTypeParamDecl *OTPDecl, > ArrayRef protocols) { > ID.AddPointer(OTPDecl); > + ID.AddPointer(OTPDecl->getUnderlyingType().getAsOpaquePtr()); > ID.AddInteger(protocols.size()); > for (auto proto : protocols) > ID.AddPointer(proto); > > diff --git a/clang/lib/Sema/SemaDeclObjC.cpp > b/clang/lib/Sema/SemaDeclObjC.cpp > index 934e1a23141c..6db57898e378 100644 > --- a/clang/lib/Sema/SemaDeclObjC.cpp > +++ b/clang/lib/Sema/SemaDeclObjC.cpp > @@ -938,8 +938,7 @@ static bool checkTypeParamListConsistency(Sema &S, > > // Override the new type parameter's bound type with the previous > type, > // so that it's consistent. > - newTypeParam->setTypeSourceInfo( > - > S.Context.getTrivialTypeSourceInfo(prevTypeParam->getUnderlyingType())); > + S.Context.adjustObjCTypeParamBoundType(prevTypeParam, newTypeParam); > continue; > } > > @@ -966,8 +965,7 @@ static bool checkTypeParamListConsistency(Sema &S, > } > > // Update the new type parameter's bound to match the previous one. > - newTypeParam->setTypeSourceInfo( > - > S.Context.getTrivialTypeSourceInfo(prevTypeParam->getUnderlyingType())); > + S.Context.adjustObjCTypeParamBoundType(prevTypeParam, newTypeParam); > } > > return false; > > diff --git > a/clang/test/SemaObjC/parameterized_classes_collection_literal.m > b/clang/test/SemaObjC/parameterized_classes_collection_literal.m > index 472746e09db9..034d2e8da217 100644 > --- a/clang/test/SemaObjC/parameterized_classes_collection_literal.m > +++ b/clang/test/SemaObjC/parameterized_classes_collection_literal.m > @@ -29,7 +29,9 @@ + (instancetype)arrayWithObjects:(const T [])objects > count:(NSUInteger)cnt; > @end > > @interface NSDictionary : NSObject > -+ (instancetype)dictionaryWithObjects:(const V [])objects forKeys:(const > K [])keys count:(NSUInteger)cnt; > ++ (instancetype)dictionaryWithObjects:(const V [])objects > + forKeys:(const K [])keys > + count:(NSUInteger)cnt; > @end > > void testArrayLiteral(void) { > @@ -50,3 +52,9 @@ void testDictionaryLiteral(void) { > @"world" : @"blah" // expected-warning{{object of type 'NSString *' > is not compatible with dictionary value type 'NSNumber *'}} > }; > } > + > +void testCastingInDictionaryLiteral(NSString *arg) { > + NSDictionary *dict = @{ > + (id)arg : @"foo", > + }; > +} > > diff --git a/clang/test/SemaObjC/parameterized_classes_subst.m > b/clang/test/SemaObjC/parameterized_classes_subst.m > index d14a6e9deb40..b6d884760d29 100644 > --- a/clang/test/SemaObjC/parameterized_classes_subst.m > +++ b/clang/test/SemaObjC/parameterized_classes_subst.m > @@ -467,3 +467,17 @@ - (void)mapUsingBlock:(id (^)(id))block { > - (void)mapUsingBlock2:(id)block { // expected-warning{{conflicting > parameter types in implementation}} > } > @end > + > +// > -------------------------------------------------------------------------- > +// Use a type parameter as a type argument. > +// > -------------------------------------------------------------------------- > +// Type bounds in a category/extension are omitted. > rdar://problem/54329242 > + at interface ParameterizedContainer> > +- (ParameterizedContainer *)inInterface; > + at end > + at interface ParameterizedContainer (Cat) > +- (ParameterizedContainer *)inCategory; > + at end > + at interface ParameterizedContainer () > +- (ParameterizedContainer *)inExtension; > + at end > > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cfe-commits at lists.llvm.org Sun Apr 5 10:40:23 2020 From: cfe-commits at lists.llvm.org (John McCall via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 17:40:23 +0000 (UTC) Subject: [PATCH] D77028: [NFC] Refactor DeferredDiagsEmitter and skip redundant visit In-Reply-To: References: Message-ID: rjmccall added inline comments. ================ Comment at: clang/lib/Sema/Sema.cpp:1508 void checkFunc(SourceLocation Loc, FunctionDecl *FD) { + auto DiagsCountIt = DiagsCount.find(FD); FunctionDecl *Caller = UseStack.empty() ? nullptr : UseStack.back(); ---------------- yaxunl wrote: > rjmccall wrote: > > yaxunl wrote: > > > rjmccall wrote: > > > > yaxunl wrote: > > > > > rjmccall wrote: > > > > > > yaxunl wrote: > > > > > > > rjmccall wrote: > > > > > > > > It makes me a little uncomfortable to be holding an iterator this long while calling a fair amount of other stuff in the meantime. > > > > > > > > > > > > > > > > Your use of DiagsCount is subtle enough that it really needs to be explained in some comments. You're doing stuff conditionally based on both whether the entry exists but also whether it's non-zero. > > > > > > > added comments > > > > > > Okay, thanks for that. Two points, then. First, it looks like the count is really just a boolean for whether the function recursively triggers any diagnostics. And second, can't it just be as simple as whether we've visited that function at all in a context that's forcing diagnostics to be emitted? The logic seems to be to try to emit the diagnostics for each use-path, but why would we want that? > > > > > For the second comment, we need to visit a function again for each use-path because we need to report each use-path that triggers a diagnostic, otherwise users will see a new error after they fix one error, instead of seeing all the errors at once. > > > > > > > > > > For the first comment, I will change the count to two flags: one for the case where the function is not in device context, the other is for the case where the function is in device context. This will allow us to avoid redundant visits whether or not we are in a device context. > > > > > For the second comment, we need to visit a function again for each use-path because we need to report each use-path that triggers a diagnostic, otherwise users will see a new error after they fix one error, instead of seeing all the errors at once. > > > > > > > > This is not what we do in analogous cases where errors are triggered by a use, like in template instantiation. The bug might be that the device program is using a function that it shouldn't be using, or the bug might be that a function that's supposed to be usable from the device is written incorrectly. In the former case, yes, not reporting the errors for each use-path may force the programmer to build multiple times to find all the problematic uses. However, in the latter case you can easily end up emitting a massive number of errors that completely drowns out everything else. It's also non-linear: the number of different use-paths of a particular function can be combinatoric. > > > The deferred diagnostics fall into the first case mostly. > > > > > > Not all diagnostic messages happen in device host functions are deferred. Most of diagnostic messages are emitted immediately, disregarding whether the function is emitted or not. > > > > > > Only a few special types of diagnostic messages e.g. inline assembly errors, exceptions, varags are deferred. This is because clang has to use pragmas to make all functions device and host in some system headers to be able to use them in device compilation, whereas some of these functions will cause error only if they are emitted in device compilation. Since we cannot change these headers, we have to defer such diagnostics to the point where they are actually triggered. Therefore we are mostly interested in "who is calling these functions" instead of the diagnostics themselves. > > > > > > For normal programs containing no diagnostics, the current approach should sufficiently avoid all redundant visits and all functions will be visited once. > > > > > > The functions may be visited multiple times when there are deferred diagnostics, however this should be limited by the maximum number of errors. > > Okay. I understand the point now about being mostly concerned about using functions in headers. > > > > My concern about visiting things a combinatorial number of times is less about generating an excessive number of errors and more about taking an excessive amount of time to finish compilation. The compiler really should not be using any exponential algorithms; a simple visited set will ensure that, but I think what you're doing does not. Can you make a case for why that's not true? > The current approach is linear for the number of visits to functions. > > Let's assume the number of functions is N. > > The current approach already restricted revisiting a node that's already in the current use-path to prevent infinite recursion, therefore a use-path has maximum length N. > > The functions can be classified as two categories: > > Those who trigger deferred diags directly or indirectly, which we call trigger nodes. > > Those who do not trigger deferred diags directly or indirectly, which we call non-trigger nodes. > > Non-trigger nodes can be identified at most with two visits. All other visits are skipped. Therefore the total number of visits of non-trigger nodes is less than 2*N. > > We can also classify the use-paths as trigger paths and non-trigger paths. Each trigger path causes at least one diagnostic emitted. Each non-trigger path does not cause any diagnostics emitted. > > Due to limit of maximum diagnostics allowed, the algorithm will stop after a finite number of use-paths visited. Let's say it is M. (In reality, M could be much smaller than the maximum diagnostic allowed.) Then the number of trigger paths is at most M. > > Let's list all the use-paths visited and count all the nodes visited in these use-paths. > > First we consider all the use-paths that containing only non-trigger nodes, since each non-trigger nodes can only be visited twice. The total number of visits of nodes is less than 2*N. > > Then we consider all the trigger paths. Since the maximum path length is N, the total number of nodes visited is less than N*M. > > Now we only need to consider the non-trigger paths that starts with trigger nodes and end with a non-trigger node. For example, ABCD, where A, B, C, D denote nodes (functions) visited in the path. We can prove that A, B, C must be trigger nodes, since if any of A, B, C is a non-trigger node, the path will ends earlier, not reaching D. We can also prove that the sub-path ABC must be shared with a trigger path e.g. ABCEF, since otherwise C will be a non-trigger node. Then we do not need to count visit of A, B, and C, since they have already been counted when we count the visited nodes by trigger paths. > > Therefore, the total number of visits for functions is less than (2+M)*N, where M is actual number of diagnostics emitted. > > Due to limit of maximum diagnostics allowed, the algorithm will stop after a finite number of use-paths visited. Why do you think this is true? I don't see anything in your actual code which asks whether the error limit has been reached; it just does all the work and trusts the diagnostics engine to stop emitting diagnostics eventually. Try turning the error limit off (which will tell you how much work you're doing, since you're not short-circuiting when it's reached) and seeing how many diagnostics you get if you have a chain of functions like this: ``` // All of these functions should be emitted on demand. void hasInvalid() { /* this function should trigger a deferred diagnostic of some sort */ } void use0() { hasInvalid(); hasInvalid(); } void use1() { use0(); use0(); } void use2() { use1(); use1(); } void use3() { use2(); use2(); } void use4() { use3(); use3(); } // The final function should be a kernel or something like that. ``` Also, in general, since the error limit can be disabled, I don't think it's a good idea for it to be the only thing stopping you from doing an exponential amount of work. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77028/new/ https://reviews.llvm.org/D77028 From cfe-commits at lists.llvm.org Sun Apr 5 10:40:26 2020 From: cfe-commits at lists.llvm.org (Hongtao Yu via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 17:40:26 +0000 (UTC) Subject: [PATCH] D77484: [Vector] Pass VectLib to LTO backend so TLI build correct vector function list In-Reply-To: References: Message-ID: hoyFB added a comment. In D77484#1962445 , @tejohnson wrote: > We're trying to move towards encoding all of this in the IR. And in fact, I recently implemented a series of patches to make the TLI to be built per-function, and along with some patches from @gchatelet to encode -fno-builtin* as function attributes, we now handle that part of the TLII with IR. See D67923 which is the last patch in the series. We should encode the vectlib as function attributes similarly, and just thread that through to the TLI. That's an interesting idea. How does the linkage work if two functions have different vectlib attributes? Linking against two vectlibs may cause name conflicts or other issues. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77484/new/ https://reviews.llvm.org/D77484 From cfe-commits at lists.llvm.org Sun Apr 5 11:44:43 2020 From: cfe-commits at lists.llvm.org (Teresa Johnson via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 18:44:43 +0000 (UTC) Subject: [PATCH] D77484: [Vector] Pass VectLib to LTO backend so TLI build correct vector function list In-Reply-To: References: Message-ID: tejohnson added a comment. In D77484#1962581 , @hoyFB wrote: > In D77484#1962445 , @tejohnson wrote: > > > We're trying to move towards encoding all of this in the IR. And in fact, I recently implemented a series of patches to make the TLI to be built per-function, and along with some patches from @gchatelet to encode -fno-builtin* as function attributes, we now handle that part of the TLII with IR. See D67923 which is the last patch in the series. We should encode the vectlib as function attributes similarly, and just thread that through to the TLI. > > > That's an interesting idea. How does the linkage work if two functions have different vectlib attributes? Linking against two vectlibs may cause name conflicts or other issues. Actually this may be best encoded in a module metadata that with an error merging type, so that conflicting options get flagged. What happens today in a non-LTO build if conflicting veclib options are provided to different TUs? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77484/new/ https://reviews.llvm.org/D77484 From cfe-commits at lists.llvm.org Sun Apr 5 11:44:43 2020 From: cfe-commits at lists.llvm.org (Tyker via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 18:44:43 +0000 (UTC) Subject: [PATCH] D71739: [WIP] Use operand bundles to encode alignment assumptions In-Reply-To: References: Message-ID: Tyker added a comment. In D71739#1961508 , @jdoerfert wrote: > @lebedev.ri We'd need to identify other uses of the alignment encoding in-tree so we can replace them as well. Also, this patch uses not only the alignment but also the offset in the operand bundle. We can either allow that or encode the offset via a gep in the IR. I guess the latter is easier to implement until we have more reasons to allow more complex operand bundles (which we will need to have eventually). for now i think we will stay with the current "simple" alignment assumptions in operand bundles. but we can improve it later. > @Tyker Do you want to take this? i am fine with taking this. but there is a few thing to do before this. i think that this patch depends on a few things: - add an API to build assumes from provided knowledge. - update users of alignment assumptions. and a few things that i would like to do before: - finish patches currently in review. - improve generation of assume with operand bundles to minimize duplicates and extra instructions. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71739/new/ https://reviews.llvm.org/D71739 From cfe-commits at lists.llvm.org Sun Apr 5 11:52:56 2020 From: cfe-commits at lists.llvm.org (Richard Smith via cfe-commits) Date: Sun, 5 Apr 2020 11:52:56 -0700 Subject: [libcxx-dev] [clang] 4ede887 - PR45402: Make the restrictions on constant evaluation of memcmp and In-Reply-To: <6c87a15d-885c-43e4-b7de-462c4cbfb460@www.fastmail.com> References: <5e87e25e.1c69fb81.933ef.f8d6@mx.google.com> <6c87a15d-885c-43e4-b7de-462c4cbfb460@www.fastmail.com> Message-ID: Thanks. We need to figure out what the right way to support char8_t with string builtins is. These ones could work in principle, whereas things like __builtin_strlen would never work because they take operands of the wrong types (and we can't cast const char8_t* -> const char* in a constant expression). On Sun, 5 Apr 2020 at 04:14, David Zarzycki via cfe-commits < cfe-commits at lists.llvm.org> wrote: > Hi Richard, > > I'm going to commit a narrow fix to clang to make the libcxx test suite > pass again by allowing char8_t again. If you feel that this is the wrong > long-term solution, please help the libcxx folks with whatever adjustments > they need. > > Thanks! > > Dave > > > On Sat, Apr 4, 2020, at 9:55 AM, David Zarzycki via libcxx-dev wrote: > > Hi Richard, > > > > This breaks libcxx. Can we please revert this or is a quick fix to > > libcxx possible? > > > > > > FAIL: libc++ :: > > > std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp > (58624 of 62672) > > ******************** TEST 'libc++ :: > > > std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp' > FAILED ******************** > > Command: ['/p/tllvm/bin/clang++', '-o', > > > '/tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o', > '-x', 'c++', > '/home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp', > '-c', '-v', '-Werror=thread-safety', '-std=c++2a', '-include', > '/home/dave/s/lp/libcxx/test/support/nasty_macros.h', '-nostdinc++', > '-I/home/dave/s/lp/libcxx/include', > '-I/tmp/_update_lc/t/projects/libcxx/include/c++build', > '-D__STDC_FORMAT_MACROS', '-D__STDC_LIMIT_MACROS', > '-D__STDC_CONSTANT_MACROS', '-I/home/dave/s/lp/libcxx/test/support', > '-ftemplate-depth=270', '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER', '-Wall', > '-Wextra', '-Werror', '-Wuser-defined-warnings', '-Wshadow', > '-Wno-unused-command-line-argument', '-Wno-attributes', > '-Wno-pessimizing-move', '-Wno-c++11-extensions', > '-Wno-user-defined-literals', '-Wno-noexcept-type', '-Wsign-compare', > '-Wunused-variable', '-Wunused-parameter', '-Wunreachable-code', '-c'] > > Exit Code: 1 > > Standard Error: > > -- > > clang version 11.0.0 (https://github.com/llvm/llvm-project.git > > 22127da8f17c03c69231f3631472f7f99ad9cb7f) > > Target: x86_64-unknown-linux-gnu > > Thread model: posix > > InstalledDir: /p/tllvm/bin > > Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 > > Selected GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 > > Candidate multilib: .;@m64 > > Candidate multilib: 32;@m32 > > Selected multilib: .;@m64 > > (in-process) > > "/p/tllvm/bin/clang-11" -cc1 -triple x86_64-unknown-linux-gnu > > -emit-obj -mrelax-all -disable-free -disable-llvm-verifier > > -discard-value-names -main-file-name compare.pass.cpp > > -mrelocation-model static -mthread-model posix -mframe-pointer=all > > -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables > > -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining > > -debugger-tuning=gdb -v -nostdinc++ -resource-dir > > /p/tllvm/lib64/clang/11.0.0 -include > > /home/dave/s/lp/libcxx/test/support/nasty_macros.h -I > > /home/dave/s/lp/libcxx/include -I > > /tmp/_update_lc/t/projects/libcxx/include/c++build -D > > __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS > > -I /home/dave/s/lp/libcxx/test/support -D > > _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -internal-isystem > > /usr/local/include -internal-isystem > > /p/tllvm/lib64/clang/11.0.0/include -internal-externc-isystem /include > > -internal-externc-isystem /usr/include -Werror=thread-safety -Wall > > -Wextra -Werror -Wuser-defined-warnings -Wshadow > > -Wno-unused-command-line-argument -Wno-attributes -Wno-pessimizing-move > > -Wno-c++11-extensions -Wno-user-defined-literals -Wno-noexcept-type > > -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code > > -std=c++2a -fdeprecated-macro -fdebug-compilation-dir > > > /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t > -ftemplate-depth 270 -ferror-limit 19 -fgnuc-version=4.2.1 > -fno-implicit-modules -fcxx-exceptions -fexceptions -faddrsig -o > /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o > -x c++ > /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp > > clang -cc1 version 11.0.0 based upon LLVM 11.0.0git default target > > x86_64-unknown-linux-gnu > > ignoring nonexistent directory "/include" > > #include "..." search starts here: > > #include <...> search starts here: > > /home/dave/s/lp/libcxx/include > > /tmp/_update_lc/t/projects/libcxx/include/c++build > > /home/dave/s/lp/libcxx/test/support > > /usr/local/include > > /p/tllvm/lib64/clang/11.0.0/include > > /usr/include > > End of search list. > > > /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: > error: static_assert expression is not an integral constant expression > > static_assert(test_constexpr(), "" ); > > ^~~~~~~~~~~~~~~~ > > /home/dave/s/lp/libcxx/include/__string:662:12: note: constant > > evaluation of '__builtin_memcmp' between arrays of types 'const > > char8_t' and 'const char8_t' is not supported; only arrays of narrow > > character types can be compared > > return __builtin_memcmp(__s1, __s2, __n); > > ^ > > > /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:24:12: > note: in call to 'compare(&u8"123"[0], &u8"223"[0], 3)' > > return std::char_traits::compare(u8"123", u8"223", 3) < 0 > > ^ > > > /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: > note: in call to 'test_constexpr()' > > static_assert(test_constexpr(), "" ); > > ^ > > 1 error generated. > > -- > > > > Compilation failed unexpectedly! > > ******************** > > > > Testing Time: 135.49s > > ******************** > > Failing Tests (1): > > libc++ :: > > > std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp > > > > Expected Passes : 45503 > > Expected Failures : 118 > > Unsupported Tests : 17050 > > Unexpected Failures: 1 > > > > > > On Fri, Apr 3, 2020, at 9:26 PM, Richard Smith via cfe-commits wrote: > > > > > > Author: Richard Smith > > > Date: 2020-04-03T18:26:14-07:00 > > > New Revision: 4ede8879924c08ae5b495d3f421c167d822a60be > > > > > > URL: > > > > https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be > > > DIFF: > > > > https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be.diff > > > > > > LOG: PR45402: Make the restrictions on constant evaluation of memcmp > and > > > memchr consistent and comprehensible, and document them. > > > > > > We previously allowed evaluation of memcmp on arrays of integers of any > > > size, so long as the call evaluated to 0, and allowed evaluation of > > > memchr on any array of integral type of size 1 (including enums). The > > > purpose of constant-evaluating these builtins is only to support > > > constexpr std::char_traits, so we now consistently allow them on arrays > > > of (possibly signed or unsigned) char only. > > > > > > Added: > > > > > > > > > Modified: > > > clang/docs/LanguageExtensions.rst > > > clang/include/clang/Basic/DiagnosticASTKinds.td > > > clang/lib/AST/ExprConstant.cpp > > > clang/test/SemaCXX/constexpr-string.cpp > > > > > > Removed: > > > > > > > > > > > > > ################################################################################ > > > diff --git a/clang/docs/LanguageExtensions.rst > > > b/clang/docs/LanguageExtensions.rst > > > index 558ce7dee653..6dcfd1a49f06 100644 > > > --- a/clang/docs/LanguageExtensions.rst > > > +++ b/clang/docs/LanguageExtensions.rst > > > @@ -2333,10 +2333,11 @@ String builtins > > > --------------- > > > > > > Clang provides constant expression evaluation support for builtins > forms of > > > -the following functions from the C standard library ```` > header: > > > +the following functions from the C standard library headers > > > +```` and ````: > > > > > > * ``memchr`` > > > -* ``memcmp`` > > > +* ``memcmp`` (and its deprecated BSD / POSIX alias ``bcmp``) > > > * ``strchr`` > > > * ``strcmp`` > > > * ``strlen`` > > > @@ -2366,7 +2367,11 @@ In addition to the above, one further builtin > is > > > provided: > > > constant expressions in C++11 onwards (where a cast from ``void*`` to > > > ``char*`` > > > is disallowed in general). > > > > > > -Support for constant expression evaluation for the above builtins be > > > detected > > > +Constant evaluation support for the ``__builtin_mem*`` functions is > > > provided > > > +only for arrays of ``char``, ``signed char``, or ``unsigned char``, > > > despite > > > +these functions accepting an argument of type ``const void*``. > > > + > > > +Support for constant expression evaluation for the above builtins can > > > be detected > > > with ``__has_feature(cxx_constexpr_string_builtins)``. > > > > > > Memory builtins > > > @@ -2386,6 +2391,25 @@ more information. > > > > > > Note that the `size` argument must be a compile time constant. > > > > > > +Clang provides constant expression evaluation support for builtin > > > forms of the > > > +following functions from the C standard library headers > > > +```` and ````: > > > + > > > +* ``memcpy`` > > > +* ``memmove`` > > > +* ``wmemcpy`` > > > +* ``wmemmove`` > > > + > > > +In each case, the builtin form has the name of the C library function > > > prefixed > > > +by ``__builtin_``. > > > + > > > +Constant evaluation support is only provided when the source and > > > destination > > > +are pointers to arrays with the same trivially copyable element type, > > > and the > > > +given size is an exact multiple of the element size that is no > greater > > > than > > > +the number of elements accessible through the source and destination > > > operands. > > > + > > > +Constant evaluation support is not yet provided for > > > ``__builtin_memcpy_inline``. > > > + > > > Atomic Min/Max builtins with memory ordering > > > -------------------------------------------- > > > > > > > > > diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td > > > b/clang/include/clang/Basic/DiagnosticASTKinds.td > > > index 544573edffdf..a1415f9ec0e1 100644 > > > --- a/clang/include/clang/Basic/DiagnosticASTKinds.td > > > +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td > > > @@ -244,6 +244,12 @@ def note_constexpr_unsupported_unsized_array : > > > Note< > > > def note_constexpr_unsized_array_indexed : Note< > > > "indexing of array without known bound is not allowed " > > > "in a constant expression">; > > > +def note_constexpr_memcmp_unsupported : Note< > > > + "constant evaluation of %0 between arrays of types %1 and %2 " > > > + "is not supported; only arrays of narrow character types can be > > > compared">; > > > +def note_constexpr_memchr_unsupported : Note< > > > + "constant evaluation of %0 on array of type %1 " > > > + "is not supported; only arrays of narrow character types can be > > > searched">; > > > def note_constexpr_memcpy_null : Note< > > > "%select{source|destination}2 of " > > > "'%select{%select{memcpy|wmemcpy}1|%select{memmove|wmemmove}1}0' " > > > > > > diff --git a/clang/lib/AST/ExprConstant.cpp > > > b/clang/lib/AST/ExprConstant.cpp > > > index c6e1cc7b67df..a83b2e24e17f 100644 > > > --- a/clang/lib/AST/ExprConstant.cpp > > > +++ b/clang/lib/AST/ExprConstant.cpp > > > @@ -8469,8 +8469,12 @@ bool > > > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, > > > } > > > // Give up on byte-oriented matching against multibyte elements. > > > // FIXME: We can compare the bytes in the correct order. > > > - if (IsRawByte && Info.Ctx.getTypeSizeInChars(CharTy) != > > > CharUnits::One()) > > > + if (IsRawByte && !CharTy->isCharType()) { > > > + Info.FFDiag(E, diag::note_constexpr_memchr_unsupported) > > > + << (std::string("'") + > > > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") > > > + << CharTy; > > > return false; > > > + } > > > // Figure out what value we're actually looking for (after > > > converting to > > > // the corresponding unsigned type if necessary). > > > uint64_t DesiredVal; > > > @@ -8586,6 +8590,7 @@ bool > > > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, > > > QualType T = Dest.Designator.getType(Info.Ctx); > > > QualType SrcT = Src.Designator.getType(Info.Ctx); > > > if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) { > > > + // FIXME: Consider using our bit_cast implementation to support > > > this. > > > Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) << Move << > > > SrcT << T; > > > return false; > > > } > > > @@ -11149,6 +11154,16 @@ bool > > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, > > > CharTy1, E->getArg(0)->getType()->getPointeeType()) && > > > Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2))); > > > > > > + // For memcmp, allow comparing any arrays of '[[un]signed] char', > > > + // but no other types. > > > + if (IsRawByte && !(CharTy1->isCharType() && > > > CharTy2->isCharType())) { > > > + // FIXME: Consider using our bit_cast implementation to support > > > this. > > > + Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported) > > > + << (std::string("'") + > > > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") > > > + << CharTy1 << CharTy2; > > > + return false; > > > + } > > > + > > > const auto &ReadCurElems = [&](APValue &Char1, APValue &Char2) { > > > return handleLValueToRValueConversion(Info, E, CharTy1, > String1, > > > Char1) && > > > handleLValueToRValueConversion(Info, E, CharTy2, > String2, > > > Char2) && > > > @@ -11159,57 +11174,6 @@ bool > > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, > > > HandleLValueArrayAdjustment(Info, E, String2, CharTy2, > 1); > > > }; > > > > > > - if (IsRawByte) { > > > - uint64_t BytesRemaining = MaxLength; > > > - // Pointers to const void may point to objects of incomplete > > > type. > > > - if (CharTy1->isIncompleteType()) { > > > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << > > > CharTy1; > > > - return false; > > > - } > > > - if (CharTy2->isIncompleteType()) { > > > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << > > > CharTy2; > > > - return false; > > > - } > > > - uint64_t CharTy1Width{Info.Ctx.getTypeSize(CharTy1)}; > > > - CharUnits CharTy1Size = > > > Info.Ctx.toCharUnitsFromBits(CharTy1Width); > > > - // Give up on comparing between elements with disparate widths. > > > - if (CharTy1Size != Info.Ctx.getTypeSizeInChars(CharTy2)) > > > - return false; > > > - uint64_t BytesPerElement = CharTy1Size.getQuantity(); > > > - assert(BytesRemaining && "BytesRemaining should not be zero: > the > > > " > > > - "following loop considers at least one > > > element"); > > > - while (true) { > > > - APValue Char1, Char2; > > > - if (!ReadCurElems(Char1, Char2)) > > > - return false; > > > - // We have compatible in-memory widths, but a possible type > and > > > - // (for `bool`) internal representation mismatch. > > > - // Assuming two's complement representation, including 0 for > > > `false` and > > > - // 1 for `true`, we can check an appropriate number of > > > elements for > > > - // equality even if they are not byte-sized. > > > - APSInt Char1InMem = Char1.getInt().extOrTrunc(CharTy1Width); > > > - APSInt Char2InMem = Char2.getInt().extOrTrunc(CharTy1Width); > > > - if (Char1InMem.ne(Char2InMem)) { > > > - // If the elements are byte-sized, then we can produce a > > > three-way > > > - // comparison result in a straightforward manner. > > > - if (BytesPerElement == 1u) { > > > - // memcmp always compares unsigned chars. > > > - return Success(Char1InMem.ult(Char2InMem) ? -1 : 1, E); > > > - } > > > - // The result is byte-order sensitive, and we have > multibyte > > > elements. > > > - // FIXME: We can compare the remaining bytes in the correct > > > order. > > > - return false; > > > - } > > > - if (!AdvanceElems()) > > > - return false; > > > - if (BytesRemaining <= BytesPerElement) > > > - break; > > > - BytesRemaining -= BytesPerElement; > > > - } > > > - // Enough elements are equal to account for the memcmp limit. > > > - return Success(0, E); > > > - } > > > - > > > bool StopAtNull = > > > (BuiltinOp != Builtin::BImemcmp && BuiltinOp != > > > Builtin::BIbcmp && > > > BuiltinOp != Builtin::BIwmemcmp && > > > @@ -11227,7 +11191,7 @@ bool > > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, > > > APValue Char1, Char2; > > > if (!ReadCurElems(Char1, Char2)) > > > return false; > > > - if (Char1.getInt() != Char2.getInt()) { > > > + if (Char1.getInt().ne(Char2.getInt())) { > > > if (IsWide) // wmemcmp compares with wchar_t signedness. > > > return Success(Char1.getInt() < Char2.getInt() ? -1 : 1, E); > > > // memcmp always compares unsigned chars. > > > > > > diff --git a/clang/test/SemaCXX/constexpr-string.cpp > > > b/clang/test/SemaCXX/constexpr-string.cpp > > > index f540be8f8e5b..79ac3bf2cc4d 100644 > > > --- a/clang/test/SemaCXX/constexpr-string.cpp > > > +++ b/clang/test/SemaCXX/constexpr-string.cpp > > > @@ -47,7 +47,7 @@ extern "C" { > > > extern wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n); > > > } > > > > > > -# 45 "SemaCXX/constexpr-string.cpp" 2 > > > +# 51 "SemaCXX/constexpr-string.cpp" 2 > > > namespace Strlen { > > > constexpr int n = __builtin_strlen("hello"); // ok > > > static_assert(n == 5); > > > @@ -121,13 +121,13 @@ namespace StrcmpEtc { > > > extern struct Incomplete incomplete; > > > static_assert(__builtin_memcmp(&incomplete, "", 0u) == 0); > > > static_assert(__builtin_memcmp("", &incomplete, 0u) == 0); > > > - static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // > > > expected-error {{not an integral constant}} expected-note {{read of > > > incomplete type 'struct Incomplete'}} > > > - static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // > > > expected-error {{not an integral constant}} expected-note {{read of > > > incomplete type 'struct Incomplete'}} > > > + static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // > > > expected-error {{not an integral constant}} expected-note {{not > > > supported}} > > > + static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // > > > expected-error {{not an integral constant}} expected-note {{not > > > supported}} > > > > > > static_assert(__builtin_bcmp(&incomplete, "", 0u) == 0); > > > static_assert(__builtin_bcmp("", &incomplete, 0u) == 0); > > > - static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // > > > expected-error {{not an integral constant}} expected-note {{read of > > > incomplete type 'struct Incomplete'}} > > > - static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // > > > expected-error {{not an integral constant}} expected-note {{read of > > > incomplete type 'struct Incomplete'}} > > > + static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // > > > expected-error {{not an integral constant}} expected-note {{not > > > supported}} > > > + static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // > > > expected-error {{not an integral constant}} expected-note {{not > > > supported}} > > > > > > constexpr unsigned char ku00fe00[] = {0x00, 0xfe, 0x00}; > > > constexpr unsigned char ku00feff[] = {0x00, 0xfe, 0xff}; > > > @@ -155,11 +155,11 @@ namespace StrcmpEtc { > > > > > > struct Bool3Tuple { bool bb[3]; }; > > > constexpr Bool3Tuple kb000100 = {{false, true, false}}; > > > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, > > > kb000100.bb, 1) == 0); > > > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, > > > kb000100.bb, 2) == 1); > > > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, > > > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note > > > {{not supported}} > > > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, > > > kb000100.bb, 2) == 1); // expected-error {{constant}} expected-note > > > {{not supported}} > > > > > > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, > > > kb000100.bb, 1) == 0); > > > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, > > > kb000100.bb, 2) != 0); > > > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, > > > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note > > > {{not supported}} > > > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, > > > kb000100.bb, 2) != 0); // expected-error {{constant}} expected-note > > > {{not supported}} > > > > > > constexpr long ksl[] = {0, -1}; > > > constexpr unsigned int kui[] = {0, 0u - 1}; > > > @@ -173,25 +173,25 @@ namespace StrcmpEtc { > > > return nullptr; > > > } > > > } > > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) - > > > 1) == 0); > > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + > > > 0) == 0); > > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + > > > 1) == 0); > > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) > - > > > 1) == 0); > > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) > + > > > 0) == 0); > > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) > + > > > 1) == 42); // expected-error {{not an integral constant}} > expected-note > > > {{dereferenced one-past-the-end}} > > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > > > sizeof(long) - 1) == 0); > > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > > > sizeof(long) + 0) == 0); > > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > > > sizeof(long) + 1) == 42); // expected-error {{not an integral > > > constant}} expected-note {{dereferenced one-past-the-end}} > > > - > > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - 1) > > > == 0); > > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 0) > > > == 0); > > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 1) > > > == 0); > > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) - > > > 1) == 0); > > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > > > 0) == 0); > > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > > > 1) == 42); // expected-error {{not an integral constant}} > expected-note > > > {{dereferenced one-past-the-end}} > > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > > > sizeof(long) - 1) == 0); > > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > > > sizeof(long) + 0) == 0); > > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > > > sizeof(long) + 1) == 42); // expected-error {{not an integral > > > constant}} expected-note {{dereferenced one-past-the-end}} > > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) - > > > 1) == 0); // expected-error {{constant}} expected-note {{not > supported}} > > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + > > > 0) == 0); // expected-error {{constant}} expected-note {{not > supported}} > > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + > > > 1) == 0); // expected-error {{constant}} expected-note {{not > supported}} > > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) > - > > > 1) == 0); // expected-error {{constant}} expected-note {{not > supported}} > > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) > + > > > 0) == 0); // expected-error {{constant}} expected-note {{not > supported}} > > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) > + > > > 1) == 42); // expected-error {{constant}} expected-note {{not > > > supported}} > > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > > > sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note > > > {{not supported}} > > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > > > sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note > > > {{not supported}} > > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, > > > sizeof(long) + 1) == 42); // expected-error {{constant}} expected-note > > > {{not supported}} > > > + > > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - 1) > > > == 0); // expected-error {{constant}} expected-note {{not supported}} > > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 0) > > > == 0); // expected-error {{constant}} expected-note {{not supported}} > > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 1) > > > == 0); // expected-error {{constant}} expected-note {{not supported}} > > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) - > > > 1) == 0); // expected-error {{constant}} expected-note {{not > supported}} > > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > > > 0) == 0); // expected-error {{constant}} expected-note {{not > supported}} > > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + > > > 1) == 42); // expected-error {{constant}} expected-note {{not > > > supported}} > > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > > > sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note > > > {{not supported}} > > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > > > sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note > > > {{not supported}} > > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, > > > sizeof(long) + 1) == 42); // expected-error {{constant}} expected-note > > > {{not supported}} > > > > > > constexpr int a = strcmp("hello", "world"); // expected-error > > > {{constant expression}} expected-note {{non-constexpr function > 'strcmp' > > > cannot be used in a constant expression}} > > > constexpr int b = strncmp("hello", "world", 3); // expected-error > > > {{constant expression}} expected-note {{non-constexpr function > > > 'strncmp' cannot be used in a constant expression}} > > > @@ -385,14 +385,14 @@ namespace StrchrEtc { > > > enum class E : unsigned char {}; > > > struct EPair { E e, f; }; > > > constexpr EPair ee{E{240}}; > > > - static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); > > > + static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); // > > > expected-error {{constant}} expected-note {{not supported}} > > > > > > constexpr bool kBool[] = {false, true, false}; > > > constexpr const bool *const kBoolPastTheEndPtr = kBool + 3; > > > - static_assert(sizeof(bool) != 1u || > > > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); > > > - static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, 0, > > > 99) == kBoolPastTheEndPtr - 1); > > > - static_assert(sizeof(bool) != 1u || > > > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); > > > - static_assert(sizeof(bool) != 1u || > > > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // > > > expected-error {{not an integral constant}} expected-note > > > {{dereferenced one-past-the-end}} > > > + static_assert(sizeof(bool) != 1u || > > > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); // > > > expected-error {{constant}} expected-note {{not supported}} > > > + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, 0, > > > 99) == kBoolPastTheEndPtr - 1); // expected-error {{constant}} > > > expected-note {{not supported}} > > > + static_assert(sizeof(bool) != 1u || > > > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); // > > > expected-error {{constant}} expected-note {{not supported}} > > > + static_assert(sizeof(bool) != 1u || > > > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // > > > expected-error {{constant}} expected-note {{not supported}} > > > > > > static_assert(__builtin_char_memchr(kStr, 'a', 0) == nullptr); > > > static_assert(__builtin_char_memchr(kStr, 'a', 1) == kStr); > > > > > > > > > > > > _______________________________________________ > > > cfe-commits mailing list > > > cfe-commits at lists.llvm.org > > > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > > > > > _______________________________________________ > > libcxx-dev mailing list > > libcxx-dev at lists.llvm.org > > https://lists.llvm.org/cgi-bin/mailman/listinfo/libcxx-dev > > > _______________________________________________ > cfe-commits mailing list > cfe-commits at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cfe-commits at lists.llvm.org Sun Apr 5 12:16:52 2020 From: cfe-commits at lists.llvm.org (Vince Bridgers via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 19:16:52 +0000 (UTC) Subject: [PATCH] D77507: [clangd] Fix HitMapping assertion in Tokens.cpp Message-ID: vabridgers created this revision. vabridgers added reviewers: ilya-biryukov, sammccall. Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous, MaskRay. Herald added a project: clang. Extend test cases for tokens, and remove assertion that is unneeded and hitting in Tokens.cpp. Fixes Bugzilla https://bugs.llvm.org/show_bug.cgi?id=45428 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77507 Files: clang/lib/Tooling/Syntax/Tokens.cpp clang/unittests/Tooling/Syntax/TokensTest.cpp Index: clang/unittests/Tooling/Syntax/TokensTest.cpp =================================================================== --- clang/unittests/Tooling/Syntax/TokensTest.cpp +++ clang/unittests/Tooling/Syntax/TokensTest.cpp @@ -484,6 +484,57 @@ ['EMPTY'_9, 'EMPTY_FUNC'_10) => [''_0, ''_0) ['EMPTY_FUNC'_10, ''_18) => [''_0, ''_0) )"}, + // Baseline case, bugz: https://bugs.llvm.org/show_bug.cgi?id=45428 + {R"cpp( + #define NUM 42 + #define M2(a1,...) {__VA_ARGS__;} + #define M1(a2,...) M2(a2,__VA_ARGS__) + void foo(void) { M1(0, NUM); } + )cpp", + R"(expanded tokens: + void foo ( void ) { { 42 ; } ; } +file './input.cpp' + spelled tokens: + # define NUM 42 # define M2 ( a1 , ... ) { __VA_ARGS__ ; } # define M1 ( a2 , ... ) M2 ( a2 , __VA_ARGS__ ) void foo ( void ) { M1 ( 0 , NUM ) ; } + mappings: + ['#'_0, 'void'_30) => ['void'_0, 'void'_0) + ['M1'_36, ';'_42) => ['{'_6, ';'_10) +)"}, + // Reproducer, bugz: https://bugs.llvm.org/show_bug.cgi?id=45428. + // Causes mapping miss when invoking tryConsumeSpelledUntil + {R"cpp( + #define NUM 42 + #define M2(a1,...) {__VA_ARGS__;} + #define M1(a2,...) M2(a2,__VA_ARGS__) + #define M0 M1 + void foo(void) { M0(0, NUM); } + )cpp", + R"(expanded tokens: + void foo ( void ) { { 42 ; } ; } +file './input.cpp' + spelled tokens: + # define NUM 42 # define M2 ( a1 , ... ) { __VA_ARGS__ ; } # define M1 ( a2 , ... ) M2 ( a2 , __VA_ARGS__ ) # define M0 M1 void foo ( void ) { M0 ( 0 , NUM ) ; } + mappings: + ['#'_0, 'void'_34) => ['void'_0, 'void'_0) + ['M0'_40, 'NUM'_44) => ['{'_6, ';'_10) + ['NUM'_44, ')'_45) => [';'_10, ';'_10) + [')'_45, ';'_46) => [';'_10, ';'_10) +)"}, + // Simplified version of new issue + {R"cpp( + #define N 42 + #define M0(a1) foo(a1) + M0(N); + )cpp", + R"(expanded tokens: + foo ( 42 ) ; +file './input.cpp' + spelled tokens: + # define N 42 # define M0 ( a1 ) foo ( a1 ) M0 ( N ) ; + mappings: + ['#'_0, 'M0'_14) => ['foo'_0, 'foo'_0) + ['M0'_14, ';'_18) => ['foo'_0, ';'_4) +)"}, // File ends with a macro replacement. {R"cpp( #define FOO 10+10; Index: clang/lib/Tooling/Syntax/Tokens.cpp =================================================================== --- clang/lib/Tooling/Syntax/Tokens.cpp +++ clang/lib/Tooling/Syntax/Tokens.cpp @@ -614,10 +614,7 @@ unsigned MappingBegin = SpelledIndex; ++SpelledIndex; - bool HitMapping = - tryConsumeSpelledUntil(File, EndOffset + 1, SpelledIndex).hasValue(); - (void)HitMapping; - assert(!HitMapping && "recursive macro expansion?"); + (void)tryConsumeSpelledUntil(File, EndOffset + 1, SpelledIndex).hasValue(); TokenBuffer::Mapping M; M.BeginExpanded = BeginExpanded; -------------- next part -------------- A non-text attachment was scrubbed... Name: D77507.255179.patch Type: text/x-patch Size: 2838 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 13:21:32 2020 From: cfe-commits at lists.llvm.org (Wenlei He via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 20:21:32 +0000 (UTC) Subject: [PATCH] D77484: [Vector] Pass VectLib to LTO backend so TLI build correct vector function list In-Reply-To: References: Message-ID: wenlei added a comment. > Linking against two vectlibs may cause name conflicts or other issues. Of all three supported match libraries, all functions from Accelerate are prefixed with `v`; all MASS library functions are suffixed with `_massv`; and all SVML functions are prefixed with `__svml_`. See `VecFuncs.def`. So at least the exported functions don't have name conflicts. > What happens today in a non-LTO build if conflicting veclib options are provided to different TUs? I think it will work, as long as used math libraries are all provided to linker. Even if not, I'm not sure if this is something we want to actively prevent from the use of fvectlib switch. fvectlib controls codegen/optimizer, and whether the resulting codegen can leads to linking problem (if any), is kind of orthogonal, and probably no different from a regular linking/symbol resolution problem if there're conflicts in the libraries provide. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77484/new/ https://reviews.llvm.org/D77484 From cfe-commits at lists.llvm.org Sun Apr 5 13:53:49 2020 From: cfe-commits at lists.llvm.org (Vince Bridgers via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 20:53:49 +0000 (UTC) Subject: [PATCH] D77507: [clangd] Fix HitMapping assertion in Tokens.cpp In-Reply-To: References: Message-ID: <3bb3709bc96cec35faf8de653d378ef8@localhost.localdomain> vabridgers updated this revision to Diff 255193. vabridgers added a comment. Remove extraneous test case Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77507/new/ https://reviews.llvm.org/D77507 Files: clang/lib/Tooling/Syntax/Tokens.cpp clang/unittests/Tooling/Syntax/TokensTest.cpp Index: clang/unittests/Tooling/Syntax/TokensTest.cpp =================================================================== --- clang/unittests/Tooling/Syntax/TokensTest.cpp +++ clang/unittests/Tooling/Syntax/TokensTest.cpp @@ -484,6 +484,42 @@ ['EMPTY'_9, 'EMPTY_FUNC'_10) => [''_0, ''_0) ['EMPTY_FUNC'_10, ''_18) => [''_0, ''_0) )"}, + // Baseline case, bugz: https://bugs.llvm.org/show_bug.cgi?id=45428 + {R"cpp( + #define NUM 42 + #define M2(a1,...) {__VA_ARGS__;} + #define M1(a2,...) M2(a2,__VA_ARGS__) + void foo(void) { M1(0, NUM); } + )cpp", + R"(expanded tokens: + void foo ( void ) { { 42 ; } ; } +file './input.cpp' + spelled tokens: + # define NUM 42 # define M2 ( a1 , ... ) { __VA_ARGS__ ; } # define M1 ( a2 , ... ) M2 ( a2 , __VA_ARGS__ ) void foo ( void ) { M1 ( 0 , NUM ) ; } + mappings: + ['#'_0, 'void'_30) => ['void'_0, 'void'_0) + ['M1'_36, ';'_42) => ['{'_6, ';'_10) +)"}, + // Reproducer, bugz: https://bugs.llvm.org/show_bug.cgi?id=45428. + // Causes mapping miss when invoking tryConsumeSpelledUntil + {R"cpp( + #define NUM 42 + #define M2(a1,...) {__VA_ARGS__;} + #define M1(a2,...) M2(a2,__VA_ARGS__) + #define M0 M1 + void foo(void) { M0(0, NUM); } + )cpp", + R"(expanded tokens: + void foo ( void ) { { 42 ; } ; } +file './input.cpp' + spelled tokens: + # define NUM 42 # define M2 ( a1 , ... ) { __VA_ARGS__ ; } # define M1 ( a2 , ... ) M2 ( a2 , __VA_ARGS__ ) # define M0 M1 void foo ( void ) { M0 ( 0 , NUM ) ; } + mappings: + ['#'_0, 'void'_34) => ['void'_0, 'void'_0) + ['M0'_40, 'NUM'_44) => ['{'_6, ';'_10) + ['NUM'_44, ')'_45) => [';'_10, ';'_10) + [')'_45, ';'_46) => [';'_10, ';'_10) +)"}, // File ends with a macro replacement. {R"cpp( #define FOO 10+10; Index: clang/lib/Tooling/Syntax/Tokens.cpp =================================================================== --- clang/lib/Tooling/Syntax/Tokens.cpp +++ clang/lib/Tooling/Syntax/Tokens.cpp @@ -614,10 +614,7 @@ unsigned MappingBegin = SpelledIndex; ++SpelledIndex; - bool HitMapping = - tryConsumeSpelledUntil(File, EndOffset + 1, SpelledIndex).hasValue(); - (void)HitMapping; - assert(!HitMapping && "recursive macro expansion?"); + (void)tryConsumeSpelledUntil(File, EndOffset + 1, SpelledIndex).hasValue(); TokenBuffer::Mapping M; M.BeginExpanded = BeginExpanded; -------------- next part -------------- A non-text attachment was scrubbed... Name: D77507.255193.patch Type: text/x-patch Size: 2461 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 14:44:52 2020 From: cfe-commits at lists.llvm.org (David Zarzycki via cfe-commits) Date: Sun, 5 Apr 2020 17:44:52 -0400 Subject: [libcxx-dev] [clang] 4ede887 - PR45402: Make the restrictions on constant evaluation of memcmp and In-Reply-To: References: Message-ID: <110D5BC7-412C-4E2E-85C8-54AA91D2EDA2@znu.io> We have overloaded builtins. Can that not solve __builtin_strlen? -- Sent from my iPhone > On Apr 5, 2020, at 14:53, Richard Smith wrote: > >  > Thanks. We need to figure out what the right way to support char8_t with string builtins is. These ones could work in principle, whereas things like __builtin_strlen would never work because they take operands of the wrong types (and we can't cast const char8_t* -> const char* in a constant expression). > >> On Sun, 5 Apr 2020 at 04:14, David Zarzycki via cfe-commits wrote: >> Hi Richard, >> >> I'm going to commit a narrow fix to clang to make the libcxx test suite pass again by allowing char8_t again. If you feel that this is the wrong long-term solution, please help the libcxx folks with whatever adjustments they need. >> >> Thanks! >> >> Dave >> >> >> On Sat, Apr 4, 2020, at 9:55 AM, David Zarzycki via libcxx-dev wrote: >> > Hi Richard, >> > >> > This breaks libcxx. Can we please revert this or is a quick fix to >> > libcxx possible? >> > >> > >> > FAIL: libc++ :: >> > std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp (58624 of 62672) >> > ******************** TEST 'libc++ :: >> > std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp' FAILED ******************** >> > Command: ['/p/tllvm/bin/clang++', '-o', >> > '/tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o', '-x', 'c++', '/home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp', '-c', '-v', '-Werror=thread-safety', '-std=c++2a', '-include', '/home/dave/s/lp/libcxx/test/support/nasty_macros.h', '-nostdinc++', '-I/home/dave/s/lp/libcxx/include', '-I/tmp/_update_lc/t/projects/libcxx/include/c++build', '-D__STDC_FORMAT_MACROS', '-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-I/home/dave/s/lp/libcxx/test/support', '-ftemplate-depth=270', '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER', '-Wall', '-Wextra', '-Werror', '-Wuser-defined-warnings', '-Wshadow', '-Wno-unused-command-line-argument', '-Wno-attributes', '-Wno-pessimizing-move', '-Wno-c++11-extensions', '-Wno-user-defined-literals', '-Wno-noexcept-type', '-Wsign-compare', '-Wunused-variable', '-Wunused-parameter', '-Wunreachable-code', '-c'] >> > Exit Code: 1 >> > Standard Error: >> > -- >> > clang version 11.0.0 (https://github.com/llvm/llvm-project.git >> > 22127da8f17c03c69231f3631472f7f99ad9cb7f) >> > Target: x86_64-unknown-linux-gnu >> > Thread model: posix >> > InstalledDir: /p/tllvm/bin >> > Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 >> > Selected GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 >> > Candidate multilib: .;@m64 >> > Candidate multilib: 32;@m32 >> > Selected multilib: .;@m64 >> > (in-process) >> > "/p/tllvm/bin/clang-11" -cc1 -triple x86_64-unknown-linux-gnu >> > -emit-obj -mrelax-all -disable-free -disable-llvm-verifier >> > -discard-value-names -main-file-name compare.pass.cpp >> > -mrelocation-model static -mthread-model posix -mframe-pointer=all >> > -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables >> > -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining >> > -debugger-tuning=gdb -v -nostdinc++ -resource-dir >> > /p/tllvm/lib64/clang/11.0.0 -include >> > /home/dave/s/lp/libcxx/test/support/nasty_macros.h -I >> > /home/dave/s/lp/libcxx/include -I >> > /tmp/_update_lc/t/projects/libcxx/include/c++build -D >> > __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS >> > -I /home/dave/s/lp/libcxx/test/support -D >> > _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -internal-isystem >> > /usr/local/include -internal-isystem >> > /p/tllvm/lib64/clang/11.0.0/include -internal-externc-isystem /include >> > -internal-externc-isystem /usr/include -Werror=thread-safety -Wall >> > -Wextra -Werror -Wuser-defined-warnings -Wshadow >> > -Wno-unused-command-line-argument -Wno-attributes -Wno-pessimizing-move >> > -Wno-c++11-extensions -Wno-user-defined-literals -Wno-noexcept-type >> > -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code >> > -std=c++2a -fdeprecated-macro -fdebug-compilation-dir >> > /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t -ftemplate-depth 270 -ferror-limit 19 -fgnuc-version=4.2.1 -fno-implicit-modules -fcxx-exceptions -fexceptions -faddrsig -o /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o -x c++ /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp >> > clang -cc1 version 11.0.0 based upon LLVM 11.0.0git default target >> > x86_64-unknown-linux-gnu >> > ignoring nonexistent directory "/include" >> > #include "..." search starts here: >> > #include <...> search starts here: >> > /home/dave/s/lp/libcxx/include >> > /tmp/_update_lc/t/projects/libcxx/include/c++build >> > /home/dave/s/lp/libcxx/test/support >> > /usr/local/include >> > /p/tllvm/lib64/clang/11.0.0/include >> > /usr/include >> > End of search list. >> > /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: error: static_assert expression is not an integral constant expression >> > static_assert(test_constexpr(), "" ); >> > ^~~~~~~~~~~~~~~~ >> > /home/dave/s/lp/libcxx/include/__string:662:12: note: constant >> > evaluation of '__builtin_memcmp' between arrays of types 'const >> > char8_t' and 'const char8_t' is not supported; only arrays of narrow >> > character types can be compared >> > return __builtin_memcmp(__s1, __s2, __n); >> > ^ >> > /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:24:12: note: in call to 'compare(&u8"123"[0], &u8"223"[0], 3)' >> > return std::char_traits::compare(u8"123", u8"223", 3) < 0 >> > ^ >> > /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: note: in call to 'test_constexpr()' >> > static_assert(test_constexpr(), "" ); >> > ^ >> > 1 error generated. >> > -- >> > >> > Compilation failed unexpectedly! >> > ******************** >> > >> > Testing Time: 135.49s >> > ******************** >> > Failing Tests (1): >> > libc++ :: >> > std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp >> > >> > Expected Passes : 45503 >> > Expected Failures : 118 >> > Unsupported Tests : 17050 >> > Unexpected Failures: 1 >> > >> > >> > On Fri, Apr 3, 2020, at 9:26 PM, Richard Smith via cfe-commits wrote: >> > > >> > > Author: Richard Smith >> > > Date: 2020-04-03T18:26:14-07:00 >> > > New Revision: 4ede8879924c08ae5b495d3f421c167d822a60be >> > > >> > > URL: >> > > https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be >> > > DIFF: >> > > https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be.diff >> > > >> > > LOG: PR45402: Make the restrictions on constant evaluation of memcmp and >> > > memchr consistent and comprehensible, and document them. >> > > >> > > We previously allowed evaluation of memcmp on arrays of integers of any >> > > size, so long as the call evaluated to 0, and allowed evaluation of >> > > memchr on any array of integral type of size 1 (including enums). The >> > > purpose of constant-evaluating these builtins is only to support >> > > constexpr std::char_traits, so we now consistently allow them on arrays >> > > of (possibly signed or unsigned) char only. >> > > >> > > Added: >> > > >> > > >> > > Modified: >> > > clang/docs/LanguageExtensions.rst >> > > clang/include/clang/Basic/DiagnosticASTKinds.td >> > > clang/lib/AST/ExprConstant.cpp >> > > clang/test/SemaCXX/constexpr-string.cpp >> > > >> > > Removed: >> > > >> > > >> > > >> > > ################################################################################ >> > > diff --git a/clang/docs/LanguageExtensions.rst >> > > b/clang/docs/LanguageExtensions.rst >> > > index 558ce7dee653..6dcfd1a49f06 100644 >> > > --- a/clang/docs/LanguageExtensions.rst >> > > +++ b/clang/docs/LanguageExtensions.rst >> > > @@ -2333,10 +2333,11 @@ String builtins >> > > --------------- >> > > >> > > Clang provides constant expression evaluation support for builtins forms of >> > > -the following functions from the C standard library ```` header: >> > > +the following functions from the C standard library headers >> > > +```` and ````: >> > > >> > > * ``memchr`` >> > > -* ``memcmp`` >> > > +* ``memcmp`` (and its deprecated BSD / POSIX alias ``bcmp``) >> > > * ``strchr`` >> > > * ``strcmp`` >> > > * ``strlen`` >> > > @@ -2366,7 +2367,11 @@ In addition to the above, one further builtin is >> > > provided: >> > > constant expressions in C++11 onwards (where a cast from ``void*`` to >> > > ``char*`` >> > > is disallowed in general). >> > > >> > > -Support for constant expression evaluation for the above builtins be >> > > detected >> > > +Constant evaluation support for the ``__builtin_mem*`` functions is >> > > provided >> > > +only for arrays of ``char``, ``signed char``, or ``unsigned char``, >> > > despite >> > > +these functions accepting an argument of type ``const void*``. >> > > + >> > > +Support for constant expression evaluation for the above builtins can >> > > be detected >> > > with ``__has_feature(cxx_constexpr_string_builtins)``. >> > > >> > > Memory builtins >> > > @@ -2386,6 +2391,25 @@ more information. >> > > >> > > Note that the `size` argument must be a compile time constant. >> > > >> > > +Clang provides constant expression evaluation support for builtin >> > > forms of the >> > > +following functions from the C standard library headers >> > > +```` and ````: >> > > + >> > > +* ``memcpy`` >> > > +* ``memmove`` >> > > +* ``wmemcpy`` >> > > +* ``wmemmove`` >> > > + >> > > +In each case, the builtin form has the name of the C library function >> > > prefixed >> > > +by ``__builtin_``. >> > > + >> > > +Constant evaluation support is only provided when the source and >> > > destination >> > > +are pointers to arrays with the same trivially copyable element type, >> > > and the >> > > +given size is an exact multiple of the element size that is no greater >> > > than >> > > +the number of elements accessible through the source and destination >> > > operands. >> > > + >> > > +Constant evaluation support is not yet provided for >> > > ``__builtin_memcpy_inline``. >> > > + >> > > Atomic Min/Max builtins with memory ordering >> > > -------------------------------------------- >> > > >> > > >> > > diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td >> > > b/clang/include/clang/Basic/DiagnosticASTKinds.td >> > > index 544573edffdf..a1415f9ec0e1 100644 >> > > --- a/clang/include/clang/Basic/DiagnosticASTKinds.td >> > > +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td >> > > @@ -244,6 +244,12 @@ def note_constexpr_unsupported_unsized_array : >> > > Note< >> > > def note_constexpr_unsized_array_indexed : Note< >> > > "indexing of array without known bound is not allowed " >> > > "in a constant expression">; >> > > +def note_constexpr_memcmp_unsupported : Note< >> > > + "constant evaluation of %0 between arrays of types %1 and %2 " >> > > + "is not supported; only arrays of narrow character types can be >> > > compared">; >> > > +def note_constexpr_memchr_unsupported : Note< >> > > + "constant evaluation of %0 on array of type %1 " >> > > + "is not supported; only arrays of narrow character types can be >> > > searched">; >> > > def note_constexpr_memcpy_null : Note< >> > > "%select{source|destination}2 of " >> > > "'%select{%select{memcpy|wmemcpy}1|%select{memmove|wmemmove}1}0' " >> > > >> > > diff --git a/clang/lib/AST/ExprConstant.cpp >> > > b/clang/lib/AST/ExprConstant.cpp >> > > index c6e1cc7b67df..a83b2e24e17f 100644 >> > > --- a/clang/lib/AST/ExprConstant.cpp >> > > +++ b/clang/lib/AST/ExprConstant.cpp >> > > @@ -8469,8 +8469,12 @@ bool >> > > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >> > > } >> > > // Give up on byte-oriented matching against multibyte elements. >> > > // FIXME: We can compare the bytes in the correct order. >> > > - if (IsRawByte && Info.Ctx.getTypeSizeInChars(CharTy) != >> > > CharUnits::One()) >> > > + if (IsRawByte && !CharTy->isCharType()) { >> > > + Info.FFDiag(E, diag::note_constexpr_memchr_unsupported) >> > > + << (std::string("'") + >> > > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") >> > > + << CharTy; >> > > return false; >> > > + } >> > > // Figure out what value we're actually looking for (after >> > > converting to >> > > // the corresponding unsigned type if necessary). >> > > uint64_t DesiredVal; >> > > @@ -8586,6 +8590,7 @@ bool >> > > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >> > > QualType T = Dest.Designator.getType(Info.Ctx); >> > > QualType SrcT = Src.Designator.getType(Info.Ctx); >> > > if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) { >> > > + // FIXME: Consider using our bit_cast implementation to support >> > > this. >> > > Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) << Move << >> > > SrcT << T; >> > > return false; >> > > } >> > > @@ -11149,6 +11154,16 @@ bool >> > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >> > > CharTy1, E->getArg(0)->getType()->getPointeeType()) && >> > > Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2))); >> > > >> > > + // For memcmp, allow comparing any arrays of '[[un]signed] char', >> > > + // but no other types. >> > > + if (IsRawByte && !(CharTy1->isCharType() && >> > > CharTy2->isCharType())) { >> > > + // FIXME: Consider using our bit_cast implementation to support >> > > this. >> > > + Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported) >> > > + << (std::string("'") + >> > > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") >> > > + << CharTy1 << CharTy2; >> > > + return false; >> > > + } >> > > + >> > > const auto &ReadCurElems = [&](APValue &Char1, APValue &Char2) { >> > > return handleLValueToRValueConversion(Info, E, CharTy1, String1, >> > > Char1) && >> > > handleLValueToRValueConversion(Info, E, CharTy2, String2, >> > > Char2) && >> > > @@ -11159,57 +11174,6 @@ bool >> > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >> > > HandleLValueArrayAdjustment(Info, E, String2, CharTy2, 1); >> > > }; >> > > >> > > - if (IsRawByte) { >> > > - uint64_t BytesRemaining = MaxLength; >> > > - // Pointers to const void may point to objects of incomplete >> > > type. >> > > - if (CharTy1->isIncompleteType()) { >> > > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << >> > > CharTy1; >> > > - return false; >> > > - } >> > > - if (CharTy2->isIncompleteType()) { >> > > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << >> > > CharTy2; >> > > - return false; >> > > - } >> > > - uint64_t CharTy1Width{Info.Ctx.getTypeSize(CharTy1)}; >> > > - CharUnits CharTy1Size = >> > > Info.Ctx.toCharUnitsFromBits(CharTy1Width); >> > > - // Give up on comparing between elements with disparate widths. >> > > - if (CharTy1Size != Info.Ctx.getTypeSizeInChars(CharTy2)) >> > > - return false; >> > > - uint64_t BytesPerElement = CharTy1Size.getQuantity(); >> > > - assert(BytesRemaining && "BytesRemaining should not be zero: the >> > > " >> > > - "following loop considers at least one >> > > element"); >> > > - while (true) { >> > > - APValue Char1, Char2; >> > > - if (!ReadCurElems(Char1, Char2)) >> > > - return false; >> > > - // We have compatible in-memory widths, but a possible type and >> > > - // (for `bool`) internal representation mismatch. >> > > - // Assuming two's complement representation, including 0 for >> > > `false` and >> > > - // 1 for `true`, we can check an appropriate number of >> > > elements for >> > > - // equality even if they are not byte-sized. >> > > - APSInt Char1InMem = Char1.getInt().extOrTrunc(CharTy1Width); >> > > - APSInt Char2InMem = Char2.getInt().extOrTrunc(CharTy1Width); >> > > - if (Char1InMem.ne(Char2InMem)) { >> > > - // If the elements are byte-sized, then we can produce a >> > > three-way >> > > - // comparison result in a straightforward manner. >> > > - if (BytesPerElement == 1u) { >> > > - // memcmp always compares unsigned chars. >> > > - return Success(Char1InMem.ult(Char2InMem) ? -1 : 1, E); >> > > - } >> > > - // The result is byte-order sensitive, and we have multibyte >> > > elements. >> > > - // FIXME: We can compare the remaining bytes in the correct >> > > order. >> > > - return false; >> > > - } >> > > - if (!AdvanceElems()) >> > > - return false; >> > > - if (BytesRemaining <= BytesPerElement) >> > > - break; >> > > - BytesRemaining -= BytesPerElement; >> > > - } >> > > - // Enough elements are equal to account for the memcmp limit. >> > > - return Success(0, E); >> > > - } >> > > - >> > > bool StopAtNull = >> > > (BuiltinOp != Builtin::BImemcmp && BuiltinOp != >> > > Builtin::BIbcmp && >> > > BuiltinOp != Builtin::BIwmemcmp && >> > > @@ -11227,7 +11191,7 @@ bool >> > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >> > > APValue Char1, Char2; >> > > if (!ReadCurElems(Char1, Char2)) >> > > return false; >> > > - if (Char1.getInt() != Char2.getInt()) { >> > > + if (Char1.getInt().ne(Char2.getInt())) { >> > > if (IsWide) // wmemcmp compares with wchar_t signedness. >> > > return Success(Char1.getInt() < Char2.getInt() ? -1 : 1, E); >> > > // memcmp always compares unsigned chars. >> > > >> > > diff --git a/clang/test/SemaCXX/constexpr-string.cpp >> > > b/clang/test/SemaCXX/constexpr-string.cpp >> > > index f540be8f8e5b..79ac3bf2cc4d 100644 >> > > --- a/clang/test/SemaCXX/constexpr-string.cpp >> > > +++ b/clang/test/SemaCXX/constexpr-string.cpp >> > > @@ -47,7 +47,7 @@ extern "C" { >> > > extern wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n); >> > > } >> > > >> > > -# 45 "SemaCXX/constexpr-string.cpp" 2 >> > > +# 51 "SemaCXX/constexpr-string.cpp" 2 >> > > namespace Strlen { >> > > constexpr int n = __builtin_strlen("hello"); // ok >> > > static_assert(n == 5); >> > > @@ -121,13 +121,13 @@ namespace StrcmpEtc { >> > > extern struct Incomplete incomplete; >> > > static_assert(__builtin_memcmp(&incomplete, "", 0u) == 0); >> > > static_assert(__builtin_memcmp("", &incomplete, 0u) == 0); >> > > - static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{read of >> > > incomplete type 'struct Incomplete'}} >> > > - static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{read of >> > > incomplete type 'struct Incomplete'}} >> > > + static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{not >> > > supported}} >> > > + static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{not >> > > supported}} >> > > >> > > static_assert(__builtin_bcmp(&incomplete, "", 0u) == 0); >> > > static_assert(__builtin_bcmp("", &incomplete, 0u) == 0); >> > > - static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{read of >> > > incomplete type 'struct Incomplete'}} >> > > - static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{read of >> > > incomplete type 'struct Incomplete'}} >> > > + static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{not >> > > supported}} >> > > + static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{not >> > > supported}} >> > > >> > > constexpr unsigned char ku00fe00[] = {0x00, 0xfe, 0x00}; >> > > constexpr unsigned char ku00feff[] = {0x00, 0xfe, 0xff}; >> > > @@ -155,11 +155,11 @@ namespace StrcmpEtc { >> > > >> > > struct Bool3Tuple { bool bb[3]; }; >> > > constexpr Bool3Tuple kb000100 = {{false, true, false}}; >> > > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >> > > kb000100.bb, 1) == 0); >> > > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >> > > kb000100.bb, 2) == 1); >> > > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >> > > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >> > > kb000100.bb, 2) == 1); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > >> > > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >> > > kb000100.bb, 1) == 0); >> > > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >> > > kb000100.bb, 2) != 0); >> > > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >> > > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >> > > kb000100.bb, 2) != 0); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > >> > > constexpr long ksl[] = {0, -1}; >> > > constexpr unsigned int kui[] = {0, 0u - 1}; >> > > @@ -173,25 +173,25 @@ namespace StrcmpEtc { >> > > return nullptr; >> > > } >> > > } >> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) - >> > > 1) == 0); >> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + >> > > 0) == 0); >> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + >> > > 1) == 0); >> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) - >> > > 1) == 0); >> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >> > > 0) == 0); >> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >> > > 1) == 42); // expected-error {{not an integral constant}} expected-note >> > > {{dereferenced one-past-the-end}} >> > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) - 1) == 0); >> > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 0) == 0); >> > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 1) == 42); // expected-error {{not an integral >> > > constant}} expected-note {{dereferenced one-past-the-end}} >> > > - >> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - 1) >> > > == 0); >> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 0) >> > > == 0); >> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 1) >> > > == 0); >> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) - >> > > 1) == 0); >> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >> > > 0) == 0); >> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >> > > 1) == 42); // expected-error {{not an integral constant}} expected-note >> > > {{dereferenced one-past-the-end}} >> > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) - 1) == 0); >> > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 0) == 0); >> > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 1) == 42); // expected-error {{not an integral >> > > constant}} expected-note {{dereferenced one-past-the-end}} >> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) - >> > > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + >> > > 0) == 0); // expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + >> > > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) - >> > > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >> > > 0) == 0); // expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >> > > 1) == 42); // expected-error {{constant}} expected-note {{not >> > > supported}} >> > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 1) == 42); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > + >> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - 1) >> > > == 0); // expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 0) >> > > == 0); // expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 1) >> > > == 0); // expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) - >> > > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >> > > 0) == 0); // expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >> > > 1) == 42); // expected-error {{constant}} expected-note {{not >> > > supported}} >> > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 1) == 42); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > >> > > constexpr int a = strcmp("hello", "world"); // expected-error >> > > {{constant expression}} expected-note {{non-constexpr function 'strcmp' >> > > cannot be used in a constant expression}} >> > > constexpr int b = strncmp("hello", "world", 3); // expected-error >> > > {{constant expression}} expected-note {{non-constexpr function >> > > 'strncmp' cannot be used in a constant expression}} >> > > @@ -385,14 +385,14 @@ namespace StrchrEtc { >> > > enum class E : unsigned char {}; >> > > struct EPair { E e, f; }; >> > > constexpr EPair ee{E{240}}; >> > > - static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); >> > > + static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); // >> > > expected-error {{constant}} expected-note {{not supported}} >> > > >> > > constexpr bool kBool[] = {false, true, false}; >> > > constexpr const bool *const kBoolPastTheEndPtr = kBool + 3; >> > > - static_assert(sizeof(bool) != 1u || >> > > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); >> > > - static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, 0, >> > > 99) == kBoolPastTheEndPtr - 1); >> > > - static_assert(sizeof(bool) != 1u || >> > > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); >> > > - static_assert(sizeof(bool) != 1u || >> > > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // >> > > expected-error {{not an integral constant}} expected-note >> > > {{dereferenced one-past-the-end}} >> > > + static_assert(sizeof(bool) != 1u || >> > > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); // >> > > expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, 0, >> > > 99) == kBoolPastTheEndPtr - 1); // expected-error {{constant}} >> > > expected-note {{not supported}} >> > > + static_assert(sizeof(bool) != 1u || >> > > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); // >> > > expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(sizeof(bool) != 1u || >> > > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // >> > > expected-error {{constant}} expected-note {{not supported}} >> > > >> > > static_assert(__builtin_char_memchr(kStr, 'a', 0) == nullptr); >> > > static_assert(__builtin_char_memchr(kStr, 'a', 1) == kStr); >> > > >> > > >> > > >> > > _______________________________________________ >> > > cfe-commits mailing list >> > > cfe-commits at lists.llvm.org >> > > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > > >> > _______________________________________________ >> > libcxx-dev mailing list >> > libcxx-dev at lists.llvm.org >> > https://lists.llvm.org/cgi-bin/mailman/listinfo/libcxx-dev >> > >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits at lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits -------------- next part -------------- An HTML attachment was scrubbed... URL: From cfe-commits at lists.llvm.org Sun Apr 5 14:57:57 2020 From: cfe-commits at lists.llvm.org (Teresa Johnson via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 21:57:57 +0000 (UTC) Subject: [PATCH] D77484: [Vector] Pass VectLib to LTO backend so TLI build correct vector function list In-Reply-To: References: Message-ID: tejohnson added a comment. In D77484#1962667 , @wenlei wrote: > > Linking against two vectlibs may cause name conflicts or other issues. > > Of all three supported match libraries, all functions from Accelerate are prefixed with `v`; all MASS library functions are suffixed with `_massv`; and all SVML functions are prefixed with `__svml_`. See `VecFuncs.def`. So at least the exported functions don't have name conflicts. Ok then it does sound like these could be handled on a per-function basis, similar to how -fno-builtin* are handled. I.e. a function attribute to indicate the veclib, which would then be naturally preserved during LTO even after merging/importing across modules. Similar to how -fno-builtin* are handled, these would need to be examined when inlining (see the new TargetLibraryInfo::areInlineCompatible). Presumably we would want to block inlining between functions with different veclib attributes in the LTO backends. > > >> What happens today in a non-LTO build if conflicting veclib options are provided to different TUs? > > I think it will work, as long as used math libraries are all provided to linker. Even if not, I'm not sure if this is something we want to actively prevent from the use of fvectlib switch. fvectlib controls codegen/optimizer, and whether the resulting codegen can leads to linking problem (if any), is kind of orthogonal, and probably no different from a regular linking/symbol resolution problem if there're conflicts in the libraries provide. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77484/new/ https://reviews.llvm.org/D77484 From cfe-commits at lists.llvm.org Sun Apr 5 15:17:43 2020 From: cfe-commits at lists.llvm.org (Richard Smith via cfe-commits) Date: Sun, 5 Apr 2020 15:17:43 -0700 Subject: [libcxx-dev] [clang] 4ede887 - PR45402: Make the restrictions on constant evaluation of memcmp and In-Reply-To: <110D5BC7-412C-4E2E-85C8-54AA91D2EDA2@znu.io> References: <110D5BC7-412C-4E2E-85C8-54AA91D2EDA2@znu.io> Message-ID: On Sun, 5 Apr 2020 at 14:44, David Zarzycki via cfe-commits < cfe-commits at lists.llvm.org> wrote: > We have overloaded builtins. Can that not solve __builtin_strlen? > I suppose it could, but we generally want __builtin_ to behave the same as . (The difference would not be visible most of the time, but there's enough pre-existing use of __builtin_strlen through "clever" macros and the like that I'd be worried that this would break something important.) Maybe we should just make the mem* functions work again for char8_t; then you can use __builtin_memchr(p, 0) - p as an optimized compile-time strlen. > -- > Sent from my iPhone > > On Apr 5, 2020, at 14:53, Richard Smith wrote: > >  > Thanks. We need to figure out what the right way to support char8_t with > string builtins is. These ones could work in principle, whereas things like > __builtin_strlen would never work because they take operands of the wrong > types (and we can't cast const char8_t* -> const char* in a constant > expression). > > On Sun, 5 Apr 2020 at 04:14, David Zarzycki via cfe-commits < > cfe-commits at lists.llvm.org> wrote: > >> Hi Richard, >> >> I'm going to commit a narrow fix to clang to make the libcxx test suite >> pass again by allowing char8_t again. If you feel that this is the wrong >> long-term solution, please help the libcxx folks with whatever adjustments >> they need. >> >> Thanks! >> >> Dave >> >> >> On Sat, Apr 4, 2020, at 9:55 AM, David Zarzycki via libcxx-dev wrote: >> > Hi Richard, >> > >> > This breaks libcxx. Can we please revert this or is a quick fix to >> > libcxx possible? >> > >> > >> > FAIL: libc++ :: >> > >> std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp >> (58624 of 62672) >> > ******************** TEST 'libc++ :: >> > >> std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp' >> FAILED ******************** >> > Command: ['/p/tllvm/bin/clang++', '-o', >> > >> '/tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o', >> '-x', 'c++', >> '/home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp', >> '-c', '-v', '-Werror=thread-safety', '-std=c++2a', '-include', >> '/home/dave/s/lp/libcxx/test/support/nasty_macros.h', '-nostdinc++', >> '-I/home/dave/s/lp/libcxx/include', >> '-I/tmp/_update_lc/t/projects/libcxx/include/c++build', >> '-D__STDC_FORMAT_MACROS', '-D__STDC_LIMIT_MACROS', >> '-D__STDC_CONSTANT_MACROS', '-I/home/dave/s/lp/libcxx/test/support', >> '-ftemplate-depth=270', '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER', '-Wall', >> '-Wextra', '-Werror', '-Wuser-defined-warnings', '-Wshadow', >> '-Wno-unused-command-line-argument', '-Wno-attributes', >> '-Wno-pessimizing-move', '-Wno-c++11-extensions', >> '-Wno-user-defined-literals', '-Wno-noexcept-type', '-Wsign-compare', >> '-Wunused-variable', '-Wunused-parameter', '-Wunreachable-code', '-c'] >> > Exit Code: 1 >> > Standard Error: >> > -- >> > clang version 11.0.0 (https://github.com/llvm/llvm-project.git >> > 22127da8f17c03c69231f3631472f7f99ad9cb7f) >> > Target: x86_64-unknown-linux-gnu >> > Thread model: posix >> > InstalledDir: /p/tllvm/bin >> > Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 >> > Selected GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 >> > Candidate multilib: .;@m64 >> > Candidate multilib: 32;@m32 >> > Selected multilib: .;@m64 >> > (in-process) >> > "/p/tllvm/bin/clang-11" -cc1 -triple x86_64-unknown-linux-gnu >> > -emit-obj -mrelax-all -disable-free -disable-llvm-verifier >> > -discard-value-names -main-file-name compare.pass.cpp >> > -mrelocation-model static -mthread-model posix -mframe-pointer=all >> > -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables >> > -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining >> > -debugger-tuning=gdb -v -nostdinc++ -resource-dir >> > /p/tllvm/lib64/clang/11.0.0 -include >> > /home/dave/s/lp/libcxx/test/support/nasty_macros.h -I >> > /home/dave/s/lp/libcxx/include -I >> > /tmp/_update_lc/t/projects/libcxx/include/c++build -D >> > __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS >> > -I /home/dave/s/lp/libcxx/test/support -D >> > _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -internal-isystem >> > /usr/local/include -internal-isystem >> > /p/tllvm/lib64/clang/11.0.0/include -internal-externc-isystem /include >> > -internal-externc-isystem /usr/include -Werror=thread-safety -Wall >> > -Wextra -Werror -Wuser-defined-warnings -Wshadow >> > -Wno-unused-command-line-argument -Wno-attributes -Wno-pessimizing-move >> > -Wno-c++11-extensions -Wno-user-defined-literals -Wno-noexcept-type >> > -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code >> > -std=c++2a -fdeprecated-macro -fdebug-compilation-dir >> > >> /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t >> -ftemplate-depth 270 -ferror-limit 19 -fgnuc-version=4.2.1 >> -fno-implicit-modules -fcxx-exceptions -fexceptions -faddrsig -o >> /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o >> -x c++ >> /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp >> > clang -cc1 version 11.0.0 based upon LLVM 11.0.0git default target >> > x86_64-unknown-linux-gnu >> > ignoring nonexistent directory "/include" >> > #include "..." search starts here: >> > #include <...> search starts here: >> > /home/dave/s/lp/libcxx/include >> > /tmp/_update_lc/t/projects/libcxx/include/c++build >> > /home/dave/s/lp/libcxx/test/support >> > /usr/local/include >> > /p/tllvm/lib64/clang/11.0.0/include >> > /usr/include >> > End of search list. >> > >> /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: >> error: static_assert expression is not an integral constant expression >> > static_assert(test_constexpr(), "" ); >> > ^~~~~~~~~~~~~~~~ >> > /home/dave/s/lp/libcxx/include/__string:662:12: note: constant >> > evaluation of '__builtin_memcmp' between arrays of types 'const >> > char8_t' and 'const char8_t' is not supported; only arrays of narrow >> > character types can be compared >> > return __builtin_memcmp(__s1, __s2, __n); >> > ^ >> > >> /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:24:12: >> note: in call to 'compare(&u8"123"[0], &u8"223"[0], 3)' >> > return std::char_traits::compare(u8"123", u8"223", 3) < 0 >> > ^ >> > >> /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: >> note: in call to 'test_constexpr()' >> > static_assert(test_constexpr(), "" ); >> > ^ >> > 1 error generated. >> > -- >> > >> > Compilation failed unexpectedly! >> > ******************** >> > >> > Testing Time: 135.49s >> > ******************** >> > Failing Tests (1): >> > libc++ :: >> > >> std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp >> > >> > Expected Passes : 45503 >> > Expected Failures : 118 >> > Unsupported Tests : 17050 >> > Unexpected Failures: 1 >> > >> > >> > On Fri, Apr 3, 2020, at 9:26 PM, Richard Smith via cfe-commits wrote: >> > > >> > > Author: Richard Smith >> > > Date: 2020-04-03T18:26:14-07:00 >> > > New Revision: 4ede8879924c08ae5b495d3f421c167d822a60be >> > > >> > > URL: >> > > >> https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be >> > > DIFF: >> > > >> https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be.diff >> > > >> > > LOG: PR45402: Make the restrictions on constant evaluation of memcmp >> and >> > > memchr consistent and comprehensible, and document them. >> > > >> > > We previously allowed evaluation of memcmp on arrays of integers of >> any >> > > size, so long as the call evaluated to 0, and allowed evaluation of >> > > memchr on any array of integral type of size 1 (including enums). The >> > > purpose of constant-evaluating these builtins is only to support >> > > constexpr std::char_traits, so we now consistently allow them on >> arrays >> > > of (possibly signed or unsigned) char only. >> > > >> > > Added: >> > > >> > > >> > > Modified: >> > > clang/docs/LanguageExtensions.rst >> > > clang/include/clang/Basic/DiagnosticASTKinds.td >> > > clang/lib/AST/ExprConstant.cpp >> > > clang/test/SemaCXX/constexpr-string.cpp >> > > >> > > Removed: >> > > >> > > >> > > >> > > >> ################################################################################ >> > > diff --git a/clang/docs/LanguageExtensions.rst >> > > b/clang/docs/LanguageExtensions.rst >> > > index 558ce7dee653..6dcfd1a49f06 100644 >> > > --- a/clang/docs/LanguageExtensions.rst >> > > +++ b/clang/docs/LanguageExtensions.rst >> > > @@ -2333,10 +2333,11 @@ String builtins >> > > --------------- >> > > >> > > Clang provides constant expression evaluation support for builtins >> forms of >> > > -the following functions from the C standard library ```` >> header: >> > > +the following functions from the C standard library headers >> > > +```` and ````: >> > > >> > > * ``memchr`` >> > > -* ``memcmp`` >> > > +* ``memcmp`` (and its deprecated BSD / POSIX alias ``bcmp``) >> > > * ``strchr`` >> > > * ``strcmp`` >> > > * ``strlen`` >> > > @@ -2366,7 +2367,11 @@ In addition to the above, one further builtin >> is >> > > provided: >> > > constant expressions in C++11 onwards (where a cast from ``void*`` >> to >> > > ``char*`` >> > > is disallowed in general). >> > > >> > > -Support for constant expression evaluation for the above builtins be >> > > detected >> > > +Constant evaluation support for the ``__builtin_mem*`` functions is >> > > provided >> > > +only for arrays of ``char``, ``signed char``, or ``unsigned char``, >> > > despite >> > > +these functions accepting an argument of type ``const void*``. >> > > + >> > > +Support for constant expression evaluation for the above builtins >> can >> > > be detected >> > > with ``__has_feature(cxx_constexpr_string_builtins)``. >> > > >> > > Memory builtins >> > > @@ -2386,6 +2391,25 @@ more information. >> > > >> > > Note that the `size` argument must be a compile time constant. >> > > >> > > +Clang provides constant expression evaluation support for builtin >> > > forms of the >> > > +following functions from the C standard library headers >> > > +```` and ````: >> > > + >> > > +* ``memcpy`` >> > > +* ``memmove`` >> > > +* ``wmemcpy`` >> > > +* ``wmemmove`` >> > > + >> > > +In each case, the builtin form has the name of the C library >> function >> > > prefixed >> > > +by ``__builtin_``. >> > > + >> > > +Constant evaluation support is only provided when the source and >> > > destination >> > > +are pointers to arrays with the same trivially copyable element >> type, >> > > and the >> > > +given size is an exact multiple of the element size that is no >> greater >> > > than >> > > +the number of elements accessible through the source and destination >> > > operands. >> > > + >> > > +Constant evaluation support is not yet provided for >> > > ``__builtin_memcpy_inline``. >> > > + >> > > Atomic Min/Max builtins with memory ordering >> > > -------------------------------------------- >> > > >> > > >> > > diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td >> > > b/clang/include/clang/Basic/DiagnosticASTKinds.td >> > > index 544573edffdf..a1415f9ec0e1 100644 >> > > --- a/clang/include/clang/Basic/DiagnosticASTKinds.td >> > > +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td >> > > @@ -244,6 +244,12 @@ def note_constexpr_unsupported_unsized_array : >> > > Note< >> > > def note_constexpr_unsized_array_indexed : Note< >> > > "indexing of array without known bound is not allowed " >> > > "in a constant expression">; >> > > +def note_constexpr_memcmp_unsupported : Note< >> > > + "constant evaluation of %0 between arrays of types %1 and %2 " >> > > + "is not supported; only arrays of narrow character types can be >> > > compared">; >> > > +def note_constexpr_memchr_unsupported : Note< >> > > + "constant evaluation of %0 on array of type %1 " >> > > + "is not supported; only arrays of narrow character types can be >> > > searched">; >> > > def note_constexpr_memcpy_null : Note< >> > > "%select{source|destination}2 of " >> > > "'%select{%select{memcpy|wmemcpy}1|%select{memmove|wmemmove}1}0' " >> > > >> > > diff --git a/clang/lib/AST/ExprConstant.cpp >> > > b/clang/lib/AST/ExprConstant.cpp >> > > index c6e1cc7b67df..a83b2e24e17f 100644 >> > > --- a/clang/lib/AST/ExprConstant.cpp >> > > +++ b/clang/lib/AST/ExprConstant.cpp >> > > @@ -8469,8 +8469,12 @@ bool >> > > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >> > > } >> > > // Give up on byte-oriented matching against multibyte elements. >> > > // FIXME: We can compare the bytes in the correct order. >> > > - if (IsRawByte && Info.Ctx.getTypeSizeInChars(CharTy) != >> > > CharUnits::One()) >> > > + if (IsRawByte && !CharTy->isCharType()) { >> > > + Info.FFDiag(E, diag::note_constexpr_memchr_unsupported) >> > > + << (std::string("'") + >> > > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") >> > > + << CharTy; >> > > return false; >> > > + } >> > > // Figure out what value we're actually looking for (after >> > > converting to >> > > // the corresponding unsigned type if necessary). >> > > uint64_t DesiredVal; >> > > @@ -8586,6 +8590,7 @@ bool >> > > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >> > > QualType T = Dest.Designator.getType(Info.Ctx); >> > > QualType SrcT = Src.Designator.getType(Info.Ctx); >> > > if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) { >> > > + // FIXME: Consider using our bit_cast implementation to >> support >> > > this. >> > > Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) << Move >> << >> > > SrcT << T; >> > > return false; >> > > } >> > > @@ -11149,6 +11154,16 @@ bool >> > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >> > > CharTy1, E->getArg(0)->getType()->getPointeeType()) >> && >> > > Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2))); >> > > >> > > + // For memcmp, allow comparing any arrays of '[[un]signed] char', >> > > + // but no other types. >> > > + if (IsRawByte && !(CharTy1->isCharType() && >> > > CharTy2->isCharType())) { >> > > + // FIXME: Consider using our bit_cast implementation to >> support >> > > this. >> > > + Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported) >> > > + << (std::string("'") + >> > > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") >> > > + << CharTy1 << CharTy2; >> > > + return false; >> > > + } >> > > + >> > > const auto &ReadCurElems = [&](APValue &Char1, APValue &Char2) { >> > > return handleLValueToRValueConversion(Info, E, CharTy1, >> String1, >> > > Char1) && >> > > handleLValueToRValueConversion(Info, E, CharTy2, >> String2, >> > > Char2) && >> > > @@ -11159,57 +11174,6 @@ bool >> > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >> > > HandleLValueArrayAdjustment(Info, E, String2, CharTy2, >> 1); >> > > }; >> > > >> > > - if (IsRawByte) { >> > > - uint64_t BytesRemaining = MaxLength; >> > > - // Pointers to const void may point to objects of incomplete >> > > type. >> > > - if (CharTy1->isIncompleteType()) { >> > > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << >> > > CharTy1; >> > > - return false; >> > > - } >> > > - if (CharTy2->isIncompleteType()) { >> > > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << >> > > CharTy2; >> > > - return false; >> > > - } >> > > - uint64_t CharTy1Width{Info.Ctx.getTypeSize(CharTy1)}; >> > > - CharUnits CharTy1Size = >> > > Info.Ctx.toCharUnitsFromBits(CharTy1Width); >> > > - // Give up on comparing between elements with disparate widths. >> > > - if (CharTy1Size != Info.Ctx.getTypeSizeInChars(CharTy2)) >> > > - return false; >> > > - uint64_t BytesPerElement = CharTy1Size.getQuantity(); >> > > - assert(BytesRemaining && "BytesRemaining should not be zero: >> the >> > > " >> > > - "following loop considers at least >> one >> > > element"); >> > > - while (true) { >> > > - APValue Char1, Char2; >> > > - if (!ReadCurElems(Char1, Char2)) >> > > - return false; >> > > - // We have compatible in-memory widths, but a possible type >> and >> > > - // (for `bool`) internal representation mismatch. >> > > - // Assuming two's complement representation, including 0 for >> > > `false` and >> > > - // 1 for `true`, we can check an appropriate number of >> > > elements for >> > > - // equality even if they are not byte-sized. >> > > - APSInt Char1InMem = Char1.getInt().extOrTrunc(CharTy1Width); >> > > - APSInt Char2InMem = Char2.getInt().extOrTrunc(CharTy1Width); >> > > - if (Char1InMem.ne(Char2InMem)) { >> > > - // If the elements are byte-sized, then we can produce a >> > > three-way >> > > - // comparison result in a straightforward manner. >> > > - if (BytesPerElement == 1u) { >> > > - // memcmp always compares unsigned chars. >> > > - return Success(Char1InMem.ult(Char2InMem) ? -1 : 1, E); >> > > - } >> > > - // The result is byte-order sensitive, and we have >> multibyte >> > > elements. >> > > - // FIXME: We can compare the remaining bytes in the >> correct >> > > order. >> > > - return false; >> > > - } >> > > - if (!AdvanceElems()) >> > > - return false; >> > > - if (BytesRemaining <= BytesPerElement) >> > > - break; >> > > - BytesRemaining -= BytesPerElement; >> > > - } >> > > - // Enough elements are equal to account for the memcmp limit. >> > > - return Success(0, E); >> > > - } >> > > - >> > > bool StopAtNull = >> > > (BuiltinOp != Builtin::BImemcmp && BuiltinOp != >> > > Builtin::BIbcmp && >> > > BuiltinOp != Builtin::BIwmemcmp && >> > > @@ -11227,7 +11191,7 @@ bool >> > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >> > > APValue Char1, Char2; >> > > if (!ReadCurElems(Char1, Char2)) >> > > return false; >> > > - if (Char1.getInt() != Char2.getInt()) { >> > > + if (Char1.getInt().ne(Char2.getInt())) { >> > > if (IsWide) // wmemcmp compares with wchar_t signedness. >> > > return Success(Char1.getInt() < Char2.getInt() ? -1 : 1, >> E); >> > > // memcmp always compares unsigned chars. >> > > >> > > diff --git a/clang/test/SemaCXX/constexpr-string.cpp >> > > b/clang/test/SemaCXX/constexpr-string.cpp >> > > index f540be8f8e5b..79ac3bf2cc4d 100644 >> > > --- a/clang/test/SemaCXX/constexpr-string.cpp >> > > +++ b/clang/test/SemaCXX/constexpr-string.cpp >> > > @@ -47,7 +47,7 @@ extern "C" { >> > > extern wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n); >> > > } >> > > >> > > -# 45 "SemaCXX/constexpr-string.cpp" 2 >> > > +# 51 "SemaCXX/constexpr-string.cpp" 2 >> > > namespace Strlen { >> > > constexpr int n = __builtin_strlen("hello"); // ok >> > > static_assert(n == 5); >> > > @@ -121,13 +121,13 @@ namespace StrcmpEtc { >> > > extern struct Incomplete incomplete; >> > > static_assert(__builtin_memcmp(&incomplete, "", 0u) == 0); >> > > static_assert(__builtin_memcmp("", &incomplete, 0u) == 0); >> > > - static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{read of >> > > incomplete type 'struct Incomplete'}} >> > > - static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{read of >> > > incomplete type 'struct Incomplete'}} >> > > + static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{not >> > > supported}} >> > > + static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{not >> > > supported}} >> > > >> > > static_assert(__builtin_bcmp(&incomplete, "", 0u) == 0); >> > > static_assert(__builtin_bcmp("", &incomplete, 0u) == 0); >> > > - static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{read of >> > > incomplete type 'struct Incomplete'}} >> > > - static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{read of >> > > incomplete type 'struct Incomplete'}} >> > > + static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{not >> > > supported}} >> > > + static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // >> > > expected-error {{not an integral constant}} expected-note {{not >> > > supported}} >> > > >> > > constexpr unsigned char ku00fe00[] = {0x00, 0xfe, 0x00}; >> > > constexpr unsigned char ku00feff[] = {0x00, 0xfe, 0xff}; >> > > @@ -155,11 +155,11 @@ namespace StrcmpEtc { >> > > >> > > struct Bool3Tuple { bool bb[3]; }; >> > > constexpr Bool3Tuple kb000100 = {{false, true, false}}; >> > > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >> > > kb000100.bb, 1) == 0); >> > > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >> > > kb000100.bb, 2) == 1); >> > > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >> > > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >> > > kb000100.bb, 2) == 1); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > >> > > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >> > > kb000100.bb, 1) == 0); >> > > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >> > > kb000100.bb, 2) != 0); >> > > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >> > > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >> > > kb000100.bb, 2) != 0); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > >> > > constexpr long ksl[] = {0, -1}; >> > > constexpr unsigned int kui[] = {0, 0u - 1}; >> > > @@ -173,25 +173,25 @@ namespace StrcmpEtc { >> > > return nullptr; >> > > } >> > > } >> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) - >> > > 1) == 0); >> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + >> > > 0) == 0); >> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + >> > > 1) == 0); >> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) >> - >> > > 1) == 0); >> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) >> + >> > > 0) == 0); >> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) >> + >> > > 1) == 42); // expected-error {{not an integral constant}} >> expected-note >> > > {{dereferenced one-past-the-end}} >> > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) - 1) == 0); >> > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 0) == 0); >> > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 1) == 42); // expected-error {{not an integral >> > > constant}} expected-note {{dereferenced one-past-the-end}} >> > > - >> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - >> 1) >> > > == 0); >> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + >> 0) >> > > == 0); >> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + >> 1) >> > > == 0); >> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) - >> > > 1) == 0); >> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >> > > 0) == 0); >> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >> > > 1) == 42); // expected-error {{not an integral constant}} >> expected-note >> > > {{dereferenced one-past-the-end}} >> > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) - 1) == 0); >> > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 0) == 0); >> > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 1) == 42); // expected-error {{not an integral >> > > constant}} expected-note {{dereferenced one-past-the-end}} >> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) - >> > > 1) == 0); // expected-error {{constant}} expected-note {{not >> supported}} >> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + >> > > 0) == 0); // expected-error {{constant}} expected-note {{not >> supported}} >> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + >> > > 1) == 0); // expected-error {{constant}} expected-note {{not >> supported}} >> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) >> - >> > > 1) == 0); // expected-error {{constant}} expected-note {{not >> supported}} >> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) >> + >> > > 0) == 0); // expected-error {{constant}} expected-note {{not >> supported}} >> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) >> + >> > > 1) == 42); // expected-error {{constant}} expected-note {{not >> > > supported}} >> > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 1) == 42); // expected-error {{constant}} >> expected-note >> > > {{not supported}} >> > > + >> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - >> 1) >> > > == 0); // expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + >> 0) >> > > == 0); // expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + >> 1) >> > > == 0); // expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) - >> > > 1) == 0); // expected-error {{constant}} expected-note {{not >> supported}} >> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >> > > 0) == 0); // expected-error {{constant}} expected-note {{not >> supported}} >> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >> > > 1) == 42); // expected-error {{constant}} expected-note {{not >> > > supported}} >> > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note >> > > {{not supported}} >> > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >> > > sizeof(long) + 1) == 42); // expected-error {{constant}} >> expected-note >> > > {{not supported}} >> > > >> > > constexpr int a = strcmp("hello", "world"); // expected-error >> > > {{constant expression}} expected-note {{non-constexpr function >> 'strcmp' >> > > cannot be used in a constant expression}} >> > > constexpr int b = strncmp("hello", "world", 3); // expected-error >> > > {{constant expression}} expected-note {{non-constexpr function >> > > 'strncmp' cannot be used in a constant expression}} >> > > @@ -385,14 +385,14 @@ namespace StrchrEtc { >> > > enum class E : unsigned char {}; >> > > struct EPair { E e, f; }; >> > > constexpr EPair ee{E{240}}; >> > > - static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); >> > > + static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); // >> > > expected-error {{constant}} expected-note {{not supported}} >> > > >> > > constexpr bool kBool[] = {false, true, false}; >> > > constexpr const bool *const kBoolPastTheEndPtr = kBool + 3; >> > > - static_assert(sizeof(bool) != 1u || >> > > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); >> > > - static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, 0, >> > > 99) == kBoolPastTheEndPtr - 1); >> > > - static_assert(sizeof(bool) != 1u || >> > > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); >> > > - static_assert(sizeof(bool) != 1u || >> > > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // >> > > expected-error {{not an integral constant}} expected-note >> > > {{dereferenced one-past-the-end}} >> > > + static_assert(sizeof(bool) != 1u || >> > > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); // >> > > expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, 0, >> > > 99) == kBoolPastTheEndPtr - 1); // expected-error {{constant}} >> > > expected-note {{not supported}} >> > > + static_assert(sizeof(bool) != 1u || >> > > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); // >> > > expected-error {{constant}} expected-note {{not supported}} >> > > + static_assert(sizeof(bool) != 1u || >> > > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // >> > > expected-error {{constant}} expected-note {{not supported}} >> > > >> > > static_assert(__builtin_char_memchr(kStr, 'a', 0) == nullptr); >> > > static_assert(__builtin_char_memchr(kStr, 'a', 1) == kStr); >> > > >> > > >> > > >> > > _______________________________________________ >> > > cfe-commits mailing list >> > > cfe-commits at lists.llvm.org >> > > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > > >> > _______________________________________________ >> > libcxx-dev mailing list >> > libcxx-dev at lists.llvm.org >> > https://lists.llvm.org/cgi-bin/mailman/listinfo/libcxx-dev >> > >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits at lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > _______________________________________________ > cfe-commits mailing list > cfe-commits at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cfe-commits at lists.llvm.org Sun Apr 5 15:28:52 2020 From: cfe-commits at lists.llvm.org (Richard Smith via cfe-commits) Date: Sun, 05 Apr 2020 15:28:52 -0700 (PDT) Subject: [clang] 7f24db0 - Add documentation and testing for Message-ID: <5e8a5ba4.1c69fb81.e3e31.4b3a@mx.google.com> Author: Richard Smith Date: 2020-04-05T15:24:49-07:00 New Revision: 7f24db01751da6953782630bb42dcca8a111590b URL: https://github.com/llvm/llvm-project/commit/7f24db01751da6953782630bb42dcca8a111590b DIFF: https://github.com/llvm/llvm-project/commit/7f24db01751da6953782630bb42dcca8a111590b.diff LOG: Add documentation and testing for 2c88a485c71155c19e512f22c54e63ee337282a3. Also extend it to cover memchr for consistency. Added: Modified: clang/docs/LanguageExtensions.rst clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/constexpr-string.cpp Removed: ################################################################################ diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 6dcfd1a49f06..f83d7cff9c87 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -2368,8 +2368,8 @@ constant expressions in C++11 onwards (where a cast from ``void*`` to ``char*`` is disallowed in general). Constant evaluation support for the ``__builtin_mem*`` functions is provided -only for arrays of ``char``, ``signed char``, or ``unsigned char``, despite -these functions accepting an argument of type ``const void*``. +only for arrays of ``char``, ``signed char``, ``unsigned char``, or ``char8_t``, +despite these functions accepting an argument of type ``const void*``. Support for constant expression evaluation for the above builtins can be detected with ``__has_feature(cxx_constexpr_string_builtins)``. diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 7508bcbc365d..a10a4dab6dff 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -8469,7 +8469,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, } // Give up on byte-oriented matching against multibyte elements. // FIXME: We can compare the bytes in the correct order. - if (IsRawByte && !CharTy->isCharType()) { + if (IsRawByte && !CharTy->isCharType() && !CharTy->isChar8Type()) { Info.FFDiag(E, diag::note_constexpr_memchr_unsupported) << (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") << CharTy; diff --git a/clang/test/SemaCXX/constexpr-string.cpp b/clang/test/SemaCXX/constexpr-string.cpp index 79ac3bf2cc4d..b9f90adf7b76 100644 --- a/clang/test/SemaCXX/constexpr-string.cpp +++ b/clang/test/SemaCXX/constexpr-string.cpp @@ -107,6 +107,17 @@ namespace StrcmpEtc { static_assert(__builtin_memcmp("abab\0banana", "abab\0canada", 6) == -1); static_assert(__builtin_memcmp("abab\0banana", "abab\0canada", 5) == 0); + static_assert(__builtin_memcmp(u8"abaa", u8"abba", 3) == -1); + static_assert(__builtin_memcmp(u8"abaa", u8"abba", 2) == 0); + static_assert(__builtin_memcmp(u8"a\203", u8"a", 2) == 1); + static_assert(__builtin_memcmp(u8"a\203", u8"a\003", 2) == 1); + static_assert(__builtin_memcmp(0, 0, 0) == 0); + static_assert(__builtin_memcmp(u8"abab\0banana", u8"abab\0banana", 100) == 0); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} + static_assert(__builtin_memcmp(u8"abab\0banana", u8"abab\0canada", 100) == -1); // FIXME: Should we reject this? + static_assert(__builtin_memcmp(u8"abab\0banana", u8"abab\0canada", 7) == -1); + static_assert(__builtin_memcmp(u8"abab\0banana", u8"abab\0canada", 6) == -1); + static_assert(__builtin_memcmp(u8"abab\0banana", u8"abab\0canada", 5) == 0); + static_assert(__builtin_bcmp("abaa", "abba", 3) != 0); static_assert(__builtin_bcmp("abaa", "abba", 2) == 0); static_assert(__builtin_bcmp("a\203", "a", 2) != 0); @@ -373,6 +384,20 @@ namespace StrchrEtc { static_assert(__builtin_memchr(nullptr, 'x', 3) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced null}} static_assert(__builtin_memchr(nullptr, 'x', 0) == nullptr); // FIXME: Should we reject this? + constexpr const char8_t *kU8Str = u8"abca\xff\0d"; + constexpr char8_t kU8Foo[] = {u8'f', u8'o', u8'o'}; + static_assert(__builtin_memchr(kU8Str, u8'a', 0) == nullptr); + static_assert(__builtin_memchr(kU8Str, u8'a', 1) == kU8Str); + static_assert(__builtin_memchr(kU8Str, u8'\0', 5) == nullptr); + static_assert(__builtin_memchr(kU8Str, u8'\0', 6) == kU8Str + 5); + static_assert(__builtin_memchr(kU8Str, u8'\xff', 8) == kU8Str + 4); + static_assert(__builtin_memchr(kU8Str, u8'\xff' + 256, 8) == kU8Str + 4); + static_assert(__builtin_memchr(kU8Str, u8'\xff' - 256, 8) == kU8Str + 4); + static_assert(__builtin_memchr(kU8Foo, u8'x', 3) == nullptr); + static_assert(__builtin_memchr(kU8Foo, u8'x', 4) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced one-past-the-end}} + static_assert(__builtin_memchr(nullptr, u8'x', 3) == nullptr); // expected-error {{not an integral constant}} expected-note {{dereferenced null}} + static_assert(__builtin_memchr(nullptr, u8'x', 0) == nullptr); // FIXME: Should we reject this? + extern struct Incomplete incomplete; static_assert(__builtin_memchr(&incomplete, 0, 0u) == nullptr); static_assert(__builtin_memchr(&incomplete, 0, 1u) == nullptr); // expected-error {{not an integral constant}} expected-note {{read of incomplete type 'struct Incomplete'}} From cfe-commits at lists.llvm.org Sun Apr 5 15:36:17 2020 From: cfe-commits at lists.llvm.org (Richard Smith via cfe-commits) Date: Sun, 5 Apr 2020 15:36:17 -0700 Subject: [libcxx-dev] [clang] 4ede887 - PR45402: Make the restrictions on constant evaluation of memcmp and In-Reply-To: References: <110D5BC7-412C-4E2E-85C8-54AA91D2EDA2@znu.io> Message-ID: On Sun, 5 Apr 2020 at 15:17, Richard Smith wrote: > On Sun, 5 Apr 2020 at 14:44, David Zarzycki via cfe-commits < > cfe-commits at lists.llvm.org> wrote: > >> We have overloaded builtins. Can that not solve __builtin_strlen? >> > > I suppose it could, but we generally want __builtin_ to behave > the same as . (The difference would not be visible most of the > time, but there's enough pre-existing use of __builtin_strlen through > "clever" macros and the like that I'd be worried that this would break > something important.) Maybe we should just make the mem* functions work > again for char8_t; then you can use __builtin_memchr(p, 0) - p as an > optimized compile-time strlen. > I see you already did this for memcmp in llvmorg-11-init-7822-g2c88a485c71 :) I added documentation and testing and extended this to also cover memchr in llvmorg-11-init-7851-g7f24db01751. > >> -- >> Sent from my iPhone >> >> On Apr 5, 2020, at 14:53, Richard Smith wrote: >> >>  >> Thanks. We need to figure out what the right way to support char8_t with >> string builtins is. These ones could work in principle, whereas things like >> __builtin_strlen would never work because they take operands of the wrong >> types (and we can't cast const char8_t* -> const char* in a constant >> expression). >> >> On Sun, 5 Apr 2020 at 04:14, David Zarzycki via cfe-commits < >> cfe-commits at lists.llvm.org> wrote: >> >>> Hi Richard, >>> >>> I'm going to commit a narrow fix to clang to make the libcxx test suite >>> pass again by allowing char8_t again. If you feel that this is the wrong >>> long-term solution, please help the libcxx folks with whatever adjustments >>> they need. >>> >>> Thanks! >>> >>> Dave >>> >>> >>> On Sat, Apr 4, 2020, at 9:55 AM, David Zarzycki via libcxx-dev wrote: >>> > Hi Richard, >>> > >>> > This breaks libcxx. Can we please revert this or is a quick fix to >>> > libcxx possible? >>> > >>> > >>> > FAIL: libc++ :: >>> > >>> std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp >>> (58624 of 62672) >>> > ******************** TEST 'libc++ :: >>> > >>> std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp' >>> FAILED ******************** >>> > Command: ['/p/tllvm/bin/clang++', '-o', >>> > >>> '/tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o', >>> '-x', 'c++', >>> '/home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp', >>> '-c', '-v', '-Werror=thread-safety', '-std=c++2a', '-include', >>> '/home/dave/s/lp/libcxx/test/support/nasty_macros.h', '-nostdinc++', >>> '-I/home/dave/s/lp/libcxx/include', >>> '-I/tmp/_update_lc/t/projects/libcxx/include/c++build', >>> '-D__STDC_FORMAT_MACROS', '-D__STDC_LIMIT_MACROS', >>> '-D__STDC_CONSTANT_MACROS', '-I/home/dave/s/lp/libcxx/test/support', >>> '-ftemplate-depth=270', '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER', '-Wall', >>> '-Wextra', '-Werror', '-Wuser-defined-warnings', '-Wshadow', >>> '-Wno-unused-command-line-argument', '-Wno-attributes', >>> '-Wno-pessimizing-move', '-Wno-c++11-extensions', >>> '-Wno-user-defined-literals', '-Wno-noexcept-type', '-Wsign-compare', >>> '-Wunused-variable', '-Wunused-parameter', '-Wunreachable-code', '-c'] >>> > Exit Code: 1 >>> > Standard Error: >>> > -- >>> > clang version 11.0.0 (https://github.com/llvm/llvm-project.git >>> > 22127da8f17c03c69231f3631472f7f99ad9cb7f) >>> > Target: x86_64-unknown-linux-gnu >>> > Thread model: posix >>> > InstalledDir: /p/tllvm/bin >>> > Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 >>> > Selected GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 >>> > Candidate multilib: .;@m64 >>> > Candidate multilib: 32;@m32 >>> > Selected multilib: .;@m64 >>> > (in-process) >>> > "/p/tllvm/bin/clang-11" -cc1 -triple x86_64-unknown-linux-gnu >>> > -emit-obj -mrelax-all -disable-free -disable-llvm-verifier >>> > -discard-value-names -main-file-name compare.pass.cpp >>> > -mrelocation-model static -mthread-model posix -mframe-pointer=all >>> > -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables >>> > -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining >>> > -debugger-tuning=gdb -v -nostdinc++ -resource-dir >>> > /p/tllvm/lib64/clang/11.0.0 -include >>> > /home/dave/s/lp/libcxx/test/support/nasty_macros.h -I >>> > /home/dave/s/lp/libcxx/include -I >>> > /tmp/_update_lc/t/projects/libcxx/include/c++build -D >>> > __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS >>> > -I /home/dave/s/lp/libcxx/test/support -D >>> > _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -internal-isystem >>> > /usr/local/include -internal-isystem >>> > /p/tllvm/lib64/clang/11.0.0/include -internal-externc-isystem /include >>> > -internal-externc-isystem /usr/include -Werror=thread-safety -Wall >>> > -Wextra -Werror -Wuser-defined-warnings -Wshadow >>> > -Wno-unused-command-line-argument -Wno-attributes >>> -Wno-pessimizing-move >>> > -Wno-c++11-extensions -Wno-user-defined-literals -Wno-noexcept-type >>> > -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code >>> > -std=c++2a -fdeprecated-macro -fdebug-compilation-dir >>> > >>> /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t >>> -ftemplate-depth 270 -ferror-limit 19 -fgnuc-version=4.2.1 >>> -fno-implicit-modules -fcxx-exceptions -fexceptions -faddrsig -o >>> /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o >>> -x c++ >>> /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp >>> > clang -cc1 version 11.0.0 based upon LLVM 11.0.0git default target >>> > x86_64-unknown-linux-gnu >>> > ignoring nonexistent directory "/include" >>> > #include "..." search starts here: >>> > #include <...> search starts here: >>> > /home/dave/s/lp/libcxx/include >>> > /tmp/_update_lc/t/projects/libcxx/include/c++build >>> > /home/dave/s/lp/libcxx/test/support >>> > /usr/local/include >>> > /p/tllvm/lib64/clang/11.0.0/include >>> > /usr/include >>> > End of search list. >>> > >>> /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: >>> error: static_assert expression is not an integral constant expression >>> > static_assert(test_constexpr(), "" ); >>> > ^~~~~~~~~~~~~~~~ >>> > /home/dave/s/lp/libcxx/include/__string:662:12: note: constant >>> > evaluation of '__builtin_memcmp' between arrays of types 'const >>> > char8_t' and 'const char8_t' is not supported; only arrays of narrow >>> > character types can be compared >>> > return __builtin_memcmp(__s1, __s2, __n); >>> > ^ >>> > >>> /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:24:12: >>> note: in call to 'compare(&u8"123"[0], &u8"223"[0], 3)' >>> > return std::char_traits::compare(u8"123", u8"223", 3) < 0 >>> > ^ >>> > >>> /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: >>> note: in call to 'test_constexpr()' >>> > static_assert(test_constexpr(), "" ); >>> > ^ >>> > 1 error generated. >>> > -- >>> > >>> > Compilation failed unexpectedly! >>> > ******************** >>> > >>> > Testing Time: 135.49s >>> > ******************** >>> > Failing Tests (1): >>> > libc++ :: >>> > >>> std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp >>> > >>> > Expected Passes : 45503 >>> > Expected Failures : 118 >>> > Unsupported Tests : 17050 >>> > Unexpected Failures: 1 >>> > >>> > >>> > On Fri, Apr 3, 2020, at 9:26 PM, Richard Smith via cfe-commits wrote: >>> > > >>> > > Author: Richard Smith >>> > > Date: 2020-04-03T18:26:14-07:00 >>> > > New Revision: 4ede8879924c08ae5b495d3f421c167d822a60be >>> > > >>> > > URL: >>> > > >>> https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be >>> > > DIFF: >>> > > >>> https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be.diff >>> > > >>> > > LOG: PR45402: Make the restrictions on constant evaluation of memcmp >>> and >>> > > memchr consistent and comprehensible, and document them. >>> > > >>> > > We previously allowed evaluation of memcmp on arrays of integers of >>> any >>> > > size, so long as the call evaluated to 0, and allowed evaluation of >>> > > memchr on any array of integral type of size 1 (including enums). The >>> > > purpose of constant-evaluating these builtins is only to support >>> > > constexpr std::char_traits, so we now consistently allow them on >>> arrays >>> > > of (possibly signed or unsigned) char only. >>> > > >>> > > Added: >>> > > >>> > > >>> > > Modified: >>> > > clang/docs/LanguageExtensions.rst >>> > > clang/include/clang/Basic/DiagnosticASTKinds.td >>> > > clang/lib/AST/ExprConstant.cpp >>> > > clang/test/SemaCXX/constexpr-string.cpp >>> > > >>> > > Removed: >>> > > >>> > > >>> > > >>> > > >>> ################################################################################ >>> > > diff --git a/clang/docs/LanguageExtensions.rst >>> > > b/clang/docs/LanguageExtensions.rst >>> > > index 558ce7dee653..6dcfd1a49f06 100644 >>> > > --- a/clang/docs/LanguageExtensions.rst >>> > > +++ b/clang/docs/LanguageExtensions.rst >>> > > @@ -2333,10 +2333,11 @@ String builtins >>> > > --------------- >>> > > >>> > > Clang provides constant expression evaluation support for builtins >>> forms of >>> > > -the following functions from the C standard library ```` >>> header: >>> > > +the following functions from the C standard library headers >>> > > +```` and ````: >>> > > >>> > > * ``memchr`` >>> > > -* ``memcmp`` >>> > > +* ``memcmp`` (and its deprecated BSD / POSIX alias ``bcmp``) >>> > > * ``strchr`` >>> > > * ``strcmp`` >>> > > * ``strlen`` >>> > > @@ -2366,7 +2367,11 @@ In addition to the above, one further builtin >>> is >>> > > provided: >>> > > constant expressions in C++11 onwards (where a cast from ``void*`` >>> to >>> > > ``char*`` >>> > > is disallowed in general). >>> > > >>> > > -Support for constant expression evaluation for the above builtins >>> be >>> > > detected >>> > > +Constant evaluation support for the ``__builtin_mem*`` functions is >>> > > provided >>> > > +only for arrays of ``char``, ``signed char``, or ``unsigned char``, >>> > > despite >>> > > +these functions accepting an argument of type ``const void*``. >>> > > + >>> > > +Support for constant expression evaluation for the above builtins >>> can >>> > > be detected >>> > > with ``__has_feature(cxx_constexpr_string_builtins)``. >>> > > >>> > > Memory builtins >>> > > @@ -2386,6 +2391,25 @@ more information. >>> > > >>> > > Note that the `size` argument must be a compile time constant. >>> > > >>> > > +Clang provides constant expression evaluation support for builtin >>> > > forms of the >>> > > +following functions from the C standard library headers >>> > > +```` and ````: >>> > > + >>> > > +* ``memcpy`` >>> > > +* ``memmove`` >>> > > +* ``wmemcpy`` >>> > > +* ``wmemmove`` >>> > > + >>> > > +In each case, the builtin form has the name of the C library >>> function >>> > > prefixed >>> > > +by ``__builtin_``. >>> > > + >>> > > +Constant evaluation support is only provided when the source and >>> > > destination >>> > > +are pointers to arrays with the same trivially copyable element >>> type, >>> > > and the >>> > > +given size is an exact multiple of the element size that is no >>> greater >>> > > than >>> > > +the number of elements accessible through the source and >>> destination >>> > > operands. >>> > > + >>> > > +Constant evaluation support is not yet provided for >>> > > ``__builtin_memcpy_inline``. >>> > > + >>> > > Atomic Min/Max builtins with memory ordering >>> > > -------------------------------------------- >>> > > >>> > > >>> > > diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td >>> > > b/clang/include/clang/Basic/DiagnosticASTKinds.td >>> > > index 544573edffdf..a1415f9ec0e1 100644 >>> > > --- a/clang/include/clang/Basic/DiagnosticASTKinds.td >>> > > +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td >>> > > @@ -244,6 +244,12 @@ def note_constexpr_unsupported_unsized_array : >>> > > Note< >>> > > def note_constexpr_unsized_array_indexed : Note< >>> > > "indexing of array without known bound is not allowed " >>> > > "in a constant expression">; >>> > > +def note_constexpr_memcmp_unsupported : Note< >>> > > + "constant evaluation of %0 between arrays of types %1 and %2 " >>> > > + "is not supported; only arrays of narrow character types can be >>> > > compared">; >>> > > +def note_constexpr_memchr_unsupported : Note< >>> > > + "constant evaluation of %0 on array of type %1 " >>> > > + "is not supported; only arrays of narrow character types can be >>> > > searched">; >>> > > def note_constexpr_memcpy_null : Note< >>> > > "%select{source|destination}2 of " >>> > > "'%select{%select{memcpy|wmemcpy}1|%select{memmove|wmemmove}1}0' " >>> > > >>> > > diff --git a/clang/lib/AST/ExprConstant.cpp >>> > > b/clang/lib/AST/ExprConstant.cpp >>> > > index c6e1cc7b67df..a83b2e24e17f 100644 >>> > > --- a/clang/lib/AST/ExprConstant.cpp >>> > > +++ b/clang/lib/AST/ExprConstant.cpp >>> > > @@ -8469,8 +8469,12 @@ bool >>> > > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >>> > > } >>> > > // Give up on byte-oriented matching against multibyte elements. >>> > > // FIXME: We can compare the bytes in the correct order. >>> > > - if (IsRawByte && Info.Ctx.getTypeSizeInChars(CharTy) != >>> > > CharUnits::One()) >>> > > + if (IsRawByte && !CharTy->isCharType()) { >>> > > + Info.FFDiag(E, diag::note_constexpr_memchr_unsupported) >>> > > + << (std::string("'") + >>> > > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") >>> > > + << CharTy; >>> > > return false; >>> > > + } >>> > > // Figure out what value we're actually looking for (after >>> > > converting to >>> > > // the corresponding unsigned type if necessary). >>> > > uint64_t DesiredVal; >>> > > @@ -8586,6 +8590,7 @@ bool >>> > > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >>> > > QualType T = Dest.Designator.getType(Info.Ctx); >>> > > QualType SrcT = Src.Designator.getType(Info.Ctx); >>> > > if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) { >>> > > + // FIXME: Consider using our bit_cast implementation to >>> support >>> > > this. >>> > > Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) << Move >>> << >>> > > SrcT << T; >>> > > return false; >>> > > } >>> > > @@ -11149,6 +11154,16 @@ bool >>> > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >>> > > CharTy1, E->getArg(0)->getType()->getPointeeType()) >>> && >>> > > Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2))); >>> > > >>> > > + // For memcmp, allow comparing any arrays of '[[un]signed] >>> char', >>> > > + // but no other types. >>> > > + if (IsRawByte && !(CharTy1->isCharType() && >>> > > CharTy2->isCharType())) { >>> > > + // FIXME: Consider using our bit_cast implementation to >>> support >>> > > this. >>> > > + Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported) >>> > > + << (std::string("'") + >>> > > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") >>> > > + << CharTy1 << CharTy2; >>> > > + return false; >>> > > + } >>> > > + >>> > > const auto &ReadCurElems = [&](APValue &Char1, APValue &Char2) { >>> > > return handleLValueToRValueConversion(Info, E, CharTy1, >>> String1, >>> > > Char1) && >>> > > handleLValueToRValueConversion(Info, E, CharTy2, >>> String2, >>> > > Char2) && >>> > > @@ -11159,57 +11174,6 @@ bool >>> > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >>> > > HandleLValueArrayAdjustment(Info, E, String2, CharTy2, >>> 1); >>> > > }; >>> > > >>> > > - if (IsRawByte) { >>> > > - uint64_t BytesRemaining = MaxLength; >>> > > - // Pointers to const void may point to objects of incomplete >>> > > type. >>> > > - if (CharTy1->isIncompleteType()) { >>> > > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) >>> << >>> > > CharTy1; >>> > > - return false; >>> > > - } >>> > > - if (CharTy2->isIncompleteType()) { >>> > > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) >>> << >>> > > CharTy2; >>> > > - return false; >>> > > - } >>> > > - uint64_t CharTy1Width{Info.Ctx.getTypeSize(CharTy1)}; >>> > > - CharUnits CharTy1Size = >>> > > Info.Ctx.toCharUnitsFromBits(CharTy1Width); >>> > > - // Give up on comparing between elements with disparate >>> widths. >>> > > - if (CharTy1Size != Info.Ctx.getTypeSizeInChars(CharTy2)) >>> > > - return false; >>> > > - uint64_t BytesPerElement = CharTy1Size.getQuantity(); >>> > > - assert(BytesRemaining && "BytesRemaining should not be zero: >>> the >>> > > " >>> > > - "following loop considers at least >>> one >>> > > element"); >>> > > - while (true) { >>> > > - APValue Char1, Char2; >>> > > - if (!ReadCurElems(Char1, Char2)) >>> > > - return false; >>> > > - // We have compatible in-memory widths, but a possible type >>> and >>> > > - // (for `bool`) internal representation mismatch. >>> > > - // Assuming two's complement representation, including 0 >>> for >>> > > `false` and >>> > > - // 1 for `true`, we can check an appropriate number of >>> > > elements for >>> > > - // equality even if they are not byte-sized. >>> > > - APSInt Char1InMem = Char1.getInt().extOrTrunc(CharTy1Width); >>> > > - APSInt Char2InMem = Char2.getInt().extOrTrunc(CharTy1Width); >>> > > - if (Char1InMem.ne(Char2InMem)) { >>> > > - // If the elements are byte-sized, then we can produce a >>> > > three-way >>> > > - // comparison result in a straightforward manner. >>> > > - if (BytesPerElement == 1u) { >>> > > - // memcmp always compares unsigned chars. >>> > > - return Success(Char1InMem.ult(Char2InMem) ? -1 : 1, E); >>> > > - } >>> > > - // The result is byte-order sensitive, and we have >>> multibyte >>> > > elements. >>> > > - // FIXME: We can compare the remaining bytes in the >>> correct >>> > > order. >>> > > - return false; >>> > > - } >>> > > - if (!AdvanceElems()) >>> > > - return false; >>> > > - if (BytesRemaining <= BytesPerElement) >>> > > - break; >>> > > - BytesRemaining -= BytesPerElement; >>> > > - } >>> > > - // Enough elements are equal to account for the memcmp limit. >>> > > - return Success(0, E); >>> > > - } >>> > > - >>> > > bool StopAtNull = >>> > > (BuiltinOp != Builtin::BImemcmp && BuiltinOp != >>> > > Builtin::BIbcmp && >>> > > BuiltinOp != Builtin::BIwmemcmp && >>> > > @@ -11227,7 +11191,7 @@ bool >>> > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >>> > > APValue Char1, Char2; >>> > > if (!ReadCurElems(Char1, Char2)) >>> > > return false; >>> > > - if (Char1.getInt() != Char2.getInt()) { >>> > > + if (Char1.getInt().ne(Char2.getInt())) { >>> > > if (IsWide) // wmemcmp compares with wchar_t signedness. >>> > > return Success(Char1.getInt() < Char2.getInt() ? -1 : 1, >>> E); >>> > > // memcmp always compares unsigned chars. >>> > > >>> > > diff --git a/clang/test/SemaCXX/constexpr-string.cpp >>> > > b/clang/test/SemaCXX/constexpr-string.cpp >>> > > index f540be8f8e5b..79ac3bf2cc4d 100644 >>> > > --- a/clang/test/SemaCXX/constexpr-string.cpp >>> > > +++ b/clang/test/SemaCXX/constexpr-string.cpp >>> > > @@ -47,7 +47,7 @@ extern "C" { >>> > > extern wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n); >>> > > } >>> > > >>> > > -# 45 "SemaCXX/constexpr-string.cpp" 2 >>> > > +# 51 "SemaCXX/constexpr-string.cpp" 2 >>> > > namespace Strlen { >>> > > constexpr int n = __builtin_strlen("hello"); // ok >>> > > static_assert(n == 5); >>> > > @@ -121,13 +121,13 @@ namespace StrcmpEtc { >>> > > extern struct Incomplete incomplete; >>> > > static_assert(__builtin_memcmp(&incomplete, "", 0u) == 0); >>> > > static_assert(__builtin_memcmp("", &incomplete, 0u) == 0); >>> > > - static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{read of >>> > > incomplete type 'struct Incomplete'}} >>> > > - static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{read of >>> > > incomplete type 'struct Incomplete'}} >>> > > + static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{not >>> > > supported}} >>> > > + static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{not >>> > > supported}} >>> > > >>> > > static_assert(__builtin_bcmp(&incomplete, "", 0u) == 0); >>> > > static_assert(__builtin_bcmp("", &incomplete, 0u) == 0); >>> > > - static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{read of >>> > > incomplete type 'struct Incomplete'}} >>> > > - static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{read of >>> > > incomplete type 'struct Incomplete'}} >>> > > + static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{not >>> > > supported}} >>> > > + static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{not >>> > > supported}} >>> > > >>> > > constexpr unsigned char ku00fe00[] = {0x00, 0xfe, 0x00}; >>> > > constexpr unsigned char ku00feff[] = {0x00, 0xfe, 0xff}; >>> > > @@ -155,11 +155,11 @@ namespace StrcmpEtc { >>> > > >>> > > struct Bool3Tuple { bool bb[3]; }; >>> > > constexpr Bool3Tuple kb000100 = {{false, true, false}}; >>> > > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >>> > > kb000100.bb, 1) == 0); >>> > > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >>> > > kb000100.bb, 2) == 1); >>> > > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >>> > > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note >>> > > {{not supported}} >>> > > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >>> > > kb000100.bb, 2) == 1); // expected-error {{constant}} expected-note >>> > > {{not supported}} >>> > > >>> > > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >>> > > kb000100.bb, 1) == 0); >>> > > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >>> > > kb000100.bb, 2) != 0); >>> > > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >>> > > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note >>> > > {{not supported}} >>> > > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >>> > > kb000100.bb, 2) != 0); // expected-error {{constant}} expected-note >>> > > {{not supported}} >>> > > >>> > > constexpr long ksl[] = {0, -1}; >>> > > constexpr unsigned int kui[] = {0, 0u - 1}; >>> > > @@ -173,25 +173,25 @@ namespace StrcmpEtc { >>> > > return nullptr; >>> > > } >>> > > } >>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) >>> - >>> > > 1) == 0); >>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) >>> + >>> > > 0) == 0); >>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) >>> + >>> > > 1) == 0); >>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), >>> 2*sizeof(long) - >>> > > 1) == 0); >>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), >>> 2*sizeof(long) + >>> > > 0) == 0); >>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), >>> 2*sizeof(long) + >>> > > 1) == 42); // expected-error {{not an integral constant}} >>> expected-note >>> > > {{dereferenced one-past-the-end}} >>> > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) - 1) == 0); >>> > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 0) == 0); >>> > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 1) == 42); // expected-error {{not an integral >>> > > constant}} expected-note {{dereferenced one-past-the-end}} >>> > > - >>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - >>> 1) >>> > > == 0); >>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + >>> 0) >>> > > == 0); >>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + >>> 1) >>> > > == 0); >>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) >>> - >>> > > 1) == 0); >>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) >>> + >>> > > 0) == 0); >>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) >>> + >>> > > 1) == 42); // expected-error {{not an integral constant}} >>> expected-note >>> > > {{dereferenced one-past-the-end}} >>> > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) - 1) == 0); >>> > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 0) == 0); >>> > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 1) == 42); // expected-error {{not an integral >>> > > constant}} expected-note {{dereferenced one-past-the-end}} >>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) >>> - >>> > > 1) == 0); // expected-error {{constant}} expected-note {{not >>> supported}} >>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) >>> + >>> > > 0) == 0); // expected-error {{constant}} expected-note {{not >>> supported}} >>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) >>> + >>> > > 1) == 0); // expected-error {{constant}} expected-note {{not >>> supported}} >>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), >>> 2*sizeof(long) - >>> > > 1) == 0); // expected-error {{constant}} expected-note {{not >>> supported}} >>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), >>> 2*sizeof(long) + >>> > > 0) == 0); // expected-error {{constant}} expected-note {{not >>> supported}} >>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), >>> 2*sizeof(long) + >>> > > 1) == 42); // expected-error {{constant}} expected-note {{not >>> > > supported}} >>> > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) - 1) == 0); // expected-error {{constant}} >>> expected-note >>> > > {{not supported}} >>> > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 0) == 0); // expected-error {{constant}} >>> expected-note >>> > > {{not supported}} >>> > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 1) == 42); // expected-error {{constant}} >>> expected-note >>> > > {{not supported}} >>> > > + >>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - >>> 1) >>> > > == 0); // expected-error {{constant}} expected-note {{not supported}} >>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + >>> 0) >>> > > == 0); // expected-error {{constant}} expected-note {{not supported}} >>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + >>> 1) >>> > > == 0); // expected-error {{constant}} expected-note {{not supported}} >>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) >>> - >>> > > 1) == 0); // expected-error {{constant}} expected-note {{not >>> supported}} >>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) >>> + >>> > > 0) == 0); // expected-error {{constant}} expected-note {{not >>> supported}} >>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) >>> + >>> > > 1) == 42); // expected-error {{constant}} expected-note {{not >>> > > supported}} >>> > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) - 1) == 0); // expected-error {{constant}} >>> expected-note >>> > > {{not supported}} >>> > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 0) == 0); // expected-error {{constant}} >>> expected-note >>> > > {{not supported}} >>> > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 1) == 42); // expected-error {{constant}} >>> expected-note >>> > > {{not supported}} >>> > > >>> > > constexpr int a = strcmp("hello", "world"); // expected-error >>> > > {{constant expression}} expected-note {{non-constexpr function >>> 'strcmp' >>> > > cannot be used in a constant expression}} >>> > > constexpr int b = strncmp("hello", "world", 3); // expected-error >>> > > {{constant expression}} expected-note {{non-constexpr function >>> > > 'strncmp' cannot be used in a constant expression}} >>> > > @@ -385,14 +385,14 @@ namespace StrchrEtc { >>> > > enum class E : unsigned char {}; >>> > > struct EPair { E e, f; }; >>> > > constexpr EPair ee{E{240}}; >>> > > - static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); >>> > > + static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); // >>> > > expected-error {{constant}} expected-note {{not supported}} >>> > > >>> > > constexpr bool kBool[] = {false, true, false}; >>> > > constexpr const bool *const kBoolPastTheEndPtr = kBool + 3; >>> > > - static_assert(sizeof(bool) != 1u || >>> > > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); >>> > > - static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, >>> 0, >>> > > 99) == kBoolPastTheEndPtr - 1); >>> > > - static_assert(sizeof(bool) != 1u || >>> > > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); >>> > > - static_assert(sizeof(bool) != 1u || >>> > > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // >>> > > expected-error {{not an integral constant}} expected-note >>> > > {{dereferenced one-past-the-end}} >>> > > + static_assert(sizeof(bool) != 1u || >>> > > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); // >>> > > expected-error {{constant}} expected-note {{not supported}} >>> > > + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, >>> 0, >>> > > 99) == kBoolPastTheEndPtr - 1); // expected-error {{constant}} >>> > > expected-note {{not supported}} >>> > > + static_assert(sizeof(bool) != 1u || >>> > > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); // >>> > > expected-error {{constant}} expected-note {{not supported}} >>> > > + static_assert(sizeof(bool) != 1u || >>> > > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // >>> > > expected-error {{constant}} expected-note {{not supported}} >>> > > >>> > > static_assert(__builtin_char_memchr(kStr, 'a', 0) == nullptr); >>> > > static_assert(__builtin_char_memchr(kStr, 'a', 1) == kStr); >>> > > >>> > > >>> > > >>> > > _______________________________________________ >>> > > cfe-commits mailing list >>> > > cfe-commits at lists.llvm.org >>> > > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>> > > >>> > _______________________________________________ >>> > libcxx-dev mailing list >>> > libcxx-dev at lists.llvm.org >>> > https://lists.llvm.org/cgi-bin/mailman/listinfo/libcxx-dev >>> > >>> _______________________________________________ >>> cfe-commits mailing list >>> cfe-commits at lists.llvm.org >>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits at lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cfe-commits at lists.llvm.org Sun Apr 5 15:37:42 2020 From: cfe-commits at lists.llvm.org (Richard Smith via cfe-commits) Date: Sun, 05 Apr 2020 15:37:42 -0700 (PDT) Subject: [clang] 944db8a - Permit constant evaluation of mixed __builtin_memcmp between char and Message-ID: <5e8a5db6.1c69fb81.4341c.0f80@mx.google.com> Author: Richard Smith Date: 2020-04-05T15:35:32-07:00 New Revision: 944db8a433f591e514219c12fa33b7e8fdd5e883 URL: https://github.com/llvm/llvm-project/commit/944db8a433f591e514219c12fa33b7e8fdd5e883 DIFF: https://github.com/llvm/llvm-project/commit/944db8a433f591e514219c12fa33b7e8fdd5e883.diff LOG: Permit constant evaluation of mixed __builtin_memcmp between char and char8_t. Added: Modified: clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/constexpr-string.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index a10a4dab6dff..35232bebbb3a 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -8319,6 +8319,12 @@ bool PointerExprEvaluator::VisitCallExpr(const CallExpr *E) { return visitNonBuiltinCallExpr(E); } +// Determine if T is a character type for which we guarantee that +// sizeof(T) == 1. +static bool isOneByteCharacterType(QualType T) { + return T->isCharType() || T->isChar8Type(); +} + bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, unsigned BuiltinOp) { switch (BuiltinOp) { @@ -8469,7 +8475,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, } // Give up on byte-oriented matching against multibyte elements. // FIXME: We can compare the bytes in the correct order. - if (IsRawByte && !CharTy->isCharType() && !CharTy->isChar8Type()) { + if (IsRawByte && !isOneByteCharacterType(CharTy)) { Info.FFDiag(E, diag::note_constexpr_memchr_unsupported) << (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") << CharTy; @@ -11156,9 +11162,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, // For memcmp, allow comparing any arrays of '[[un]signed] char' or // 'char8_t', but no other types. - bool IsChar = CharTy1->isCharType() && CharTy2->isCharType(); - bool IsChar8 = CharTy1->isChar8Type() && CharTy2->isChar8Type(); - if (IsRawByte && !IsChar && !IsChar8) { + if (IsRawByte && + !(isOneByteCharacterType(CharTy1) && isOneByteCharacterType(CharTy2))) { // FIXME: Consider using our bit_cast implementation to support this. Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported) << (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") diff --git a/clang/test/SemaCXX/constexpr-string.cpp b/clang/test/SemaCXX/constexpr-string.cpp index b9f90adf7b76..f33627e812b2 100644 --- a/clang/test/SemaCXX/constexpr-string.cpp +++ b/clang/test/SemaCXX/constexpr-string.cpp @@ -118,6 +118,9 @@ namespace StrcmpEtc { static_assert(__builtin_memcmp(u8"abab\0banana", u8"abab\0canada", 6) == -1); static_assert(__builtin_memcmp(u8"abab\0banana", u8"abab\0canada", 5) == 0); + static_assert(__builtin_memcmp(u8"\u1234", "\xE1\x88\xB4", 4) == 0); + static_assert(__builtin_memcmp(u8"\u1234", "\xE1\x88\xB3", 4) == 1); + static_assert(__builtin_bcmp("abaa", "abba", 3) != 0); static_assert(__builtin_bcmp("abaa", "abba", 2) == 0); static_assert(__builtin_bcmp("a\203", "a", 2) != 0); From cfe-commits at lists.llvm.org Sun Apr 5 15:41:09 2020 From: cfe-commits at lists.llvm.org (David Zarzycki via cfe-commits) Date: Sun, 5 Apr 2020 18:41:09 -0400 Subject: [libcxx-dev] [clang] 4ede887 - PR45402: Make the restrictions on constant evaluation of memcmp and In-Reply-To: References: Message-ID: <16D0B65F-8EA8-42B2-9AE0-6FA2A94D6B0E@znu.io> Subjectively speaking, using char8_t instead of char shouldn’t feel like a regression. So yes, making the builtin mem* functions work with char8_t again seems right. As for strlen, I can see arguments either way. Personally, if you’re concerned about clever macros, then I’d make the overload only visible in C++20 mode where char8_t was introduced. -- Sent from my iPhone > On Apr 5, 2020, at 18:18, Richard Smith wrote: > >  >> On Sun, 5 Apr 2020 at 14:44, David Zarzycki via cfe-commits wrote: > >> We have overloaded builtins. Can that not solve __builtin_strlen? > > I suppose it could, but we generally want __builtin_ to behave the same as . (The difference would not be visible most of the time, but there's enough pre-existing use of __builtin_strlen through "clever" macros and the like that I'd be worried that this would break something important.) Maybe we should just make the mem* functions work again for char8_t; then you can use __builtin_memchr(p, 0) - p as an optimized compile-time strlen. > >> -- >> Sent from my iPhone >> >>>> On Apr 5, 2020, at 14:53, Richard Smith wrote: >>>> >>>  >>> Thanks. We need to figure out what the right way to support char8_t with string builtins is. These ones could work in principle, whereas things like __builtin_strlen would never work because they take operands of the wrong types (and we can't cast const char8_t* -> const char* in a constant expression). >>> >>>> On Sun, 5 Apr 2020 at 04:14, David Zarzycki via cfe-commits wrote: >>>> Hi Richard, >>>> >>>> I'm going to commit a narrow fix to clang to make the libcxx test suite pass again by allowing char8_t again. If you feel that this is the wrong long-term solution, please help the libcxx folks with whatever adjustments they need. >>>> >>>> Thanks! >>>> >>>> Dave >>>> >>>> >>>> On Sat, Apr 4, 2020, at 9:55 AM, David Zarzycki via libcxx-dev wrote: >>>> > Hi Richard, >>>> > >>>> > This breaks libcxx. Can we please revert this or is a quick fix to >>>> > libcxx possible? >>>> > >>>> > >>>> > FAIL: libc++ :: >>>> > std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp (58624 of 62672) >>>> > ******************** TEST 'libc++ :: >>>> > std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp' FAILED ******************** >>>> > Command: ['/p/tllvm/bin/clang++', '-o', >>>> > '/tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o', '-x', 'c++', '/home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp', '-c', '-v', '-Werror=thread-safety', '-std=c++2a', '-include', '/home/dave/s/lp/libcxx/test/support/nasty_macros.h', '-nostdinc++', '-I/home/dave/s/lp/libcxx/include', '-I/tmp/_update_lc/t/projects/libcxx/include/c++build', '-D__STDC_FORMAT_MACROS', '-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-I/home/dave/s/lp/libcxx/test/support', '-ftemplate-depth=270', '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER', '-Wall', '-Wextra', '-Werror', '-Wuser-defined-warnings', '-Wshadow', '-Wno-unused-command-line-argument', '-Wno-attributes', '-Wno-pessimizing-move', '-Wno-c++11-extensions', '-Wno-user-defined-literals', '-Wno-noexcept-type', '-Wsign-compare', '-Wunused-variable', '-Wunused-parameter', '-Wunreachable-code', '-c'] >>>> > Exit Code: 1 >>>> > Standard Error: >>>> > -- >>>> > clang version 11.0.0 (https://github.com/llvm/llvm-project.git >>>> > 22127da8f17c03c69231f3631472f7f99ad9cb7f) >>>> > Target: x86_64-unknown-linux-gnu >>>> > Thread model: posix >>>> > InstalledDir: /p/tllvm/bin >>>> > Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 >>>> > Selected GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 >>>> > Candidate multilib: .;@m64 >>>> > Candidate multilib: 32;@m32 >>>> > Selected multilib: .;@m64 >>>> > (in-process) >>>> > "/p/tllvm/bin/clang-11" -cc1 -triple x86_64-unknown-linux-gnu >>>> > -emit-obj -mrelax-all -disable-free -disable-llvm-verifier >>>> > -discard-value-names -main-file-name compare.pass.cpp >>>> > -mrelocation-model static -mthread-model posix -mframe-pointer=all >>>> > -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables >>>> > -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining >>>> > -debugger-tuning=gdb -v -nostdinc++ -resource-dir >>>> > /p/tllvm/lib64/clang/11.0.0 -include >>>> > /home/dave/s/lp/libcxx/test/support/nasty_macros.h -I >>>> > /home/dave/s/lp/libcxx/include -I >>>> > /tmp/_update_lc/t/projects/libcxx/include/c++build -D >>>> > __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS >>>> > -I /home/dave/s/lp/libcxx/test/support -D >>>> > _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -internal-isystem >>>> > /usr/local/include -internal-isystem >>>> > /p/tllvm/lib64/clang/11.0.0/include -internal-externc-isystem /include >>>> > -internal-externc-isystem /usr/include -Werror=thread-safety -Wall >>>> > -Wextra -Werror -Wuser-defined-warnings -Wshadow >>>> > -Wno-unused-command-line-argument -Wno-attributes -Wno-pessimizing-move >>>> > -Wno-c++11-extensions -Wno-user-defined-literals -Wno-noexcept-type >>>> > -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code >>>> > -std=c++2a -fdeprecated-macro -fdebug-compilation-dir >>>> > /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t -ftemplate-depth 270 -ferror-limit 19 -fgnuc-version=4.2.1 -fno-implicit-modules -fcxx-exceptions -fexceptions -faddrsig -o /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o -x c++ /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp >>>> > clang -cc1 version 11.0.0 based upon LLVM 11.0.0git default target >>>> > x86_64-unknown-linux-gnu >>>> > ignoring nonexistent directory "/include" >>>> > #include "..." search starts here: >>>> > #include <...> search starts here: >>>> > /home/dave/s/lp/libcxx/include >>>> > /tmp/_update_lc/t/projects/libcxx/include/c++build >>>> > /home/dave/s/lp/libcxx/test/support >>>> > /usr/local/include >>>> > /p/tllvm/lib64/clang/11.0.0/include >>>> > /usr/include >>>> > End of search list. >>>> > /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: error: static_assert expression is not an integral constant expression >>>> > static_assert(test_constexpr(), "" ); >>>> > ^~~~~~~~~~~~~~~~ >>>> > /home/dave/s/lp/libcxx/include/__string:662:12: note: constant >>>> > evaluation of '__builtin_memcmp' between arrays of types 'const >>>> > char8_t' and 'const char8_t' is not supported; only arrays of narrow >>>> > character types can be compared >>>> > return __builtin_memcmp(__s1, __s2, __n); >>>> > ^ >>>> > /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:24:12: note: in call to 'compare(&u8"123"[0], &u8"223"[0], 3)' >>>> > return std::char_traits::compare(u8"123", u8"223", 3) < 0 >>>> > ^ >>>> > /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: note: in call to 'test_constexpr()' >>>> > static_assert(test_constexpr(), "" ); >>>> > ^ >>>> > 1 error generated. >>>> > -- >>>> > >>>> > Compilation failed unexpectedly! >>>> > ******************** >>>> > >>>> > Testing Time: 135.49s >>>> > ******************** >>>> > Failing Tests (1): >>>> > libc++ :: >>>> > std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp >>>> > >>>> > Expected Passes : 45503 >>>> > Expected Failures : 118 >>>> > Unsupported Tests : 17050 >>>> > Unexpected Failures: 1 >>>> > >>>> > >>>> > On Fri, Apr 3, 2020, at 9:26 PM, Richard Smith via cfe-commits wrote: >>>> > > >>>> > > Author: Richard Smith >>>> > > Date: 2020-04-03T18:26:14-07:00 >>>> > > New Revision: 4ede8879924c08ae5b495d3f421c167d822a60be >>>> > > >>>> > > URL: >>>> > > https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be >>>> > > DIFF: >>>> > > https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be.diff >>>> > > >>>> > > LOG: PR45402: Make the restrictions on constant evaluation of memcmp and >>>> > > memchr consistent and comprehensible, and document them. >>>> > > >>>> > > We previously allowed evaluation of memcmp on arrays of integers of any >>>> > > size, so long as the call evaluated to 0, and allowed evaluation of >>>> > > memchr on any array of integral type of size 1 (including enums). The >>>> > > purpose of constant-evaluating these builtins is only to support >>>> > > constexpr std::char_traits, so we now consistently allow them on arrays >>>> > > of (possibly signed or unsigned) char only. >>>> > > >>>> > > Added: >>>> > > >>>> > > >>>> > > Modified: >>>> > > clang/docs/LanguageExtensions.rst >>>> > > clang/include/clang/Basic/DiagnosticASTKinds.td >>>> > > clang/lib/AST/ExprConstant.cpp >>>> > > clang/test/SemaCXX/constexpr-string.cpp >>>> > > >>>> > > Removed: >>>> > > >>>> > > >>>> > > >>>> > > ################################################################################ >>>> > > diff --git a/clang/docs/LanguageExtensions.rst >>>> > > b/clang/docs/LanguageExtensions.rst >>>> > > index 558ce7dee653..6dcfd1a49f06 100644 >>>> > > --- a/clang/docs/LanguageExtensions.rst >>>> > > +++ b/clang/docs/LanguageExtensions.rst >>>> > > @@ -2333,10 +2333,11 @@ String builtins >>>> > > --------------- >>>> > > >>>> > > Clang provides constant expression evaluation support for builtins forms of >>>> > > -the following functions from the C standard library ```` header: >>>> > > +the following functions from the C standard library headers >>>> > > +```` and ````: >>>> > > >>>> > > * ``memchr`` >>>> > > -* ``memcmp`` >>>> > > +* ``memcmp`` (and its deprecated BSD / POSIX alias ``bcmp``) >>>> > > * ``strchr`` >>>> > > * ``strcmp`` >>>> > > * ``strlen`` >>>> > > @@ -2366,7 +2367,11 @@ In addition to the above, one further builtin is >>>> > > provided: >>>> > > constant expressions in C++11 onwards (where a cast from ``void*`` to >>>> > > ``char*`` >>>> > > is disallowed in general). >>>> > > >>>> > > -Support for constant expression evaluation for the above builtins be >>>> > > detected >>>> > > +Constant evaluation support for the ``__builtin_mem*`` functions is >>>> > > provided >>>> > > +only for arrays of ``char``, ``signed char``, or ``unsigned char``, >>>> > > despite >>>> > > +these functions accepting an argument of type ``const void*``. >>>> > > + >>>> > > +Support for constant expression evaluation for the above builtins can >>>> > > be detected >>>> > > with ``__has_feature(cxx_constexpr_string_builtins)``. >>>> > > >>>> > > Memory builtins >>>> > > @@ -2386,6 +2391,25 @@ more information. >>>> > > >>>> > > Note that the `size` argument must be a compile time constant. >>>> > > >>>> > > +Clang provides constant expression evaluation support for builtin >>>> > > forms of the >>>> > > +following functions from the C standard library headers >>>> > > +```` and ````: >>>> > > + >>>> > > +* ``memcpy`` >>>> > > +* ``memmove`` >>>> > > +* ``wmemcpy`` >>>> > > +* ``wmemmove`` >>>> > > + >>>> > > +In each case, the builtin form has the name of the C library function >>>> > > prefixed >>>> > > +by ``__builtin_``. >>>> > > + >>>> > > +Constant evaluation support is only provided when the source and >>>> > > destination >>>> > > +are pointers to arrays with the same trivially copyable element type, >>>> > > and the >>>> > > +given size is an exact multiple of the element size that is no greater >>>> > > than >>>> > > +the number of elements accessible through the source and destination >>>> > > operands. >>>> > > + >>>> > > +Constant evaluation support is not yet provided for >>>> > > ``__builtin_memcpy_inline``. >>>> > > + >>>> > > Atomic Min/Max builtins with memory ordering >>>> > > -------------------------------------------- >>>> > > >>>> > > >>>> > > diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td >>>> > > b/clang/include/clang/Basic/DiagnosticASTKinds.td >>>> > > index 544573edffdf..a1415f9ec0e1 100644 >>>> > > --- a/clang/include/clang/Basic/DiagnosticASTKinds.td >>>> > > +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td >>>> > > @@ -244,6 +244,12 @@ def note_constexpr_unsupported_unsized_array : >>>> > > Note< >>>> > > def note_constexpr_unsized_array_indexed : Note< >>>> > > "indexing of array without known bound is not allowed " >>>> > > "in a constant expression">; >>>> > > +def note_constexpr_memcmp_unsupported : Note< >>>> > > + "constant evaluation of %0 between arrays of types %1 and %2 " >>>> > > + "is not supported; only arrays of narrow character types can be >>>> > > compared">; >>>> > > +def note_constexpr_memchr_unsupported : Note< >>>> > > + "constant evaluation of %0 on array of type %1 " >>>> > > + "is not supported; only arrays of narrow character types can be >>>> > > searched">; >>>> > > def note_constexpr_memcpy_null : Note< >>>> > > "%select{source|destination}2 of " >>>> > > "'%select{%select{memcpy|wmemcpy}1|%select{memmove|wmemmove}1}0' " >>>> > > >>>> > > diff --git a/clang/lib/AST/ExprConstant.cpp >>>> > > b/clang/lib/AST/ExprConstant.cpp >>>> > > index c6e1cc7b67df..a83b2e24e17f 100644 >>>> > > --- a/clang/lib/AST/ExprConstant.cpp >>>> > > +++ b/clang/lib/AST/ExprConstant.cpp >>>> > > @@ -8469,8 +8469,12 @@ bool >>>> > > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >>>> > > } >>>> > > // Give up on byte-oriented matching against multibyte elements. >>>> > > // FIXME: We can compare the bytes in the correct order. >>>> > > - if (IsRawByte && Info.Ctx.getTypeSizeInChars(CharTy) != >>>> > > CharUnits::One()) >>>> > > + if (IsRawByte && !CharTy->isCharType()) { >>>> > > + Info.FFDiag(E, diag::note_constexpr_memchr_unsupported) >>>> > > + << (std::string("'") + >>>> > > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") >>>> > > + << CharTy; >>>> > > return false; >>>> > > + } >>>> > > // Figure out what value we're actually looking for (after >>>> > > converting to >>>> > > // the corresponding unsigned type if necessary). >>>> > > uint64_t DesiredVal; >>>> > > @@ -8586,6 +8590,7 @@ bool >>>> > > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >>>> > > QualType T = Dest.Designator.getType(Info.Ctx); >>>> > > QualType SrcT = Src.Designator.getType(Info.Ctx); >>>> > > if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) { >>>> > > + // FIXME: Consider using our bit_cast implementation to support >>>> > > this. >>>> > > Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) << Move << >>>> > > SrcT << T; >>>> > > return false; >>>> > > } >>>> > > @@ -11149,6 +11154,16 @@ bool >>>> > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >>>> > > CharTy1, E->getArg(0)->getType()->getPointeeType()) && >>>> > > Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2))); >>>> > > >>>> > > + // For memcmp, allow comparing any arrays of '[[un]signed] char', >>>> > > + // but no other types. >>>> > > + if (IsRawByte && !(CharTy1->isCharType() && >>>> > > CharTy2->isCharType())) { >>>> > > + // FIXME: Consider using our bit_cast implementation to support >>>> > > this. >>>> > > + Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported) >>>> > > + << (std::string("'") + >>>> > > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") >>>> > > + << CharTy1 << CharTy2; >>>> > > + return false; >>>> > > + } >>>> > > + >>>> > > const auto &ReadCurElems = [&](APValue &Char1, APValue &Char2) { >>>> > > return handleLValueToRValueConversion(Info, E, CharTy1, String1, >>>> > > Char1) && >>>> > > handleLValueToRValueConversion(Info, E, CharTy2, String2, >>>> > > Char2) && >>>> > > @@ -11159,57 +11174,6 @@ bool >>>> > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >>>> > > HandleLValueArrayAdjustment(Info, E, String2, CharTy2, 1); >>>> > > }; >>>> > > >>>> > > - if (IsRawByte) { >>>> > > - uint64_t BytesRemaining = MaxLength; >>>> > > - // Pointers to const void may point to objects of incomplete >>>> > > type. >>>> > > - if (CharTy1->isIncompleteType()) { >>>> > > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << >>>> > > CharTy1; >>>> > > - return false; >>>> > > - } >>>> > > - if (CharTy2->isIncompleteType()) { >>>> > > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) << >>>> > > CharTy2; >>>> > > - return false; >>>> > > - } >>>> > > - uint64_t CharTy1Width{Info.Ctx.getTypeSize(CharTy1)}; >>>> > > - CharUnits CharTy1Size = >>>> > > Info.Ctx.toCharUnitsFromBits(CharTy1Width); >>>> > > - // Give up on comparing between elements with disparate widths. >>>> > > - if (CharTy1Size != Info.Ctx.getTypeSizeInChars(CharTy2)) >>>> > > - return false; >>>> > > - uint64_t BytesPerElement = CharTy1Size.getQuantity(); >>>> > > - assert(BytesRemaining && "BytesRemaining should not be zero: the >>>> > > " >>>> > > - "following loop considers at least one >>>> > > element"); >>>> > > - while (true) { >>>> > > - APValue Char1, Char2; >>>> > > - if (!ReadCurElems(Char1, Char2)) >>>> > > - return false; >>>> > > - // We have compatible in-memory widths, but a possible type and >>>> > > - // (for `bool`) internal representation mismatch. >>>> > > - // Assuming two's complement representation, including 0 for >>>> > > `false` and >>>> > > - // 1 for `true`, we can check an appropriate number of >>>> > > elements for >>>> > > - // equality even if they are not byte-sized. >>>> > > - APSInt Char1InMem = Char1.getInt().extOrTrunc(CharTy1Width); >>>> > > - APSInt Char2InMem = Char2.getInt().extOrTrunc(CharTy1Width); >>>> > > - if (Char1InMem.ne(Char2InMem)) { >>>> > > - // If the elements are byte-sized, then we can produce a >>>> > > three-way >>>> > > - // comparison result in a straightforward manner. >>>> > > - if (BytesPerElement == 1u) { >>>> > > - // memcmp always compares unsigned chars. >>>> > > - return Success(Char1InMem.ult(Char2InMem) ? -1 : 1, E); >>>> > > - } >>>> > > - // The result is byte-order sensitive, and we have multibyte >>>> > > elements. >>>> > > - // FIXME: We can compare the remaining bytes in the correct >>>> > > order. >>>> > > - return false; >>>> > > - } >>>> > > - if (!AdvanceElems()) >>>> > > - return false; >>>> > > - if (BytesRemaining <= BytesPerElement) >>>> > > - break; >>>> > > - BytesRemaining -= BytesPerElement; >>>> > > - } >>>> > > - // Enough elements are equal to account for the memcmp limit. >>>> > > - return Success(0, E); >>>> > > - } >>>> > > - >>>> > > bool StopAtNull = >>>> > > (BuiltinOp != Builtin::BImemcmp && BuiltinOp != >>>> > > Builtin::BIbcmp && >>>> > > BuiltinOp != Builtin::BIwmemcmp && >>>> > > @@ -11227,7 +11191,7 @@ bool >>>> > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >>>> > > APValue Char1, Char2; >>>> > > if (!ReadCurElems(Char1, Char2)) >>>> > > return false; >>>> > > - if (Char1.getInt() != Char2.getInt()) { >>>> > > + if (Char1.getInt().ne(Char2.getInt())) { >>>> > > if (IsWide) // wmemcmp compares with wchar_t signedness. >>>> > > return Success(Char1.getInt() < Char2.getInt() ? -1 : 1, E); >>>> > > // memcmp always compares unsigned chars. >>>> > > >>>> > > diff --git a/clang/test/SemaCXX/constexpr-string.cpp >>>> > > b/clang/test/SemaCXX/constexpr-string.cpp >>>> > > index f540be8f8e5b..79ac3bf2cc4d 100644 >>>> > > --- a/clang/test/SemaCXX/constexpr-string.cpp >>>> > > +++ b/clang/test/SemaCXX/constexpr-string.cpp >>>> > > @@ -47,7 +47,7 @@ extern "C" { >>>> > > extern wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n); >>>> > > } >>>> > > >>>> > > -# 45 "SemaCXX/constexpr-string.cpp" 2 >>>> > > +# 51 "SemaCXX/constexpr-string.cpp" 2 >>>> > > namespace Strlen { >>>> > > constexpr int n = __builtin_strlen("hello"); // ok >>>> > > static_assert(n == 5); >>>> > > @@ -121,13 +121,13 @@ namespace StrcmpEtc { >>>> > > extern struct Incomplete incomplete; >>>> > > static_assert(__builtin_memcmp(&incomplete, "", 0u) == 0); >>>> > > static_assert(__builtin_memcmp("", &incomplete, 0u) == 0); >>>> > > - static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // >>>> > > expected-error {{not an integral constant}} expected-note {{read of >>>> > > incomplete type 'struct Incomplete'}} >>>> > > - static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // >>>> > > expected-error {{not an integral constant}} expected-note {{read of >>>> > > incomplete type 'struct Incomplete'}} >>>> > > + static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // >>>> > > expected-error {{not an integral constant}} expected-note {{not >>>> > > supported}} >>>> > > + static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // >>>> > > expected-error {{not an integral constant}} expected-note {{not >>>> > > supported}} >>>> > > >>>> > > static_assert(__builtin_bcmp(&incomplete, "", 0u) == 0); >>>> > > static_assert(__builtin_bcmp("", &incomplete, 0u) == 0); >>>> > > - static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // >>>> > > expected-error {{not an integral constant}} expected-note {{read of >>>> > > incomplete type 'struct Incomplete'}} >>>> > > - static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // >>>> > > expected-error {{not an integral constant}} expected-note {{read of >>>> > > incomplete type 'struct Incomplete'}} >>>> > > + static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // >>>> > > expected-error {{not an integral constant}} expected-note {{not >>>> > > supported}} >>>> > > + static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // >>>> > > expected-error {{not an integral constant}} expected-note {{not >>>> > > supported}} >>>> > > >>>> > > constexpr unsigned char ku00fe00[] = {0x00, 0xfe, 0x00}; >>>> > > constexpr unsigned char ku00feff[] = {0x00, 0xfe, 0xff}; >>>> > > @@ -155,11 +155,11 @@ namespace StrcmpEtc { >>>> > > >>>> > > struct Bool3Tuple { bool bb[3]; }; >>>> > > constexpr Bool3Tuple kb000100 = {{false, true, false}}; >>>> > > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >>>> > > kb000100.bb, 1) == 0); >>>> > > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >>>> > > kb000100.bb, 2) == 1); >>>> > > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >>>> > > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note >>>> > > {{not supported}} >>>> > > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >>>> > > kb000100.bb, 2) == 1); // expected-error {{constant}} expected-note >>>> > > {{not supported}} >>>> > > >>>> > > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >>>> > > kb000100.bb, 1) == 0); >>>> > > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >>>> > > kb000100.bb, 2) != 0); >>>> > > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >>>> > > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note >>>> > > {{not supported}} >>>> > > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >>>> > > kb000100.bb, 2) != 0); // expected-error {{constant}} expected-note >>>> > > {{not supported}} >>>> > > >>>> > > constexpr long ksl[] = {0, -1}; >>>> > > constexpr unsigned int kui[] = {0, 0u - 1}; >>>> > > @@ -173,25 +173,25 @@ namespace StrcmpEtc { >>>> > > return nullptr; >>>> > > } >>>> > > } >>>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) - >>>> > > 1) == 0); >>>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + >>>> > > 0) == 0); >>>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + >>>> > > 1) == 0); >>>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) - >>>> > > 1) == 0); >>>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >>>> > > 0) == 0); >>>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >>>> > > 1) == 42); // expected-error {{not an integral constant}} expected-note >>>> > > {{dereferenced one-past-the-end}} >>>> > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>>> > > sizeof(long) - 1) == 0); >>>> > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>>> > > sizeof(long) + 0) == 0); >>>> > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>>> > > sizeof(long) + 1) == 42); // expected-error {{not an integral >>>> > > constant}} expected-note {{dereferenced one-past-the-end}} >>>> > > - >>>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - 1) >>>> > > == 0); >>>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 0) >>>> > > == 0); >>>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 1) >>>> > > == 0); >>>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) - >>>> > > 1) == 0); >>>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >>>> > > 0) == 0); >>>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >>>> > > 1) == 42); // expected-error {{not an integral constant}} expected-note >>>> > > {{dereferenced one-past-the-end}} >>>> > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>>> > > sizeof(long) - 1) == 0); >>>> > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>>> > > sizeof(long) + 0) == 0); >>>> > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>>> > > sizeof(long) + 1) == 42); // expected-error {{not an integral >>>> > > constant}} expected-note {{dereferenced one-past-the-end}} >>>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) - >>>> > > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} >>>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + >>>> > > 0) == 0); // expected-error {{constant}} expected-note {{not supported}} >>>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) + >>>> > > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} >>>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) - >>>> > > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} >>>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >>>> > > 0) == 0); // expected-error {{constant}} expected-note {{not supported}} >>>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >>>> > > 1) == 42); // expected-error {{constant}} expected-note {{not >>>> > > supported}} >>>> > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>>> > > sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note >>>> > > {{not supported}} >>>> > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>>> > > sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note >>>> > > {{not supported}} >>>> > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>>> > > sizeof(long) + 1) == 42); // expected-error {{constant}} expected-note >>>> > > {{not supported}} >>>> > > + >>>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - 1) >>>> > > == 0); // expected-error {{constant}} expected-note {{not supported}} >>>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 0) >>>> > > == 0); // expected-error {{constant}} expected-note {{not supported}} >>>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + 1) >>>> > > == 0); // expected-error {{constant}} expected-note {{not supported}} >>>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) - >>>> > > 1) == 0); // expected-error {{constant}} expected-note {{not supported}} >>>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >>>> > > 0) == 0); // expected-error {{constant}} expected-note {{not supported}} >>>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) + >>>> > > 1) == 42); // expected-error {{constant}} expected-note {{not >>>> > > supported}} >>>> > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>>> > > sizeof(long) - 1) == 0); // expected-error {{constant}} expected-note >>>> > > {{not supported}} >>>> > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>>> > > sizeof(long) + 0) == 0); // expected-error {{constant}} expected-note >>>> > > {{not supported}} >>>> > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>>> > > sizeof(long) + 1) == 42); // expected-error {{constant}} expected-note >>>> > > {{not supported}} >>>> > > >>>> > > constexpr int a = strcmp("hello", "world"); // expected-error >>>> > > {{constant expression}} expected-note {{non-constexpr function 'strcmp' >>>> > > cannot be used in a constant expression}} >>>> > > constexpr int b = strncmp("hello", "world", 3); // expected-error >>>> > > {{constant expression}} expected-note {{non-constexpr function >>>> > > 'strncmp' cannot be used in a constant expression}} >>>> > > @@ -385,14 +385,14 @@ namespace StrchrEtc { >>>> > > enum class E : unsigned char {}; >>>> > > struct EPair { E e, f; }; >>>> > > constexpr EPair ee{E{240}}; >>>> > > - static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); >>>> > > + static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); // >>>> > > expected-error {{constant}} expected-note {{not supported}} >>>> > > >>>> > > constexpr bool kBool[] = {false, true, false}; >>>> > > constexpr const bool *const kBoolPastTheEndPtr = kBool + 3; >>>> > > - static_assert(sizeof(bool) != 1u || >>>> > > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); >>>> > > - static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, 0, >>>> > > 99) == kBoolPastTheEndPtr - 1); >>>> > > - static_assert(sizeof(bool) != 1u || >>>> > > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); >>>> > > - static_assert(sizeof(bool) != 1u || >>>> > > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // >>>> > > expected-error {{not an integral constant}} expected-note >>>> > > {{dereferenced one-past-the-end}} >>>> > > + static_assert(sizeof(bool) != 1u || >>>> > > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); // >>>> > > expected-error {{constant}} expected-note {{not supported}} >>>> > > + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, 0, >>>> > > 99) == kBoolPastTheEndPtr - 1); // expected-error {{constant}} >>>> > > expected-note {{not supported}} >>>> > > + static_assert(sizeof(bool) != 1u || >>>> > > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); // >>>> > > expected-error {{constant}} expected-note {{not supported}} >>>> > > + static_assert(sizeof(bool) != 1u || >>>> > > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // >>>> > > expected-error {{constant}} expected-note {{not supported}} >>>> > > >>>> > > static_assert(__builtin_char_memchr(kStr, 'a', 0) == nullptr); >>>> > > static_assert(__builtin_char_memchr(kStr, 'a', 1) == kStr); >>>> > > >>>> > > >>>> > > >>>> > > _______________________________________________ >>>> > > cfe-commits mailing list >>>> > > cfe-commits at lists.llvm.org >>>> > > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>>> > > >>>> > _______________________________________________ >>>> > libcxx-dev mailing list >>>> > libcxx-dev at lists.llvm.org >>>> > https://lists.llvm.org/cgi-bin/mailman/listinfo/libcxx-dev >>>> > >>>> _______________________________________________ >>>> cfe-commits mailing list >>>> cfe-commits at lists.llvm.org >>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits at lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits -------------- next part -------------- An HTML attachment was scrubbed... URL: From cfe-commits at lists.llvm.org Sun Apr 5 15:57:04 2020 From: cfe-commits at lists.llvm.org (Richard Smith via cfe-commits) Date: Sun, 5 Apr 2020 15:57:04 -0700 Subject: [libcxx-dev] [clang] 4ede887 - PR45402: Make the restrictions on constant evaluation of memcmp and In-Reply-To: <16D0B65F-8EA8-42B2-9AE0-6FA2A94D6B0E@znu.io> References: <16D0B65F-8EA8-42B2-9AE0-6FA2A94D6B0E@znu.io> Message-ID: On Sun, 5 Apr 2020 at 15:41, David Zarzycki via cfe-commits < cfe-commits at lists.llvm.org> wrote: > Subjectively speaking, using char8_t instead of char shouldn’t feel like a > regression. So yes, making the builtin mem* functions work with char8_t > again seems right. As for strlen, I can see arguments either way. > Personally, if you’re concerned about clever macros, then I’d make the > overload only visible in C++20 mode where char8_t was introduced. > I don't think that solves the problem. For example, the glibc headers do clever things with __builtin_strlen (which they do, at least in some cases), then this may still result in miscompiles. Eg, consider: struct microseconds { operator const char*() { return "us"; } operator const char8_t*() { return "µs"; } }; char buffer[32]; strcpy(buffer, microseconds()); This should compile, but won't if the implementation of strcpy is a macro that calls __builtin_strlen (as it sometimes is with glibc). Worse would be if the char8_t conversion function is preferred over the char conversion function for some reason, where strcpy might expand to `memcpy(buffer, microseconds(), __builtin_strlen(microseconds()))`, potentially resulting in a buffer overflow (copying using the length of the char8_t string but the content of the char string). If we want to introduce a strlen builtin for char8_t, I think we should give it a different name. I've realized that my suggestion of using __builtin_memchr(p, 0) - p for strlen doesn't actually work, for the usual reason that memchr is mostly useless in constant expressions (because it returns a void*). So maybe we should add a __builtin_memchr_char8_t to parallel the existing __builtin_memchr_char, or maybe make __builtin_memchr_char overloaded on character type? -- > Sent from my iPhone > > On Apr 5, 2020, at 18:18, Richard Smith wrote: > >  > On Sun, 5 Apr 2020 at 14:44, David Zarzycki via cfe-commits < > cfe-commits at lists.llvm.org> wrote: > >> We have overloaded builtins. Can that not solve __builtin_strlen? >> > > I suppose it could, but we generally want __builtin_ to behave > the same as . (The difference would not be visible most of the > time, but there's enough pre-existing use of __builtin_strlen through > "clever" macros and the like that I'd be worried that this would break > something important.) Maybe we should just make the mem* functions work > again for char8_t; then you can use __builtin_memchr(p, 0) - p as an > optimized compile-time strlen. > > >> -- >> Sent from my iPhone >> >> On Apr 5, 2020, at 14:53, Richard Smith wrote: >> >>  >> Thanks. We need to figure out what the right way to support char8_t with >> string builtins is. These ones could work in principle, whereas things like >> __builtin_strlen would never work because they take operands of the wrong >> types (and we can't cast const char8_t* -> const char* in a constant >> expression). >> >> On Sun, 5 Apr 2020 at 04:14, David Zarzycki via cfe-commits < >> cfe-commits at lists.llvm.org> wrote: >> >>> Hi Richard, >>> >>> I'm going to commit a narrow fix to clang to make the libcxx test suite >>> pass again by allowing char8_t again. If you feel that this is the wrong >>> long-term solution, please help the libcxx folks with whatever adjustments >>> they need. >>> >>> Thanks! >>> >>> Dave >>> >>> >>> On Sat, Apr 4, 2020, at 9:55 AM, David Zarzycki via libcxx-dev wrote: >>> > Hi Richard, >>> > >>> > This breaks libcxx. Can we please revert this or is a quick fix to >>> > libcxx possible? >>> > >>> > >>> > FAIL: libc++ :: >>> > >>> std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp >>> (58624 of 62672) >>> > ******************** TEST 'libc++ :: >>> > >>> std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp' >>> FAILED ******************** >>> > Command: ['/p/tllvm/bin/clang++', '-o', >>> > >>> '/tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o', >>> '-x', 'c++', >>> '/home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp', >>> '-c', '-v', '-Werror=thread-safety', '-std=c++2a', '-include', >>> '/home/dave/s/lp/libcxx/test/support/nasty_macros.h', '-nostdinc++', >>> '-I/home/dave/s/lp/libcxx/include', >>> '-I/tmp/_update_lc/t/projects/libcxx/include/c++build', >>> '-D__STDC_FORMAT_MACROS', '-D__STDC_LIMIT_MACROS', >>> '-D__STDC_CONSTANT_MACROS', '-I/home/dave/s/lp/libcxx/test/support', >>> '-ftemplate-depth=270', '-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER', '-Wall', >>> '-Wextra', '-Werror', '-Wuser-defined-warnings', '-Wshadow', >>> '-Wno-unused-command-line-argument', '-Wno-attributes', >>> '-Wno-pessimizing-move', '-Wno-c++11-extensions', >>> '-Wno-user-defined-literals', '-Wno-noexcept-type', '-Wsign-compare', >>> '-Wunused-variable', '-Wunused-parameter', '-Wunreachable-code', '-c'] >>> > Exit Code: 1 >>> > Standard Error: >>> > -- >>> > clang version 11.0.0 (https://github.com/llvm/llvm-project.git >>> > 22127da8f17c03c69231f3631472f7f99ad9cb7f) >>> > Target: x86_64-unknown-linux-gnu >>> > Thread model: posix >>> > InstalledDir: /p/tllvm/bin >>> > Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 >>> > Selected GCC installation: /usr/lib/gcc/x86_64-redhat-linux/9 >>> > Candidate multilib: .;@m64 >>> > Candidate multilib: 32;@m32 >>> > Selected multilib: .;@m64 >>> > (in-process) >>> > "/p/tllvm/bin/clang-11" -cc1 -triple x86_64-unknown-linux-gnu >>> > -emit-obj -mrelax-all -disable-free -disable-llvm-verifier >>> > -discard-value-names -main-file-name compare.pass.cpp >>> > -mrelocation-model static -mthread-model posix -mframe-pointer=all >>> > -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables >>> > -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining >>> > -debugger-tuning=gdb -v -nostdinc++ -resource-dir >>> > /p/tllvm/lib64/clang/11.0.0 -include >>> > /home/dave/s/lp/libcxx/test/support/nasty_macros.h -I >>> > /home/dave/s/lp/libcxx/include -I >>> > /tmp/_update_lc/t/projects/libcxx/include/c++build -D >>> > __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS >>> > -I /home/dave/s/lp/libcxx/test/support -D >>> > _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER -internal-isystem >>> > /usr/local/include -internal-isystem >>> > /p/tllvm/lib64/clang/11.0.0/include -internal-externc-isystem /include >>> > -internal-externc-isystem /usr/include -Werror=thread-safety -Wall >>> > -Wextra -Werror -Wuser-defined-warnings -Wshadow >>> > -Wno-unused-command-line-argument -Wno-attributes >>> -Wno-pessimizing-move >>> > -Wno-c++11-extensions -Wno-user-defined-literals -Wno-noexcept-type >>> > -Wsign-compare -Wunused-variable -Wunused-parameter -Wunreachable-code >>> > -std=c++2a -fdeprecated-macro -fdebug-compilation-dir >>> > >>> /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t >>> -ftemplate-depth 270 -ferror-limit 19 -fgnuc-version=4.2.1 >>> -fno-implicit-modules -fcxx-exceptions -fexceptions -faddrsig -o >>> /tmp/_update_lc/t/projects/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/Output/compare.pass.cpp.o >>> -x c++ >>> /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp >>> > clang -cc1 version 11.0.0 based upon LLVM 11.0.0git default target >>> > x86_64-unknown-linux-gnu >>> > ignoring nonexistent directory "/include" >>> > #include "..." search starts here: >>> > #include <...> search starts here: >>> > /home/dave/s/lp/libcxx/include >>> > /tmp/_update_lc/t/projects/libcxx/include/c++build >>> > /home/dave/s/lp/libcxx/test/support >>> > /usr/local/include >>> > /p/tllvm/lib64/clang/11.0.0/include >>> > /usr/include >>> > End of search list. >>> > >>> /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: >>> error: static_assert expression is not an integral constant expression >>> > static_assert(test_constexpr(), "" ); >>> > ^~~~~~~~~~~~~~~~ >>> > /home/dave/s/lp/libcxx/include/__string:662:12: note: constant >>> > evaluation of '__builtin_memcmp' between arrays of types 'const >>> > char8_t' and 'const char8_t' is not supported; only arrays of narrow >>> > character types can be compared >>> > return __builtin_memcmp(__s1, __s2, __n); >>> > ^ >>> > >>> /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:24:12: >>> note: in call to 'compare(&u8"123"[0], &u8"223"[0], 3)' >>> > return std::char_traits::compare(u8"123", u8"223", 3) < 0 >>> > ^ >>> > >>> /home/dave/s/lp/libcxx/test/std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp:53:19: >>> note: in call to 'test_constexpr()' >>> > static_assert(test_constexpr(), "" ); >>> > ^ >>> > 1 error generated. >>> > -- >>> > >>> > Compilation failed unexpectedly! >>> > ******************** >>> > >>> > Testing Time: 135.49s >>> > ******************** >>> > Failing Tests (1): >>> > libc++ :: >>> > >>> std/strings/char.traits/char.traits.specializations/char.traits.specializations.char8_t/compare.pass.cpp >>> > >>> > Expected Passes : 45503 >>> > Expected Failures : 118 >>> > Unsupported Tests : 17050 >>> > Unexpected Failures: 1 >>> > >>> > >>> > On Fri, Apr 3, 2020, at 9:26 PM, Richard Smith via cfe-commits wrote: >>> > > >>> > > Author: Richard Smith >>> > > Date: 2020-04-03T18:26:14-07:00 >>> > > New Revision: 4ede8879924c08ae5b495d3f421c167d822a60be >>> > > >>> > > URL: >>> > > >>> https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be >>> > > DIFF: >>> > > >>> https://github.com/llvm/llvm-project/commit/4ede8879924c08ae5b495d3f421c167d822a60be.diff >>> > > >>> > > LOG: PR45402: Make the restrictions on constant evaluation of memcmp >>> and >>> > > memchr consistent and comprehensible, and document them. >>> > > >>> > > We previously allowed evaluation of memcmp on arrays of integers of >>> any >>> > > size, so long as the call evaluated to 0, and allowed evaluation of >>> > > memchr on any array of integral type of size 1 (including enums). The >>> > > purpose of constant-evaluating these builtins is only to support >>> > > constexpr std::char_traits, so we now consistently allow them on >>> arrays >>> > > of (possibly signed or unsigned) char only. >>> > > >>> > > Added: >>> > > >>> > > >>> > > Modified: >>> > > clang/docs/LanguageExtensions.rst >>> > > clang/include/clang/Basic/DiagnosticASTKinds.td >>> > > clang/lib/AST/ExprConstant.cpp >>> > > clang/test/SemaCXX/constexpr-string.cpp >>> > > >>> > > Removed: >>> > > >>> > > >>> > > >>> > > >>> ################################################################################ >>> > > diff --git a/clang/docs/LanguageExtensions.rst >>> > > b/clang/docs/LanguageExtensions.rst >>> > > index 558ce7dee653..6dcfd1a49f06 100644 >>> > > --- a/clang/docs/LanguageExtensions.rst >>> > > +++ b/clang/docs/LanguageExtensions.rst >>> > > @@ -2333,10 +2333,11 @@ String builtins >>> > > --------------- >>> > > >>> > > Clang provides constant expression evaluation support for builtins >>> forms of >>> > > -the following functions from the C standard library ```` >>> header: >>> > > +the following functions from the C standard library headers >>> > > +```` and ````: >>> > > >>> > > * ``memchr`` >>> > > -* ``memcmp`` >>> > > +* ``memcmp`` (and its deprecated BSD / POSIX alias ``bcmp``) >>> > > * ``strchr`` >>> > > * ``strcmp`` >>> > > * ``strlen`` >>> > > @@ -2366,7 +2367,11 @@ In addition to the above, one further builtin >>> is >>> > > provided: >>> > > constant expressions in C++11 onwards (where a cast from ``void*`` >>> to >>> > > ``char*`` >>> > > is disallowed in general). >>> > > >>> > > -Support for constant expression evaluation for the above builtins >>> be >>> > > detected >>> > > +Constant evaluation support for the ``__builtin_mem*`` functions is >>> > > provided >>> > > +only for arrays of ``char``, ``signed char``, or ``unsigned char``, >>> > > despite >>> > > +these functions accepting an argument of type ``const void*``. >>> > > + >>> > > +Support for constant expression evaluation for the above builtins >>> can >>> > > be detected >>> > > with ``__has_feature(cxx_constexpr_string_builtins)``. >>> > > >>> > > Memory builtins >>> > > @@ -2386,6 +2391,25 @@ more information. >>> > > >>> > > Note that the `size` argument must be a compile time constant. >>> > > >>> > > +Clang provides constant expression evaluation support for builtin >>> > > forms of the >>> > > +following functions from the C standard library headers >>> > > +```` and ````: >>> > > + >>> > > +* ``memcpy`` >>> > > +* ``memmove`` >>> > > +* ``wmemcpy`` >>> > > +* ``wmemmove`` >>> > > + >>> > > +In each case, the builtin form has the name of the C library >>> function >>> > > prefixed >>> > > +by ``__builtin_``. >>> > > + >>> > > +Constant evaluation support is only provided when the source and >>> > > destination >>> > > +are pointers to arrays with the same trivially copyable element >>> type, >>> > > and the >>> > > +given size is an exact multiple of the element size that is no >>> greater >>> > > than >>> > > +the number of elements accessible through the source and >>> destination >>> > > operands. >>> > > + >>> > > +Constant evaluation support is not yet provided for >>> > > ``__builtin_memcpy_inline``. >>> > > + >>> > > Atomic Min/Max builtins with memory ordering >>> > > -------------------------------------------- >>> > > >>> > > >>> > > diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td >>> > > b/clang/include/clang/Basic/DiagnosticASTKinds.td >>> > > index 544573edffdf..a1415f9ec0e1 100644 >>> > > --- a/clang/include/clang/Basic/DiagnosticASTKinds.td >>> > > +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td >>> > > @@ -244,6 +244,12 @@ def note_constexpr_unsupported_unsized_array : >>> > > Note< >>> > > def note_constexpr_unsized_array_indexed : Note< >>> > > "indexing of array without known bound is not allowed " >>> > > "in a constant expression">; >>> > > +def note_constexpr_memcmp_unsupported : Note< >>> > > + "constant evaluation of %0 between arrays of types %1 and %2 " >>> > > + "is not supported; only arrays of narrow character types can be >>> > > compared">; >>> > > +def note_constexpr_memchr_unsupported : Note< >>> > > + "constant evaluation of %0 on array of type %1 " >>> > > + "is not supported; only arrays of narrow character types can be >>> > > searched">; >>> > > def note_constexpr_memcpy_null : Note< >>> > > "%select{source|destination}2 of " >>> > > "'%select{%select{memcpy|wmemcpy}1|%select{memmove|wmemmove}1}0' " >>> > > >>> > > diff --git a/clang/lib/AST/ExprConstant.cpp >>> > > b/clang/lib/AST/ExprConstant.cpp >>> > > index c6e1cc7b67df..a83b2e24e17f 100644 >>> > > --- a/clang/lib/AST/ExprConstant.cpp >>> > > +++ b/clang/lib/AST/ExprConstant.cpp >>> > > @@ -8469,8 +8469,12 @@ bool >>> > > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >>> > > } >>> > > // Give up on byte-oriented matching against multibyte elements. >>> > > // FIXME: We can compare the bytes in the correct order. >>> > > - if (IsRawByte && Info.Ctx.getTypeSizeInChars(CharTy) != >>> > > CharUnits::One()) >>> > > + if (IsRawByte && !CharTy->isCharType()) { >>> > > + Info.FFDiag(E, diag::note_constexpr_memchr_unsupported) >>> > > + << (std::string("'") + >>> > > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") >>> > > + << CharTy; >>> > > return false; >>> > > + } >>> > > // Figure out what value we're actually looking for (after >>> > > converting to >>> > > // the corresponding unsigned type if necessary). >>> > > uint64_t DesiredVal; >>> > > @@ -8586,6 +8590,7 @@ bool >>> > > PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >>> > > QualType T = Dest.Designator.getType(Info.Ctx); >>> > > QualType SrcT = Src.Designator.getType(Info.Ctx); >>> > > if (!Info.Ctx.hasSameUnqualifiedType(T, SrcT)) { >>> > > + // FIXME: Consider using our bit_cast implementation to >>> support >>> > > this. >>> > > Info.FFDiag(E, diag::note_constexpr_memcpy_type_pun) << Move >>> << >>> > > SrcT << T; >>> > > return false; >>> > > } >>> > > @@ -11149,6 +11154,16 @@ bool >>> > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >>> > > CharTy1, E->getArg(0)->getType()->getPointeeType()) >>> && >>> > > Info.Ctx.hasSameUnqualifiedType(CharTy1, CharTy2))); >>> > > >>> > > + // For memcmp, allow comparing any arrays of '[[un]signed] >>> char', >>> > > + // but no other types. >>> > > + if (IsRawByte && !(CharTy1->isCharType() && >>> > > CharTy2->isCharType())) { >>> > > + // FIXME: Consider using our bit_cast implementation to >>> support >>> > > this. >>> > > + Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported) >>> > > + << (std::string("'") + >>> > > Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'") >>> > > + << CharTy1 << CharTy2; >>> > > + return false; >>> > > + } >>> > > + >>> > > const auto &ReadCurElems = [&](APValue &Char1, APValue &Char2) { >>> > > return handleLValueToRValueConversion(Info, E, CharTy1, >>> String1, >>> > > Char1) && >>> > > handleLValueToRValueConversion(Info, E, CharTy2, >>> String2, >>> > > Char2) && >>> > > @@ -11159,57 +11174,6 @@ bool >>> > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >>> > > HandleLValueArrayAdjustment(Info, E, String2, CharTy2, >>> 1); >>> > > }; >>> > > >>> > > - if (IsRawByte) { >>> > > - uint64_t BytesRemaining = MaxLength; >>> > > - // Pointers to const void may point to objects of incomplete >>> > > type. >>> > > - if (CharTy1->isIncompleteType()) { >>> > > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) >>> << >>> > > CharTy1; >>> > > - return false; >>> > > - } >>> > > - if (CharTy2->isIncompleteType()) { >>> > > - Info.FFDiag(E, diag::note_constexpr_ltor_incomplete_type) >>> << >>> > > CharTy2; >>> > > - return false; >>> > > - } >>> > > - uint64_t CharTy1Width{Info.Ctx.getTypeSize(CharTy1)}; >>> > > - CharUnits CharTy1Size = >>> > > Info.Ctx.toCharUnitsFromBits(CharTy1Width); >>> > > - // Give up on comparing between elements with disparate >>> widths. >>> > > - if (CharTy1Size != Info.Ctx.getTypeSizeInChars(CharTy2)) >>> > > - return false; >>> > > - uint64_t BytesPerElement = CharTy1Size.getQuantity(); >>> > > - assert(BytesRemaining && "BytesRemaining should not be zero: >>> the >>> > > " >>> > > - "following loop considers at least >>> one >>> > > element"); >>> > > - while (true) { >>> > > - APValue Char1, Char2; >>> > > - if (!ReadCurElems(Char1, Char2)) >>> > > - return false; >>> > > - // We have compatible in-memory widths, but a possible type >>> and >>> > > - // (for `bool`) internal representation mismatch. >>> > > - // Assuming two's complement representation, including 0 >>> for >>> > > `false` and >>> > > - // 1 for `true`, we can check an appropriate number of >>> > > elements for >>> > > - // equality even if they are not byte-sized. >>> > > - APSInt Char1InMem = Char1.getInt().extOrTrunc(CharTy1Width); >>> > > - APSInt Char2InMem = Char2.getInt().extOrTrunc(CharTy1Width); >>> > > - if (Char1InMem.ne(Char2InMem)) { >>> > > - // If the elements are byte-sized, then we can produce a >>> > > three-way >>> > > - // comparison result in a straightforward manner. >>> > > - if (BytesPerElement == 1u) { >>> > > - // memcmp always compares unsigned chars. >>> > > - return Success(Char1InMem.ult(Char2InMem) ? -1 : 1, E); >>> > > - } >>> > > - // The result is byte-order sensitive, and we have >>> multibyte >>> > > elements. >>> > > - // FIXME: We can compare the remaining bytes in the >>> correct >>> > > order. >>> > > - return false; >>> > > - } >>> > > - if (!AdvanceElems()) >>> > > - return false; >>> > > - if (BytesRemaining <= BytesPerElement) >>> > > - break; >>> > > - BytesRemaining -= BytesPerElement; >>> > > - } >>> > > - // Enough elements are equal to account for the memcmp limit. >>> > > - return Success(0, E); >>> > > - } >>> > > - >>> > > bool StopAtNull = >>> > > (BuiltinOp != Builtin::BImemcmp && BuiltinOp != >>> > > Builtin::BIbcmp && >>> > > BuiltinOp != Builtin::BIwmemcmp && >>> > > @@ -11227,7 +11191,7 @@ bool >>> > > IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, >>> > > APValue Char1, Char2; >>> > > if (!ReadCurElems(Char1, Char2)) >>> > > return false; >>> > > - if (Char1.getInt() != Char2.getInt()) { >>> > > + if (Char1.getInt().ne(Char2.getInt())) { >>> > > if (IsWide) // wmemcmp compares with wchar_t signedness. >>> > > return Success(Char1.getInt() < Char2.getInt() ? -1 : 1, >>> E); >>> > > // memcmp always compares unsigned chars. >>> > > >>> > > diff --git a/clang/test/SemaCXX/constexpr-string.cpp >>> > > b/clang/test/SemaCXX/constexpr-string.cpp >>> > > index f540be8f8e5b..79ac3bf2cc4d 100644 >>> > > --- a/clang/test/SemaCXX/constexpr-string.cpp >>> > > +++ b/clang/test/SemaCXX/constexpr-string.cpp >>> > > @@ -47,7 +47,7 @@ extern "C" { >>> > > extern wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n); >>> > > } >>> > > >>> > > -# 45 "SemaCXX/constexpr-string.cpp" 2 >>> > > +# 51 "SemaCXX/constexpr-string.cpp" 2 >>> > > namespace Strlen { >>> > > constexpr int n = __builtin_strlen("hello"); // ok >>> > > static_assert(n == 5); >>> > > @@ -121,13 +121,13 @@ namespace StrcmpEtc { >>> > > extern struct Incomplete incomplete; >>> > > static_assert(__builtin_memcmp(&incomplete, "", 0u) == 0); >>> > > static_assert(__builtin_memcmp("", &incomplete, 0u) == 0); >>> > > - static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{read of >>> > > incomplete type 'struct Incomplete'}} >>> > > - static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{read of >>> > > incomplete type 'struct Incomplete'}} >>> > > + static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{not >>> > > supported}} >>> > > + static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{not >>> > > supported}} >>> > > >>> > > static_assert(__builtin_bcmp(&incomplete, "", 0u) == 0); >>> > > static_assert(__builtin_bcmp("", &incomplete, 0u) == 0); >>> > > - static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{read of >>> > > incomplete type 'struct Incomplete'}} >>> > > - static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{read of >>> > > incomplete type 'struct Incomplete'}} >>> > > + static_assert(__builtin_bcmp(&incomplete, "", 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{not >>> > > supported}} >>> > > + static_assert(__builtin_bcmp("", &incomplete, 1u) == 42); // >>> > > expected-error {{not an integral constant}} expected-note {{not >>> > > supported}} >>> > > >>> > > constexpr unsigned char ku00fe00[] = {0x00, 0xfe, 0x00}; >>> > > constexpr unsigned char ku00feff[] = {0x00, 0xfe, 0xff}; >>> > > @@ -155,11 +155,11 @@ namespace StrcmpEtc { >>> > > >>> > > struct Bool3Tuple { bool bb[3]; }; >>> > > constexpr Bool3Tuple kb000100 = {{false, true, false}}; >>> > > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >>> > > kb000100.bb, 1) == 0); >>> > > - static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >>> > > kb000100.bb, 2) == 1); >>> > > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >>> > > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note >>> > > {{not supported}} >>> > > + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, >>> > > kb000100.bb, 2) == 1); // expected-error {{constant}} expected-note >>> > > {{not supported}} >>> > > >>> > > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >>> > > kb000100.bb, 1) == 0); >>> > > - static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >>> > > kb000100.bb, 2) != 0); >>> > > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >>> > > kb000100.bb, 1) == 0); // expected-error {{constant}} expected-note >>> > > {{not supported}} >>> > > + static_assert(sizeof(bool) != 1u || __builtin_bcmp(ks00fe00, >>> > > kb000100.bb, 2) != 0); // expected-error {{constant}} expected-note >>> > > {{not supported}} >>> > > >>> > > constexpr long ksl[] = {0, -1}; >>> > > constexpr unsigned int kui[] = {0, 0u - 1}; >>> > > @@ -173,25 +173,25 @@ namespace StrcmpEtc { >>> > > return nullptr; >>> > > } >>> > > } >>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) >>> - >>> > > 1) == 0); >>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) >>> + >>> > > 0) == 0); >>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) >>> + >>> > > 1) == 0); >>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), >>> 2*sizeof(long) - >>> > > 1) == 0); >>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), >>> 2*sizeof(long) + >>> > > 0) == 0); >>> > > - static_assert(__builtin_memcmp(ksl, kuSizeofLong(), >>> 2*sizeof(long) + >>> > > 1) == 42); // expected-error {{not an integral constant}} >>> expected-note >>> > > {{dereferenced one-past-the-end}} >>> > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) - 1) == 0); >>> > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 0) == 0); >>> > > - static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 1) == 42); // expected-error {{not an integral >>> > > constant}} expected-note {{dereferenced one-past-the-end}} >>> > > - >>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - >>> 1) >>> > > == 0); >>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + >>> 0) >>> > > == 0); >>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + >>> 1) >>> > > == 0); >>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) >>> - >>> > > 1) == 0); >>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) >>> + >>> > > 0) == 0); >>> > > - static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) >>> + >>> > > 1) == 42); // expected-error {{not an integral constant}} >>> expected-note >>> > > {{dereferenced one-past-the-end}} >>> > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) - 1) == 0); >>> > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 0) == 0); >>> > > - static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 1) == 42); // expected-error {{not an integral >>> > > constant}} expected-note {{dereferenced one-past-the-end}} >>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) >>> - >>> > > 1) == 0); // expected-error {{constant}} expected-note {{not >>> supported}} >>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) >>> + >>> > > 0) == 0); // expected-error {{constant}} expected-note {{not >>> supported}} >>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), sizeof(long) >>> + >>> > > 1) == 0); // expected-error {{constant}} expected-note {{not >>> supported}} >>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), >>> 2*sizeof(long) - >>> > > 1) == 0); // expected-error {{constant}} expected-note {{not >>> supported}} >>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), >>> 2*sizeof(long) + >>> > > 0) == 0); // expected-error {{constant}} expected-note {{not >>> supported}} >>> > > + static_assert(__builtin_memcmp(ksl, kuSizeofLong(), >>> 2*sizeof(long) + >>> > > 1) == 42); // expected-error {{constant}} expected-note {{not >>> > > supported}} >>> > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) - 1) == 0); // expected-error {{constant}} >>> expected-note >>> > > {{not supported}} >>> > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 0) == 0); // expected-error {{constant}} >>> expected-note >>> > > {{not supported}} >>> > > + static_assert(__builtin_memcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 1) == 42); // expected-error {{constant}} >>> expected-note >>> > > {{not supported}} >>> > > + >>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) - >>> 1) >>> > > == 0); // expected-error {{constant}} expected-note {{not supported}} >>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + >>> 0) >>> > > == 0); // expected-error {{constant}} expected-note {{not supported}} >>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), sizeof(long) + >>> 1) >>> > > == 0); // expected-error {{constant}} expected-note {{not supported}} >>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) >>> - >>> > > 1) == 0); // expected-error {{constant}} expected-note {{not >>> supported}} >>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) >>> + >>> > > 0) == 0); // expected-error {{constant}} expected-note {{not >>> supported}} >>> > > + static_assert(__builtin_bcmp(ksl, kuSizeofLong(), 2*sizeof(long) >>> + >>> > > 1) == 42); // expected-error {{constant}} expected-note {{not >>> > > supported}} >>> > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) - 1) == 0); // expected-error {{constant}} >>> expected-note >>> > > {{not supported}} >>> > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 0) == 0); // expected-error {{constant}} >>> expected-note >>> > > {{not supported}} >>> > > + static_assert(__builtin_bcmp(ksl + 1, kuSizeofLong() + 1, >>> > > sizeof(long) + 1) == 42); // expected-error {{constant}} >>> expected-note >>> > > {{not supported}} >>> > > >>> > > constexpr int a = strcmp("hello", "world"); // expected-error >>> > > {{constant expression}} expected-note {{non-constexpr function >>> 'strcmp' >>> > > cannot be used in a constant expression}} >>> > > constexpr int b = strncmp("hello", "world", 3); // expected-error >>> > > {{constant expression}} expected-note {{non-constexpr function >>> > > 'strncmp' cannot be used in a constant expression}} >>> > > @@ -385,14 +385,14 @@ namespace StrchrEtc { >>> > > enum class E : unsigned char {}; >>> > > struct EPair { E e, f; }; >>> > > constexpr EPair ee{E{240}}; >>> > > - static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); >>> > > + static_assert(__builtin_memchr(&ee.e, 240, 1) == &ee.e); // >>> > > expected-error {{constant}} expected-note {{not supported}} >>> > > >>> > > constexpr bool kBool[] = {false, true, false}; >>> > > constexpr const bool *const kBoolPastTheEndPtr = kBool + 3; >>> > > - static_assert(sizeof(bool) != 1u || >>> > > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); >>> > > - static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, >>> 0, >>> > > 99) == kBoolPastTheEndPtr - 1); >>> > > - static_assert(sizeof(bool) != 1u || >>> > > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); >>> > > - static_assert(sizeof(bool) != 1u || >>> > > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // >>> > > expected-error {{not an integral constant}} expected-note >>> > > {{dereferenced one-past-the-end}} >>> > > + static_assert(sizeof(bool) != 1u || >>> > > __builtin_memchr(kBoolPastTheEndPtr - 3, 1, 99) == kBool + 1); // >>> > > expected-error {{constant}} expected-note {{not supported}} >>> > > + static_assert(sizeof(bool) != 1u || __builtin_memchr(kBool + 1, >>> 0, >>> > > 99) == kBoolPastTheEndPtr - 1); // expected-error {{constant}} >>> > > expected-note {{not supported}} >>> > > + static_assert(sizeof(bool) != 1u || >>> > > __builtin_memchr(kBoolPastTheEndPtr - 3, -1, 3) == nullptr); // >>> > > expected-error {{constant}} expected-note {{not supported}} >>> > > + static_assert(sizeof(bool) != 1u || >>> > > __builtin_memchr(kBoolPastTheEndPtr, 0, 1) == nullptr); // >>> > > expected-error {{constant}} expected-note {{not supported}} >>> > > >>> > > static_assert(__builtin_char_memchr(kStr, 'a', 0) == nullptr); >>> > > static_assert(__builtin_char_memchr(kStr, 'a', 1) == kStr); >>> > > >>> > > >>> > > >>> > > _______________________________________________ >>> > > cfe-commits mailing list >>> > > cfe-commits at lists.llvm.org >>> > > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>> > > >>> > _______________________________________________ >>> > libcxx-dev mailing list >>> > libcxx-dev at lists.llvm.org >>> > https://lists.llvm.org/cgi-bin/mailman/listinfo/libcxx-dev >>> > >>> _______________________________________________ >>> cfe-commits mailing list >>> cfe-commits at lists.llvm.org >>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits at lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > _______________________________________________ > cfe-commits mailing list > cfe-commits at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cfe-commits at lists.llvm.org Sun Apr 5 16:02:02 2020 From: cfe-commits at lists.llvm.org (Richard Smith - zygoloid via Phabricator via cfe-commits) Date: Sun, 05 Apr 2020 23:02:02 +0000 (UTC) Subject: [PATCH] D68115: Zero initialize padding in unions In-Reply-To: References: Message-ID: rsmith added a comment. In D68115#1946990 , @jfb wrote: > In D68115#1946757 , @rsmith wrote: > > > In D68115#1946668 , @hubert.reinterpretcast wrote: > > > > > It sounds like we are looking for `-fzero-union-padding`. That's been where the discussion has left off twice for months. > > > > > > I believe the state of Clang prior to this patch is actually wrong. > > > That's my understanding as well. I'd like it if this patch (or a follow-up) got us back to standard behavior. In either case, I'd like the proposed behavior to bee on-by-default when doing initialization of stack variables. Your preference is noted. However, I think the majority opinion expressed on this review at this point favors not guaranteeing zero-initialization except where required by the relevant standard. That'd also be consistent with our stance on trivial auto variable initialization in general. I'm not yet sure about whether we want separate controls for this and for `-ftrivial-auto-init`, or whether from a user's perspective there's really only one question: should bits left uninitialized be `undef`, guaranteed zero, or guaranteed to be filled with a pattern -- independent of whether they're padding bits? (And related, do we actually want control over zeroing union padding in all cases or only for trivial automatic variables? And do we want control over zeroing or pattern-filling objects allocated with `new` with trivial initialization?) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68115/new/ https://reviews.llvm.org/D68115 From cfe-commits at lists.llvm.org Sun Apr 5 16:31:38 2020 From: cfe-commits at lists.llvm.org (David Blaikie via cfe-commits) Date: Sun, 05 Apr 2020 16:31:38 -0700 (PDT) Subject: [clang] e9644e6 - DebugInfo: Fix default template parameter computation for dependent non-type template parameters Message-ID: <5e8a6a5a.1c69fb81.4139e.72cd@mx.google.com> Author: David Blaikie Date: 2020-04-05T16:31:30-07:00 New Revision: e9644e6f4f21e6b6177ef9085cdc9ed9f44b7783 URL: https://github.com/llvm/llvm-project/commit/e9644e6f4f21e6b6177ef9085cdc9ed9f44b7783 DIFF: https://github.com/llvm/llvm-project/commit/e9644e6f4f21e6b6177ef9085cdc9ed9f44b7783.diff LOG: DebugInfo: Fix default template parameter computation for dependent non-type template parameters This addresses the immediate bug, though in theory we could still produce a default parameter for the DWARF in this test case - but other cases will be definitely unachievable (you could have a default parameter that cannot be evaluated - so long as the user overrode it with another value rather than relying on that default) Added: Modified: clang/lib/CodeGen/CGDebugInfo.cpp clang/test/CodeGenCXX/debug-info-template-parameter.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 6d3c2ad66cdc..5f05323f61ef 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1816,7 +1816,8 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList, if (TPList && CGM.getCodeGenOpts().DwarfVersion >= 5) if (auto *templateType = dyn_cast_or_null(TPList->getParam(i))) - if (templateType->hasDefaultArgument()) + if (templateType->hasDefaultArgument() && + !templateType->getDefaultArgument()->isValueDependent()) defaultParameter = llvm::APSInt::isSameValue( templateType->getDefaultArgument()->EvaluateKnownConstInt( CGM.getContext()), diff --git a/clang/test/CodeGenCXX/debug-info-template-parameter.cpp b/clang/test/CodeGenCXX/debug-info-template-parameter.cpp index c38c535d8b06..fee6dfe8b898 100644 --- a/clang/test/CodeGenCXX/debug-info-template-parameter.cpp +++ b/clang/test/CodeGenCXX/debug-info-template-parameter.cpp @@ -8,24 +8,24 @@ // CHECK: DILocalVariable(name: "f1", {{.*}}, type: ![[TEMPLATE_TYPE:[0-9]+]] // CHECK: [[TEMPLATE_TYPE]] = {{.*}}!DICompositeType({{.*}}, templateParams: ![[F1_TYPE:[0-9]+]] -// CHECK: [[F1_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]], ![[THIRD:[0-9]+]]} +// CHECK: [[F1_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]], ![[THIRD:[0-9]+]], ![[FORTH:[0-9]+]]} // CHECK: [[FIRST]] = !DITemplateTypeParameter(name: "T", type: !{{[0-9]*}}) // CHECK: [[SECOND]] = !DITemplateValueParameter(name: "i", type: !{{[0-9]*}}, value: i32 6) // CHECK: [[THIRD]] = !DITemplateValueParameter(name: "b", type: !{{[0-9]*}}, value: i8 0) // CHECK: DILocalVariable(name: "f2", {{.*}}, type: ![[TEMPLATE_TYPE:[0-9]+]] // CHECK: [[TEMPLATE_TYPE]] = {{.*}}!DICompositeType({{.*}}, templateParams: ![[F2_TYPE:[0-9]+]] -// CHECK: [[F2_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]], ![[THIRD:[0-9]+]]} +// CHECK: [[F2_TYPE]] = !{![[FIRST:[0-9]+]], ![[SECOND:[0-9]+]], ![[THIRD:[0-9]+]], ![[FORTH:[0-9]+]]} // CHECK: [[FIRST]] = !DITemplateTypeParameter(name: "T", type: !{{[0-9]*}}, defaulted: true) // CHECK: [[SECOND]] = !DITemplateValueParameter(name: "i", type: !{{[0-9]*}}, defaulted: true, value: i32 3) // CHECK: [[THIRD]] = !DITemplateValueParameter(name: "b", type: !{{[0-9]*}}, defaulted: true, value: i8 1) -template +template class foo { }; int main() { - foo f1; + foo f1; foo<> f2; return 0; } From cfe-commits at lists.llvm.org Sun Apr 5 17:06:20 2020 From: cfe-commits at lists.llvm.org (Mike Rice via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 00:06:20 +0000 (UTC) Subject: [PATCH] D77414: [OpenMP] Add match_{all,any,none} declare variant selector extensions. In-Reply-To: References: Message-ID: <2c1bf48759babad6b02c7b3598414331@localhost.localdomain> mikerice added inline comments. ================ Comment at: clang/lib/Parse/ParseOpenMP.cpp:1823 ASTContext &ASTCtx = Actions.getASTContext(); - TI.getAsVariantMatchInfo(ASTCtx, VMI, /* DeviceSetOnly */ true); + TI.getAsVariantMatchInfo(ASTCtx, VMI); OMPContext OMPCtx(ASTCtx.getLangOpts().OpenMPIsDevice, ---------------- One of the lit tests fails because this is called before semantic checks on the score expression. This function tries to evaluate the score as a constant and if it isn't will crash. Probably not specific to this change but how can we deal with that? ``` int foo(void); #pragma omp begin declare variant match(implementation={vendor(score(foo()) ibm)}) #pragma omp end declare variant ``` ================ Comment at: llvm/lib/Frontend/OpenMP/OMPContext.cpp:161 + bool WasFound) -> Optional /* Result */ { + // For kind "any" a single match is enough but we ignore non-matched properties. + if (MK == MK_ANY) { ---------------- Line too long? ================ Comment at: llvm/lib/Frontend/OpenMP/OMPContext.cpp:252 + bool DeviceSetOnly) { + return isVariantApplicableInContextHelper(VMI, Ctx, nullptr, DeviceSetOnly); } ---------------- Comment on nullptr would be nice. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77414/new/ https://reviews.llvm.org/D77414 From cfe-commits at lists.llvm.org Sun Apr 5 17:06:20 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 00:06:20 +0000 (UTC) Subject: [PATCH] D77290: [OpenMP] Specialize OpenMP calls after template instantiation In-Reply-To: References: Message-ID: jdoerfert updated this revision to Diff 255210. jdoerfert added a comment. rebase Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77290/new/ https://reviews.llvm.org/D77290 Files: clang/lib/Sema/SemaTemplateInstantiate.cpp clang/test/AST/ast-dump-openmp-begin-declare-variant_template_1.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77290.255210.patch Type: text/x-patch Size: 14835 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 17:09:15 2020 From: cfe-commits at lists.llvm.org (JF Bastien via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 00:09:15 +0000 (UTC) Subject: [PATCH] D68115: Zero initialize padding in unions In-Reply-To: References: Message-ID: jfb added a comment. In D68115#1962833 , @rsmith wrote: > In D68115#1946990 , @jfb wrote: > > > In D68115#1946757 , @rsmith wrote: > > > > > In D68115#1946668 , @hubert.reinterpretcast wrote: > > > > > > > It sounds like we are looking for `-fzero-union-padding`. That's been where the discussion has left off twice for months. > > > > > > > > > I believe the state of Clang prior to this patch is actually wrong. > > > > > > That's my understanding as well. I'd like it if this patch (or a follow-up) got us back to standard behavior. In either case, I'd like the proposed behavior to bee on-by-default when doing initialization of stack variables. > > > Your preference is noted. However, I think the majority opinion expressed on this review at this point favors not guaranteeing zero-initialization except where required by the relevant standard. That'd also be consistent with our stance on trivial auto variable initialization in general. Sorry, I didn't express myself well: if trivial auto-var init is on, then I want initialization of union padding to also be on. I think this is exactly compatible with what you want, as is says nothing of the behavior when trivial auto-var init is not on. > I'm not yet sure about whether we want separate controls for this and for `-ftrivial-auto-init`, or whether from a user's perspective there's really only one question: should bits left uninitialized be `undef`, guaranteed zero, or guaranteed to be filled with a pattern -- independent of whether they're padding bits? (And related, do we actually want control over zeroing union padding in all cases or only for trivial automatic variables? And do we want control over zeroing or pattern-filling objects allocated with `new` with trivial initialization?) Trivial auto-var init should always initialize all stack padding, and should not also initialize heap padding. There should be separate controls for heap padding, in part because this interacts with the allocator (whereas stack initialization does not). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68115/new/ https://reviews.llvm.org/D68115 From cfe-commits at lists.llvm.org Sun Apr 5 17:38:08 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 00:38:08 +0000 (UTC) Subject: [PATCH] D77414: [OpenMP] Add match_{all,any,none} declare variant selector extensions. In-Reply-To: References: Message-ID: jdoerfert updated this revision to Diff 255212. jdoerfert added a comment. Rebase and fix a problem with evaluation of non-constants Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77414/new/ https://reviews.llvm.org/D77414 Files: clang/include/clang/AST/OpenMPClause.h clang/include/clang/Basic/AttrDocs.td clang/include/clang/Basic/DiagnosticParseKinds.td clang/lib/AST/OpenMPClause.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/test/AST/ast-dump-openmp-declare-variant-extensions-messages.c clang/test/AST/ast-dump-openmp-declare-variant-extensions.c clang/test/OpenMP/declare_variant_ast_print.c clang/test/OpenMP/declare_variant_messages.c llvm/include/llvm/Frontend/OpenMP/OMPContext.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPContext.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77414.255212.patch Type: text/x-patch Size: 55163 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 18:10:13 2020 From: cfe-commits at lists.llvm.org (Richard Smith - zygoloid via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 01:10:13 +0000 (UTC) Subject: [PATCH] D68115: Zero initialize padding in unions In-Reply-To: References: Message-ID: <1b0989c71a288bef480e75653cfff73d@localhost.localdomain> rsmith added a comment. In D68115#1962863 , @jfb wrote: > In D68115#1962833 , @rsmith wrote: > > > I think the majority opinion expressed on this review at this point favors not guaranteeing zero-initialization except where required by the relevant standard. That'd also be consistent with our stance on trivial auto variable initialization in general. > > > Sorry, I didn't express myself well: if trivial auto-var init is on, then I want initialization of union padding to also be on. I think this is exactly compatible with what you want, as is says nothing of the behavior when trivial auto-var init is not on. > > > I'm not yet sure about whether we want separate controls for this and for `-ftrivial-auto-init`, or whether from a user's perspective there's really only one question: should bits left uninitialized be `undef`, guaranteed zero, or guaranteed to be filled with a pattern -- independent of whether they're padding bits? (And related, do we actually want control over zeroing union padding in all cases or only for trivial automatic variables? And do we want control over zeroing or pattern-filling objects allocated with `new` with trivial initialization?) > > Trivial auto-var init should always initialize all stack padding, and should not also initialize heap padding. There should be separate controls for heap padding, in part because this interacts with the allocator (whereas stack initialization does not). That sounds reasonable to me. So the behavior we're looking for is: - If `-ftrivial-auto-init` is off, then we guarantee to zero padding when the language spec requires it, and otherwise provide no such guarantee. - If `-ftrivial-auto-init=zeroes` then we guarantee to zero padding within structs and unions with automatic storage duration, when that padding would otherwise be left uninitialized. - If `-ftrivial-auto-init=pattern` then we guarantee to pattern-fill padding within structs and unions with automatic storage duration, when that padding would otherwise be left uninitialized (and will provide the zeroes required by the language rule when that is the required behavior). [One possible tweak: for the `pattern` case, should we guarantee that the uninitialized padding will be pattern-filled? It would be simpler if we guaranteed it to be *either* zero- or pattern-filled; that way we can provide a conservatively-correct approximation by zero-filling whenever we're unsure.] And we do not initially provide any guarantees as to what happens to padding within objects of other storage durations beyond what the language spec requires. (We might at some point in the future, but that would be behind a separate flag from `-ftrivial-auto-init`.) I'd be happy with that approach. Does that address everyone's concerns? If so, how do we make progress on this? @vitalybuka, are you interested in doing the work to track whether padding should be zeroed in `APValue`? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68115/new/ https://reviews.llvm.org/D68115 From cfe-commits at lists.llvm.org Sun Apr 5 19:14:03 2020 From: cfe-commits at lists.llvm.org (David Blaikie via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 02:14:03 +0000 (UTC) Subject: [PATCH] D76646: Rename/refactor isIntegerConstantExpression to getIntegerConstantExpression In-Reply-To: References: Message-ID: <55cf69e357c7a4c6b0b73106cdff73c0@localhost.localdomain> dblaikie added a comment. Ping Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D76646/new/ https://reviews.llvm.org/D76646 From cfe-commits at lists.llvm.org Sun Apr 5 19:14:03 2020 From: cfe-commits at lists.llvm.org (Zoe Carver via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 02:14:03 +0000 (UTC) Subject: [PATCH] D77519: Fix __is_pointer builtin type trait to work with Objective-C pointer types. Message-ID: zoecarver created this revision. Herald added projects: clang, libc++. Herald added subscribers: libcxx-commits, cfe-commits. Herald added a reviewer: libc++. zoecarver added reviewers: ldionne, rsmith, EricWF. Herald added a subscriber: dexonsmith. 5ade17e broke __is_pointer for Objective-C pointer types. This patch fixes the builtin and re-applies the change to type_traits. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77519 Files: clang/lib/Sema/SemaExprCXX.cpp clang/test/SemaObjC/type-traits-is-pointer.mm libcxx/include/type_traits -------------- next part -------------- A non-text attachment was scrubbed... Name: D77519.255214.patch Type: text/x-patch Size: 3165 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 19:45:49 2020 From: cfe-commits at lists.llvm.org (Jakub Kuderski via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 02:45:49 +0000 (UTC) Subject: [PATCH] D77341: [DomTree] Replace ChildrenGetter with GraphTraits over GraphDiff. In-Reply-To: References: Message-ID: <0b96ddaac5b192ccb95fd1ddbfe84f1c@localhost.localdomain> kuhar added a comment. In D77341#1960854 , @asbirlea wrote: > Address comments. Thanks for the changes and explanations. It think with a few more tweaks this will be a good refactoring step towards phasing out BUI. ================ Comment at: llvm/include/llvm/IR/CFGDiff.h:198 +namespace { +template ---------------- What benefit does an anonymous namespace in a header have over a named one, e.g., `detail`/`impl`? Doesn't it make it more difficult to deduplicate symbols across different translation units? Not sure what the best practices are in C++ now in this area. ================ Comment at: llvm/include/llvm/Support/GenericDomTreeConstruction.h:325 + auto &GD = BUI ? BUI->PreViewCFG : EmptyGD; + return !empty(children({&GD, N})); } ---------------- This pattern repeats a few times. Could it be pushed into a helper function to get something like this? ``` return !empty(children(GetGraphDiffNodePair(BUI, N))); ``` Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77341/new/ https://reviews.llvm.org/D77341 From cfe-commits at lists.llvm.org Sun Apr 5 19:45:49 2020 From: cfe-commits at lists.llvm.org (Jakub Kuderski via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 02:45:49 +0000 (UTC) Subject: [PATCH] D77341: [DomTree] Replace ChildrenGetter with GraphTraits over GraphDiff. In-Reply-To: References: Message-ID: <68124faafb61149761119dd38ed8c68f@localhost.localdomain> kuhar added inline comments. ================ Comment at: llvm/include/llvm/IR/CFGDiff.h:198 +namespace { +template ---------------- kuhar wrote: > What benefit does an anonymous namespace in a header have over a named one, e.g., `detail`/`impl`? Doesn't it make it more difficult to deduplicate symbols across different translation units? Not sure what the best practices are in C++ now in this area. Found an article on this matter: https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL59-CPP.+Do+not+define+an+unnamed+namespace+in+a+header+file Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77341/new/ https://reviews.llvm.org/D77341 From cfe-commits at lists.llvm.org Sun Apr 5 20:31:46 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via cfe-commits) Date: Sun, 05 Apr 2020 20:31:46 -0700 (PDT) Subject: [clang] 419a559 - [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` Message-ID: <5e8aa2a2.1c69fb81.74c72.f873@mx.google.com> Author: Johannes Doerfert Date: 2020-04-05T22:30:29-05:00 New Revision: 419a559c5a73f13578d891feb1299cada08d581e URL: https://github.com/llvm/llvm-project/commit/419a559c5a73f13578d891feb1299cada08d581e DIFF: https://github.com/llvm/llvm-project/commit/419a559c5a73f13578d891feb1299cada08d581e.diff LOG: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` This is a cleanup and normalization patch that also enables reuse with Flang later on. A follow up will clean up and move the directive -> clauses mapping. Reviewed By: fghanim Differential Revision: https://reviews.llvm.org/D77112 Added: Modified: clang/include/clang/AST/ASTFwd.h clang/include/clang/AST/ASTTypeTraits.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/Basic/Attr.td clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Basic/OpenMPKinds.h clang/lib/AST/ASTTypeTraits.cpp clang/lib/AST/AttrImpl.cpp clang/lib/AST/OpenMPClause.cpp clang/lib/AST/StmtProfile.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/ASTMatchers/CMakeLists.txt clang/lib/ASTMatchers/Dynamic/Marshallers.h clang/lib/Analysis/CMakeLists.txt clang/lib/Basic/OpenMPKinds.cpp clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt clang/lib/StaticAnalyzer/Core/CMakeLists.txt clang/tools/libclang/CIndex.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp llvm/include/llvm/Frontend/OpenMP/OMPConstants.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPConstants.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/ASTFwd.h b/clang/include/clang/AST/ASTFwd.h index 5a891817b336..65319a19728b 100644 --- a/clang/include/clang/AST/ASTFwd.h +++ b/clang/include/clang/AST/ASTFwd.h @@ -27,8 +27,8 @@ class Type; #include "clang/AST/TypeNodes.inc" class CXXCtorInitializer; class OMPClause; -#define OPENMP_CLAUSE(KIND, CLASSNAME) class CLASSNAME; -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) class Class; +#include "llvm/Frontend/OpenMP/OMPKinds.def" } // end namespace clang diff --git a/clang/include/clang/AST/ASTTypeTraits.h b/clang/include/clang/AST/ASTTypeTraits.h index a9c2e334a29e..cd80e9bc3808 100644 --- a/clang/include/clang/AST/ASTTypeTraits.h +++ b/clang/include/clang/AST/ASTTypeTraits.h @@ -148,8 +148,8 @@ class ASTNodeKind { #define TYPE(DERIVED, BASE) NKI_##DERIVED##Type, #include "clang/AST/TypeNodes.inc" NKI_OMPClause, -#define OPENMP_CLAUSE(TextualSpelling, Class) NKI_##Class, -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) NKI_##Class, +#include "llvm/Frontend/OpenMP/OMPKinds.def" NKI_NumberOfKinds }; @@ -204,8 +204,8 @@ KIND_TO_KIND_ID(OMPClause) #include "clang/AST/StmtNodes.inc" #define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type) #include "clang/AST/TypeNodes.inc" -#define OPENMP_CLAUSE(TextualSpelling, Class) KIND_TO_KIND_ID(Class) -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class) +#include "llvm/Frontend/OpenMP/OMPKinds.def" #undef KIND_TO_KIND_ID inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) { diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index efa6d0554a7c..9f5ff5a85182 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -285,12 +285,13 @@ class OMPAllocatorClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_allocator, StartLoc, EndLoc), LParenLoc(LParenLoc), - Allocator(A) {} + : OMPClause(llvm::omp::OMPC_allocator, StartLoc, EndLoc), + LParenLoc(LParenLoc), Allocator(A) {} /// Build an empty clause. OMPAllocatorClause() - : OMPClause(OMPC_allocator, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_allocator, SourceLocation(), + SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -315,7 +316,7 @@ class OMPAllocatorClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_allocator; + return T->getClauseKind() == llvm::omp::OMPC_allocator; } }; @@ -350,17 +351,17 @@ class OMPAllocateClause final OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc, Expr *Allocator, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_allocate, StartLoc, LParenLoc, - EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_allocate, StartLoc, + LParenLoc, EndLoc, N), Allocator(Allocator), ColonLoc(ColonLoc) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPAllocateClause(unsigned N) - : OMPVarListClause(OMPC_allocate, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_allocate, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} /// Sets location of ':' symbol in clause. void setColonLoc(SourceLocation CL) { ColonLoc = CL; } @@ -412,7 +413,7 @@ class OMPAllocateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_allocate; + return T->getClauseKind() == llvm::omp::OMPC_allocate; } }; @@ -470,15 +471,16 @@ class OMPIfClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc) - : OMPClause(OMPC_if, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Condition(Cond), ColonLoc(ColonLoc), - NameModifier(NameModifier), NameModifierLoc(NameModifierLoc) { + : OMPClause(llvm::omp::OMPC_if, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond), + ColonLoc(ColonLoc), NameModifier(NameModifier), + NameModifierLoc(NameModifierLoc) { setPreInitStmt(HelperCond, CaptureRegion); } /// Build an empty clause. OMPIfClause() - : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_if, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -512,7 +514,7 @@ class OMPIfClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_if; + return T->getClauseKind() == llvm::omp::OMPC_if; } }; @@ -548,14 +550,14 @@ class OMPFinalClause : public OMPClause, public OMPClauseWithPreInit { OMPFinalClause(Expr *Cond, Stmt *HelperCond, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_final, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Condition(Cond) { + : OMPClause(llvm::omp::OMPC_final, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) { setPreInitStmt(HelperCond, CaptureRegion); } /// Build an empty clause. OMPFinalClause() - : OMPClause(OMPC_final, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_final, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -580,7 +582,7 @@ class OMPFinalClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_final; + return T->getClauseKind() == llvm::omp::OMPC_final; } }; @@ -618,7 +620,7 @@ class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_threads, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_num_threads, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumThreads(NumThreads) { setPreInitStmt(HelperNumThreads, CaptureRegion); @@ -626,7 +628,8 @@ class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit { /// Build an empty clause. OMPNumThreadsClause() - : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_num_threads, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -652,7 +655,7 @@ class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_num_threads; + return T->getClauseKind() == llvm::omp::OMPC_num_threads; } }; @@ -688,12 +691,13 @@ class OMPSafelenClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc), - Safelen(Len) {} + : OMPClause(llvm::omp::OMPC_safelen, StartLoc, EndLoc), + LParenLoc(LParenLoc), Safelen(Len) {} /// Build an empty clause. explicit OMPSafelenClause() - : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_safelen, SourceLocation(), SourceLocation()) { + } /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -718,7 +722,7 @@ class OMPSafelenClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_safelen; + return T->getClauseKind() == llvm::omp::OMPC_safelen; } }; @@ -753,12 +757,13 @@ class OMPSimdlenClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_simdlen, StartLoc, EndLoc), LParenLoc(LParenLoc), - Simdlen(Len) {} + : OMPClause(llvm::omp::OMPC_simdlen, StartLoc, EndLoc), + LParenLoc(LParenLoc), Simdlen(Len) {} /// Build an empty clause. explicit OMPSimdlenClause() - : OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_simdlen, SourceLocation(), SourceLocation()) { + } /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -783,7 +788,7 @@ class OMPSimdlenClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_simdlen; + return T->getClauseKind() == llvm::omp::OMPC_simdlen; } }; @@ -819,12 +824,13 @@ class OMPCollapseClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPCollapseClause(Expr *Num, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc), - NumForLoops(Num) {} + : OMPClause(llvm::omp::OMPC_collapse, StartLoc, EndLoc), + LParenLoc(LParenLoc), NumForLoops(Num) {} /// Build an empty clause. explicit OMPCollapseClause() - : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_collapse, SourceLocation(), + SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -849,7 +855,7 @@ class OMPCollapseClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_collapse; + return T->getClauseKind() == llvm::omp::OMPC_collapse; } }; @@ -893,12 +899,13 @@ class OMPDefaultClause : public OMPClause { OMPDefaultClause(llvm::omp::DefaultKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(A), KindKwLoc(ALoc) {} + : OMPClause(llvm::omp::OMPC_default, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPDefaultClause() - : OMPClause(OMPC_default, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_default, SourceLocation(), SourceLocation()) { + } /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -928,7 +935,7 @@ class OMPDefaultClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_default; + return T->getClauseKind() == llvm::omp::OMPC_default; } }; @@ -974,12 +981,13 @@ class OMPProcBindClause : public OMPClause { OMPProcBindClause(llvm::omp::ProcBindKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(A), KindKwLoc(ALoc) {} + : OMPClause(llvm::omp::OMPC_proc_bind, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPProcBindClause() - : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_proc_bind, SourceLocation(), + SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -1009,7 +1017,7 @@ class OMPProcBindClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_proc_bind; + return T->getClauseKind() == llvm::omp::OMPC_proc_bind; } }; @@ -1029,11 +1037,12 @@ class OMPUnifiedAddressClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_unified_address, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_unified_address, StartLoc, EndLoc) {} /// Build an empty clause. OMPUnifiedAddressClause() - : OMPClause(OMPC_unified_address, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_unified_address, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1051,7 +1060,7 @@ class OMPUnifiedAddressClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_unified_address; + return T->getClauseKind() == llvm::omp::OMPC_unified_address; } }; @@ -1071,11 +1080,12 @@ class OMPUnifiedSharedMemoryClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_unified_shared_memory, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_unified_shared_memory, StartLoc, EndLoc) {} /// Build an empty clause. OMPUnifiedSharedMemoryClause() - : OMPClause(OMPC_unified_shared_memory, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_unified_shared_memory, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1093,7 +1103,7 @@ class OMPUnifiedSharedMemoryClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_unified_shared_memory; + return T->getClauseKind() == llvm::omp::OMPC_unified_shared_memory; } }; @@ -1113,11 +1123,12 @@ class OMPReverseOffloadClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_reverse_offload, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_reverse_offload, StartLoc, EndLoc) {} /// Build an empty clause. OMPReverseOffloadClause() - : OMPClause(OMPC_reverse_offload, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_reverse_offload, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1135,7 +1146,7 @@ class OMPReverseOffloadClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_reverse_offload; + return T->getClauseKind() == llvm::omp::OMPC_reverse_offload; } }; @@ -1155,12 +1166,12 @@ class OMPDynamicAllocatorsClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_dynamic_allocators, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_dynamic_allocators, StartLoc, EndLoc) {} /// Build an empty clause. OMPDynamicAllocatorsClause() - : OMPClause(OMPC_dynamic_allocators, SourceLocation(), SourceLocation()) { - } + : OMPClause(llvm::omp::OMPC_dynamic_allocators, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1178,7 +1189,7 @@ class OMPDynamicAllocatorsClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_dynamic_allocators; + return T->getClauseKind() == llvm::omp::OMPC_dynamic_allocators; } }; @@ -1230,12 +1241,12 @@ class OMPAtomicDefaultMemOrderClause final : public OMPClause { SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_atomic_default_mem_order, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, StartLoc, EndLoc), LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPAtomicDefaultMemOrderClause() - : OMPClause(OMPC_atomic_default_mem_order, SourceLocation(), + : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. @@ -1268,7 +1279,7 @@ class OMPAtomicDefaultMemOrderClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_atomic_default_mem_order; + return T->getClauseKind() == llvm::omp::OMPC_atomic_default_mem_order; } }; @@ -1387,9 +1398,9 @@ class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { Expr *ChunkSize, Stmt *HelperChunkSize, OpenMPScheduleClauseModifier M1, SourceLocation M1Loc, OpenMPScheduleClauseModifier M2, SourceLocation M2Loc) - : OMPClause(OMPC_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), - ChunkSize(ChunkSize) { + : OMPClause(llvm::omp::OMPC_schedule, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), + KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { setPreInitStmt(HelperChunkSize); Modifiers[FIRST] = M1; Modifiers[SECOND] = M2; @@ -1399,7 +1410,7 @@ class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { /// Build an empty clause. explicit OMPScheduleClause() - : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_schedule, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) { Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown; Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown; @@ -1461,7 +1472,7 @@ class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_schedule; + return T->getClauseKind() == llvm::omp::OMPC_schedule; } }; @@ -1496,12 +1507,12 @@ class OMPOrderedClause final /// \param EndLoc Ending location of the clause. OMPOrderedClause(Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_ordered, StartLoc, EndLoc), LParenLoc(LParenLoc), - NumForLoops(Num), NumberOfLoops(NumLoops) {} + : OMPClause(llvm::omp::OMPC_ordered, StartLoc, EndLoc), + LParenLoc(LParenLoc), NumForLoops(Num), NumberOfLoops(NumLoops) {} /// Build an empty clause. explicit OMPOrderedClause(unsigned NumLoops) - : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_ordered, SourceLocation(), SourceLocation()), NumberOfLoops(NumLoops) {} /// Set the number of associated for-loops. @@ -1557,7 +1568,7 @@ class OMPOrderedClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_ordered; + return T->getClauseKind() == llvm::omp::OMPC_ordered; } }; @@ -1574,11 +1585,11 @@ class OMPNowaitClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_nowait, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_nowait, StartLoc, EndLoc) {} /// Build an empty clause. OMPNowaitClause() - : OMPClause(OMPC_nowait, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_nowait, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1596,7 +1607,7 @@ class OMPNowaitClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_nowait; + return T->getClauseKind() == llvm::omp::OMPC_nowait; } }; @@ -1613,11 +1624,11 @@ class OMPUntiedClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_untied, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_untied, StartLoc, EndLoc) {} /// Build an empty clause. OMPUntiedClause() - : OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_untied, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1635,7 +1646,7 @@ class OMPUntiedClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_untied; + return T->getClauseKind() == llvm::omp::OMPC_untied; } }; @@ -1653,11 +1664,12 @@ class OMPMergeableClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_mergeable, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_mergeable, StartLoc, EndLoc) {} /// Build an empty clause. OMPMergeableClause() - : OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_mergeable, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1675,7 +1687,7 @@ class OMPMergeableClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_mergeable; + return T->getClauseKind() == llvm::omp::OMPC_mergeable; } }; @@ -1692,10 +1704,11 @@ class OMPReadClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_read, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_read, StartLoc, EndLoc) {} /// Build an empty clause. - OMPReadClause() : OMPClause(OMPC_read, SourceLocation(), SourceLocation()) {} + OMPReadClause() + : OMPClause(llvm::omp::OMPC_read, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1713,7 +1726,7 @@ class OMPReadClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_read; + return T->getClauseKind() == llvm::omp::OMPC_read; } }; @@ -1730,11 +1743,11 @@ class OMPWriteClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_write, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_write, StartLoc, EndLoc) {} /// Build an empty clause. OMPWriteClause() - : OMPClause(OMPC_write, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_write, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1752,7 +1765,7 @@ class OMPWriteClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_write; + return T->getClauseKind() == llvm::omp::OMPC_write; } }; @@ -1812,11 +1825,12 @@ class OMPUpdateClause final /// \param EndLoc Ending location of the clause. OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc, bool IsExtended) - : OMPClause(OMPC_update, StartLoc, EndLoc), IsExtended(IsExtended) {} + : OMPClause(llvm::omp::OMPC_update, StartLoc, EndLoc), + IsExtended(IsExtended) {} /// Build an empty clause. OMPUpdateClause(bool IsExtended) - : OMPClause(OMPC_update, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_update, SourceLocation(), SourceLocation()), IsExtended(IsExtended) {} public: @@ -1886,7 +1900,7 @@ class OMPUpdateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_update; + return T->getClauseKind() == llvm::omp::OMPC_update; } }; @@ -1904,11 +1918,12 @@ class OMPCaptureClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_capture, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_capture, StartLoc, EndLoc) {} /// Build an empty clause. OMPCaptureClause() - : OMPClause(OMPC_capture, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_capture, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1926,7 +1941,7 @@ class OMPCaptureClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_capture; + return T->getClauseKind() == llvm::omp::OMPC_capture; } }; @@ -1944,11 +1959,12 @@ class OMPSeqCstClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_seq_cst, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_seq_cst, StartLoc, EndLoc) {} /// Build an empty clause. OMPSeqCstClause() - : OMPClause(OMPC_seq_cst, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_seq_cst, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1966,7 +1982,7 @@ class OMPSeqCstClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_seq_cst; + return T->getClauseKind() == llvm::omp::OMPC_seq_cst; } }; @@ -1984,11 +2000,12 @@ class OMPAcqRelClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_acq_rel, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_acq_rel, StartLoc, EndLoc) {} /// Build an empty clause. OMPAcqRelClause() - : OMPClause(OMPC_acq_rel, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_acq_rel, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2006,7 +2023,7 @@ class OMPAcqRelClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_acq_rel; + return T->getClauseKind() == llvm::omp::OMPC_acq_rel; } }; @@ -2024,11 +2041,12 @@ class OMPAcquireClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_acquire, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_acquire, StartLoc, EndLoc) {} /// Build an empty clause. OMPAcquireClause() - : OMPClause(OMPC_acquire, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_acquire, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2046,7 +2064,7 @@ class OMPAcquireClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_acquire; + return T->getClauseKind() == llvm::omp::OMPC_acquire; } }; @@ -2064,11 +2082,12 @@ class OMPReleaseClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReleaseClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_release, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_release, StartLoc, EndLoc) {} /// Build an empty clause. OMPReleaseClause() - : OMPClause(OMPC_release, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_release, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2086,7 +2105,7 @@ class OMPReleaseClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_release; + return T->getClauseKind() == llvm::omp::OMPC_release; } }; @@ -2104,11 +2123,12 @@ class OMPRelaxedClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_relaxed, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_relaxed, StartLoc, EndLoc) {} /// Build an empty clause. OMPRelaxedClause() - : OMPClause(OMPC_relaxed, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_relaxed, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -2126,7 +2146,7 @@ class OMPRelaxedClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_relaxed; + return T->getClauseKind() == llvm::omp::OMPC_relaxed; } }; @@ -2152,16 +2172,16 @@ class OMPPrivateClause final /// \param N Number of the variables in the clause. OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_private, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_private, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPPrivateClause(unsigned N) - : OMPVarListClause(OMPC_private, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_private, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} /// Sets the list of references to private copies with initializers for /// new private variables. @@ -2231,7 +2251,7 @@ class OMPPrivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_private; + return T->getClauseKind() == llvm::omp::OMPC_private; } }; @@ -2259,8 +2279,8 @@ class OMPFirstprivateClause final /// \param N Number of the variables in the clause. OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_firstprivate, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_firstprivate, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPreInit(this) {} /// Build an empty clause. @@ -2268,7 +2288,7 @@ class OMPFirstprivateClause final /// \param N Number of variables. explicit OMPFirstprivateClause(unsigned N) : OMPVarListClause( - OMPC_firstprivate, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_firstprivate, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPreInit(this) {} @@ -2372,7 +2392,7 @@ class OMPFirstprivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_firstprivate; + return T->getClauseKind() == llvm::omp::OMPC_firstprivate; } }; @@ -2425,8 +2445,8 @@ class OMPLastprivateClause final SourceLocation EndLoc, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, unsigned N) - : OMPVarListClause(OMPC_lastprivate, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_lastprivate, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), LPKind(LPKind), LPKindLoc(LPKindLoc), ColonLoc(ColonLoc) {} @@ -2435,7 +2455,7 @@ class OMPLastprivateClause final /// \param N Number of variables. explicit OMPLastprivateClause(unsigned N) : OMPVarListClause( - OMPC_lastprivate, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_lastprivate, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -2611,7 +2631,7 @@ class OMPLastprivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_lastprivate; + return T->getClauseKind() == llvm::omp::OMPC_lastprivate; } }; @@ -2636,16 +2656,16 @@ class OMPSharedClause final /// \param N Number of the variables in the clause. OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_shared, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_shared, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPSharedClause(unsigned N) - : OMPVarListClause(OMPC_shared, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_shared, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -2683,7 +2703,7 @@ class OMPSharedClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_shared; + return T->getClauseKind() == llvm::omp::OMPC_shared; } }; @@ -2734,8 +2754,8 @@ class OMPReductionClause final OpenMPReductionClauseModifier Modifier, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause(OMPC_reduction, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_reduction, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -2744,9 +2764,9 @@ class OMPReductionClause final /// /// \param N Number of variables. explicit OMPReductionClause(unsigned N) - : OMPVarListClause(OMPC_reduction, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_reduction, SourceLocation(), SourceLocation(), - N), + SourceLocation(), N), OMPClauseWithPostUpdate(this) {} /// Sets reduction modifier. @@ -2943,7 +2963,7 @@ class OMPReductionClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_reduction; + return T->getClauseKind() == llvm::omp::OMPC_reduction; } }; @@ -2985,8 +3005,8 @@ class OMPTaskReductionClause final SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause(OMPC_task_reduction, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause( + llvm::omp::OMPC_task_reduction, StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -2995,7 +3015,7 @@ class OMPTaskReductionClause final /// \param N Number of variables. explicit OMPTaskReductionClause(unsigned N) : OMPVarListClause( - OMPC_task_reduction, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_task_reduction, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -3175,7 +3195,7 @@ class OMPTaskReductionClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_task_reduction; + return T->getClauseKind() == llvm::omp::OMPC_task_reduction; } }; @@ -3216,8 +3236,8 @@ class OMPInReductionClause final SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause(OMPC_in_reduction, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause(llvm::omp::OMPC_in_reduction, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -3226,7 +3246,7 @@ class OMPInReductionClause final /// \param N Number of variables. explicit OMPInReductionClause(unsigned N) : OMPVarListClause( - OMPC_in_reduction, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_in_reduction, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -3430,7 +3450,7 @@ class OMPInReductionClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_in_reduction; + return T->getClauseKind() == llvm::omp::OMPC_in_reduction; } }; @@ -3476,8 +3496,8 @@ class OMPLinearClause final OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned NumVars) - : OMPVarListClause(OMPC_linear, StartLoc, LParenLoc, - EndLoc, NumVars), + : OMPVarListClause(llvm::omp::OMPC_linear, StartLoc, + LParenLoc, EndLoc, NumVars), OMPClauseWithPostUpdate(this), Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {} @@ -3485,9 +3505,9 @@ class OMPLinearClause final /// /// \param NumVars Number of variables. explicit OMPLinearClause(unsigned NumVars) - : OMPVarListClause(OMPC_linear, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_linear, SourceLocation(), SourceLocation(), - NumVars), + SourceLocation(), NumVars), OMPClauseWithPostUpdate(this) {} /// Gets the list of initial values for linear variables. @@ -3707,7 +3727,7 @@ class OMPLinearClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_linear; + return T->getClauseKind() == llvm::omp::OMPC_linear; } }; @@ -3742,17 +3762,17 @@ class OMPAlignedClause final OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned NumVars) - : OMPVarListClause(OMPC_aligned, StartLoc, LParenLoc, - EndLoc, NumVars), + : OMPVarListClause(llvm::omp::OMPC_aligned, StartLoc, + LParenLoc, EndLoc, NumVars), ColonLoc(ColonLoc) {} /// Build an empty clause. /// /// \param NumVars Number of variables. explicit OMPAlignedClause(unsigned NumVars) - : OMPVarListClause(OMPC_aligned, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_aligned, SourceLocation(), SourceLocation(), - NumVars) {} + SourceLocation(), NumVars) {} public: /// Creates clause with a list of variables \a VL and alignment \a A. @@ -3806,7 +3826,7 @@ class OMPAlignedClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_aligned; + return T->getClauseKind() == llvm::omp::OMPC_aligned; } }; @@ -3845,16 +3865,16 @@ class OMPCopyinClause final /// \param N Number of the variables in the clause. OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_copyin, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_copyin, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPCopyinClause(unsigned N) - : OMPVarListClause(OMPC_copyin, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_copyin, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} /// Set list of helper expressions, required for proper codegen of the /// clause. These expressions represent source expression in the final @@ -3982,7 +4002,7 @@ class OMPCopyinClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_copyin; + return T->getClauseKind() == llvm::omp::OMPC_copyin; } }; @@ -4009,15 +4029,16 @@ class OMPCopyprivateClause final /// \param N Number of the variables in the clause. OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_copyprivate, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_copyprivate, + StartLoc, LParenLoc, EndLoc, N) { + } /// Build an empty clause. /// /// \param N Number of variables. explicit OMPCopyprivateClause(unsigned N) : OMPVarListClause( - OMPC_copyprivate, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_copyprivate, SourceLocation(), SourceLocation(), SourceLocation(), N) {} /// Set list of helper expressions, required for proper codegen of the @@ -4145,7 +4166,7 @@ class OMPCopyprivateClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_copyprivate; + return T->getClauseKind() == llvm::omp::OMPC_copyprivate; } }; @@ -4175,16 +4196,16 @@ class OMPFlushClause final /// \param N Number of the variables in the clause. OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_flush, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_flush, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPFlushClause(unsigned N) - : OMPVarListClause(OMPC_flush, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_flush, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -4222,7 +4243,7 @@ class OMPFlushClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_flush; + return T->getClauseKind() == llvm::omp::OMPC_flush; } }; @@ -4254,12 +4275,13 @@ class OMPDepobjClause final : public OMPClause { /// \param EndLoc Ending location of the clause. OMPDepobjClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_depobj, StartLoc, EndLoc), LParenLoc(LParenLoc) {} + : OMPClause(llvm::omp::OMPC_depobj, StartLoc, EndLoc), + LParenLoc(LParenLoc) {} /// Build an empty clause. /// explicit OMPDepobjClause() - : OMPClause(OMPC_depobj, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_depobj, SourceLocation(), SourceLocation()) {} void setDepobj(Expr *E) { Depobj = E; } @@ -4308,7 +4330,7 @@ class OMPDepobjClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_depobj; + return T->getClauseKind() == llvm::omp::OMPC_depobj; } }; @@ -4349,8 +4371,9 @@ class OMPDependClause final /// clause. OMPDependClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N, unsigned NumLoops) - : OMPVarListClause(OMPC_depend, StartLoc, LParenLoc, - EndLoc, N), NumLoops(NumLoops) {} + : OMPVarListClause(llvm::omp::OMPC_depend, StartLoc, + LParenLoc, EndLoc, N), + NumLoops(NumLoops) {} /// Build an empty clause. /// @@ -4358,9 +4381,9 @@ class OMPDependClause final /// \param NumLoops Number of loops that is associated with this depend /// clause. explicit OMPDependClause(unsigned N, unsigned NumLoops) - : OMPVarListClause(OMPC_depend, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_depend, SourceLocation(), SourceLocation(), - N), + SourceLocation(), N), NumLoops(NumLoops) {} /// Set dependency kind. @@ -4448,7 +4471,7 @@ class OMPDependClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_depend; + return T->getClauseKind() == llvm::omp::OMPC_depend; } }; @@ -4501,15 +4524,15 @@ class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc) - : OMPClause(OMPC_device, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Modifier(Modifier), ModifierLoc(ModifierLoc), - Device(E) { + : OMPClause(llvm::omp::OMPC_device, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier), + ModifierLoc(ModifierLoc), Device(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPDeviceClause() - : OMPClause(OMPC_device, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_device, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -4544,7 +4567,7 @@ class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_device; + return T->getClauseKind() == llvm::omp::OMPC_device; } }; @@ -4561,11 +4584,12 @@ class OMPThreadsClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_threads, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_threads, StartLoc, EndLoc) {} /// Build an empty clause. OMPThreadsClause() - : OMPClause(OMPC_threads, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_threads, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -4583,7 +4607,7 @@ class OMPThreadsClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_threads; + return T->getClauseKind() == llvm::omp::OMPC_threads; } }; @@ -4600,10 +4624,11 @@ class OMPSIMDClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_simd, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_simd, StartLoc, EndLoc) {} /// Build an empty clause. - OMPSIMDClause() : OMPClause(OMPC_simd, SourceLocation(), SourceLocation()) {} + OMPSIMDClause() + : OMPClause(llvm::omp::OMPC_simd, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -4621,7 +4646,7 @@ class OMPSIMDClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_simd; + return T->getClauseKind() == llvm::omp::OMPC_simd; } }; @@ -5297,8 +5322,8 @@ class OMPMapClause final : public OMPMappableExprListClause, OpenMPMapClauseKind MapType, bool MapTypeIsImplicit, SourceLocation MapLoc, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_map, Locs, Sizes, &MapperQualifierLoc, - &MapperIdInfo), + : OMPMappableExprListClause(llvm::omp::OMPC_map, Locs, Sizes, + &MapperQualifierLoc, &MapperIdInfo), MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) { assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() && "Unexpected number of map type modifiers."); @@ -5318,7 +5343,8 @@ class OMPMapClause final : public OMPMappableExprListClause, /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPMapClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_map, OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_map, OMPVarListLocTy(), + Sizes) {} /// Set map-type-modifier for the clause. /// @@ -5465,7 +5491,7 @@ class OMPMapClause final : public OMPMappableExprListClause, static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_map; + return T->getClauseKind() == llvm::omp::OMPC_map; } }; @@ -5504,14 +5530,15 @@ class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit { OMPNumTeamsClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_teams, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), NumTeams(E) { + : OMPClause(llvm::omp::OMPC_num_teams, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTeams(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPNumTeamsClause() - : OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_num_teams, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5540,7 +5567,7 @@ class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_num_teams; + return T->getClauseKind() == llvm::omp::OMPC_num_teams; } }; @@ -5580,14 +5607,15 @@ class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit { OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_thread_limit, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_thread_limit, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadLimit(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPThreadLimitClause() - : OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_thread_limit, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5616,7 +5644,7 @@ class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_thread_limit; + return T->getClauseKind() == llvm::omp::OMPC_thread_limit; } }; @@ -5655,14 +5683,14 @@ class OMPPriorityClause : public OMPClause, public OMPClauseWithPreInit { OMPPriorityClause(Expr *Priority, Stmt *HelperPriority, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_priority, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Priority(Priority) { + : OMPClause(llvm::omp::OMPC_priority, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Priority(Priority) { setPreInitStmt(HelperPriority, CaptureRegion); } /// Build an empty clause. OMPPriorityClause() - : OMPClause(OMPC_priority, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_priority, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5690,7 +5718,7 @@ class OMPPriorityClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_priority; + return T->getClauseKind() == llvm::omp::OMPC_priority; } }; @@ -5726,14 +5754,15 @@ class OMPGrainsizeClause : public OMPClause, public OMPClauseWithPreInit { OMPGrainsizeClause(Expr *Size, Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_grainsize, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Grainsize(Size) { + : OMPClause(llvm::omp::OMPC_grainsize, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Grainsize(Size) { setPreInitStmt(HelperSize, CaptureRegion); } /// Build an empty clause. explicit OMPGrainsizeClause() - : OMPClause(OMPC_grainsize, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_grainsize, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5758,7 +5787,7 @@ class OMPGrainsizeClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_grainsize; + return T->getClauseKind() == llvm::omp::OMPC_grainsize; } }; @@ -5775,11 +5804,12 @@ class OMPNogroupClause : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_nogroup, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_nogroup, StartLoc, EndLoc) {} /// Build an empty clause. OMPNogroupClause() - : OMPClause(OMPC_nogroup, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_nogroup, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -5797,7 +5827,7 @@ class OMPNogroupClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_nogroup; + return T->getClauseKind() == llvm::omp::OMPC_nogroup; } }; @@ -5833,14 +5863,15 @@ class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit { OMPNumTasksClause(Expr *Size, Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_tasks, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), NumTasks(Size) { + : OMPClause(llvm::omp::OMPC_num_tasks, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTasks(Size) { setPreInitStmt(HelperSize, CaptureRegion); } /// Build an empty clause. explicit OMPNumTasksClause() - : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_num_tasks, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5865,7 +5896,7 @@ class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_num_tasks; + return T->getClauseKind() == llvm::omp::OMPC_num_tasks; } }; @@ -5897,11 +5928,12 @@ class OMPHintClause : public OMPClause { /// \param EndLoc Ending location of the clause. OMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc), + : OMPClause(llvm::omp::OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc), Hint(Hint) {} /// Build an empty clause. - OMPHintClause() : OMPClause(OMPC_hint, SourceLocation(), SourceLocation()) {} + OMPHintClause() + : OMPClause(llvm::omp::OMPC_hint, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -5926,7 +5958,7 @@ class OMPHintClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_hint; + return T->getClauseKind() == llvm::omp::OMPC_hint; } }; @@ -5998,7 +6030,7 @@ class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { SourceLocation EndLoc, OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, Stmt *HelperChunkSize) - : OMPClause(OMPC_dist_schedule, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_dist_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { setPreInitStmt(HelperChunkSize); @@ -6006,7 +6038,8 @@ class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { /// Build an empty clause. explicit OMPDistScheduleClause() - : OMPClause(OMPC_dist_schedule, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_dist_schedule, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Get kind of the clause. @@ -6045,7 +6078,7 @@ class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_dist_schedule; + return T->getClauseKind() == llvm::omp::OMPC_dist_schedule; } }; @@ -6115,12 +6148,14 @@ class OMPDefaultmapClause : public OMPClause { SourceLocation MLoc, SourceLocation KLoc, SourceLocation EndLoc, OpenMPDefaultmapClauseKind Kind, OpenMPDefaultmapClauseModifier M) - : OMPClause(OMPC_defaultmap, StartLoc, EndLoc), LParenLoc(LParenLoc), - Modifier(M), ModifierLoc(MLoc), Kind(Kind), KindLoc(KLoc) {} + : OMPClause(llvm::omp::OMPC_defaultmap, StartLoc, EndLoc), + LParenLoc(LParenLoc), Modifier(M), ModifierLoc(MLoc), Kind(Kind), + KindLoc(KLoc) {} /// Build an empty clause. explicit OMPDefaultmapClause() - : OMPClause(OMPC_defaultmap, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_defaultmap, SourceLocation(), + SourceLocation()) {} /// Get kind of the clause. OpenMPDefaultmapClauseKind getDefaultmapKind() const { return Kind; } @@ -6157,7 +6192,7 @@ class OMPDefaultmapClause : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_defaultmap; + return T->getClauseKind() == llvm::omp::OMPC_defaultmap; } }; @@ -6195,8 +6230,8 @@ class OMPToClause final : public OMPMappableExprListClause, DeclarationNameInfo MapperIdInfo, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_to, Locs, Sizes, &MapperQualifierLoc, - &MapperIdInfo) {} + : OMPMappableExprListClause(llvm::omp::OMPC_to, Locs, Sizes, + &MapperQualifierLoc, &MapperIdInfo) {} /// Build an empty clause. /// @@ -6206,7 +6241,8 @@ class OMPToClause final : public OMPMappableExprListClause, /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPToClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_to, OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_to, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6274,7 +6310,7 @@ class OMPToClause final : public OMPMappableExprListClause, } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_to; + return T->getClauseKind() == llvm::omp::OMPC_to; } }; @@ -6313,8 +6349,8 @@ class OMPFromClause final DeclarationNameInfo MapperIdInfo, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_from, Locs, Sizes, &MapperQualifierLoc, - &MapperIdInfo) {} + : OMPMappableExprListClause(llvm::omp::OMPC_from, Locs, Sizes, + &MapperQualifierLoc, &MapperIdInfo) {} /// Build an empty clause. /// @@ -6324,7 +6360,8 @@ class OMPFromClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPFromClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_from, OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_from, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6392,7 +6429,7 @@ class OMPFromClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_from; + return T->getClauseKind() == llvm::omp::OMPC_from; } }; @@ -6426,7 +6463,8 @@ class OMPUseDevicePtrClause final /// NumComponents: total number of expression components in the clause. explicit OMPUseDevicePtrClause(const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_use_device_ptr, Locs, Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, Locs, Sizes) { + } /// Build an empty clause. /// @@ -6436,8 +6474,8 @@ class OMPUseDevicePtrClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPUseDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_use_device_ptr, OMPVarListLocTy(), - Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, + OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6555,7 +6593,7 @@ class OMPUseDevicePtrClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_use_device_ptr; + return T->getClauseKind() == llvm::omp::OMPC_use_device_ptr; } }; @@ -6589,7 +6627,7 @@ class OMPIsDevicePtrClause final /// NumComponents: total number of expression components in the clause. explicit OMPIsDevicePtrClause(const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_is_device_ptr, Locs, Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, Locs, Sizes) {} /// Build an empty clause. /// @@ -6599,8 +6637,8 @@ class OMPIsDevicePtrClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPIsDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_is_device_ptr, OMPVarListLocTy(), - Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, + OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6658,7 +6696,7 @@ class OMPIsDevicePtrClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_is_device_ptr; + return T->getClauseKind() == llvm::omp::OMPC_is_device_ptr; } }; @@ -6684,15 +6722,16 @@ class OMPNontemporalClause final /// \param N Number of the variables in the clause. OMPNontemporalClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_nontemporal, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_nontemporal, + StartLoc, LParenLoc, EndLoc, N) { + } /// Build an empty clause. /// /// \param N Number of variables. explicit OMPNontemporalClause(unsigned N) : OMPVarListClause( - OMPC_nontemporal, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_nontemporal, SourceLocation(), SourceLocation(), SourceLocation(), N) {} /// Get the list of privatied copies if the member expression was captured by @@ -6754,7 +6793,7 @@ class OMPNontemporalClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_nontemporal; + return T->getClauseKind() == llvm::omp::OMPC_nontemporal; } }; @@ -6798,12 +6837,12 @@ class OMPOrderClause final : public OMPClause { OMPOrderClause(OpenMPOrderClauseKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_order, StartLoc, EndLoc), LParenLoc(LParenLoc), Kind(A), - KindKwLoc(ALoc) {} + : OMPClause(llvm::omp::OMPC_order, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPOrderClause() - : OMPClause(OMPC_order, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_order, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -6833,7 +6872,7 @@ class OMPOrderClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_order; + return T->getClauseKind() == llvm::omp::OMPC_order; } }; @@ -6851,11 +6890,12 @@ class OMPDestroyClause final : public OMPClause { /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPDestroyClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_destroy, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_destroy, StartLoc, EndLoc) {} /// Build an empty clause. OMPDestroyClause() - : OMPClause(OMPC_destroy, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_destroy, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -6873,7 +6913,7 @@ class OMPDestroyClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_destroy; + return T->getClauseKind() == llvm::omp::OMPC_destroy; } }; @@ -6908,12 +6948,12 @@ class OMPDetachClause final : public OMPClause { /// \param EndLoc Ending location of the clause. OMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_detach, StartLoc, EndLoc), LParenLoc(LParenLoc), - Evt(Evt) {} + : OMPClause(llvm::omp::OMPC_detach, StartLoc, EndLoc), + LParenLoc(LParenLoc), Evt(Evt) {} /// Build an empty clause. OMPDetachClause() - : OMPClause(OMPC_detach, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_detach, SourceLocation(), SourceLocation()) {} /// Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } @@ -6935,7 +6975,7 @@ class OMPDetachClause final : public OMPClause { } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_detach; + return T->getClauseKind() == llvm::omp::OMPC_detach; } }; @@ -6961,16 +7001,16 @@ class OMPInclusiveClause final /// \param N Number of the variables in the clause. OMPInclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_inclusive, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_inclusive, + StartLoc, LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPInclusiveClause(unsigned N) - : OMPVarListClause(OMPC_inclusive, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_inclusive, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -7009,7 +7049,7 @@ class OMPInclusiveClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_inclusive; + return T->getClauseKind() == llvm::omp::OMPC_inclusive; } }; @@ -7035,16 +7075,16 @@ class OMPExclusiveClause final /// \param N Number of the variables in the clause. OMPExclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause(OMPC_exclusive, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause(llvm::omp::OMPC_exclusive, + StartLoc, LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPExclusiveClause(unsigned N) - : OMPVarListClause(OMPC_exclusive, SourceLocation(), + : OMPVarListClause(llvm::omp::OMPC_exclusive, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -7083,7 +7123,7 @@ class OMPExclusiveClause final } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_exclusive; + return T->getClauseKind() == llvm::omp::OMPC_exclusive; } }; @@ -7096,17 +7136,20 @@ class OMPClauseVisitorBase { #define DISPATCH(CLASS) \ return static_cast(this)->Visit##CLASS(static_cast(S)) -#define OPENMP_CLAUSE(Name, Class) \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); } -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" RetTy Visit(PTR(OMPClause) S) { // Top switch clause: visit each OMPClause. switch (S->getClauseKind()) { - default: llvm_unreachable("Unknown clause kind!"); -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_ ## Name : return Visit ## Class(static_cast(S)); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case llvm::omp::Clause::Enum: \ + return Visit##Class(static_cast(S)); +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Clause::Enum: \ + break; +#include "llvm/Frontend/OpenMP/OMPKinds.def" } } // Base case, ignore it. :) @@ -7135,8 +7178,9 @@ class OMPClausePrinter final : public OMPClauseVisitor { OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy) : OS(OS), Policy(Policy) {} -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + void Visit##Class(Class *S); +#include "llvm/Frontend/OpenMP/OMPKinds.def" }; struct OMPTraitProperty { diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 345333849659..b19b566294b7 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -534,8 +534,8 @@ template class RecursiveASTVisitor { bool TraverseOMPExecutableDirective(OMPExecutableDirective *S); bool TraverseOMPLoopDirective(OMPLoopDirective *S); bool TraverseOMPClause(OMPClause *C); -#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C); +#include "llvm/Frontend/OpenMP/OMPKinds.def" /// Process clauses with list of variables. template bool VisitOMPClauseList(T *Node); /// Process clauses with pre-initis. @@ -2957,17 +2957,14 @@ bool RecursiveASTVisitor::TraverseOMPClause(OMPClause *C) { if (!C) return true; switch (C->getClauseKind()) { -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case llvm::omp::Clause::Enum: \ TRY_TO(Visit##Class(static_cast(C))); \ break; -#include "clang/Basic/OpenMPKinds.def" - case OMPC_threadprivate: - case OMPC_uniform: - case OMPC_device_type: - case OMPC_match: - case OMPC_unknown: +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Clause::Enum: \ break; +#include "llvm/Frontend/OpenMP/OMPKinds.def" } return true; } diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 96bfdd313f47..f55ce2cc84dd 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3242,8 +3242,13 @@ def OMPCaptureKind : Attr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let SemaHandler = 0; - let Args = [UnsignedArgument<"CaptureKind">]; + let Args = [UnsignedArgument<"CaptureKindVal">]; let Documentation = [Undocumented]; + let AdditionalMembers = [{ + llvm::omp::Clause getCaptureKind() const { + return static_cast(getCaptureKindVal()); + } + }]; } def OMPReferencedVar : Attr { diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index 3cf92ead9560..4a4e6c6cb4c3 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -222,74 +222,6 @@ #define OPENMP_REDUCTION_MODIFIER(Name) #endif -// OpenMP clauses. -OPENMP_CLAUSE(allocator, OMPAllocatorClause) -OPENMP_CLAUSE(if, OMPIfClause) -OPENMP_CLAUSE(final, OMPFinalClause) -OPENMP_CLAUSE(num_threads, OMPNumThreadsClause) -OPENMP_CLAUSE(safelen, OMPSafelenClause) -OPENMP_CLAUSE(simdlen, OMPSimdlenClause) -OPENMP_CLAUSE(collapse, OMPCollapseClause) -OPENMP_CLAUSE(default, OMPDefaultClause) -OPENMP_CLAUSE(private, OMPPrivateClause) -OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause) -OPENMP_CLAUSE(lastprivate, OMPLastprivateClause) -OPENMP_CLAUSE(shared, OMPSharedClause) -OPENMP_CLAUSE(reduction, OMPReductionClause) -OPENMP_CLAUSE(linear, OMPLinearClause) -OPENMP_CLAUSE(aligned, OMPAlignedClause) -OPENMP_CLAUSE(copyin, OMPCopyinClause) -OPENMP_CLAUSE(copyprivate, OMPCopyprivateClause) -OPENMP_CLAUSE(proc_bind, OMPProcBindClause) -OPENMP_CLAUSE(schedule, OMPScheduleClause) -OPENMP_CLAUSE(ordered, OMPOrderedClause) -OPENMP_CLAUSE(nowait, OMPNowaitClause) -OPENMP_CLAUSE(untied, OMPUntiedClause) -OPENMP_CLAUSE(mergeable, OMPMergeableClause) -OPENMP_CLAUSE(flush, OMPFlushClause) -OPENMP_CLAUSE(read, OMPReadClause) -OPENMP_CLAUSE(write, OMPWriteClause) -OPENMP_CLAUSE(update, OMPUpdateClause) -OPENMP_CLAUSE(capture, OMPCaptureClause) -OPENMP_CLAUSE(seq_cst, OMPSeqCstClause) -OPENMP_CLAUSE(acq_rel, OMPAcqRelClause) -OPENMP_CLAUSE(acquire, OMPAcquireClause) -OPENMP_CLAUSE(release, OMPReleaseClause) -OPENMP_CLAUSE(relaxed, OMPRelaxedClause) -OPENMP_CLAUSE(depend, OMPDependClause) -OPENMP_CLAUSE(device, OMPDeviceClause) -OPENMP_CLAUSE(threads, OMPThreadsClause) -OPENMP_CLAUSE(simd, OMPSIMDClause) -OPENMP_CLAUSE(map, OMPMapClause) -OPENMP_CLAUSE(num_teams, OMPNumTeamsClause) -OPENMP_CLAUSE(thread_limit, OMPThreadLimitClause) -OPENMP_CLAUSE(priority, OMPPriorityClause) -OPENMP_CLAUSE(grainsize, OMPGrainsizeClause) -OPENMP_CLAUSE(nogroup, OMPNogroupClause) -OPENMP_CLAUSE(num_tasks, OMPNumTasksClause) -OPENMP_CLAUSE(hint, OMPHintClause) -OPENMP_CLAUSE(dist_schedule, OMPDistScheduleClause) -OPENMP_CLAUSE(defaultmap, OMPDefaultmapClause) -OPENMP_CLAUSE(to, OMPToClause) -OPENMP_CLAUSE(from, OMPFromClause) -OPENMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause) -OPENMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause) -OPENMP_CLAUSE(task_reduction, OMPTaskReductionClause) -OPENMP_CLAUSE(in_reduction, OMPInReductionClause) -OPENMP_CLAUSE(unified_address, OMPUnifiedAddressClause) -OPENMP_CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause) -OPENMP_CLAUSE(reverse_offload, OMPReverseOffloadClause) -OPENMP_CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause) -OPENMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause) -OPENMP_CLAUSE(allocate, OMPAllocateClause) -OPENMP_CLAUSE(nontemporal, OMPNontemporalClause) -OPENMP_CLAUSE(order, OMPOrderClause) -OPENMP_CLAUSE(depobj, OMPDepobjClause) -OPENMP_CLAUSE(destroy, OMPDestroyClause) -OPENMP_CLAUSE(detach, OMPDetachClause) -OPENMP_CLAUSE(inclusive, OMPInclusiveClause) -OPENMP_CLAUSE(exclusive, OMPExclusiveClause) - // Clauses allowed for OpenMP directive 'scan'. OPENMP_SCAN_CLAUSE(inclusive) OPENMP_SCAN_CLAUSE(exclusive) diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index f12b5545d0c1..9a6a2050a165 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -23,16 +23,7 @@ namespace clang { using OpenMPDirectiveKind = llvm::omp::Directive; /// OpenMP clauses. -enum OpenMPClauseKind { -#define OPENMP_CLAUSE(Name, Class) \ - OMPC_##Name, -#include "clang/Basic/OpenMPKinds.def" - OMPC_threadprivate, - OMPC_uniform, - OMPC_device_type, - OMPC_match, - OMPC_unknown -}; +using OpenMPClauseKind = llvm::omp::Clause; /// OpenMP attributes for 'schedule' clause. enum OpenMPScheduleClauseKind { @@ -179,9 +170,6 @@ enum OpenMPReductionClauseModifier { OMPC_REDUCTION_unknown, }; -OpenMPClauseKind getOpenMPClauseKind(llvm::StringRef Str); -const char *getOpenMPClauseName(OpenMPClauseKind Kind); - unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str); const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type); diff --git a/clang/lib/AST/ASTTypeTraits.cpp b/clang/lib/AST/ASTTypeTraits.cpp index e4ea3f41af36..6404edd79679 100644 --- a/clang/lib/AST/ASTTypeTraits.cpp +++ b/clang/lib/AST/ASTTypeTraits.cpp @@ -39,8 +39,8 @@ const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = { #define TYPE(DERIVED, BASE) { NKI_##BASE, #DERIVED "Type" }, #include "clang/AST/TypeNodes.inc" { NKI_None, "OMPClause" }, -#define OPENMP_CLAUSE(TextualSpelling, Class) {NKI_OMPClause, #Class}, -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) {NKI_OMPClause, #Class}, +#include "llvm/Frontend/OpenMP/OMPKinds.def" }; bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const { @@ -111,15 +111,13 @@ ASTNodeKind ASTNodeKind::getFromNode(const Type &T) { ASTNodeKind ASTNodeKind::getFromNode(const OMPClause &C) { switch (C.getClauseKind()) { -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: return ASTNodeKind(NKI_##Class); -#include "clang/Basic/OpenMPKinds.def" - case OMPC_threadprivate: - case OMPC_uniform: - case OMPC_device_type: - case OMPC_match: - case OMPC_unknown: +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case llvm::omp::Clause::Enum: \ + return ASTNodeKind(NKI_##Class); +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Clause::Enum: \ llvm_unreachable("unexpected OpenMP clause kind"); +#include "llvm/Frontend/OpenMP/OMPKinds.def" } llvm_unreachable("invalid stmt kind"); } diff --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp index bc0db1ba10a2..7818fbb1918b 100644 --- a/clang/lib/AST/AttrImpl.cpp +++ b/clang/lib/AST/AttrImpl.cpp @@ -108,7 +108,8 @@ void OMPDeclareSimdDeclAttr::printPrettyPragma( for (auto *E : linears()) { OS << " linear("; if (*MI != OMPC_LINEAR_unknown) - OS << getOpenMPSimpleClauseTypeName(OMPC_linear, *MI) << "("; + OS << getOpenMPSimpleClauseTypeName(llvm::omp::Clause::OMPC_linear, *MI) + << "("; E->printPretty(OS, nullptr, Policy); if (*MI != OMPC_LINEAR_unknown) OS << ")"; diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index a205a1bca1b9..0fdbec634103 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -31,20 +31,20 @@ OMPClause::child_range OMPClause::children() { switch (getClauseKind()) { default: break; -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case Enum: \ return static_cast(this)->children(); -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" } llvm_unreachable("unknown OMPClause"); } OMPClause::child_range OMPClause::used_children() { switch (getClauseKind()) { -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case Enum: \ return static_cast(this)->used_children(); -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" case OMPC_threadprivate: case OMPC_uniform: case OMPC_device_type: diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index fec12ac98b4e..be0bc13ccb4d 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -414,9 +414,8 @@ class OMPClauseProfiler : public ConstOMPClauseVisitor { public: OMPClauseProfiler(StmtProfiler *P) : Profiler(P) { } -#define OPENMP_CLAUSE(Name, Class) \ - void Visit##Class(const Class *C); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C); +#include "llvm/Frontend/OpenMP/OMPKinds.def" void VistOMPClauseWithPreInit(const OMPClauseWithPreInit *C); void VistOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C); }; diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index dc0dd92f09df..2933457b5711 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -314,7 +314,7 @@ void TextNodeDumper::Visit(const OMPClause *C) { } { ColorScope Color(OS, ShowColors, AttrColor); - StringRef ClauseName(getOpenMPClauseName(C->getClauseKind())); + StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind())); OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() << ClauseName.drop_front() << "Clause"; } @@ -1534,7 +1534,8 @@ void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) { } { ColorScope Color(OS, ShowColors, AttrColor); - StringRef ClauseName(getOpenMPClauseName(C->getClauseKind())); + StringRef ClauseName( + llvm::omp::getOpenMPClauseName(C->getClauseKind())); OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() << ClauseName.drop_front() << "Clause"; } diff --git a/clang/lib/ASTMatchers/CMakeLists.txt b/clang/lib/ASTMatchers/CMakeLists.txt index 8f700ca3226b..cde871cd31ca 100644 --- a/clang/lib/ASTMatchers/CMakeLists.txt +++ b/clang/lib/ASTMatchers/CMakeLists.txt @@ -1,6 +1,9 @@ add_subdirectory(Dynamic) -set(LLVM_LINK_COMPONENTS support) +set(LLVM_LINK_COMPONENTS + FrontendOpenMP + Support +) add_clang_library(clangASTMatchers ASTMatchFinder.cpp diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h index 48a454e3397e..db9122acede7 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -170,9 +170,8 @@ template <> struct ArgTypeTraits { private: static Optional getClauseKind(llvm::StringRef ClauseKind) { return llvm::StringSwitch>(ClauseKind) -#define OPENMP_CLAUSE(TextualSpelling, Class) \ - .Case("OMPC_" #TextualSpelling, OMPC_##TextualSpelling) -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) .Case(#Enum, llvm::omp::Clause::Enum) +#include "llvm/Frontend/OpenMP/OMPKinds.def" .Default(llvm::None); } diff --git a/clang/lib/Analysis/CMakeLists.txt b/clang/lib/Analysis/CMakeLists.txt index c1d0d6ed62c5..3333eab3b96d 100644 --- a/clang/lib/Analysis/CMakeLists.txt +++ b/clang/lib/Analysis/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 7a7c66c8e587..981bd7adbe9b 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -20,50 +20,6 @@ using namespace clang; using namespace llvm::omp; -OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) { - // 'flush' clause cannot be specified explicitly, because this is an implicit - // clause for 'flush' directive. If the 'flush' clause is explicitly specified - // the Parser should generate a warning about extra tokens at the end of the - // directive. - // 'depobj' clause cannot be specified explicitly, because this is an implicit - // clause for 'depobj' directive. If the 'depobj' clause is explicitly - // specified the Parser should generate a warning about extra tokens at the - // end of the directive. - if (llvm::StringSwitch(Str) - .Case("flush", true) - .Case("depobj", true) - .Default(false)) - return OMPC_unknown; - return llvm::StringSwitch(Str) -#define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name) -#include "clang/Basic/OpenMPKinds.def" - .Case("uniform", OMPC_uniform) - .Case("device_type", OMPC_device_type) - .Case("match", OMPC_match) - .Default(OMPC_unknown); -} - -const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) { - assert(Kind <= OMPC_unknown); - switch (Kind) { - case OMPC_unknown: - return "unknown"; -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ - return #Name; -#include "clang/Basic/OpenMPKinds.def" - case OMPC_uniform: - return "uniform"; - case OMPC_threadprivate: - return "threadprivate or thread local"; - case OMPC_device_type: - return "device_type"; - case OMPC_match: - return "match"; - } - llvm_unreachable("Invalid OpenMP clause kind"); -} - unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str) { switch (Kind) { diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp index aa6b6bc64c32..b6db63545c2c 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -341,8 +341,7 @@ class CheckVarsEscapingDeclContext final if (!Attr) return; if (((Attr->getCaptureKind() != OMPC_map) && - !isOpenMPPrivate( - static_cast(Attr->getCaptureKind()))) || + !isOpenMPPrivate(Attr->getCaptureKind())) || ((Attr->getCaptureKind() == OMPC_map) && !FD->getType()->isAnyPointerType())) return; diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 4bec5f557ab8..4da1b4146af3 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -1389,7 +1389,7 @@ bool Parser::parseOMPDeclareVariantMatchClause(SourceLocation Loc, // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(OMPC_match))) { + getOpenMPClauseName(OMPC_match).data())) { while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch)) ; // Skip the last annot_pragma_openmp_end. @@ -1436,7 +1436,7 @@ parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind) { // Parse '('. BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(Kind))) + getOpenMPClauseName(Kind).data())) return llvm::None; unsigned Type = getOpenMPSimpleClauseType( @@ -1675,18 +1675,18 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( SmallVector Clauses; if (Tok.isNot(tok::annot_pragma_openmp_end)) { SmallVector, - OMPC_unknown + 1> - FirstClauses(OMPC_unknown + 1); + unsigned(OMPC_unknown) + 1> + FirstClauses(unsigned(OMPC_unknown) + 1); while (Tok.isNot(tok::annot_pragma_openmp_end)) { OpenMPClauseKind CKind = Tok.isAnnotation() ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind, - !FirstClauses[CKind].getInt()); + OMPClause *Clause = ParseOpenMPClause( + OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt()); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[CKind].setInt(true); + FirstClauses[unsigned(CKind)].setInt(true); if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -1710,8 +1710,9 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( case OMPD_requires: { SourceLocation StartLoc = ConsumeToken(); SmallVector Clauses; - SmallVector, OMPC_unknown + 1> - FirstClauses(OMPC_unknown + 1); + SmallVector, + unsigned(OMPC_unknown) + 1> + FirstClauses(unsigned(OMPC_unknown) + 1); if (Tok.is(tok::annot_pragma_openmp_end)) { Diag(Tok, diag::err_omp_expected_clause) << getOpenMPDirectiveName(OMPD_requires); @@ -1722,11 +1723,11 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind, - !FirstClauses[CKind].getInt()); + OMPClause *Clause = ParseOpenMPClause( + OMPD_requires, CKind, !FirstClauses[unsigned(CKind)].getInt()); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[CKind].setInt(true); + FirstClauses[unsigned(CKind)].setInt(true); if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -2025,8 +2026,9 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { ParsingOpenMPDirectiveRAII DirScope(*this); ParenBraceBracketBalancer BalancerRAIIObj(*this); SmallVector Clauses; - SmallVector, OMPC_unknown + 1> - FirstClauses(OMPC_unknown + 1); + SmallVector, + unsigned(OMPC_unknown) + 1> + FirstClauses(unsigned(OMPC_unknown) + 1); unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope; SourceLocation Loc = ConsumeAnnotationToken(), EndLoc; @@ -2071,18 +2073,18 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { SmallVector Clauses; if (Tok.isNot(tok::annot_pragma_openmp_end)) { SmallVector, - OMPC_unknown + 1> - FirstClauses(OMPC_unknown + 1); + unsigned(OMPC_unknown) + 1> + FirstClauses(unsigned(OMPC_unknown) + 1); while (Tok.isNot(tok::annot_pragma_openmp_end)) { OpenMPClauseKind CKind = Tok.isAnnotation() ? OMPC_unknown : getOpenMPClauseKind(PP.getSpelling(Tok)); Actions.StartOpenMPClause(CKind); - OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind, - !FirstClauses[CKind].getInt()); + OMPClause *Clause = ParseOpenMPClause( + OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt()); SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch); - FirstClauses[CKind].setInt(true); + FirstClauses[unsigned(CKind)].setInt(true); if (Clause != nullptr) Clauses.push_back(Clause); if (Tok.is(tok::annot_pragma_openmp_end)) { @@ -2250,11 +2252,11 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { ImplicitClauseAllowed = false; Actions.StartOpenMPClause(CKind); HasImplicitClause = false; - OMPClause *Clause = - ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt()); - FirstClauses[CKind].setInt(true); + OMPClause *Clause = ParseOpenMPClause( + DKind, CKind, !FirstClauses[unsigned(CKind)].getInt()); + FirstClauses[unsigned(CKind)].setInt(true); if (Clause) { - FirstClauses[CKind].setPointer(Clause); + FirstClauses[unsigned(CKind)].setPointer(Clause); Clauses.push_back(Clause); } @@ -2271,7 +2273,7 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { // OpenMP [2.13.8, ordered Construct, Syntax] // If the depend clause is specified, the ordered construct is a stand-alone // directive. - if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) { + if (DKind == OMPD_ordered && FirstClauses[unsigned(OMPC_depend)].getInt()) { if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) == ParsedStmtContext()) { Diag(Loc, diag::err_omp_immediate_directive) @@ -2756,7 +2758,7 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind, // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(Kind))) + getOpenMPClauseName(Kind).data())) return nullptr; ExprResult Val; @@ -3176,7 +3178,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); if (T.expectAndConsume(diag::err_expected_lparen_after, - getOpenMPClauseName(Kind))) + getOpenMPClauseName(Kind).data())) return true; bool DependWithIterator = false; diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index cfaf981983c1..dfb809e0aaa1 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -2233,7 +2233,7 @@ void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, } } if (OMPC != OMPC_unknown) - FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); + FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); } bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index de05d436d3b9..1f88f9c57465 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -730,10 +730,10 @@ class TreeTransform { #define ABSTRACT_STMT(Stmt) #include "clang/AST/StmtNodes.inc" -#define OPENMP_CLAUSE(Name, Class) \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ LLVM_ATTRIBUTE_NOINLINE \ OMPClause *Transform ## Class(Class *S); -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" /// Build a new qualified type given its unqualified type and type location. /// @@ -3597,10 +3597,10 @@ OMPClause *TreeTransform::TransformOMPClause(OMPClause *S) { switch (S->getClauseKind()) { default: break; // Transform individual clause nodes -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_ ## Name : \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case Enum: \ return getDerived().Transform ## Class(cast(S)); -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" } return S; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 7d84f1108c85..22a3771e4b85 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -11616,8 +11616,8 @@ class OMPClauseReader : public OMPClauseVisitor { OMPClauseReader(ASTRecordReader &Record) : Record(Record), Context(Record.getContext()) {} -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *C); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *C); +#include "llvm/Frontend/OpenMP/OMPKinds.def" OMPClause *readClause(); void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C); void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C); @@ -11631,149 +11631,149 @@ OMPClause *ASTRecordReader::readOMPClause() { OMPClause *OMPClauseReader::readClause() { OMPClause *C = nullptr; - switch (Record.readInt()) { - case OMPC_if: + switch (llvm::omp::Clause(Record.readInt())) { + case llvm::omp::OMPC_if: C = new (Context) OMPIfClause(); break; - case OMPC_final: + case llvm::omp::OMPC_final: C = new (Context) OMPFinalClause(); break; - case OMPC_num_threads: + case llvm::omp::OMPC_num_threads: C = new (Context) OMPNumThreadsClause(); break; - case OMPC_safelen: + case llvm::omp::OMPC_safelen: C = new (Context) OMPSafelenClause(); break; - case OMPC_simdlen: + case llvm::omp::OMPC_simdlen: C = new (Context) OMPSimdlenClause(); break; - case OMPC_allocator: + case llvm::omp::OMPC_allocator: C = new (Context) OMPAllocatorClause(); break; - case OMPC_collapse: + case llvm::omp::OMPC_collapse: C = new (Context) OMPCollapseClause(); break; - case OMPC_default: + case llvm::omp::OMPC_default: C = new (Context) OMPDefaultClause(); break; - case OMPC_proc_bind: + case llvm::omp::OMPC_proc_bind: C = new (Context) OMPProcBindClause(); break; - case OMPC_schedule: + case llvm::omp::OMPC_schedule: C = new (Context) OMPScheduleClause(); break; - case OMPC_ordered: + case llvm::omp::OMPC_ordered: C = OMPOrderedClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_nowait: + case llvm::omp::OMPC_nowait: C = new (Context) OMPNowaitClause(); break; - case OMPC_untied: + case llvm::omp::OMPC_untied: C = new (Context) OMPUntiedClause(); break; - case OMPC_mergeable: + case llvm::omp::OMPC_mergeable: C = new (Context) OMPMergeableClause(); break; - case OMPC_read: + case llvm::omp::OMPC_read: C = new (Context) OMPReadClause(); break; - case OMPC_write: + case llvm::omp::OMPC_write: C = new (Context) OMPWriteClause(); break; - case OMPC_update: + case llvm::omp::OMPC_update: C = OMPUpdateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_capture: + case llvm::omp::OMPC_capture: C = new (Context) OMPCaptureClause(); break; - case OMPC_seq_cst: + case llvm::omp::OMPC_seq_cst: C = new (Context) OMPSeqCstClause(); break; - case OMPC_acq_rel: + case llvm::omp::OMPC_acq_rel: C = new (Context) OMPAcqRelClause(); break; - case OMPC_acquire: + case llvm::omp::OMPC_acquire: C = new (Context) OMPAcquireClause(); break; - case OMPC_release: + case llvm::omp::OMPC_release: C = new (Context) OMPReleaseClause(); break; - case OMPC_relaxed: + case llvm::omp::OMPC_relaxed: C = new (Context) OMPRelaxedClause(); break; - case OMPC_threads: + case llvm::omp::OMPC_threads: C = new (Context) OMPThreadsClause(); break; - case OMPC_simd: + case llvm::omp::OMPC_simd: C = new (Context) OMPSIMDClause(); break; - case OMPC_nogroup: + case llvm::omp::OMPC_nogroup: C = new (Context) OMPNogroupClause(); break; - case OMPC_unified_address: + case llvm::omp::OMPC_unified_address: C = new (Context) OMPUnifiedAddressClause(); break; - case OMPC_unified_shared_memory: + case llvm::omp::OMPC_unified_shared_memory: C = new (Context) OMPUnifiedSharedMemoryClause(); break; - case OMPC_reverse_offload: + case llvm::omp::OMPC_reverse_offload: C = new (Context) OMPReverseOffloadClause(); break; - case OMPC_dynamic_allocators: + case llvm::omp::OMPC_dynamic_allocators: C = new (Context) OMPDynamicAllocatorsClause(); break; - case OMPC_atomic_default_mem_order: + case llvm::omp::OMPC_atomic_default_mem_order: C = new (Context) OMPAtomicDefaultMemOrderClause(); break; - case OMPC_private: + case llvm::omp::OMPC_private: C = OMPPrivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_firstprivate: + case llvm::omp::OMPC_firstprivate: C = OMPFirstprivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_lastprivate: + case llvm::omp::OMPC_lastprivate: C = OMPLastprivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_shared: + case llvm::omp::OMPC_shared: C = OMPSharedClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_reduction: + case llvm::omp::OMPC_reduction: C = OMPReductionClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_task_reduction: + case llvm::omp::OMPC_task_reduction: C = OMPTaskReductionClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_in_reduction: + case llvm::omp::OMPC_in_reduction: C = OMPInReductionClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_linear: + case llvm::omp::OMPC_linear: C = OMPLinearClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_aligned: + case llvm::omp::OMPC_aligned: C = OMPAlignedClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_copyin: + case llvm::omp::OMPC_copyin: C = OMPCopyinClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_copyprivate: + case llvm::omp::OMPC_copyprivate: C = OMPCopyprivateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_flush: + case llvm::omp::OMPC_flush: C = OMPFlushClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_depobj: + case llvm::omp::OMPC_depobj: C = OMPDepobjClause::CreateEmpty(Context); break; - case OMPC_depend: { + case llvm::omp::OMPC_depend: { unsigned NumVars = Record.readInt(); unsigned NumLoops = Record.readInt(); C = OMPDependClause::CreateEmpty(Context, NumVars, NumLoops); break; } - case OMPC_device: + case llvm::omp::OMPC_device: C = new (Context) OMPDeviceClause(); break; - case OMPC_map: { + case llvm::omp::OMPC_map: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11782,31 +11782,31 @@ OMPClause *OMPClauseReader::readClause() { C = OMPMapClause::CreateEmpty(Context, Sizes); break; } - case OMPC_num_teams: + case llvm::omp::OMPC_num_teams: C = new (Context) OMPNumTeamsClause(); break; - case OMPC_thread_limit: + case llvm::omp::OMPC_thread_limit: C = new (Context) OMPThreadLimitClause(); break; - case OMPC_priority: + case llvm::omp::OMPC_priority: C = new (Context) OMPPriorityClause(); break; - case OMPC_grainsize: + case llvm::omp::OMPC_grainsize: C = new (Context) OMPGrainsizeClause(); break; - case OMPC_num_tasks: + case llvm::omp::OMPC_num_tasks: C = new (Context) OMPNumTasksClause(); break; - case OMPC_hint: + case llvm::omp::OMPC_hint: C = new (Context) OMPHintClause(); break; - case OMPC_dist_schedule: + case llvm::omp::OMPC_dist_schedule: C = new (Context) OMPDistScheduleClause(); break; - case OMPC_defaultmap: + case llvm::omp::OMPC_defaultmap: C = new (Context) OMPDefaultmapClause(); break; - case OMPC_to: { + case llvm::omp::OMPC_to: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11815,7 +11815,7 @@ OMPClause *OMPClauseReader::readClause() { C = OMPToClause::CreateEmpty(Context, Sizes); break; } - case OMPC_from: { + case llvm::omp::OMPC_from: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11824,7 +11824,7 @@ OMPClause *OMPClauseReader::readClause() { C = OMPFromClause::CreateEmpty(Context, Sizes); break; } - case OMPC_use_device_ptr: { + case llvm::omp::OMPC_use_device_ptr: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11833,7 +11833,7 @@ OMPClause *OMPClauseReader::readClause() { C = OMPUseDevicePtrClause::CreateEmpty(Context, Sizes); break; } - case OMPC_is_device_ptr: { + case llvm::omp::OMPC_is_device_ptr: { OMPMappableExprListSizeTy Sizes; Sizes.NumVars = Record.readInt(); Sizes.NumUniqueDeclarations = Record.readInt(); @@ -11842,27 +11842,31 @@ OMPClause *OMPClauseReader::readClause() { C = OMPIsDevicePtrClause::CreateEmpty(Context, Sizes); break; } - case OMPC_allocate: + case llvm::omp::OMPC_allocate: C = OMPAllocateClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_nontemporal: + case llvm::omp::OMPC_nontemporal: C = OMPNontemporalClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_inclusive: + case llvm::omp::OMPC_inclusive: C = OMPInclusiveClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_exclusive: + case llvm::omp::OMPC_exclusive: C = OMPExclusiveClause::CreateEmpty(Context, Record.readInt()); break; - case OMPC_order: + case llvm::omp::OMPC_order: C = new (Context) OMPOrderClause(); break; - case OMPC_destroy: + case llvm::omp::OMPC_destroy: C = new (Context) OMPDestroyClause(); break; - case OMPC_detach: + case llvm::omp::OMPC_detach: C = new (Context) OMPDetachClause(); break; +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Enum: \ + break; +#include "llvm/Frontend/OpenMP/OMPKinds.def" } assert(C && "Unknown OMPClause type"); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 89ba7e623965..3b72f0f1cef2 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -6037,8 +6037,8 @@ class OMPClauseWriter : public OMPClauseVisitor { public: OMPClauseWriter(ASTRecordWriter &Record) : Record(Record) {} -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *S); +#include "llvm/Frontend/OpenMP/OMPKinds.def" void writeClause(OMPClause *C); void VisitOMPClauseWithPreInit(OMPClauseWithPreInit *C); void VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *C); @@ -6051,7 +6051,7 @@ void ASTRecordWriter::writeOMPClause(OMPClause *C) { } void OMPClauseWriter::writeClause(OMPClause *C) { - Record.push_back(C->getClauseKind()); + Record.push_back(unsigned(C->getClauseKind())); Visit(C); Record.AddSourceLocation(C->getBeginLoc()); Record.AddSourceLocation(C->getEndLoc()); diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt index b7fb0d90c980..bcf2dfdb8326 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt index dc2a6279b737..057cdd4bb18a 100644 --- a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt @@ -1,4 +1,7 @@ -set(LLVM_LINK_COMPONENTS support) +set(LLVM_LINK_COMPONENTS + FrontendOpenMP + Support +) add_clang_library(clangStaticAnalyzerCore APSIntType.cpp diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 14814f89d97d..50c088606538 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2153,8 +2153,8 @@ class OMPClauseEnqueue : public ConstOMPClauseVisitor { public: OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {} -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(const Class *C); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C); +#include "llvm/Frontend/OpenMP/OMPKinds.def" void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C); void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C); }; diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp index fbf2ff130785..428879d0695c 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -2612,7 +2612,7 @@ TEST(HasExternalFormalLinkage, Basic) { } TEST(HasDefaultArgument, Basic) { - EXPECT_TRUE(matches("void x(int val = 0) {}", + EXPECT_TRUE(matches("void x(int val = 0) {}", parmVarDecl(hasDefaultArgument()))); EXPECT_TRUE(notMatches("void x(int val) {}", parmVarDecl(hasDefaultArgument()))); @@ -2665,7 +2665,7 @@ TEST(HasTrailingReturn, MatchesTrailingReturn) { EXPECT_TRUE(matches("auto Y() -> int { return 0; }", functionDecl(hasTrailingReturn()))); EXPECT_TRUE(matches("auto X() -> int;", functionDecl(hasTrailingReturn()))); - EXPECT_TRUE(notMatches("int X() { return 0; }", + EXPECT_TRUE(notMatches("int X() { return 0; }", functionDecl(hasTrailingReturn()))); EXPECT_TRUE(notMatches("int X();", functionDecl(hasTrailingReturn()))); EXPECT_TRUE(notMatchesC("void X();", functionDecl(hasTrailingReturn()))); @@ -2891,8 +2891,8 @@ void x(int x) { } TEST(OMPExecutableDirective, isAllowedToContainClauseKind) { - auto Matcher = - ompExecutableDirective(isAllowedToContainClauseKind(OMPC_default)); + auto Matcher = ompExecutableDirective( + isAllowedToContainClauseKind(llvm::omp::OMPC_default)); const std::string Source0 = R"( void x() { diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h index 7cda3197473f..d32fa8dc98ef 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h @@ -34,11 +34,18 @@ enum class Directive { #include "llvm/Frontend/OpenMP/OMPKinds.def" }; +/// IDs for all OpenMP clauses. +enum class Clause { +#define OMP_CLAUSE(Enum, ...) Enum, +#include "llvm/Frontend/OpenMP/OMPKinds.def" +}; + /// Make the enum values available in the llvm::omp namespace. This allows us to /// write something like OMPD_parallel if we have a `using namespace omp`. At /// the same time we do not loose the strong type guarantees of the enum class, /// that is we cannot pass an unsigned as Directive without an explicit cast. #define OMP_DIRECTIVE(Enum, ...) constexpr auto Enum = omp::Directive::Enum; +#define OMP_CLAUSE(Enum, ...) constexpr auto Enum = omp::Clause::Enum; #include "llvm/Frontend/OpenMP/OMPKinds.def" /// IDs for all omp runtime library (RTL) functions. @@ -87,6 +94,12 @@ Directive getOpenMPDirectiveKind(StringRef Str); /// Return a textual representation of the directive \p D. StringRef getOpenMPDirectiveName(Directive D); +/// Parse \p Str and return the clause it matches or OMPC_unknown if none. +Clause getOpenMPClauseKind(StringRef Str); + +/// Return a textual representation of the clause \p C. +StringRef getOpenMPClauseName(Clause C); + /// Forward declarations for LLVM-IR types (simple, function and structure) are /// generated below. Their names are defined and used in OpenMP/OMPKinds.def. /// Here we provide the forward declarations, the initializeTypes function will diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def index c80ecc7cbf77..09468358415f 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -105,6 +105,117 @@ __OMP_DIRECTIVE(unknown) ///} +/// OpenMP Clauses +/// +///{ + +#ifndef OMP_CLAUSE +#define OMP_CLAUSE(Enum, Str, Implicit) +#endif +#ifndef OMP_CLAUSE_CLASS +#define OMP_CLAUSE_CLASS(Enum, Str, Class) +#endif +#ifndef OMP_CLAUSE_NO_CLASS +#define OMP_CLAUSE_NO_CLASS(Enum, Str) +#endif + +#define __OMP_CLAUSE(Name, Class) \ + OMP_CLAUSE(OMPC_##Name, #Name, /* Implicit */ false) \ + OMP_CLAUSE_CLASS(OMPC_##Name, #Name, Class) +#define __OMP_CLAUSE_NO_CLASS(Name) \ + OMP_CLAUSE(OMPC_##Name, #Name, /* Implicit */ false) \ + OMP_CLAUSE_NO_CLASS(OMPC_##Name, #Name) +#define __OMP_IMPLICIT_CLAUSE_CLASS(Name, Str, Class) \ + OMP_CLAUSE(OMPC_##Name, Str, /* Implicit */ true) \ + OMP_CLAUSE_CLASS(OMPC_##Name, Str, Class) +#define __OMP_IMPLICIT_CLAUSE_NO_CLASS(Name, Str) \ + OMP_CLAUSE(OMPC_##Name, Str, /* Implicit */ true) \ + OMP_CLAUSE_NO_CLASS(OMPC_##Name, Str) + +__OMP_CLAUSE(allocator, OMPAllocatorClause) +__OMP_CLAUSE(if, OMPIfClause) +__OMP_CLAUSE(final, OMPFinalClause) +__OMP_CLAUSE(num_threads, OMPNumThreadsClause) +__OMP_CLAUSE(safelen, OMPSafelenClause) +__OMP_CLAUSE(simdlen, OMPSimdlenClause) +__OMP_CLAUSE(collapse, OMPCollapseClause) +__OMP_CLAUSE(default, OMPDefaultClause) +__OMP_CLAUSE(private, OMPPrivateClause) +__OMP_CLAUSE(firstprivate, OMPFirstprivateClause) +__OMP_CLAUSE(lastprivate, OMPLastprivateClause) +__OMP_CLAUSE(shared, OMPSharedClause) +__OMP_CLAUSE(reduction, OMPReductionClause) +__OMP_CLAUSE(linear, OMPLinearClause) +__OMP_CLAUSE(aligned, OMPAlignedClause) +__OMP_CLAUSE(copyin, OMPCopyinClause) +__OMP_CLAUSE(copyprivate, OMPCopyprivateClause) +__OMP_CLAUSE(proc_bind, OMPProcBindClause) +__OMP_CLAUSE(schedule, OMPScheduleClause) +__OMP_CLAUSE(ordered, OMPOrderedClause) +__OMP_CLAUSE(nowait, OMPNowaitClause) +__OMP_CLAUSE(untied, OMPUntiedClause) +__OMP_CLAUSE(mergeable, OMPMergeableClause) +__OMP_CLAUSE(read, OMPReadClause) +__OMP_CLAUSE(write, OMPWriteClause) +__OMP_CLAUSE(update, OMPUpdateClause) +__OMP_CLAUSE(capture, OMPCaptureClause) +__OMP_CLAUSE(seq_cst, OMPSeqCstClause) +__OMP_CLAUSE(acq_rel, OMPAcqRelClause) +__OMP_CLAUSE(acquire, OMPAcquireClause) +__OMP_CLAUSE(release, OMPReleaseClause) +__OMP_CLAUSE(relaxed, OMPRelaxedClause) +__OMP_CLAUSE(depend, OMPDependClause) +__OMP_CLAUSE(device, OMPDeviceClause) +__OMP_CLAUSE(threads, OMPThreadsClause) +__OMP_CLAUSE(simd, OMPSIMDClause) +__OMP_CLAUSE(map, OMPMapClause) +__OMP_CLAUSE(num_teams, OMPNumTeamsClause) +__OMP_CLAUSE(thread_limit, OMPThreadLimitClause) +__OMP_CLAUSE(priority, OMPPriorityClause) +__OMP_CLAUSE(grainsize, OMPGrainsizeClause) +__OMP_CLAUSE(nogroup, OMPNogroupClause) +__OMP_CLAUSE(num_tasks, OMPNumTasksClause) +__OMP_CLAUSE(hint, OMPHintClause) +__OMP_CLAUSE(dist_schedule, OMPDistScheduleClause) +__OMP_CLAUSE(defaultmap, OMPDefaultmapClause) +__OMP_CLAUSE(to, OMPToClause) +__OMP_CLAUSE(from, OMPFromClause) +__OMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause) +__OMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause) +__OMP_CLAUSE(task_reduction, OMPTaskReductionClause) +__OMP_CLAUSE(in_reduction, OMPInReductionClause) +__OMP_CLAUSE(unified_address, OMPUnifiedAddressClause) +__OMP_CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause) +__OMP_CLAUSE(reverse_offload, OMPReverseOffloadClause) +__OMP_CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause) +__OMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause) +__OMP_CLAUSE(allocate, OMPAllocateClause) +__OMP_CLAUSE(nontemporal, OMPNontemporalClause) +__OMP_CLAUSE(order, OMPOrderClause) +__OMP_CLAUSE(destroy, OMPDestroyClause) +__OMP_CLAUSE(detach, OMPDetachClause) +__OMP_CLAUSE(inclusive, OMPInclusiveClause) +__OMP_CLAUSE(exclusive, OMPExclusiveClause) + +__OMP_CLAUSE_NO_CLASS(uniform) +__OMP_CLAUSE_NO_CLASS(device_type) +__OMP_CLAUSE_NO_CLASS(match) + +__OMP_IMPLICIT_CLAUSE_CLASS(depobj, "depobj", OMPDepobjClause) +__OMP_IMPLICIT_CLAUSE_CLASS(flush, "flush", OMPFlushClause) + +__OMP_IMPLICIT_CLAUSE_NO_CLASS(threadprivate, "threadprivate or thread local") +__OMP_IMPLICIT_CLAUSE_NO_CLASS(unknown, "unknown") + +#undef __OMP_IMPLICIT_CLAUSE_NO_CLASS +#undef __OMP_IMPLICIT_CLAUSE_CLASS +#undef __OMP_CLAUSE +#undef OMP_CLAUSE_NO_CLASS +#undef OMP_CLAUSE_CLASS +#undef OMP_CLAUSE + +///} + /// Types used in runtime structs or runtime functions /// ///{ @@ -232,8 +343,10 @@ __OMP_RTL(omp_set_max_active_levels, false, Void, Int32) __OMP_RTL(__kmpc_master, false, Int32, IdentPtr, Int32) __OMP_RTL(__kmpc_end_master, false, Void, IdentPtr, Int32) __OMP_RTL(__kmpc_critical, false, Void, IdentPtr, Int32, KmpCriticalNamePtrTy) -__OMP_RTL(__kmpc_critical_with_hint, false, Void, IdentPtr, Int32, KmpCriticalNamePtrTy, Int32) -__OMP_RTL(__kmpc_end_critical, false, Void, IdentPtr, Int32, KmpCriticalNamePtrTy) +__OMP_RTL(__kmpc_critical_with_hint, false, Void, IdentPtr, Int32, + KmpCriticalNamePtrTy, Int32) +__OMP_RTL(__kmpc_end_critical, false, Void, IdentPtr, Int32, + KmpCriticalNamePtrTy) __OMP_RTL(__last, false, Void, ) diff --git a/llvm/lib/Frontend/OpenMP/OMPConstants.cpp b/llvm/lib/Frontend/OpenMP/OMPConstants.cpp index 6ee44958d1c7..edd857d7b250 100644 --- a/llvm/lib/Frontend/OpenMP/OMPConstants.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPConstants.cpp @@ -36,6 +36,24 @@ StringRef llvm::omp::getOpenMPDirectiveName(Directive Kind) { llvm_unreachable("Invalid OpenMP directive kind"); } +Clause llvm::omp::getOpenMPClauseKind(StringRef Str) { + return llvm::StringSwitch(Str) +#define OMP_CLAUSE(Enum, Str, Implicit) \ + .Case(Str, Implicit ? OMPC_unknown : Enum) +#include "llvm/Frontend/OpenMP/OMPKinds.def" + .Default(OMPC_unknown); +} + +StringRef llvm::omp::getOpenMPClauseName(Clause C) { + switch (C) { +#define OMP_CLAUSE(Enum, Str, ...) \ + case Enum: \ + return Str; +#include "llvm/Frontend/OpenMP/OMPKinds.def" + } + llvm_unreachable("Invalid OpenMP clause kind"); +} + /// Declarations for LLVM-IR types (simple, array, function and structure) are /// generated below. Their names are defined and used in OpenMPKinds.def. Here /// we provide the declarations, the initializeTypes function will provide the From cfe-commits at lists.llvm.org Sun Apr 5 20:32:23 2020 From: cfe-commits at lists.llvm.org (Nathan Ridge via cfe-commits) Date: Sun, 05 Apr 2020 20:32:23 -0700 (PDT) Subject: [clang] 8b3b755 - [clang] Persist Attr::IsPackExpansion into the PCH Message-ID: <5e8aa2c7.1c69fb81.fc83d.cc7d@mx.google.com> Author: Nathan Ridge Date: 2020-04-05T23:32:03-04:00 New Revision: 8b3b7556e9ab6084e9fd337d64dac1c165867d32 URL: https://github.com/llvm/llvm-project/commit/8b3b7556e9ab6084e9fd337d64dac1c165867d32 DIFF: https://github.com/llvm/llvm-project/commit/8b3b7556e9ab6084e9fd337d64dac1c165867d32.diff LOG: [clang] Persist Attr::IsPackExpansion into the PCH Summary: Fixes https://github.com/clangd/clangd/issues/309 Subscribers: ilya-biryukov, kadircet, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77194 Added: clang/test/PCH/cxx-attrs-packexpansion.cpp Modified: clang/utils/TableGen/ClangAttrEmitter.cpp Removed: ################################################################################ diff --git a/clang/test/PCH/cxx-attrs-packexpansion.cpp b/clang/test/PCH/cxx-attrs-packexpansion.cpp new file mode 100644 index 000000000000..6d292ec1e3e0 --- /dev/null +++ b/clang/test/PCH/cxx-attrs-packexpansion.cpp @@ -0,0 +1,25 @@ +// Test this without pch. +// RUN: %clang_cc1 -include %s -emit-llvm -o - %s + +// Test with pch. +// RUN: %clang_cc1 -emit-pch -o %t %s +// RUN: %clang_cc1 -include-pch %t -emit-llvm -o - %s + +#ifndef HEADER +#define HEADER + +template +struct static_variant { + alignas(Types...) T storage[10]; +}; + +#else + +struct A { + static_variant a; +}; +struct B { + static_variant _b; +}; + +#endif diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index e9f91c685ee4..486799eb81ba 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -2911,6 +2911,7 @@ void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) { if (R.isSubClassOf(InhClass)) OS << " bool isInherited = Record.readInt();\n"; OS << " bool isImplicit = Record.readInt();\n"; + OS << " bool isPackExpansion = Record.readInt();\n"; ArgRecords = R.getValueAsListOfDefs("Args"); Args.clear(); for (const auto *Arg : ArgRecords) { @@ -2926,6 +2927,7 @@ void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) { if (R.isSubClassOf(InhClass)) OS << " cast(New)->setInherited(isInherited);\n"; OS << " New->setImplicit(isImplicit);\n"; + OS << " New->setPackExpansion(isPackExpansion);\n"; OS << " break;\n"; OS << " }\n"; } @@ -2952,6 +2954,7 @@ void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) { if (R.isSubClassOf(InhClass)) OS << " Record.push_back(SA->isInherited());\n"; OS << " Record.push_back(A->isImplicit());\n"; + OS << " Record.push_back(A->isPackExpansion());\n"; for (const auto *Arg : Args) createArgument(*Arg, R.getName())->writePCHWrite(OS); From cfe-commits at lists.llvm.org Sun Apr 5 20:49:14 2020 From: cfe-commits at lists.llvm.org (Yaxun Liu via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 03:49:14 +0000 (UTC) Subject: [PATCH] D77028: [NFC] Refactor DeferredDiagsEmitter and skip redundant visit In-Reply-To: References: Message-ID: <0fb969a8e96d85a954fcf40dae9d5e74@localhost.localdomain> yaxunl marked 3 inline comments as done. yaxunl added inline comments. ================ Comment at: clang/lib/Sema/Sema.cpp:1508 void checkFunc(SourceLocation Loc, FunctionDecl *FD) { + auto DiagsCountIt = DiagsCount.find(FD); FunctionDecl *Caller = UseStack.empty() ? nullptr : UseStack.back(); ---------------- rjmccall wrote: > yaxunl wrote: > > rjmccall wrote: > > > yaxunl wrote: > > > > rjmccall wrote: > > > > > yaxunl wrote: > > > > > > rjmccall wrote: > > > > > > > yaxunl wrote: > > > > > > > > rjmccall wrote: > > > > > > > > > It makes me a little uncomfortable to be holding an iterator this long while calling a fair amount of other stuff in the meantime. > > > > > > > > > > > > > > > > > > Your use of DiagsCount is subtle enough that it really needs to be explained in some comments. You're doing stuff conditionally based on both whether the entry exists but also whether it's non-zero. > > > > > > > > added comments > > > > > > > Okay, thanks for that. Two points, then. First, it looks like the count is really just a boolean for whether the function recursively triggers any diagnostics. And second, can't it just be as simple as whether we've visited that function at all in a context that's forcing diagnostics to be emitted? The logic seems to be to try to emit the diagnostics for each use-path, but why would we want that? > > > > > > For the second comment, we need to visit a function again for each use-path because we need to report each use-path that triggers a diagnostic, otherwise users will see a new error after they fix one error, instead of seeing all the errors at once. > > > > > > > > > > > > For the first comment, I will change the count to two flags: one for the case where the function is not in device context, the other is for the case where the function is in device context. This will allow us to avoid redundant visits whether or not we are in a device context. > > > > > > For the second comment, we need to visit a function again for each use-path because we need to report each use-path that triggers a diagnostic, otherwise users will see a new error after they fix one error, instead of seeing all the errors at once. > > > > > > > > > > This is not what we do in analogous cases where errors are triggered by a use, like in template instantiation. The bug might be that the device program is using a function that it shouldn't be using, or the bug might be that a function that's supposed to be usable from the device is written incorrectly. In the former case, yes, not reporting the errors for each use-path may force the programmer to build multiple times to find all the problematic uses. However, in the latter case you can easily end up emitting a massive number of errors that completely drowns out everything else. It's also non-linear: the number of different use-paths of a particular function can be combinatoric. > > > > The deferred diagnostics fall into the first case mostly. > > > > > > > > Not all diagnostic messages happen in device host functions are deferred. Most of diagnostic messages are emitted immediately, disregarding whether the function is emitted or not. > > > > > > > > Only a few special types of diagnostic messages e.g. inline assembly errors, exceptions, varags are deferred. This is because clang has to use pragmas to make all functions device and host in some system headers to be able to use them in device compilation, whereas some of these functions will cause error only if they are emitted in device compilation. Since we cannot change these headers, we have to defer such diagnostics to the point where they are actually triggered. Therefore we are mostly interested in "who is calling these functions" instead of the diagnostics themselves. > > > > > > > > For normal programs containing no diagnostics, the current approach should sufficiently avoid all redundant visits and all functions will be visited once. > > > > > > > > The functions may be visited multiple times when there are deferred diagnostics, however this should be limited by the maximum number of errors. > > > Okay. I understand the point now about being mostly concerned about using functions in headers. > > > > > > My concern about visiting things a combinatorial number of times is less about generating an excessive number of errors and more about taking an excessive amount of time to finish compilation. The compiler really should not be using any exponential algorithms; a simple visited set will ensure that, but I think what you're doing does not. Can you make a case for why that's not true? > > The current approach is linear for the number of visits to functions. > > > > Let's assume the number of functions is N. > > > > The current approach already restricted revisiting a node that's already in the current use-path to prevent infinite recursion, therefore a use-path has maximum length N. > > > > The functions can be classified as two categories: > > > > Those who trigger deferred diags directly or indirectly, which we call trigger nodes. > > > > Those who do not trigger deferred diags directly or indirectly, which we call non-trigger nodes. > > > > Non-trigger nodes can be identified at most with two visits. All other visits are skipped. Therefore the total number of visits of non-trigger nodes is less than 2*N. > > > > We can also classify the use-paths as trigger paths and non-trigger paths. Each trigger path causes at least one diagnostic emitted. Each non-trigger path does not cause any diagnostics emitted. > > > > Due to limit of maximum diagnostics allowed, the algorithm will stop after a finite number of use-paths visited. Let's say it is M. (In reality, M could be much smaller than the maximum diagnostic allowed.) Then the number of trigger paths is at most M. > > > > Let's list all the use-paths visited and count all the nodes visited in these use-paths. > > > > First we consider all the use-paths that containing only non-trigger nodes, since each non-trigger nodes can only be visited twice. The total number of visits of nodes is less than 2*N. > > > > Then we consider all the trigger paths. Since the maximum path length is N, the total number of nodes visited is less than N*M. > > > > Now we only need to consider the non-trigger paths that starts with trigger nodes and end with a non-trigger node. For example, ABCD, where A, B, C, D denote nodes (functions) visited in the path. We can prove that A, B, C must be trigger nodes, since if any of A, B, C is a non-trigger node, the path will ends earlier, not reaching D. We can also prove that the sub-path ABC must be shared with a trigger path e.g. ABCEF, since otherwise C will be a non-trigger node. Then we do not need to count visit of A, B, and C, since they have already been counted when we count the visited nodes by trigger paths. > > > > Therefore, the total number of visits for functions is less than (2+M)*N, where M is actual number of diagnostics emitted. > > > > Due to limit of maximum diagnostics allowed, the algorithm will stop after a finite number of use-paths visited. > > Why do you think this is true? I don't see anything in your actual code which asks whether the error limit has been reached; it just does all the work and trusts the diagnostics engine to stop emitting diagnostics eventually. > > Try turning the error limit off (which will tell you how much work you're doing, since you're not short-circuiting when it's reached) and seeing how many diagnostics you get if you have a chain of functions like this: > > ``` > // All of these functions should be emitted on demand. > void hasInvalid() { /* this function should trigger a deferred diagnostic of some sort */ } > void use0() { hasInvalid(); hasInvalid(); } > void use1() { use0(); use0(); } > void use2() { use1(); use1(); } > void use3() { use2(); use2(); } > void use4() { use3(); use3(); } > // The final function should be a kernel or something like that. > ``` > > Also, in general, since the error limit can be disabled, I don't think it's a good idea for it to be the only thing stopping you from doing an exponential amount of work. It seems not practical to emit diagnostic for each triggering use-path since this will cause exponential time and also exponential diagnostics. I will make change so that each function is visited at most twice. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77028/new/ https://reviews.llvm.org/D77028 From cfe-commits at lists.llvm.org Sun Apr 5 20:49:15 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 03:49:15 +0000 (UTC) Subject: [PATCH] D77414: [OpenMP] Add match_{all,any,none} declare variant selector extensions. In-Reply-To: References: Message-ID: <658aacfcd7c9abf0332bbbcc5754e9da@localhost.localdomain> jdoerfert marked an inline comment as done. jdoerfert added a comment. Will fix the other two nits too. ================ Comment at: clang/lib/Parse/ParseOpenMP.cpp:1823 ASTContext &ASTCtx = Actions.getASTContext(); - TI.getAsVariantMatchInfo(ASTCtx, VMI, /* DeviceSetOnly */ true); + TI.getAsVariantMatchInfo(ASTCtx, VMI); OMPContext OMPCtx(ASTCtx.getLangOpts().OpenMPIsDevice, ---------------- mikerice wrote: > One of the lit tests fails because this is called before semantic checks on the score expression. This function tries to evaluate the score as a constant and if it isn't will crash. Probably not specific to this change but how can we deal with that? > > ``` > int foo(void); > #pragma omp begin declare variant match(implementation={vendor(score(foo()) ibm)}) > #pragma omp end declare variant > ``` Saw that too late but it's fixed now. We will ignore non-constant scores and evaluae non-constant user conditions as false. Note that both are not valid inputs we will diagnose later anyway. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77414/new/ https://reviews.llvm.org/D77414 From cfe-commits at lists.llvm.org Sun Apr 5 20:49:16 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 03:49:16 +0000 (UTC) Subject: [PATCH] D77290: [OpenMP] Specialize OpenMP calls after template instantiation In-Reply-To: References: Message-ID: <0163e2898cc6524df3942302daa8ffaf@localhost.localdomain> jdoerfert marked an inline comment as done. jdoerfert added inline comments. ================ Comment at: clang/lib/Sema/SemaTemplateInstantiate.cpp:1693 +ExprResult TemplateInstantiator::TransformCallExpr(CallExpr *E) { + ExprResult R = TreeTransform::TransformCallExpr(E); + if (!SemaRef.getLangOpts().OpenMP || !R.isUsable() || !isa(R.get())) ---------------- mikerice wrote: > Is there a reason you are adding this here as opposed to in the base class RebuildCallExpr? Are there cases where we rebuild call expressions that we don't want to do this variant processing? I just didn't know about it. I'll move the code there. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77290/new/ https://reviews.llvm.org/D77290 From cfe-commits at lists.llvm.org Sun Apr 5 20:49:16 2020 From: cfe-commits at lists.llvm.org (JF Bastien via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 03:49:16 +0000 (UTC) Subject: [PATCH] D68115: Zero initialize padding in unions In-Reply-To: References: Message-ID: <442d06ffde0ad1e586cf93529199c321@localhost.localdomain> jfb added a comment. > That sounds reasonable to me. So the behavior we're looking for is: > > - If `-ftrivial-auto-init` is off, then we guarantee to zero padding when the language spec requires it, and otherwise provide no such guarantee. > - If `-ftrivial-auto-init=zeroes` then we guarantee to zero padding within structs and unions with automatic storage duration, when that padding would otherwise be left uninitialized. > - If `-ftrivial-auto-init=pattern` then we guarantee to pattern-fill padding within structs and unions with automatic storage duration, when that padding would otherwise be left uninitialized (and will provide the zeroes required by the language rule when that is the required behavior). That's exactly what I'd like, yes! > [One possible tweak: for the `pattern` case, should we guarantee that the uninitialized padding will be pattern-filled? It would be simpler if we guaranteed it to be *either* zero- or pattern-filled; that way we can provide a conservatively-correct approximation by zero-filling whenever we're unsure.] Not guaranteeing a specific value for "pattern" remains my preferred choice. Where feasible, I'd rather we generate the most-repeated pattern so it's cheaper to synthesize. > And we do not initially provide any guarantees as to what happens to padding within objects of other storage durations beyond what the language spec requires. (We might at some point in the future, but that would be behind a separate flag from `-ftrivial-auto-init`.) I'd be happy with that approach. Does that address everyone's concerns? Yup! Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68115/new/ https://reviews.llvm.org/D68115 From cfe-commits at lists.llvm.org Sun Apr 5 20:49:42 2020 From: cfe-commits at lists.llvm.org (Nathan Ridge via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 03:49:42 +0000 (UTC) Subject: [PATCH] D77194: [clang] Persist Attr::IsPackExpansion into the PCH In-Reply-To: References: Message-ID: <0209f17f82db7b008acce1f5e4356d43@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG8b3b7556e9ab: [clang] Persist Attr::IsPackExpansion into the PCH (authored by nridge). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77194/new/ https://reviews.llvm.org/D77194 Files: clang/test/PCH/cxx-attrs-packexpansion.cpp clang/utils/TableGen/ClangAttrEmitter.cpp Index: clang/utils/TableGen/ClangAttrEmitter.cpp =================================================================== --- clang/utils/TableGen/ClangAttrEmitter.cpp +++ clang/utils/TableGen/ClangAttrEmitter.cpp @@ -2911,6 +2911,7 @@ if (R.isSubClassOf(InhClass)) OS << " bool isInherited = Record.readInt();\n"; OS << " bool isImplicit = Record.readInt();\n"; + OS << " bool isPackExpansion = Record.readInt();\n"; ArgRecords = R.getValueAsListOfDefs("Args"); Args.clear(); for (const auto *Arg : ArgRecords) { @@ -2926,6 +2927,7 @@ if (R.isSubClassOf(InhClass)) OS << " cast(New)->setInherited(isInherited);\n"; OS << " New->setImplicit(isImplicit);\n"; + OS << " New->setPackExpansion(isPackExpansion);\n"; OS << " break;\n"; OS << " }\n"; } @@ -2952,6 +2954,7 @@ if (R.isSubClassOf(InhClass)) OS << " Record.push_back(SA->isInherited());\n"; OS << " Record.push_back(A->isImplicit());\n"; + OS << " Record.push_back(A->isPackExpansion());\n"; for (const auto *Arg : Args) createArgument(*Arg, R.getName())->writePCHWrite(OS); Index: clang/test/PCH/cxx-attrs-packexpansion.cpp =================================================================== --- /dev/null +++ clang/test/PCH/cxx-attrs-packexpansion.cpp @@ -0,0 +1,25 @@ +// Test this without pch. +// RUN: %clang_cc1 -include %s -emit-llvm -o - %s + +// Test with pch. +// RUN: %clang_cc1 -emit-pch -o %t %s +// RUN: %clang_cc1 -include-pch %t -emit-llvm -o - %s + +#ifndef HEADER +#define HEADER + +template +struct static_variant { + alignas(Types...) T storage[10]; +}; + +#else + +struct A { + static_variant a; +}; +struct B { + static_variant _b; +}; + +#endif -------------- next part -------------- A non-text attachment was scrubbed... Name: D77194.255217.patch Type: text/x-patch Size: 1818 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 20:49:43 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 03:49:43 +0000 (UTC) Subject: [PATCH] D77112: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` In-Reply-To: References: Message-ID: <70c94d4dacd9046602880d84a64bf969@localhost.localdomain> This revision was automatically updated to reflect the committed changes. Closed by commit rG419a559c5a73: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` (authored by jdoerfert). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77112/new/ https://reviews.llvm.org/D77112 Files: clang/include/clang/AST/ASTFwd.h clang/include/clang/AST/ASTTypeTraits.h clang/include/clang/AST/OpenMPClause.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/Basic/Attr.td clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Basic/OpenMPKinds.h clang/lib/AST/ASTTypeTraits.cpp clang/lib/AST/AttrImpl.cpp clang/lib/AST/OpenMPClause.cpp clang/lib/AST/StmtProfile.cpp clang/lib/AST/TextNodeDumper.cpp clang/lib/ASTMatchers/CMakeLists.txt clang/lib/ASTMatchers/Dynamic/Marshallers.h clang/lib/Analysis/CMakeLists.txt clang/lib/Basic/OpenMPKinds.cpp clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt clang/lib/StaticAnalyzer/Core/CMakeLists.txt clang/tools/libclang/CIndex.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp llvm/include/llvm/Frontend/OpenMP/OMPConstants.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPConstants.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77112.255216.patch Type: text/x-patch Size: 118681 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 21:12:03 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via cfe-commits) Date: Sun, 05 Apr 2020 21:12:03 -0700 (PDT) Subject: [clang-tools-extra] 8ea07f6 - [OpenMP] Add extra qualification to OpenMP clause id Message-ID: <5e8aac13.1c69fb81.a2353.08b4@mx.google.com> Author: Johannes Doerfert Date: 2020-04-05T23:10:58-05:00 New Revision: 8ea07f62a6f06bdb7da981425227995423867a4d URL: https://github.com/llvm/llvm-project/commit/8ea07f62a6f06bdb7da981425227995423867a4d DIFF: https://github.com/llvm/llvm-project/commit/8ea07f62a6f06bdb7da981425227995423867a4d.diff LOG: [OpenMP] Add extra qualification to OpenMP clause id Forgot to adjust this use in 419a559c5a73f13578d891feb1299cada08d581e. Added: Modified: clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cpp b/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cpp index efd70e778c6f..724e9b9b9cbc 100644 --- a/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cpp +++ b/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cpp @@ -24,7 +24,7 @@ namespace openmp { void UseDefaultNoneCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( ompExecutableDirective( - allOf(isAllowedToContainClauseKind(OMPC_default), + allOf(isAllowedToContainClauseKind(llvm::omp::OMPC_default), anyOf(unless(hasAnyClause(ompDefaultClause())), hasAnyClause(ompDefaultClause(unless(isNoneKind())) .bind("clause"))))) From cfe-commits at lists.llvm.org Sun Apr 5 21:21:07 2020 From: cfe-commits at lists.llvm.org (Sameer Sahasrabuddhe via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 04:21:07 +0000 (UTC) Subject: [PATCH] D75917: Expose llvm fence instruction as clang intrinsic In-Reply-To: References: Message-ID: <8ff2742284535ef0ba92dcfddbd2b14b@localhost.localdomain> sameerds requested changes to this revision. sameerds added inline comments. This revision now requires changes to proceed. ================ Comment at: clang/include/clang/Basic/Builtins.def:1583 +// Second argument : target specific sync scope string +BUILTIN(__builtin_memory_fence, "vUicC*", "n") + ---------------- This should be moved to be near line 786, where atomic builtins are listed under the comment "// GCC does not support these, they are a Clang extension." ================ Comment at: clang/lib/CodeGen/CGBuiltin.cpp:13630 + + // Map C11/C++11 memory ordering to LLVM memory ordering + switch (static_cast(ord)) { ---------------- There should no mention of any high-level language here. The correct enum to validate against is llvm::AtomicOrdering from llvm/Support/AtomicOrdering.h, and not the C ABI or any other language ABI. ================ Comment at: clang/lib/CodeGen/CGBuiltin.cpp:13651 + llvm::getConstantStringInfo(Scope, scp); + SSID = getLLVMContext().getOrInsertSyncScopeID(scp); + ---------------- This seems to be creating a new ID for any arbitrary string passed as sync scope. This should be validated against LLVMContext::getSyncScopeNames(). ================ Comment at: clang/test/CodeGenHIP/builtin_memory_fence.cpp:5 + +void test_memory_fence_success() { +// CHECK-LABEL: test_memory_fence_success ---------------- There should be a line that tries to do: __builtin_memory_fence(__ATOMIC_SEQ_CST, "foobar"); ================ Comment at: clang/test/CodeGenHIP/builtin_memory_fence.cpp:9 + // CHECK: fence syncscope("workgroup") seq_cst + __builtin_memory_fence(__ATOMIC_SEQ_CST, "workgroup"); + ---------------- Orderings like `__ATOMIC_SEQ_CST` are defined for C/C++ memory models. They should not be used with the new builtin because this new builtin does not follow any specific language model. For user convenience, the right thing to do is to introduce new tokens in the Clang preprocessor, similar to the `__ATOMIC_*` tokens. The convenient shortcut is to just tell the user to supply numerical values by looking at the LLVM source code. >From llvm/Support/AtomicOrdering.h, note how the numerical value for `__ATOMIC_SEQ_CST` is 5, but the numerical value for the LLVM SequentiallyConsistent ordering is 7. The numerical value 5 refers to the LLVM ordering "release". So, if the implementation were correct, this line should result in the following unexpected LLVM IR: fence syncscope("workgroup") release Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D75917/new/ https://reviews.llvm.org/D75917 From cfe-commits at lists.llvm.org Sun Apr 5 21:21:08 2020 From: cfe-commits at lists.llvm.org (Nico Weber via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 04:21:08 +0000 (UTC) Subject: [PATCH] D77112: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` In-Reply-To: References: Message-ID: <45c92e66027d5cc92e8bbc26690e0983@localhost.localdomain> thakis added a comment. Broke clang-tools-extra again: http://lab.llvm.org:8011/builders/clang-ppc64be-linux/builds/46759/steps/build%20stage%201/logs/stdio Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77112/new/ https://reviews.llvm.org/D77112 From cfe-commits at lists.llvm.org Sun Apr 5 22:05:44 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via cfe-commits) Date: Sun, 05 Apr 2020 22:05:44 -0700 (PDT) Subject: [clang] 931c0cd - [OpenMP][NFC] Move and simplify directive -> allowed clause mapping Message-ID: <5e8ab8a8.1c69fb81.2b179.86e1@mx.google.com> Author: Johannes Doerfert Date: 2020-04-06T00:04:08-05:00 New Revision: 931c0cd713ee9b082389727bed1b518c6a44344f URL: https://github.com/llvm/llvm-project/commit/931c0cd713ee9b082389727bed1b518c6a44344f DIFF: https://github.com/llvm/llvm-project/commit/931c0cd713ee9b082389727bed1b518c6a44344f.diff LOG: [OpenMP][NFC] Move and simplify directive -> allowed clause mapping Move the listing of allowed clauses per OpenMP directive to the new macro file in `llvm/Frontend/OpenMP`. Also, use a single generic macro that specifies the directive and one allowed clause explicitly instead of a dedicated macro per directive. We save 800 loc and boilerplate for all new directives/clauses with no functional change. We also need to include the macro file only once and not once per directive. Depends on D77112. Reviewed By: JonChesterfield Differential Revision: https://reviews.llvm.org/D77113 Added: Modified: clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Basic/OpenMPKinds.h clang/lib/ASTMatchers/Dynamic/CMakeLists.txt clang/lib/Basic/OpenMPKinds.cpp clang/lib/Tooling/CMakeLists.txt clang/lib/Tooling/Transformer/CMakeLists.txt clang/unittests/AST/CMakeLists.txt clang/unittests/ASTMatchers/CMakeLists.txt clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt clang/unittests/Analysis/CMakeLists.txt clang/unittests/Rename/CMakeLists.txt clang/unittests/Sema/CMakeLists.txt clang/unittests/StaticAnalyzer/CMakeLists.txt clang/unittests/Tooling/CMakeLists.txt llvm/include/llvm/Frontend/OpenMP/OMPConstants.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPConstants.cpp Removed: ################################################################################ diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 8d97c32a0d36..9d7b4dcaacfd 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -7119,7 +7119,7 @@ AST_MATCHER(OMPDefaultClause, isSharedKind) { /// ``isAllowedToContainClauseKind("OMPC_default").`` AST_MATCHER_P(OMPExecutableDirective, isAllowedToContainClauseKind, OpenMPClauseKind, CKind) { - return isAllowedClauseForDirective( + return llvm::omp::isAllowedClauseForDirective( Node.getDirectiveKind(), CKind, Finder->getASTContext().getLangOpts().OpenMP); } diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index 4a4e6c6cb4c3..0ae0bc844e36 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -11,102 +11,6 @@ /// //===----------------------------------------------------------------------===// -#ifndef OPENMP_CLAUSE -# define OPENMP_CLAUSE(Name, Class) -#endif -#ifndef OPENMP_PARALLEL_CLAUSE -# define OPENMP_PARALLEL_CLAUSE(Name) -#endif -#ifndef OPENMP_SIMD_CLAUSE -# define OPENMP_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_FOR_CLAUSE -# define OPENMP_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_FOR_SIMD_CLAUSE -# define OPENMP_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_SECTIONS_CLAUSE -# define OPENMP_SECTIONS_CLAUSE(Name) -#endif -#ifndef OPENMP_SINGLE_CLAUSE -# define OPENMP_SINGLE_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_FOR_CLAUSE -# define OPENMP_PARALLEL_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_FOR_SIMD_CLAUSE -# define OPENMP_PARALLEL_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_MASTER_CLAUSE -# define OPENMP_PARALLEL_MASTER_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_SECTIONS_CLAUSE -# define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name) -#endif -#ifndef OPENMP_TASK_CLAUSE -# define OPENMP_TASK_CLAUSE(Name) -#endif -#ifndef OPENMP_ATOMIC_CLAUSE -# define OPENMP_ATOMIC_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_CLAUSE -# define OPENMP_TARGET_CLAUSE(Name) -#endif -#ifndef OPENMP_REQUIRES_CLAUSE -# define OPENMP_REQUIRES_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_DATA_CLAUSE -# define OPENMP_TARGET_DATA_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_ENTER_DATA_CLAUSE -#define OPENMP_TARGET_ENTER_DATA_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_EXIT_DATA_CLAUSE -#define OPENMP_TARGET_EXIT_DATA_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_PARALLEL_CLAUSE -# define OPENMP_TARGET_PARALLEL_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_PARALLEL_FOR_CLAUSE -# define OPENMP_TARGET_PARALLEL_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_UPDATE_CLAUSE -# define OPENMP_TARGET_UPDATE_CLAUSE(Name) -#endif -#ifndef OPENMP_TEAMS_CLAUSE -# define OPENMP_TEAMS_CLAUSE(Name) -#endif -#ifndef OPENMP_CANCEL_CLAUSE -# define OPENMP_CANCEL_CLAUSE(Name) -#endif -#ifndef OPENMP_ORDERED_CLAUSE -# define OPENMP_ORDERED_CLAUSE(Name) -#endif -#ifndef OPENMP_TASKLOOP_CLAUSE -# define OPENMP_TASKLOOP_CLAUSE(Name) -#endif -#ifndef OPENMP_TASKLOOP_SIMD_CLAUSE -# define OPENMP_TASKLOOP_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_MASTER_TASKLOOP_CLAUSE -# define OPENMP_MASTER_TASKLOOP_CLAUSE(Name) -#endif -#ifndef OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE -# define OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE -# define OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE -# define OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_CRITICAL_CLAUSE -# define OPENMP_CRITICAL_CLAUSE(Name) -#endif -#ifndef OPENMP_DISTRIBUTE_CLAUSE -#define OPENMP_DISTRIBUTE_CLAUSE(Name) -#endif #ifndef OPENMP_SCHEDULE_KIND #define OPENMP_SCHEDULE_KIND(Name) #endif @@ -143,164 +47,22 @@ #ifndef OPENMP_DEFAULTMAP_MODIFIER #define OPENMP_DEFAULTMAP_MODIFIER(Name) #endif -#ifndef OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#define OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#define OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_DISTRIBUTE_SIMD_CLAUSE -#define OPENMP_DISTRIBUTE_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE -#define OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_SIMD_CLAUSE -#define OPENMP_TARGET_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TEAMS_DISTRIBUTE_CLAUSE -#define OPENMP_TEAMS_DISTRIBUTE_CLAUSE(Name) -#endif -#ifndef OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE -#define OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_TEAMS_CLAUSE -#define OPENMP_TARGET_TEAMS_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TASKGROUP_CLAUSE -#define OPENMP_TASKGROUP_CLAUSE(Name) -#endif -#ifndef OPENMP_DECLARE_MAPPER_CLAUSE -#define OPENMP_DECLARE_MAPPER_CLAUSE(Name) -#endif -#ifndef OPENMP_ALLOCATE_CLAUSE -# define OPENMP_ALLOCATE_CLAUSE(Name) -#endif #ifndef OPENMP_DEVICE_TYPE_KIND #define OPENMP_DEVICE_TYPE_KIND(Name) #endif -#ifndef OPENMP_DECLARE_VARIANT_CLAUSE -#define OPENMP_DECLARE_VARIANT_CLAUSE(Name) -#endif #ifndef OPENMP_LASTPRIVATE_KIND #define OPENMP_LASTPRIVATE_KIND(Name) #endif #ifndef OPENMP_ORDER_KIND #define OPENMP_ORDER_KIND(Name) #endif -#ifndef OPENMP_FLUSH_CLAUSE -#define OPENMP_FLUSH_CLAUSE(Name) -#endif -#ifndef OPENMP_DEPOBJ_CLAUSE -#define OPENMP_DEPOBJ_CLAUSE(Name) -#endif #ifndef OPENMP_DEVICE_MODIFIER #define OPENMP_DEVICE_MODIFIER(Name) #endif -#ifndef OPENMP_SCAN_CLAUSE -#define OPENMP_SCAN_CLAUSE(Name) -#endif #ifndef OPENMP_REDUCTION_MODIFIER #define OPENMP_REDUCTION_MODIFIER(Name) #endif -// Clauses allowed for OpenMP directive 'scan'. -OPENMP_SCAN_CLAUSE(inclusive) -OPENMP_SCAN_CLAUSE(exclusive) - -// Clauses allowed for OpenMP directive 'parallel'. -OPENMP_PARALLEL_CLAUSE(if) -OPENMP_PARALLEL_CLAUSE(num_threads) -OPENMP_PARALLEL_CLAUSE(default) -OPENMP_PARALLEL_CLAUSE(proc_bind) -OPENMP_PARALLEL_CLAUSE(private) -OPENMP_PARALLEL_CLAUSE(firstprivate) -OPENMP_PARALLEL_CLAUSE(shared) -OPENMP_PARALLEL_CLAUSE(reduction) -OPENMP_PARALLEL_CLAUSE(copyin) -OPENMP_PARALLEL_CLAUSE(allocate) - -// Clauses allowed for directive 'omp simd'. -OPENMP_SIMD_CLAUSE(private) -OPENMP_SIMD_CLAUSE(lastprivate) -OPENMP_SIMD_CLAUSE(linear) -OPENMP_SIMD_CLAUSE(aligned) -OPENMP_SIMD_CLAUSE(safelen) -OPENMP_SIMD_CLAUSE(simdlen) -OPENMP_SIMD_CLAUSE(collapse) -OPENMP_SIMD_CLAUSE(reduction) -OPENMP_SIMD_CLAUSE(allocate) -OPENMP_SIMD_CLAUSE(if) -OPENMP_SIMD_CLAUSE(nontemporal) -OPENMP_SIMD_CLAUSE(order) - -// Clauses allowed for directive 'omp for'. -OPENMP_FOR_CLAUSE(private) -OPENMP_FOR_CLAUSE(lastprivate) -OPENMP_FOR_CLAUSE(firstprivate) -OPENMP_FOR_CLAUSE(reduction) -OPENMP_FOR_CLAUSE(collapse) -OPENMP_FOR_CLAUSE(schedule) -OPENMP_FOR_CLAUSE(ordered) -OPENMP_FOR_CLAUSE(nowait) -OPENMP_FOR_CLAUSE(linear) -OPENMP_FOR_CLAUSE(allocate) -OPENMP_FOR_CLAUSE(order) - -// Clauses allowed for directive 'omp for simd'. -OPENMP_FOR_SIMD_CLAUSE(private) -OPENMP_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_FOR_SIMD_CLAUSE(reduction) -OPENMP_FOR_SIMD_CLAUSE(schedule) -OPENMP_FOR_SIMD_CLAUSE(collapse) -OPENMP_FOR_SIMD_CLAUSE(nowait) -OPENMP_FOR_SIMD_CLAUSE(safelen) -OPENMP_FOR_SIMD_CLAUSE(simdlen) -OPENMP_FOR_SIMD_CLAUSE(linear) -OPENMP_FOR_SIMD_CLAUSE(aligned) -OPENMP_FOR_SIMD_CLAUSE(ordered) -OPENMP_FOR_SIMD_CLAUSE(allocate) -OPENMP_FOR_SIMD_CLAUSE(if) -OPENMP_FOR_SIMD_CLAUSE(nontemporal) -OPENMP_FOR_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'omp sections'. -OPENMP_SECTIONS_CLAUSE(private) -OPENMP_SECTIONS_CLAUSE(lastprivate) -OPENMP_SECTIONS_CLAUSE(firstprivate) -OPENMP_SECTIONS_CLAUSE(reduction) -OPENMP_SECTIONS_CLAUSE(nowait) -OPENMP_SECTIONS_CLAUSE(allocate) - -// Clauses allowed for directive 'omp single'. -OPENMP_SINGLE_CLAUSE(private) -OPENMP_SINGLE_CLAUSE(firstprivate) -OPENMP_SINGLE_CLAUSE(copyprivate) -OPENMP_SINGLE_CLAUSE(nowait) -OPENMP_SINGLE_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'cancel'. -OPENMP_CANCEL_CLAUSE(if) - // Static attributes for 'schedule' clause. OPENMP_SCHEDULE_KIND(static) OPENMP_SCHEDULE_KIND(dynamic) @@ -345,209 +107,11 @@ OPENMP_LINEAR_KIND(val) OPENMP_LINEAR_KIND(ref) OPENMP_LINEAR_KIND(uval) -// Clauses allowed for OpenMP directive 'parallel for'. -OPENMP_PARALLEL_FOR_CLAUSE(if) -OPENMP_PARALLEL_FOR_CLAUSE(num_threads) -OPENMP_PARALLEL_FOR_CLAUSE(default) -OPENMP_PARALLEL_FOR_CLAUSE(proc_bind) -OPENMP_PARALLEL_FOR_CLAUSE(private) -OPENMP_PARALLEL_FOR_CLAUSE(firstprivate) -OPENMP_PARALLEL_FOR_CLAUSE(shared) -OPENMP_PARALLEL_FOR_CLAUSE(reduction) -OPENMP_PARALLEL_FOR_CLAUSE(copyin) -OPENMP_PARALLEL_FOR_CLAUSE(lastprivate) -OPENMP_PARALLEL_FOR_CLAUSE(collapse) -OPENMP_PARALLEL_FOR_CLAUSE(schedule) -OPENMP_PARALLEL_FOR_CLAUSE(ordered) -OPENMP_PARALLEL_FOR_CLAUSE(linear) -OPENMP_PARALLEL_FOR_CLAUSE(allocate) -OPENMP_PARALLEL_FOR_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'parallel for simd'. -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(if) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(num_threads) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(default) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(private) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(shared) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(reduction) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(copyin) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(collapse) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(schedule) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(safelen) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(simdlen) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(linear) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(aligned) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(ordered) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(allocate) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(nontemporal) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'parallel master'. -OPENMP_PARALLEL_MASTER_CLAUSE(if) -OPENMP_PARALLEL_MASTER_CLAUSE(num_threads) -OPENMP_PARALLEL_MASTER_CLAUSE(default) -OPENMP_PARALLEL_MASTER_CLAUSE(private) -OPENMP_PARALLEL_MASTER_CLAUSE(firstprivate) -OPENMP_PARALLEL_MASTER_CLAUSE(shared) -OPENMP_PARALLEL_MASTER_CLAUSE(copyin) -OPENMP_PARALLEL_MASTER_CLAUSE(reduction) -OPENMP_PARALLEL_MASTER_CLAUSE(proc_bind) -OPENMP_PARALLEL_MASTER_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'parallel sections'. -OPENMP_PARALLEL_SECTIONS_CLAUSE(if) -OPENMP_PARALLEL_SECTIONS_CLAUSE(num_threads) -OPENMP_PARALLEL_SECTIONS_CLAUSE(default) -OPENMP_PARALLEL_SECTIONS_CLAUSE(proc_bind) -OPENMP_PARALLEL_SECTIONS_CLAUSE(private) -OPENMP_PARALLEL_SECTIONS_CLAUSE(firstprivate) -OPENMP_PARALLEL_SECTIONS_CLAUSE(shared) -OPENMP_PARALLEL_SECTIONS_CLAUSE(reduction) -OPENMP_PARALLEL_SECTIONS_CLAUSE(copyin) -OPENMP_PARALLEL_SECTIONS_CLAUSE(lastprivate) -OPENMP_PARALLEL_SECTIONS_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'task'. -OPENMP_TASK_CLAUSE(if) -OPENMP_TASK_CLAUSE(final) -OPENMP_TASK_CLAUSE(default) -OPENMP_TASK_CLAUSE(private) -OPENMP_TASK_CLAUSE(firstprivate) -OPENMP_TASK_CLAUSE(shared) -OPENMP_TASK_CLAUSE(untied) -OPENMP_TASK_CLAUSE(mergeable) -OPENMP_TASK_CLAUSE(depend) -OPENMP_TASK_CLAUSE(priority) -OPENMP_TASK_CLAUSE(in_reduction) -OPENMP_TASK_CLAUSE(allocate) -OPENMP_TASK_CLAUSE(detach) - -// Clauses allowed for OpenMP directive 'atomic'. -OPENMP_ATOMIC_CLAUSE(read) -OPENMP_ATOMIC_CLAUSE(write) -OPENMP_ATOMIC_CLAUSE(update) -OPENMP_ATOMIC_CLAUSE(capture) -OPENMP_ATOMIC_CLAUSE(seq_cst) -OPENMP_ATOMIC_CLAUSE(acq_rel) -OPENMP_ATOMIC_CLAUSE(acquire) -OPENMP_ATOMIC_CLAUSE(release) -OPENMP_ATOMIC_CLAUSE(relaxed) -OPENMP_ATOMIC_CLAUSE(hint) - -// Clauses allowed for OpenMP directive 'target'. -OPENMP_TARGET_CLAUSE(if) -OPENMP_TARGET_CLAUSE(device) -OPENMP_TARGET_CLAUSE(map) -OPENMP_TARGET_CLAUSE(private) -OPENMP_TARGET_CLAUSE(nowait) -OPENMP_TARGET_CLAUSE(depend) -OPENMP_TARGET_CLAUSE(defaultmap) -OPENMP_TARGET_CLAUSE(firstprivate) -OPENMP_TARGET_CLAUSE(is_device_ptr) -OPENMP_TARGET_CLAUSE(reduction) -OPENMP_TARGET_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'requires'. -OPENMP_REQUIRES_CLAUSE(unified_address) -OPENMP_REQUIRES_CLAUSE(unified_shared_memory) -OPENMP_REQUIRES_CLAUSE(reverse_offload) -OPENMP_REQUIRES_CLAUSE(dynamic_allocators) -OPENMP_REQUIRES_CLAUSE(atomic_default_mem_order) - -// Clauses allowed for OpenMP directive 'allocate'. -OPENMP_ALLOCATE_CLAUSE(allocator) - // Modifiers for 'atomic_default_mem_order' clause. OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(seq_cst) OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(acq_rel) OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(relaxed) -// Clauses allowed for OpenMP directive 'target data'. -OPENMP_TARGET_DATA_CLAUSE(if) -OPENMP_TARGET_DATA_CLAUSE(device) -OPENMP_TARGET_DATA_CLAUSE(map) -OPENMP_TARGET_DATA_CLAUSE(use_device_ptr) - -// Clauses allowed for OpenMP directive 'target enter data'. -OPENMP_TARGET_ENTER_DATA_CLAUSE(if) -OPENMP_TARGET_ENTER_DATA_CLAUSE(device) -OPENMP_TARGET_ENTER_DATA_CLAUSE(map) -OPENMP_TARGET_ENTER_DATA_CLAUSE(nowait) -OPENMP_TARGET_ENTER_DATA_CLAUSE(depend) - -// Clauses allowed for OpenMP directive 'target exit data'. -OPENMP_TARGET_EXIT_DATA_CLAUSE(if) -OPENMP_TARGET_EXIT_DATA_CLAUSE(device) -OPENMP_TARGET_EXIT_DATA_CLAUSE(map) -OPENMP_TARGET_EXIT_DATA_CLAUSE(nowait) -OPENMP_TARGET_EXIT_DATA_CLAUSE(depend) - -// Clauses allowed for OpenMP directive 'target parallel'. -OPENMP_TARGET_PARALLEL_CLAUSE(if) -OPENMP_TARGET_PARALLEL_CLAUSE(device) -OPENMP_TARGET_PARALLEL_CLAUSE(map) -OPENMP_TARGET_PARALLEL_CLAUSE(private) -OPENMP_TARGET_PARALLEL_CLAUSE(firstprivate) -OPENMP_TARGET_PARALLEL_CLAUSE(nowait) -OPENMP_TARGET_PARALLEL_CLAUSE(depend) -OPENMP_TARGET_PARALLEL_CLAUSE(defaultmap) -OPENMP_TARGET_PARALLEL_CLAUSE(num_threads) -OPENMP_TARGET_PARALLEL_CLAUSE(default) -OPENMP_TARGET_PARALLEL_CLAUSE(proc_bind) -OPENMP_TARGET_PARALLEL_CLAUSE(shared) -OPENMP_TARGET_PARALLEL_CLAUSE(reduction) -OPENMP_TARGET_PARALLEL_CLAUSE(is_device_ptr) -OPENMP_TARGET_PARALLEL_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'target parallel for'. -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(if) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(device) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(map) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(private) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(firstprivate) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(lastprivate) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(nowait) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(depend) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(defaultmap) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(num_threads) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(default) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(proc_bind) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(shared) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(reduction) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(collapse) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(schedule) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(ordered) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(linear) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(is_device_ptr) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(allocate) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'target update'. -OPENMP_TARGET_UPDATE_CLAUSE(if) -OPENMP_TARGET_UPDATE_CLAUSE(device) -OPENMP_TARGET_UPDATE_CLAUSE(to) -OPENMP_TARGET_UPDATE_CLAUSE(from) -OPENMP_TARGET_UPDATE_CLAUSE(nowait) -OPENMP_TARGET_UPDATE_CLAUSE(depend) - -// Clauses allowed for OpenMP directive 'teams'. -OPENMP_TEAMS_CLAUSE(default) -OPENMP_TEAMS_CLAUSE(private) -OPENMP_TEAMS_CLAUSE(firstprivate) -OPENMP_TEAMS_CLAUSE(shared) -OPENMP_TEAMS_CLAUSE(reduction) -OPENMP_TEAMS_CLAUSE(num_teams) -OPENMP_TEAMS_CLAUSE(thread_limit) -OPENMP_TEAMS_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'ordered'. -OPENMP_ORDERED_CLAUSE(threads) -OPENMP_ORDERED_CLAUSE(simd) -OPENMP_ORDERED_CLAUSE(depend) - // Map types for 'map' clause. OPENMP_MAP_KIND(alloc) OPENMP_MAP_KIND(to) @@ -567,552 +131,39 @@ OPENMP_TO_MODIFIER_KIND(mapper) // Modifiers for 'from' clause. OPENMP_FROM_MODIFIER_KIND(mapper) -// Clauses allowed for OpenMP directive 'taskloop'. -OPENMP_TASKLOOP_CLAUSE(if) -OPENMP_TASKLOOP_CLAUSE(shared) -OPENMP_TASKLOOP_CLAUSE(private) -OPENMP_TASKLOOP_CLAUSE(firstprivate) -OPENMP_TASKLOOP_CLAUSE(lastprivate) -OPENMP_TASKLOOP_CLAUSE(default) -OPENMP_TASKLOOP_CLAUSE(collapse) -OPENMP_TASKLOOP_CLAUSE(final) -OPENMP_TASKLOOP_CLAUSE(untied) -OPENMP_TASKLOOP_CLAUSE(mergeable) -OPENMP_TASKLOOP_CLAUSE(priority) -OPENMP_TASKLOOP_CLAUSE(grainsize) -OPENMP_TASKLOOP_CLAUSE(nogroup) -OPENMP_TASKLOOP_CLAUSE(num_tasks) -OPENMP_TASKLOOP_CLAUSE(reduction) -OPENMP_TASKLOOP_CLAUSE(in_reduction) -OPENMP_TASKLOOP_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'taskloop simd'. -OPENMP_TASKLOOP_SIMD_CLAUSE(if) -OPENMP_TASKLOOP_SIMD_CLAUSE(shared) -OPENMP_TASKLOOP_SIMD_CLAUSE(private) -OPENMP_TASKLOOP_SIMD_CLAUSE(firstprivate) -OPENMP_TASKLOOP_SIMD_CLAUSE(lastprivate) -OPENMP_TASKLOOP_SIMD_CLAUSE(default) -OPENMP_TASKLOOP_SIMD_CLAUSE(collapse) -OPENMP_TASKLOOP_SIMD_CLAUSE(final) -OPENMP_TASKLOOP_SIMD_CLAUSE(untied) -OPENMP_TASKLOOP_SIMD_CLAUSE(mergeable) -OPENMP_TASKLOOP_SIMD_CLAUSE(priority) -OPENMP_TASKLOOP_SIMD_CLAUSE(linear) -OPENMP_TASKLOOP_SIMD_CLAUSE(aligned) -OPENMP_TASKLOOP_SIMD_CLAUSE(safelen) -OPENMP_TASKLOOP_SIMD_CLAUSE(simdlen) -OPENMP_TASKLOOP_SIMD_CLAUSE(grainsize) -OPENMP_TASKLOOP_SIMD_CLAUSE(nogroup) -OPENMP_TASKLOOP_SIMD_CLAUSE(num_tasks) -OPENMP_TASKLOOP_SIMD_CLAUSE(reduction) -OPENMP_TASKLOOP_SIMD_CLAUSE(in_reduction) -OPENMP_TASKLOOP_SIMD_CLAUSE(allocate) -OPENMP_TASKLOOP_SIMD_CLAUSE(nontemporal) -OPENMP_TASKLOOP_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'master taskloop'. -OPENMP_MASTER_TASKLOOP_CLAUSE(if) -OPENMP_MASTER_TASKLOOP_CLAUSE(shared) -OPENMP_MASTER_TASKLOOP_CLAUSE(private) -OPENMP_MASTER_TASKLOOP_CLAUSE(firstprivate) -OPENMP_MASTER_TASKLOOP_CLAUSE(lastprivate) -OPENMP_MASTER_TASKLOOP_CLAUSE(default) -OPENMP_MASTER_TASKLOOP_CLAUSE(collapse) -OPENMP_MASTER_TASKLOOP_CLAUSE(final) -OPENMP_MASTER_TASKLOOP_CLAUSE(untied) -OPENMP_MASTER_TASKLOOP_CLAUSE(mergeable) -OPENMP_MASTER_TASKLOOP_CLAUSE(priority) -OPENMP_MASTER_TASKLOOP_CLAUSE(grainsize) -OPENMP_MASTER_TASKLOOP_CLAUSE(nogroup) -OPENMP_MASTER_TASKLOOP_CLAUSE(num_tasks) -OPENMP_MASTER_TASKLOOP_CLAUSE(reduction) -OPENMP_MASTER_TASKLOOP_CLAUSE(in_reduction) -OPENMP_MASTER_TASKLOOP_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'master taskloop simd'. -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(if) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(shared) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(private) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(firstprivate) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(lastprivate) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(default) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(collapse) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(final) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(untied) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(mergeable) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(priority) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(linear) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(aligned) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(safelen) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(simdlen) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(grainsize) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(nogroup) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(num_tasks) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(reduction) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(in_reduction) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(allocate) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(nontemporal) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'parallel master taskloop'. -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(if) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(shared) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(private) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(firstprivate) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(lastprivate) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(default) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(collapse) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(final) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(untied) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(mergeable) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(priority) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(grainsize) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(nogroup) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(num_tasks) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(reduction) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(allocate) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(num_threads) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(proc_bind) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(copyin) - -// Clauses allowed for OpenMP directive 'parallel master taskloop simd'. -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(if) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(shared) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(private) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(firstprivate) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(lastprivate) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(default) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(collapse) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(final) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(untied) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(mergeable) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(priority) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(grainsize) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(nogroup) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(num_tasks) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(reduction) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(allocate) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(num_threads) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(proc_bind) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(copyin) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(linear) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(aligned) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(safelen) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(simdlen) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(nontemporal) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'critical'. -OPENMP_CRITICAL_CLAUSE(hint) - -// Clauses allowed for OpenMP directive 'distribute' -OPENMP_DISTRIBUTE_CLAUSE(private) -OPENMP_DISTRIBUTE_CLAUSE(firstprivate) -OPENMP_DISTRIBUTE_CLAUSE(lastprivate) -OPENMP_DISTRIBUTE_CLAUSE(collapse) -OPENMP_DISTRIBUTE_CLAUSE(dist_schedule) -OPENMP_DISTRIBUTE_CLAUSE(allocate) - // Static attributes for 'dist_schedule' clause. OPENMP_DIST_SCHEDULE_KIND(static) -// Clauses allowed for OpenMP directive 'distribute parallel for' -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(lastprivate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(collapse) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(default) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(copyin) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(allocate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'distribute parallel for simd' -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(collapse) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(dist_schedule) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(if) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_threads) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(default) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(private) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(shared) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(reduction) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(copyin) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(schedule) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nontemporal) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'distribute simd' -OPENMP_DISTRIBUTE_SIMD_CLAUSE(private) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(firstprivate) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(lastprivate) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(collapse) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(dist_schedule) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(linear) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(aligned) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(safelen) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(simdlen) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(reduction) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(allocate) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(if) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(nontemporal) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'target parallel for simd'. -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(if) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(device) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(map) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(private) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(nowait) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(depend) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(defaultmap) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(num_threads) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(default) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(shared) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(reduction) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(collapse) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(schedule) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(ordered) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(linear) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(safelen) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(simdlen) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(aligned) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(is_device_ptr) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(allocate) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(nontemporal) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'target simd'. -OPENMP_TARGET_SIMD_CLAUSE(if) -OPENMP_TARGET_SIMD_CLAUSE(device) -OPENMP_TARGET_SIMD_CLAUSE(map) -OPENMP_TARGET_SIMD_CLAUSE(private) -OPENMP_TARGET_SIMD_CLAUSE(nowait) -OPENMP_TARGET_SIMD_CLAUSE(depend) -OPENMP_TARGET_SIMD_CLAUSE(defaultmap) -OPENMP_TARGET_SIMD_CLAUSE(firstprivate) -OPENMP_TARGET_SIMD_CLAUSE(is_device_ptr) -OPENMP_TARGET_SIMD_CLAUSE(lastprivate) -OPENMP_TARGET_SIMD_CLAUSE(linear) -OPENMP_TARGET_SIMD_CLAUSE(aligned) -OPENMP_TARGET_SIMD_CLAUSE(safelen) -OPENMP_TARGET_SIMD_CLAUSE(simdlen) -OPENMP_TARGET_SIMD_CLAUSE(collapse) -OPENMP_TARGET_SIMD_CLAUSE(reduction) -OPENMP_TARGET_SIMD_CLAUSE(allocate) -OPENMP_TARGET_SIMD_CLAUSE(nontemporal) -OPENMP_TARGET_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'teams distribute'. -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(default) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(private) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(firstprivate) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(shared) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(reduction) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(num_teams) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(thread_limit) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(lastprivate) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(collapse) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(dist_schedule) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'teams distribute simd' -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(default) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(private) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(firstprivate) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(shared) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(reduction) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(num_teams) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(thread_limit) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(lastprivate) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(collapse) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(dist_schedule) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(linear) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(allocate) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(if) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(nontemporal) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'teams distribute parallel for simd' -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(collapse) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(dist_schedule) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(if) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_threads) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(default) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(private) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(shared) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(reduction) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(schedule) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_teams) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(thread_limit) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nontemporal) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'teams distribute parallel for' -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(lastprivate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(collapse) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(default) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(copyin) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(allocate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'target teams'. -OPENMP_TARGET_TEAMS_CLAUSE(if) -OPENMP_TARGET_TEAMS_CLAUSE(device) -OPENMP_TARGET_TEAMS_CLAUSE(map) -OPENMP_TARGET_TEAMS_CLAUSE(private) -OPENMP_TARGET_TEAMS_CLAUSE(nowait) -OPENMP_TARGET_TEAMS_CLAUSE(depend) -OPENMP_TARGET_TEAMS_CLAUSE(defaultmap) -OPENMP_TARGET_TEAMS_CLAUSE(firstprivate) -OPENMP_TARGET_TEAMS_CLAUSE(is_device_ptr) -OPENMP_TARGET_TEAMS_CLAUSE(default) -OPENMP_TARGET_TEAMS_CLAUSE(shared) -OPENMP_TARGET_TEAMS_CLAUSE(reduction) -OPENMP_TARGET_TEAMS_CLAUSE(num_teams) -OPENMP_TARGET_TEAMS_CLAUSE(thread_limit) -OPENMP_TARGET_TEAMS_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'target teams distribute'. -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(if) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(device) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(map) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(private) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(nowait) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(depend) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(defaultmap) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(firstprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(is_device_ptr) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(default) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(shared) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(reduction) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(num_teams) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(thread_limit) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(lastprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(collapse) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(dist_schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'target teams distribute parallel for'. -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(device) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(map) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(nowait) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(depend) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(defaultmap) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(is_device_ptr) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(default) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(lastprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(collapse) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(allocate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(order) - -// Clauses allowed for OpenMP directive -// 'target teams distribute parallel for simd'. -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(if) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(device) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(map) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(private) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nowait) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(depend) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(defaultmap) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(is_device_ptr) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(default) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(shared) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(reduction) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_teams) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(thread_limit) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(collapse) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(dist_schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_threads) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nontemporal) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'target teams distribute simd'. -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(if) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(device) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(map) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(private) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(nowait) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(depend) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(defaultmap) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(firstprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(lastprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(is_device_ptr) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(shared) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(reduction) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(num_teams) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(thread_limit) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(collapse) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(dist_schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(linear) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(allocate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(nontemporal) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(order) - -// Clauses allowed for OpenMP directive 'taskgroup'. -OPENMP_TASKGROUP_CLAUSE(task_reduction) -OPENMP_TASKGROUP_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'declare mapper'. -OPENMP_DECLARE_MAPPER_CLAUSE(map) - // Device types for 'device_type' clause. OPENMP_DEVICE_TYPE_KIND(host) OPENMP_DEVICE_TYPE_KIND(nohost) OPENMP_DEVICE_TYPE_KIND(any) -// Clauses allowed for OpenMP directive 'declare variant'. -OPENMP_DECLARE_VARIANT_CLAUSE(match) - // Type of the 'lastprivate' clause. OPENMP_LASTPRIVATE_KIND(conditional) // Type of the 'order' clause. OPENMP_ORDER_KIND(concurrent) -// Clauses allowed for OpenMP directive 'flush'. -OPENMP_FLUSH_CLAUSE(acq_rel) -OPENMP_FLUSH_CLAUSE(acquire) -OPENMP_FLUSH_CLAUSE(release) - -// Clauses allowed for OpenMP directive 'depobj'. -OPENMP_DEPOBJ_CLAUSE(depend) -OPENMP_DEPOBJ_CLAUSE(destroy) -OPENMP_DEPOBJ_CLAUSE(update) - // Modifiers for 'reduction' clause. OPENMP_REDUCTION_MODIFIER(default) OPENMP_REDUCTION_MODIFIER(inscan) #undef OPENMP_REDUCTION_MODIFIER -#undef OPENMP_SCAN_CLAUSE #undef OPENMP_DEVICE_MODIFIER -#undef OPENMP_DEPOBJ_CLAUSE -#undef OPENMP_FLUSH_CLAUSE #undef OPENMP_ORDER_KIND #undef OPENMP_LASTPRIVATE_KIND -#undef OPENMP_DECLARE_VARIANT_CLAUSE #undef OPENMP_DEVICE_TYPE_KIND -#undef OPENMP_ALLOCATE_CLAUSE -#undef OPENMP_DECLARE_MAPPER_CLAUSE -#undef OPENMP_TASKGROUP_CLAUSE -#undef OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE -#undef OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE -#undef OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE -#undef OPENMP_MASTER_TASKLOOP_CLAUSE -#undef OPENMP_TASKLOOP_SIMD_CLAUSE -#undef OPENMP_TASKLOOP_CLAUSE #undef OPENMP_LINEAR_KIND #undef OPENMP_DEPEND_KIND #undef OPENMP_SCHEDULE_MODIFIER #undef OPENMP_SCHEDULE_KIND -#undef OPENMP_CLAUSE -#undef OPENMP_CRITICAL_CLAUSE -#undef OPENMP_ORDERED_CLAUSE -#undef OPENMP_CANCEL_CLAUSE -#undef OPENMP_SINGLE_CLAUSE -#undef OPENMP_SECTIONS_CLAUSE -#undef OPENMP_PARALLEL_CLAUSE -#undef OPENMP_PARALLEL_FOR_CLAUSE -#undef OPENMP_PARALLEL_FOR_SIMD_CLAUSE -#undef OPENMP_PARALLEL_MASTER_CLAUSE -#undef OPENMP_PARALLEL_SECTIONS_CLAUSE -#undef OPENMP_TASK_CLAUSE -#undef OPENMP_ATOMIC_CLAUSE -#undef OPENMP_TARGET_CLAUSE -#undef OPENMP_REQUIRES_CLAUSE #undef OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND -#undef OPENMP_TARGET_DATA_CLAUSE -#undef OPENMP_TARGET_ENTER_DATA_CLAUSE -#undef OPENMP_TARGET_EXIT_DATA_CLAUSE -#undef OPENMP_TARGET_PARALLEL_CLAUSE -#undef OPENMP_TARGET_PARALLEL_FOR_CLAUSE -#undef OPENMP_TEAMS_CLAUSE -#undef OPENMP_SIMD_CLAUSE -#undef OPENMP_FOR_CLAUSE -#undef OPENMP_FOR_SIMD_CLAUSE #undef OPENMP_MAP_KIND #undef OPENMP_MAP_MODIFIER_KIND #undef OPENMP_TO_MODIFIER_KIND #undef OPENMP_FROM_MODIFIER_KIND -#undef OPENMP_DISTRIBUTE_CLAUSE #undef OPENMP_DIST_SCHEDULE_KIND #undef OPENMP_DEFAULTMAP_KIND #undef OPENMP_DEFAULTMAP_MODIFIER -#undef OPENMP_TARGET_UPDATE_CLAUSE -#undef OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#undef OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#undef OPENMP_DISTRIBUTE_SIMD_CLAUSE -#undef OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE -#undef OPENMP_TARGET_SIMD_CLAUSE -#undef OPENMP_TEAMS_DISTRIBUTE_CLAUSE -#undef OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE -#undef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#undef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#undef OPENMP_TARGET_TEAMS_CLAUSE -#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE -#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE + diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index 9a6a2050a165..08aaf2d43bfd 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -173,10 +173,6 @@ enum OpenMPReductionClauseModifier { unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str); const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type); -bool isAllowedClauseForDirective(OpenMPDirectiveKind DKind, - OpenMPClauseKind CKind, - unsigned OpenMPVersion); - /// Checks if the specified directive is a directive with an associated /// loop construct. /// \param DKind Specified directive. diff --git a/clang/lib/ASTMatchers/Dynamic/CMakeLists.txt b/clang/lib/ASTMatchers/Dynamic/CMakeLists.txt index 82c12a47fa93..10bd9c455eb4 100644 --- a/clang/lib/ASTMatchers/Dynamic/CMakeLists.txt +++ b/clang/lib/ASTMatchers/Dynamic/CMakeLists.txt @@ -1,4 +1,7 @@ -set(LLVM_LINK_COMPONENTS support) +set(LLVM_LINK_COMPONENTS + FrontendOpenMP + Support +) # The registry source file ends up generating a lot of sections for each # matcher. Each matcher appears to get a vtable and several methods. Each diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp index 981bd7adbe9b..888666b30d2e 100644 --- a/clang/lib/Basic/OpenMPKinds.cpp +++ b/clang/lib/Basic/OpenMPKinds.cpp @@ -425,581 +425,6 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, llvm_unreachable("Invalid OpenMP simple clause kind"); } -bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, - OpenMPClauseKind CKind, - unsigned OpenMPVersion) { - assert(unsigned(DKind) <= unsigned(OMPD_unknown)); - assert(CKind <= OMPC_unknown); - // Nontemporal clause is not supported in OpenMP < 5.0. - if (OpenMPVersion < 50 && CKind == OMPC_nontemporal) - return false; - // Order clause is not supported in OpenMP < 5.0. - if (OpenMPVersion < 50 && CKind == OMPC_order) - return false; - switch (DKind) { - case OMPD_parallel: - switch (CKind) { -#define OPENMP_PARALLEL_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_simd: - if (OpenMPVersion < 50 && CKind == OMPC_if) - return false; - switch (CKind) { -#define OPENMP_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_for: - switch (CKind) { -#define OPENMP_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_for_simd: - if (OpenMPVersion < 50 && CKind == OMPC_if) - return false; - switch (CKind) { -#define OPENMP_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_sections: - switch (CKind) { -#define OPENMP_SECTIONS_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_single: - switch (CKind) { -#define OPENMP_SINGLE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_for: - switch (CKind) { -#define OPENMP_PARALLEL_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_for_simd: - switch (CKind) { -#define OPENMP_PARALLEL_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_master: - switch (CKind) { -#define OPENMP_PARALLEL_MASTER_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_sections: - switch (CKind) { -#define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_task: - if (OpenMPVersion < 50 && CKind == OMPC_detach) - return false; - switch (CKind) { -#define OPENMP_TASK_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_flush: - if (CKind == OMPC_flush) - return true; - if (OpenMPVersion < 50) - return false; - switch (CKind) { -#define OPENMP_FLUSH_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_depobj: - if (OpenMPVersion < 50) - return false; - switch (CKind) { -#define OPENMP_DEPOBJ_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - case OMPC_depobj: - return true; - default: - break; - } - break; - case OMPD_scan: - if (OpenMPVersion < 50) - return false; - switch (CKind) { -#define OPENMP_SCAN_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_atomic: - if (OpenMPVersion < 50 && - (CKind == OMPC_acq_rel || CKind == OMPC_acquire || - CKind == OMPC_release || CKind == OMPC_relaxed || CKind == OMPC_hint)) - return false; - switch (CKind) { -#define OPENMP_ATOMIC_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target: - switch (CKind) { -#define OPENMP_TARGET_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_requires: - switch (CKind) { -#define OPENMP_REQUIRES_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_data: - switch (CKind) { -#define OPENMP_TARGET_DATA_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_enter_data: - switch (CKind) { -#define OPENMP_TARGET_ENTER_DATA_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_exit_data: - switch (CKind) { -#define OPENMP_TARGET_EXIT_DATA_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_parallel: - switch (CKind) { -#define OPENMP_TARGET_PARALLEL_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_parallel_for: - switch (CKind) { -#define OPENMP_TARGET_PARALLEL_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_update: - switch (CKind) { -#define OPENMP_TARGET_UPDATE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_teams: - switch (CKind) { -#define OPENMP_TEAMS_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_cancel: - switch (CKind) { -#define OPENMP_CANCEL_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_ordered: - switch (CKind) { -#define OPENMP_ORDERED_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_taskloop: - switch (CKind) { -#define OPENMP_TASKLOOP_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_taskloop_simd: - switch (CKind) { -#define OPENMP_TASKLOOP_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_master_taskloop: - switch (CKind) { -#define OPENMP_MASTER_TASKLOOP_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_master_taskloop_simd: - switch (CKind) { -#define OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_master_taskloop: - switch (CKind) { -#define OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_parallel_master_taskloop_simd: - switch (CKind) { -#define OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_critical: - switch (CKind) { -#define OPENMP_CRITICAL_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_distribute: - switch (CKind) { -#define OPENMP_DISTRIBUTE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_distribute_parallel_for: - switch (CKind) { -#define OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_distribute_parallel_for_simd: - switch (CKind) { -#define OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_distribute_simd: - if (OpenMPVersion < 50 && CKind == OMPC_if) - return false; - switch (CKind) { -#define OPENMP_DISTRIBUTE_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_parallel_for_simd: - switch (CKind) { -#define OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_simd: - switch (CKind) { -#define OPENMP_TARGET_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_teams_distribute: - switch (CKind) { -#define OPENMP_TEAMS_DISTRIBUTE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_teams_distribute_simd: - if (OpenMPVersion < 50 && CKind == OMPC_if) - return false; - switch (CKind) { -#define OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_teams_distribute_parallel_for_simd: - switch (CKind) { -#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_teams_distribute_parallel_for: - switch (CKind) { -#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_teams: - switch (CKind) { -#define OPENMP_TARGET_TEAMS_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_teams_distribute: - switch (CKind) { -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_teams_distribute_parallel_for: - switch (CKind) { -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_teams_distribute_parallel_for_simd: - switch (CKind) { -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_target_teams_distribute_simd: - switch (CKind) { -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_taskgroup: - switch (CKind) { -#define OPENMP_TASKGROUP_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_declare_mapper: - switch (CKind) { -#define OPENMP_DECLARE_MAPPER_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_allocate: - switch (CKind) { -#define OPENMP_ALLOCATE_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_declare_variant: - switch (CKind) { -#define OPENMP_DECLARE_VARIANT_CLAUSE(Name) \ - case OMPC_##Name: \ - return true; -#include "clang/Basic/OpenMPKinds.def" - default: - break; - } - break; - case OMPD_begin_declare_variant: - case OMPD_end_declare_variant: - case OMPD_declare_target: - case OMPD_end_declare_target: - case OMPD_unknown: - case OMPD_threadprivate: - case OMPD_section: - case OMPD_master: - case OMPD_taskyield: - case OMPD_barrier: - case OMPD_taskwait: - case OMPD_cancellation_point: - case OMPD_declare_reduction: - case OMPD_declare_simd: - break; - } - return false; -} - bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_simd || DKind == OMPD_for || DKind == OMPD_for_simd || DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd || diff --git a/clang/lib/Tooling/CMakeLists.txt b/clang/lib/Tooling/CMakeLists.txt index 59c990daaa29..71b6cc55e504 100644 --- a/clang/lib/Tooling/CMakeLists.txt +++ b/clang/lib/Tooling/CMakeLists.txt @@ -1,5 +1,6 @@ set(LLVM_LINK_COMPONENTS Option + FrontendOpenMP Support ) diff --git a/clang/lib/Tooling/Transformer/CMakeLists.txt b/clang/lib/Tooling/Transformer/CMakeLists.txt index 68f0cfeee8f6..281af1007a65 100644 --- a/clang/lib/Tooling/Transformer/CMakeLists.txt +++ b/clang/lib/Tooling/Transformer/CMakeLists.txt @@ -1,4 +1,7 @@ -set(LLVM_LINK_COMPONENTS Support) +set(LLVM_LINK_COMPONENTS + FrontendOpenMP + Support +) add_clang_library(clangTransformer RangeSelector.cpp diff --git a/clang/unittests/AST/CMakeLists.txt b/clang/unittests/AST/CMakeLists.txt index b738ce08d06d..868635b6eea5 100644 --- a/clang/unittests/AST/CMakeLists.txt +++ b/clang/unittests/AST/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/unittests/ASTMatchers/CMakeLists.txt b/clang/unittests/ASTMatchers/CMakeLists.txt index aa5438c947f4..e128cfe695a6 100644 --- a/clang/unittests/ASTMatchers/CMakeLists.txt +++ b/clang/unittests/ASTMatchers/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt b/clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt index c40964dfaf0b..85556b01cae1 100644 --- a/clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt +++ b/clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/unittests/Analysis/CMakeLists.txt b/clang/unittests/Analysis/CMakeLists.txt index 03716e2e5e97..66069c854a6a 100644 --- a/clang/unittests/Analysis/CMakeLists.txt +++ b/clang/unittests/Analysis/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/unittests/Rename/CMakeLists.txt b/clang/unittests/Rename/CMakeLists.txt index a33d7d8ef720..6ec0c521551c 100644 --- a/clang/unittests/Rename/CMakeLists.txt +++ b/clang/unittests/Rename/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP support ) diff --git a/clang/unittests/Sema/CMakeLists.txt b/clang/unittests/Sema/CMakeLists.txt index 6832908e7fb1..24105d7756f4 100644 --- a/clang/unittests/Sema/CMakeLists.txt +++ b/clang/unittests/Sema/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/unittests/StaticAnalyzer/CMakeLists.txt b/clang/unittests/StaticAnalyzer/CMakeLists.txt index ff92bdcb299a..5ce660f00040 100644 --- a/clang/unittests/StaticAnalyzer/CMakeLists.txt +++ b/clang/unittests/StaticAnalyzer/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + FrontendOpenMP Support ) diff --git a/clang/unittests/Tooling/CMakeLists.txt b/clang/unittests/Tooling/CMakeLists.txt index 1f66ffd598d4..67ab6bea2016 100644 --- a/clang/unittests/Tooling/CMakeLists.txt +++ b/clang/unittests/Tooling/CMakeLists.txt @@ -1,5 +1,6 @@ set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} + FrontendOpenMP Support ) diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h index d32fa8dc98ef..40da41be9297 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h @@ -100,6 +100,9 @@ Clause getOpenMPClauseKind(StringRef Str); /// Return a textual representation of the clause \p C. StringRef getOpenMPClauseName(Clause C); +/// Return true if \p C is a valid clause for \p D in version \p Version. +bool isAllowedClauseForDirective(Directive D, Clause C, unsigned Version); + /// Forward declarations for LLVM-IR types (simple, function and structure) are /// generated below. Their names are defined and used in OpenMP/OMPKinds.def. /// Here we provide the forward declarations, the initializeTypes function will diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def index 09468358415f..7ac614e99201 100644 --- a/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def +++ b/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def @@ -710,3 +710,732 @@ OMP_LAST_TRAIT_PROPERTY( #undef __OMP_REQUIRES_TRAIT #undef OMP_REQUIRES_TRAIT ///} + + +/// Clauses allowed per directive +/// +///{ + +#ifndef OMP_DIRECTIVE_CLAUSE +#define OMP_DIRECTIVE_CLAUSE(Directive, MinVersion, MaxVersion, Clause) +#endif + +#define __OMP_DIRECTIVE_CLAUSE(Directive, MinVersion, MaxVersion, Clause) \ + OMP_DIRECTIVE_CLAUSE(OMPD_##Directive, unsigned(MinVersion), \ + unsigned(MaxVersion), OMPC_##Clause) + +__OMP_DIRECTIVE_CLAUSE(scan, 50, ~0, inclusive) +__OMP_DIRECTIVE_CLAUSE(scan, 50, ~0, exclusive) + +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(parallel, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(simd, 50, ~0, if) +__OMP_DIRECTIVE_CLAUSE(simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, ordered) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(for, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(for, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~1, ordered) +__OMP_DIRECTIVE_CLAUSE(for_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(for_simd, 50, ~0, if) +__OMP_DIRECTIVE_CLAUSE(for_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(for_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(sections, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(sections, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(sections, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(sections, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(sections, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(sections, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(single, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(single, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(single, 1, ~0, copyprivate) +__OMP_DIRECTIVE_CLAUSE(single, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(single, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(cancel, 1, ~0, if) + +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~1, ordered) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(parallel_for, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~1, ordered) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(parallel_for_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(parallel_master, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_sections, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, final) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, untied) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, mergeable) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, priority) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, in_reduction) +__OMP_DIRECTIVE_CLAUSE(task, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(task, 50, ~0, detach) + +__OMP_DIRECTIVE_CLAUSE(atomic, 1, ~0, read) +__OMP_DIRECTIVE_CLAUSE(atomic, 1, ~0, write) +__OMP_DIRECTIVE_CLAUSE(atomic, 1, ~0, update) +__OMP_DIRECTIVE_CLAUSE(atomic, 1, ~0, capture) +__OMP_DIRECTIVE_CLAUSE(atomic, 1, ~0, seq_cst) +__OMP_DIRECTIVE_CLAUSE(atomic, 50, ~0, acq_rel) +__OMP_DIRECTIVE_CLAUSE(atomic, 50, ~0, acquire) +__OMP_DIRECTIVE_CLAUSE(atomic, 50, ~0, release) +__OMP_DIRECTIVE_CLAUSE(atomic, 50, ~0, relaxed) +__OMP_DIRECTIVE_CLAUSE(atomic, 50, ~0, hint) + +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(requires, 1, ~0, unified_address) +__OMP_DIRECTIVE_CLAUSE(requires, 1, ~0, unified_shared_memory) +__OMP_DIRECTIVE_CLAUSE(requires, 1, ~0, reverse_offload) +__OMP_DIRECTIVE_CLAUSE(requires, 1, ~0, dynamic_allocators) +__OMP_DIRECTIVE_CLAUSE(requires, 1, ~0, atomic_default_mem_order) + +__OMP_DIRECTIVE_CLAUSE(allocate, 1, ~0, allocator) + +__OMP_DIRECTIVE_CLAUSE(target_data, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_data, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_data, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_data, 1, ~0, use_device_ptr) + +__OMP_DIRECTIVE_CLAUSE(target_enter_data, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_enter_data, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_enter_data, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_enter_data, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_enter_data, 1, ~0, depend) + +__OMP_DIRECTIVE_CLAUSE(target_exit_data, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_exit_data, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_exit_data, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_exit_data, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_exit_data, 1, ~0, depend) + +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_parallel, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~1, ordered) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(target_update, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_update, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_update, 1, ~0, to) +__OMP_DIRECTIVE_CLAUSE(target_update, 1, ~0, from) +__OMP_DIRECTIVE_CLAUSE(target_update, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_update, 1, ~0, depend) + +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(teams, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(ordered, 1, ~0, threads) +__OMP_DIRECTIVE_CLAUSE(ordered, 1, ~0, simd) +__OMP_DIRECTIVE_CLAUSE(ordered, 1, ~0, depend) + +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, final) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, untied) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, mergeable) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, priority) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, grainsize) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, nogroup) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, num_tasks) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, in_reduction) +__OMP_DIRECTIVE_CLAUSE(taskloop, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, final) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, untied) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, mergeable) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, priority) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, grainsize) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, nogroup) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, num_tasks) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, in_reduction) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(taskloop_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, final) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, untied) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, mergeable) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, priority) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, grainsize) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, nogroup) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, num_tasks) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, in_reduction) +__OMP_DIRECTIVE_CLAUSE(master_taskloop, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, final) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, untied) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, mergeable) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, priority) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, grainsize) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, nogroup) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, num_tasks) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, in_reduction) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(master_taskloop_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, final) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, untied) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, mergeable) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, priority) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, grainsize) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, nogroup) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, num_tasks) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop, 1, ~0, copyin) + +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, final) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, untied) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, mergeable) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, priority) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, grainsize) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, nogroup) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, num_tasks) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(parallel_master_taskloop_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(critical, 1, ~0, hint) + +__OMP_DIRECTIVE_CLAUSE(distribute, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(distribute, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(distribute, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(distribute, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(distribute, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(distribute, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(distribute_parallel_for_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 50, ~0, if) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(distribute_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~1, ordered) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(target_parallel_for_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(target_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(target_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(teams_distribute, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 50, ~0, if) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, copyin) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(teams_distribute_parallel_for, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(target_teams, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, + firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, + is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, default) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, + thread_limit) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, + dist_schedule) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, num_threads) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, proc_bind) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, schedule) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + private) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + default) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + reduction) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + num_teams) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + thread_limit) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + lastprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + collapse) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + dist_schedule) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + num_threads) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + proc_bind) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + schedule) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + aligned) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + safelen) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + simdlen) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 1, ~0, + allocate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 50, ~0, + nontemporal) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_parallel_for_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, if) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, device) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, map) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, private) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, nowait) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, defaultmap) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, firstprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, lastprivate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, is_device_ptr) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, shared) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, reduction) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, num_teams) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, thread_limit) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, collapse) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, dist_schedule) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, linear) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, aligned) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, safelen) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, simdlen) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 1, ~0, allocate) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 50, ~0, nontemporal) +__OMP_DIRECTIVE_CLAUSE(target_teams_distribute_simd, 50, ~0, order) + +__OMP_DIRECTIVE_CLAUSE(taskgroup, 1, ~0, task_reduction) +__OMP_DIRECTIVE_CLAUSE(taskgroup, 1, ~0, allocate) + +__OMP_DIRECTIVE_CLAUSE(declare_mapper, 1, ~0, map) + +__OMP_DIRECTIVE_CLAUSE(declare_variant, 1, ~0, match) + +__OMP_DIRECTIVE_CLAUSE(flush, 50, ~0, acq_rel) +__OMP_DIRECTIVE_CLAUSE(flush, 50, ~0, acquire) +__OMP_DIRECTIVE_CLAUSE(flush, 50, ~0, release) +// TODO This should ne `none` instead +__OMP_DIRECTIVE_CLAUSE(flush, 1, ~0, flush) + +__OMP_DIRECTIVE_CLAUSE(depobj, 50, ~0, depend) +__OMP_DIRECTIVE_CLAUSE(depobj, 50, ~0, destroy) +__OMP_DIRECTIVE_CLAUSE(depobj, 50, ~0, update) +// TODO This should ne `none` instead +__OMP_DIRECTIVE_CLAUSE(depobj, 50, ~0, depobj) + +#undef __OMP_DIRECTIVE_CLAUSE +#undef OMP_DIRECTIVE_CLAUSE +///} diff --git a/llvm/lib/Frontend/OpenMP/OMPConstants.cpp b/llvm/lib/Frontend/OpenMP/OMPConstants.cpp index edd857d7b250..ed19ae38c698 100644 --- a/llvm/lib/Frontend/OpenMP/OMPConstants.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPConstants.cpp @@ -54,6 +54,17 @@ StringRef llvm::omp::getOpenMPClauseName(Clause C) { llvm_unreachable("Invalid OpenMP clause kind"); } +bool llvm::omp::isAllowedClauseForDirective(Directive D, Clause C, + unsigned Version) { + assert(unsigned(D) <= unsigned(OMPD_unknown)); + assert(unsigned(C) <= unsigned(OMPC_unknown)); +#define OMP_DIRECTIVE_CLAUSE(Dir, MinVersion, MaxVersion, Cl) \ + if (D == Dir && C == Cl && MinVersion <= Version && MaxVersion >= Version) \ + return true; +#include "llvm/Frontend/OpenMP/OMPKinds.def" + return false; +} + /// Declarations for LLVM-IR types (simple, array, function and structure) are /// generated below. Their names are defined and used in OpenMPKinds.def. Here /// we provide the declarations, the initializeTypes function will provide the From cfe-commits at lists.llvm.org Sun Apr 5 22:25:09 2020 From: cfe-commits at lists.llvm.org (Serge Pavlov via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 05:25:09 +0000 (UTC) Subject: [PATCH] D77520: Treat default values in LangOptions.def in the scope of enums Message-ID: sepavloff created this revision. sepavloff added reviewers: rjmccall, rnk, arsenm. Herald added a subscriber: wdng. Herald added a project: clang. If an option specified in LangOptions.def is of enum type, its default value should be a member of that enum, so scope qualifier may always be added in such cases. It allows to omit the scope qualifiers from 'LangOptions.def', which improves readability. No functional changes. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D77520 Files: clang/include/clang/Basic/LangOptions.def clang/lib/Basic/LangOptions.cpp Index: clang/lib/Basic/LangOptions.cpp =================================================================== --- clang/lib/Basic/LangOptions.cpp +++ clang/lib/Basic/LangOptions.cpp @@ -16,7 +16,8 @@ LangOptions::LangOptions() { #define LANGOPT(Name, Bits, Default, Description) Name = Default; -#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) set##Name(Default); +#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ + set##Name(Type::Default); #include "clang/Basic/LangOptions.def" } @@ -24,7 +25,7 @@ #define LANGOPT(Name, Bits, Default, Description) #define BENIGN_LANGOPT(Name, Bits, Default, Description) Name = Default; #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ - Name = Default; + Name = static_cast(Type::Default); #include "clang/Basic/LangOptions.def" // These options do not affect AST generation. Index: clang/include/clang/Basic/LangOptions.def =================================================================== --- clang/include/clang/Basic/LangOptions.def +++ clang/include/clang/Basic/LangOptions.def @@ -121,7 +121,7 @@ LANGOPT(WritableStrings , 1, 0, "writable string support") LANGOPT(ConstStrings , 1, 0, "const-qualified string support") ENUM_LANGOPT(LaxVectorConversions, LaxVectorConversionKind, 2, - LaxVectorConversionKind::All, "lax vector conversions") + All, "lax vector conversions") LANGOPT(ConvergentFunctions, 1, 1, "Assume convergent functions") LANGOPT(AltiVec , 1, 0, "AltiVec-style vector initializers") LANGOPT(ZVector , 1, 0, "System z vector extensions") @@ -293,7 +293,7 @@ BENIGN_LANGOPT(SemanticInterposition , 1, 0, "semantic interposition") ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff, "stack protector mode") -ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized, +ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, Uninitialized, "trivial automatic variable initialization") ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined, "signed integer overflow handling") @@ -313,7 +313,7 @@ BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0, "if non-zero, warn about parameter or return Warn if parameter/return value is larger in bytes than this setting. 0 is no check.") VALUE_LANGOPT(MSCompatibilityVersion, 32, 0, "Microsoft Visual C/C++ Version") -ENUM_LANGOPT(VtorDispMode, MSVtorDispMode, 2, MSVtorDispMode::ForVBaseOverride, +ENUM_LANGOPT(VtorDispMode, MSVtorDispMode, 2, ForVBaseOverride, "How many vtordisps to insert") LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling") @@ -339,7 +339,7 @@ BENIGN_LANGOPT(AllowEditorPlaceholders, 1, 0, "allow editor placeholders in source") -ENUM_LANGOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest, +ENUM_LANGOPT(ClangABICompat, ClangABI, 4, Latest, "version of Clang that we should attempt to be ABI-compatible " "with") @@ -353,9 +353,9 @@ COMPATIBLE_VALUE_LANGOPT(MaxTokens, 32, 0, "Max number of tokens per TU or 0") -ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, SignReturnAddressScopeKind::None, +ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, None, "Scope of return address signing") -ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, SignReturnAddressKeyKind::AKey, +ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, AKey, "Key used for return address signing") LANGOPT(BranchTargetEnforcement, 1, 0, "Branch-target enforcement enabled") -------------- next part -------------- A non-text attachment was scrubbed... Name: D77520.255218.patch Type: text/x-patch Size: 3722 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 22:25:10 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 05:25:10 +0000 (UTC) Subject: [PATCH] D77112: [OpenMP][NFCI] Move OpenMP clause information to `lib/Frontend/OpenMP` In-Reply-To: References: Message-ID: <25de9a744c7d627ae626852b53bb0c20@localhost.localdomain> jdoerfert added a comment. In D77112#1962936 , @thakis wrote: > Broke clang-tools-extra again: http://lab.llvm.org:8011/builders/clang-ppc64be-linux/builds/46759/steps/build%20stage%201/logs/stdio Fixed in 8ea07f62a6f06bdb7da981425227995423867a4d , I might have grabbed the wrong commit locally, apologies. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77112/new/ https://reviews.llvm.org/D77112 From cfe-commits at lists.llvm.org Sun Apr 5 22:25:11 2020 From: cfe-commits at lists.llvm.org (Rui Ueyama via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 05:25:11 +0000 (UTC) Subject: [PATCH] D77484: [Vector] Pass VectLib to LTO backend so TLI build correct vector function list In-Reply-To: References: Message-ID: <28f7e4be8a5c57337257c727f497bc68@localhost.localdomain> ruiu added inline comments. ================ Comment at: lld/ELF/Config.h:132 callGraphProfile; + llvm::TargetLibraryInfoImpl::VectorLibrary VectLib; bool allowMultipleDefinition; ---------------- We name variables after their corresponding command line flags, so this should be `ltoVectorLibrary`. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77484/new/ https://reviews.llvm.org/D77484 From cfe-commits at lists.llvm.org Sun Apr 5 22:25:11 2020 From: cfe-commits at lists.llvm.org (Michael Liao via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 05:25:11 +0000 (UTC) Subject: [PATCH] D71227: [cuda][hip] Fix function overload resolution in the global initiailizer. In-Reply-To: References: Message-ID: <06ecad0137cb8980af84806343fc3781@localhost.localdomain> hliao updated this revision to Diff 255219. hliao added a comment. Rebase to the latest trunk. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D71227/new/ https://reviews.llvm.org/D71227 Files: clang/include/clang/Sema/Sema.h clang/lib/Parse/ParseDecl.cpp clang/lib/Sema/SemaCUDA.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaExprCXX.cpp clang/lib/Sema/SemaOverload.cpp clang/test/SemaCUDA/function-overload.cu clang/test/SemaCUDA/global-initializers-host.cu clang/test/SemaCUDA/hip-pinned-shadow.cu -------------- next part -------------- A non-text attachment was scrubbed... Name: D71227.255219.patch Type: text/x-patch Size: 22149 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 22:25:18 2020 From: cfe-commits at lists.llvm.org (Johannes Doerfert via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 05:25:18 +0000 (UTC) Subject: [PATCH] D77113: [OpenMP][NFC] Move and simplify directive -> allowed clause mapping In-Reply-To: References: Message-ID: This revision was automatically updated to reflect the committed changes. Closed by commit rG931c0cd713ee: [OpenMP][NFC] Move and simplify directive -> allowed clause mapping (authored by jdoerfert). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77113/new/ https://reviews.llvm.org/D77113 Files: clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/Basic/OpenMPKinds.def clang/include/clang/Basic/OpenMPKinds.h clang/lib/ASTMatchers/Dynamic/CMakeLists.txt clang/lib/Basic/OpenMPKinds.cpp clang/lib/Tooling/CMakeLists.txt clang/lib/Tooling/Transformer/CMakeLists.txt clang/unittests/AST/CMakeLists.txt clang/unittests/ASTMatchers/CMakeLists.txt clang/unittests/ASTMatchers/Dynamic/CMakeLists.txt clang/unittests/Analysis/CMakeLists.txt clang/unittests/Rename/CMakeLists.txt clang/unittests/Sema/CMakeLists.txt clang/unittests/StaticAnalyzer/CMakeLists.txt clang/unittests/Tooling/CMakeLists.txt llvm/include/llvm/Frontend/OpenMP/OMPConstants.h llvm/include/llvm/Frontend/OpenMP/OMPKinds.def llvm/lib/Frontend/OpenMP/OMPConstants.cpp -------------- next part -------------- A non-text attachment was scrubbed... Name: D77113.255221.patch Type: text/x-patch Size: 106562 bytes Desc: not available URL: From cfe-commits at lists.llvm.org Sun Apr 5 22:57:00 2020 From: cfe-commits at lists.llvm.org (Richard Smith - zygoloid via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 05:57:00 +0000 (UTC) Subject: [PATCH] D77502: [clang][CodeGen] Handle throw expression in conditional operator constant folding In-Reply-To: References: Message-ID: rsmith added inline comments. ================ Comment at: clang/lib/CodeGen/CGExpr.cpp:4337 + EmitCXXThrowExpr(ThrowExpr); + return EmitLValue(dead); + } ---------------- The IR we emit for the dead operand is unreachable; it's a bit wasteful to generate it here and (hopefully!) leave it to the optimizer to remove it again. Perhaps we could produce an `undef` lvalue instead? See `CodeGenFunction::EmitUnsupportedLValue` for an example of how to build such a value. ================ Comment at: clang/test/CodeGenCXX/throw-expressions.cpp:84-87 + void conditional_throw() { + int a, b; + (true ? throw 0 : a) = 0; + } ---------------- Please add some `CHECK`s in here to make sure we actually emit a call to `__cxa_throw`. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77502/new/ https://reviews.llvm.org/D77502 From cfe-commits at lists.llvm.org Sun Apr 5 23:03:03 2020 From: cfe-commits at lists.llvm.org (David Blaikie via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 06:03:03 +0000 (UTC) Subject: [PATCH] D77341: [DomTree] Replace ChildrenGetter with GraphTraits over GraphDiff. In-Reply-To: References: Message-ID: dblaikie added inline comments. ================ Comment at: llvm/include/llvm/IR/CFGDiff.h:198 +namespace { +template ---------------- kuhar wrote: > kuhar wrote: > > What benefit does an anonymous namespace in a header have over a named one, e.g., `detail`/`impl`? Doesn't it make it more difficult to deduplicate symbols across different translation units? Not sure what the best practices are in C++ now in this area. > Found an article on this matter: https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL59-CPP.+Do+not+define+an+unnamed+namespace+in+a+header+file Oh, yeah, sorry I didn't spot that - yeah, anonymous namespaces in header files are a no-go. This should be a `detail` (`detail` outnumbers `impl` 361 to 41 in the LLVM project) namespace within the llvm namespace as suggested. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77341/new/ https://reviews.llvm.org/D77341 From cfe-commits at lists.llvm.org Sun Apr 5 23:23:33 2020 From: cfe-commits at lists.llvm.org (Richard Smith via cfe-commits) Date: Sun, 05 Apr 2020 23:23:33 -0700 (PDT) Subject: [clang] 6163aa9 - PR45239: Don't deallocate TemplateIdAnnotations if they might still be Message-ID: <5e8acae5.1c69fb81.d6cab.329d@mx.google.com> Author: Richard Smith Date: 2020-04-05T23:23:20-07:00 New Revision: 6163aa96799cbad7f2f58e02c5bebee9647056a5 URL: https://github.com/llvm/llvm-project/commit/6163aa96799cbad7f2f58e02c5bebee9647056a5 DIFF: https://github.com/llvm/llvm-project/commit/6163aa96799cbad7f2f58e02c5bebee9647056a5.diff LOG: PR45239: Don't deallocate TemplateIdAnnotations if they might still be in the token stream. Previously we deleted all template-id annotations at the end of each top-level declaration. That doesn't work: we can do some lookahead and form a template-id annotation, and then roll back that lookahead, parse, and decide that we're missing a semicolon at the end of a top-level declaration, before we reach the annotation token. In that situation, we'd end up parsing the annotation token after deleting its associated data, leading to various forms of badness. We now only delete template-id annotations if the preprocessor can assure us that there are no annotation tokens left in the token stream (or if we're already at EOF). This lets us delete the annotation tokens earlier in a lot of cases; we now clean them up at the end of each statement and class member, not just after each top-level declaration. This also permitted some simplification of the delay-parsed templates cleanup code. Added: Modified: clang/include/clang/Lex/Preprocessor.h clang/include/clang/Parse/Parser.h clang/include/clang/Parse/RAIIObjectsForParser.h clang/lib/Parse/ParseDeclCXX.cpp clang/lib/Parse/ParseStmt.cpp clang/lib/Parse/ParseTemplate.cpp clang/lib/Parse/Parser.cpp clang/test/Parser/cxx-template-decl.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 81ed4ab57b41..61e5974c1f0d 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -1562,6 +1562,12 @@ class Preprocessor { void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind, void *AnnotationVal); + /// Determine whether it's possible for a future call to Lex to produce an + /// annotation token created by a previous call to EnterAnnotationToken. + bool mightHavePendingAnnotationTokens() { + return CurLexerKind != CLK_Lexer; + } + /// Update the current token to represent the provided /// identifier, in order to cache an action performed by typo correction. void TypoCorrectToken(const Token &Tok) { diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 71d216bfb260..3f73a1b90268 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -276,6 +276,22 @@ class Parser : public CodeCompletionHandler { /// top-level declaration is finished. SmallVector TemplateIds; + void MaybeDestroyTemplateIds() { + if (!TemplateIds.empty() && + (Tok.is(tok::eof) || !PP.mightHavePendingAnnotationTokens())) + DestroyTemplateIds(); + } + void DestroyTemplateIds(); + + /// RAII object to destroy TemplateIdAnnotations where possible, from a + /// likely-good position during parsing. + struct DestroyTemplateIdAnnotationsRAIIObj { + Parser &Self; + + DestroyTemplateIdAnnotationsRAIIObj(Parser &Self) : Self(Self) {} + ~DestroyTemplateIdAnnotationsRAIIObj() { Self.MaybeDestroyTemplateIds(); } + }; + /// Identifiers which have been declared within a tentative parse. SmallVector TentativelyDeclaredIdentifiers; @@ -1466,7 +1482,6 @@ class Parser : public CodeCompletionHandler { void ParseLateTemplatedFuncDef(LateParsedTemplate &LPT); static void LateTemplateParserCallback(void *P, LateParsedTemplate &LPT); - static void LateTemplateParserCleanupCallback(void *P); Sema::ParsingClassState PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface); diff --git a/clang/include/clang/Parse/RAIIObjectsForParser.h b/clang/include/clang/Parse/RAIIObjectsForParser.h index fb092c050783..40351bf71d9f 100644 --- a/clang/include/clang/Parse/RAIIObjectsForParser.h +++ b/clang/include/clang/Parse/RAIIObjectsForParser.h @@ -459,26 +459,6 @@ namespace clang { } void skipToEnd(); }; - - /// RAIIObject to destroy the contents of a SmallVector of - /// TemplateIdAnnotation pointers and clear the vector. - class DestroyTemplateIdAnnotationsRAIIObj { - SmallVectorImpl &Container; - - public: - DestroyTemplateIdAnnotationsRAIIObj( - SmallVectorImpl &Container) - : Container(Container) {} - - ~DestroyTemplateIdAnnotationsRAIIObj() { - for (SmallVectorImpl::iterator I = - Container.begin(), - E = Container.end(); - I != E; ++I) - (*I)->Destroy(); - Container.clear(); - } - }; } // end namespace clang #endif diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 710632379ace..cbff35ace337 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -3339,6 +3339,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, // Each iteration of this loop reads one member-declaration. ParseCXXClassMemberDeclarationWithPragmas( CurAS, AccessAttrs, static_cast(TagType), TagDecl); + MaybeDestroyTemplateIds(); } T.consumeClose(); } else { diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 492db4d6390c..57f09e93ebf7 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -105,6 +105,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, StmtResult Res = ParseStatementOrDeclarationAfterAttributes( Stmts, StmtCtx, TrailingElseLoc, Attrs); + MaybeDestroyTemplateIds(); assert((Attrs.empty() || Res.isInvalid() || Res.isUsable()) && "attributes on empty statement"); diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 5025ea5c85fe..2cc0419582da 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -1618,6 +1618,9 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) { if (!LPT.D) return; + // Destroy TemplateIdAnnotations when we're done, if possible. + DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this); + // Get the FunctionDecl. FunctionDecl *FunD = LPT.D->getAsFunction(); // Track template parameter depth. diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index e9dbd50c3ac1..5fa23f2cdc13 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -433,16 +433,7 @@ Parser::~Parser() { PP.clearCodeCompletionHandler(); - if (getLangOpts().DelayedTemplateParsing && - !PP.isIncrementalProcessingEnabled() && !TemplateIds.empty()) { - // If an ASTConsumer parsed delay-parsed templates in their - // HandleTranslationUnit() method, TemplateIds created there were not - // guarded by a DestroyTemplateIdAnnotationsRAIIObj object in - // ParseTopLevelDecl(). Destroy them here. - DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds); - } - - assert(TemplateIds.empty() && "Still alive TemplateIdAnnotations around?"); + DestroyTemplateIds(); } /// Initialize - Warm up the parser. @@ -538,11 +529,10 @@ void Parser::Initialize() { ConsumeToken(); } -void Parser::LateTemplateParserCleanupCallback(void *P) { - // While this RAII helper doesn't bracket any actual work, the destructor will - // clean up annotations that were created during ActOnEndOfTranslationUnit - // when incremental processing is enabled. - DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(((Parser *)P)->TemplateIds); +void Parser::DestroyTemplateIds() { + for (TemplateIdAnnotation *Id : TemplateIds) + Id->Destroy(); + TemplateIds.clear(); } /// Parse the first top-level declaration in a translation unit. @@ -577,7 +567,7 @@ bool Parser::ParseFirstTopLevelDecl(DeclGroupPtrTy &Result) { /// declaration /// [C++20] module-import-declaration bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result, bool IsFirstDecl) { - DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds); + DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this); // Skip over the EOF token, flagging end of previous input for incremental // processing @@ -663,9 +653,7 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result, bool IsFirstDecl) { // Late template parsing can begin. if (getLangOpts().DelayedTemplateParsing) - Actions.SetLateTemplateParser(LateTemplateParserCallback, - PP.isIncrementalProcessingEnabled() ? - LateTemplateParserCleanupCallback : nullptr, + Actions.SetLateTemplateParser(LateTemplateParserCallback, nullptr, this); if (!PP.isIncrementalProcessingEnabled()) Actions.ActOnEndOfTranslationUnit(); @@ -727,7 +715,7 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result, bool IsFirstDecl) { Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs, ParsingDeclSpec *DS) { - DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds); + DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this); ParenBraceBracketBalancer BalancerRAIIObj(*this); if (PP.isCodeCompletionReached()) { diff --git a/clang/test/Parser/cxx-template-decl.cpp b/clang/test/Parser/cxx-template-decl.cpp index 14b97f12e357..64e7ca921f57 100644 --- a/clang/test/Parser/cxx-template-decl.cpp +++ b/clang/test/Parser/cxx-template-decl.cpp @@ -279,3 +279,10 @@ namespace NoCrashOnEmptyNestedNameSpecifier { typename T = typename ABC::template arg_t<0>> // expected-error {{no template named 'ABC'}} void foo(FnT) {} } + +namespace PR45239 { + // Ensure we don't crash here. We used to deallocate the TemplateIdAnnotation + // before we'd parsed it. + template int b; + template auto f() -> b<0>; // expected-error +{{}} +} From cfe-commits at lists.llvm.org Sun Apr 5 23:25:40 2020 From: cfe-commits at lists.llvm.org (Nathan Ridge via Phabricator via cfe-commits) Date: Mon, 06 Apr 2020 06:25:40 +0000 (UTC) Subject: [PATCH] D77225: [clangd] Support textDocument/semanticTokens/edits In-Reply-To: References: Message-ID: <7301c706be48fd2926776cd672d73495@localhost.localdomain> nridge added a comment. > Tested in VSCode insiders (with a patched client to enable experimental features). In case it's useful to others: the required change to the client to opt into this appears to be calling `registerProposedFeatures()` on the `LanguageClient` object. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D77225/new/ https://reviews.llvm.org/D77225