[clang] de55ebe - Typo fix; NFC

2020-09-27 Thread Aaron Ballman via cfe-commits

Author: Aaron Ballman
Date: 2020-09-27T08:30:41-04:00
New Revision: de55ebe3bbc77882901ae2b9654503b7611b28f3

URL: 
https://github.com/llvm/llvm-project/commit/de55ebe3bbc77882901ae2b9654503b7611b28f3
DIFF: 
https://github.com/llvm/llvm-project/commit/de55ebe3bbc77882901ae2b9654503b7611b28f3.diff

LOG: Typo fix; NFC

Added: 


Modified: 
clang/lib/Parse/ParseDecl.cpp

Removed: 




diff  --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 79628cfed1b2..adec7c607682 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4152,7 +4152,7 @@ void Parser::ParseStructDeclaration(
 ///   struct-contents:
 /// struct-declaration-list
 /// [EXT]   empty
-/// [GNU]   "struct-declaration-list" without terminatoring ';'
+/// [GNU]   "struct-declaration-list" without terminating ';'
 ///   struct-declaration-list:
 /// struct-declaration
 /// struct-declaration-list struct-declaration



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


[PATCH] D86559: [Sema, CodeGen] Allow [[likely]] and [[unlikely]] on labels

2020-09-27 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:6454
 
+static bool validateLikelihoodAttr(Sema &S, Decl *D, const ParsedAttr &A) {
+  if (!isa(D)) {

This is entering into somewhat novel territory for attributes, so some of this 
feedback is me thinking out loud.

Attr.td lists these two attributes as being a `StmtAttr` and not any kind of 
declaration attribute. We have `DeclOrTypeAttr` for attributes that can be 
applied to declarations or types, but we do not have something similar for 
statement attributes yet. We do have some custom semantic handling logic in 
SemaDeclAttr.cpp for statement attributes, but you avoid hitting that code path 
by adding a `case` for the two likelihood attributes. These attributes only 
apply to label declarations currently, and labels cannot be redeclared, so 
there aren't yet questions about whether this is inheritable or not. So we 
*might* be okay with this, but I'm not 100% certain. For instance, I don't 
recall if the pretty printer or AST dumpers will need to distinguish between 
whether this attribute is written on the statement or the declaration (which is 
itself a bit of an interesting question: should the attribute attach only to 
the statement rather than trying to attach to the underlying decl? 
http://eel.is/c++draft/stmt.stmt#stmt.label-1.sentence-2 is ambiguous, but I 
don't think of `case` or `default` labels as being declarations so I tend to 
not think of identifier labels as such either.). There's a part of me that 
wonders if we have a different issue where the attribute is trying to attach to 
the declaration rather than the statement and that this should be handled 
purely as a statement attribute.

I'm curious what your thoughts are, but I'd also like to see some additional 
tests for the random other bits that interact with attributes like AST dumping 
and pretty printing to be sure the behavior is reasonable.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86559/new/

https://reviews.llvm.org/D86559

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


[PATCH] D88377: Diagnose invalid target ID for AMDGPU toolchain for assembler

2020-09-27 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl created this revision.
yaxunl added reviewers: tra, ashi1, arsenm.
Herald added subscribers: kerbowa, t-tye, Anastasia, tpr, dstuttard, nhaehnle, 
jvesely, kzhuravl.
yaxunl requested review of this revision.
Herald added a subscriber: wdng.

AMDGPU toolchain currently only diagnose invalid target ID for OpenCL
source compilation. Invalid target ID is not diagnosed for assembler.

This patch fixes that.


https://reviews.llvm.org/D88377

Files:
  clang/lib/Driver/ToolChains/AMDGPU.cpp
  clang/lib/Driver/ToolChains/AMDGPU.h
  clang/lib/Driver/ToolChains/HIP.cpp
  clang/test/Driver/amdgpu-invalid-target-id.s

Index: clang/test/Driver/amdgpu-invalid-target-id.s
===
--- /dev/null
+++ clang/test/Driver/amdgpu-invalid-target-id.s
@@ -0,0 +1,45 @@
+// REQUIRES: clang-driver
+// REQUIRES: x86-registered-target
+// REQUIRES: amdgpu-registered-target
+
+// RUN: not %clang -target amdgcn-amd-amdhsa \
+// RUN:   -mcpu=gfx908xnack -nostdlib \
+// RUN:   %s 2>&1 | FileCheck -check-prefix=NOPLUS %s
+
+// NOPLUS: error: Invalid target ID: gfx908xnack
+
+// RUN: not %clang -target amdgcn-amd-amdpal \
+// RUN:   -mcpu=gfx908:xnack+:xnack+ -nostdlib \
+// RUN:   %s 2>&1 | FileCheck -check-prefix=ORDER %s
+
+// ORDER: error: Invalid target ID: gfx908:xnack+:xnack+
+
+// RUN: not %clang -target amdgcn--mesa3d \
+// RUN:   -mcpu=gfx908:unknown+ -nostdlib \
+// RUN:   %s 2>&1 | FileCheck -check-prefix=UNK %s
+
+// UNK: error: Invalid target ID: gfx908:unknown+
+
+// RUN: not %clang -target amdgcn-amd-amdhsa \
+// RUN:   -mcpu=gfx908:sram-ecc+:unknown+ -nostdlib \
+// RUN:   %s 2>&1 | FileCheck -check-prefix=MIXED %s
+
+// MIXED: error: Invalid target ID: gfx908:sram-ecc+:unknown+
+
+// RUN: not %clang -target amdgcn-amd-amdhsa \
+// RUN:   -mcpu=gfx900:sram-ecc+ -nostdlib \
+// RUN:   %s 2>&1 | FileCheck -check-prefix=UNSUP %s
+
+// UNSUP: error: Invalid target ID: gfx900:sram-ecc+
+
+// RUN: not %clang -target amdgcn-amd-amdhsa \
+// RUN:   -mcpu=gfx900:xnack -nostdlib \
+// RUN:   %s 2>&1 | FileCheck -check-prefix=NOSIGN %s
+
+// NOSIGN: error: Invalid target ID: gfx900:xnack
+
+// RUN: not %clang -target amdgcn-amd-amdhsa \
+// RUN:   -mcpu=gfx900+xnack -nostdlib \
+// RUN:   %s 2>&1 | FileCheck -check-prefix=NOCOLON %s
+
+// NOCOLON: error: Invalid target ID: gfx900+xnack
Index: clang/lib/Driver/ToolChains/HIP.cpp
===
--- clang/lib/Driver/ToolChains/HIP.cpp
+++ clang/lib/Driver/ToolChains/HIP.cpp
@@ -240,8 +240,7 @@
 Action::OffloadKind DeviceOffloadingKind) const {
   HostTC.addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind);
 
-  // Allow using target ID in --offload-arch.
-  StringRef GpuArch = translateTargetID(DriverArgs, CC1Args);
+  StringRef GpuArch = getGPUArch(DriverArgs);
   assert(!GpuArch.empty() && "Must have an explicit GPU arch.");
   (void) GpuArch;
   assert(DeviceOffloadingKind == Action::OFK_HIP &&
@@ -358,6 +357,7 @@
 DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mcpu_EQ), BoundArch);
   }
 
+  checkTargetID(*DAL);
   return DAL;
 }
 
Index: clang/lib/Driver/ToolChains/AMDGPU.h
===
--- clang/lib/Driver/ToolChains/AMDGPU.h
+++ clang/lib/Driver/ToolChains/AMDGPU.h
@@ -91,11 +91,10 @@
   const char *getDefaultLinker() const override { return "ld.lld"; }
 
 protected:
-  /// Translate -mcpu option containing target ID to cc1 options.
-  /// Returns the GPU name.
-  StringRef translateTargetID(const llvm::opt::ArgList &DriverArgs,
-  llvm::opt::ArgStringList &CC1Args) const;
+  /// Check and diagnose invalid target ID specified by -mcpu.
+  void checkTargetID(const llvm::opt::ArgList &DriverArgs) const;
 
+  /// Get GPU arch from -mcpu without checking.
   StringRef getGPUArch(const llvm::opt::ArgList &DriverArgs) const;
 };
 
Index: clang/lib/Driver/ToolChains/AMDGPU.cpp
===
--- clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -430,6 +430,8 @@
   for (auto *A : Args)
 DAL->append(A);
 
+  checkTargetID(*DAL);
+
   if (!Args.getLastArgValue(options::OPT_x).equals("cl"))
 return DAL;
 
@@ -522,8 +524,6 @@
 const llvm::opt::ArgList &DriverArgs,
 llvm::opt::ArgStringList &CC1Args,
 Action::OffloadKind DeviceOffloadingKind) const {
-  // Allow using target ID in -mcpu.
-  translateTargetID(DriverArgs, CC1Args);
   // Default to "hidden" visibility, as object level linking will not be
   // supported for the foreseeable future.
   if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ,
@@ -540,21 +540,17 @@
   getTriple(), DriverArgs.getLastArgValue(options::OPT_mcpu_EQ));
 }
 
-StringRef
-AMDGPUToolChain::translateTargetID(const llvm::opt::ArgList &DriverArgs,
-   llvm::opt::ArgStringList &CC1Args) const {
+void

[PATCH] D88333: Better diagnostics for anonymous bit-fields with attributes or an initializer

2020-09-27 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman updated this revision to Diff 294554.
aaron.ballman retitled this revision from "Correctly parse attributes on the 
declaration of an anonymous bit-field" to "Better diagnostics for anonymous 
bit-fields with attributes or an initializer".
aaron.ballman added a comment.
Herald added a reviewer: jdoerfert.

I've updated the patch to continue to reject attributes on anonymous 
bit-fields, but with a better diagnostic. In addition, I changed how we handle 
anonymous bit-fields with an initializer (based on discussion on the Core 
reflector) -- instead of rejecting the construct as a semantic issue, I reject 
it at the parser level with a similar diagnostic (I went with "in-class 
initializer" because that's used by other parser diagnostics, but I'm fine with 
either formulation).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D88333/new/

https://reviews.llvm.org/D88333

Files:
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CXX/class/class.bit/p1.cpp
  clang/test/Parser/MicrosoftExtensions.cpp
  clang/test/Parser/c2x-attributes.c

Index: clang/test/Parser/c2x-attributes.c
===
--- clang/test/Parser/c2x-attributes.c
+++ clang/test/Parser/c2x-attributes.c
@@ -23,6 +23,8 @@
   int l[[]][10];
   [[]] int m, n;
   int o [[]] : 12;
+  int [[]] : 0; // OK, attribute applies to the type.
+  int p, [[]] : 0; // expected-error {{an attribute list cannot appear here}}
 };
 
 [[]] struct S2 { int a; }; // expected-error {{misplaced attributes}}
Index: clang/test/Parser/MicrosoftExtensions.cpp
===
--- clang/test/Parser/MicrosoftExtensions.cpp
+++ clang/test/Parser/MicrosoftExtensions.cpp
@@ -466,6 +466,6 @@
 // MSVC produces a "C4353 constant 0 as function expression" for this,
 // considering the final {} to be part of the bit-width. We follow P0683R1
 // and treat it as a default member initializer.
-enum E : int : int{}{}; // expected-error {{anonymous bit-field cannot have a default member initializer}} expected-warning {{C++20 extension}}
+enum E : int : int{}{}; // expected-error {{anonymous bit-field cannot have an in-class initializer}}
   };
 }
Index: clang/test/CXX/class/class.bit/p1.cpp
===
--- /dev/null
+++ clang/test/CXX/class/class.bit/p1.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+
+// Test various bit-field member declarations.
+constexpr int foo() { return 1; }
+struct A {
+  int a [[]] : 1;
+  int b, [[]] : 0; // expected-error {{an attribute list cannot appear here}}
+  int [[]] : 0; // OK, attribute applies to the type.
+  int [[]] c : 1; // OK, attribute applies to the type.
+  int : 2 = 1; // expected-error {{anonymous bit-field cannot have an in-class initializer}}
+  int : 0 { 1 }; // expected-error {{anonymous bit-field cannot have an in-class initializer}}
+  int : 0, d : 1 = 1;
+  int : 1 = 12, e : 1; // expected-error {{anonymous bit-field cannot have an in-class initializer}}
+  int : 0, f : 1 = 1;
+  int g [[]] : 1 = 1;
+  int h [[]] : 1 {1};
+  int i : foo() = foo();
+};
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -16707,14 +16707,6 @@
   BitWidth = nullptr;
   ZeroWidth = false;
 }
-
-// Only data members can have in-class initializers.
-if (BitWidth && !II && InitStyle) {
-  Diag(Loc, diag::err_anon_bitfield_init);
-  InvalidDecl = true;
-  BitWidth = nullptr;
-  ZeroWidth = false;
-}
   }
 
   // Check that 'mutable' is consistent with the type of the declaration.
Index: clang/lib/Parse/ParseDeclCXX.cpp
===
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -2305,14 +2305,21 @@
 Declarator &DeclaratorInfo, VirtSpecifiers &VS, ExprResult &BitfieldSize,
 LateParsedAttrList &LateParsedAttrs) {
   // member-declarator:
-  //   declarator pure-specifier[opt]
+  //   declarator virt-specifier-seq[opt] pure-specifier[opt]
   //   declarator requires-clause
   //   declarator brace-or-equal-initializer[opt]
-  //   identifier[opt] ':' constant-expression
-  if (Tok.isNot(tok::colon))
+  //   identifier attribute-specifier-seq[opt] ':' constant-expression
+  //   brace-or-equal-initializer[opt]
+  //   ':' constant-expression
+  if (Tok.isNot(tok::colon) && !isCXX11AttributeSpecifier())
 ParseDeclarator(DeclaratorInfo);
-  else
+  else {
 DeclaratorInfo.SetIdentifier(nullptr, Tok.getLocation());
+// Anonymous bit-fields cannot specify attributes; the attributes appertain
+// to the type specifi

[PATCH] D87561: [Sema] List conversion validate character array

2020-09-27 Thread Mark de Wever via Phabricator via cfe-commits
Mordante marked 2 inline comments as done.
Mordante added inline comments.



Comment at: clang/test/CXX/drs/dr14xx.cpp:411-414
+  void f(const char[4]);
+  void f(const wchar_t[4]);
+  void f(const char16_t[4]);
+  void f(const char32_t[4]);

rsmith wrote:
> rsmith wrote:
> > Mordante wrote:
> > > rsmith wrote:
> > > > These should presumably be references to arrays, rather than arrays, or 
> > > > the parameter type is as if you wrote (for example) `void f(const char 
> > > > *)`, which shouldn't get the special treatment here.
> > > > 
> > > > [over.ics.list]p4 mentions this in its footnote:
> > > > 
> > > > "Otherwise, if the parameter type is a character array [Footnote: Since 
> > > > there are no parameters of array type, this will only occur as the 
> > > > referenced type of a reference parameter.] and the initializer list has 
> > > > a single element that is an appropriately-typed string-literal (9.4.3), 
> > > > the implicit conversion sequence is the identity conversion."
> > > Ah I missed that footnote. I reread the standard and can you confirm some 
> > > cases?
> > > ```
> > > namespace A { 
> > >   void f(const char(&)[4]);
> > >   void g() { f({"abc"}); }
> > > }
> > > namespace B { 
> > >   void f(const char(&&)[4]);
> > >   void g() { f({"abc"}); }
> > > } 
> > > ```
> > > both should work and with P0388 the array without bounds will also work.
> > > 
> > > I ask since this is my interpretation of the standard, but it seems 
> > > there's a difference between implementations and `void f(const 
> > > char(&&)[4]);` fails for "abc" but works for "ab".
> > > It seems ICC and consider "abc" an lvalue in this case and not when using 
> > > "ab".
> > > 
> > > Here's a gotbolt link with the examples https://godbolt.org/z/r1TKfx
> > That's a really interesting example :)
> > 
> > The initializer is a list containing an lvalue of type `const char[4]`. Per 
> > [dcl.init.list]/3.9 and /3.10, the behavior depends on whether the 
> > referenced type is reference-related to `const char[4]` -- if so, then the 
> > reference can only bind directly and a `&&` reference will be invalid, 
> > because it's binding an rvalue reference to an lvalue, and if not, then we 
> > create an array temporary and the `&&` binding is fine.
> > 
> > Per [dcl.init.ref]/4, `const char[???]` is reference-related to `const 
> > char[4]` if they are similar types, and per [conv.qual]/2, the types are 
> > similar if `???` is omitted or `4`, and not similar otherwise.
> > 
> > So:
> > * `const char (&&r)[4] = {"abc"}` is ill-formed (types are the same, binds 
> > rvalue reference to lvalue)
> > * `const char (&&)[] = {"abc"}` is ill-formed (types are similar, binds 
> > rvalue reference to lvalue)
> > * `const char (&&r)[5] = {"abc"}` is OK (types are not similar, creates 
> > temporary)
> > 
> > That seems like a very surprising outcome to me. Perhaps we should probably 
> > ignore array bounds entirely when determining whether two types are 
> > reference-related. I'll take this to CWG for discussion.
> I think that's only an answer to half of your question. The other half is 
> that [over.ics.list]p4 does not apply (directly) to either of your testcases, 
> because the "parameter type" is a reference type, not an array type. For:
> 
> ```
> namespace A { 
>   void f(const char(&)[4]);
>   void g() { f({"abc"}); }
> }
> ```
> 
> ... we reach [over.ics.list]p9, which says to use the rules in 
> [over.ics.ref]. Those rules say that if the reference binds directly to an 
> argument expression (ignore the "expression" here; this is very old wording 
> that predates braced initializers), then we form an identity conversion. So 
> that's what happens in this case.
> 
> For
> 
> ```
> namespace B { 
>   void f(const char(&&)[4]);
>   void g() { f({"abc"}); }
> }
> ```
> 
> the same thing happens, but now [over.ics.ref]p3 says "an implicit conversion 
> sequence cannot be formed if it requires binding an lvalue reference other 
> than a reference to a non-volatile const type to an rvalue or binding an 
> rvalue reference to an lvalue other than a function lvalue", so the candidate 
> is not viable.
> 
> If the array bound were omitted or were not 4, then the reference would not 
> bind directly, and we would instead consider initializing a temporary. 
> [over.ics.ref]p2 says "When a parameter of reference type is not bound 
> directly to an argument expression, the conversion sequence is the one 
> required to convert the argument expression to the referenced type according 
> to 12.4.4.2.", which takes us back around to [over.ics.list] with the 
> "parameter type" now being the array type. That's how we can reach 
> [over.ics.list]p4 and consider string literal -> array initialization.
> 
> So I think that, according to the current rules, for
> 
> ```
> void f(const char (&&)[4]); // #1
> void f(const char (&&)[5]); // #2
> ```
> 
> ... a call to `f({"abc"})` remarkably calls #2, because #1 is not 

[PATCH] D86841: [clang] Add mustprogress and llvm.loop.mustprogress attribute deduction

2020-09-27 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert added a comment.

In what situation do we generate `mustprogress` function attributes now? I was 
expecting them in `clang/test/CodeGen/attr-mustprogress.cpp` but did not see 
any.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86841/new/

https://reviews.llvm.org/D86841

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


[PATCH] D87561: [Sema] List conversion validate character array

2020-09-27 Thread Mark de Wever via Phabricator via cfe-commits
Mordante updated this revision to Diff 294556.
Mordante added a comment.

Addresses the review comments.
Adds an extra test case to test whether the proper overload is called. The 
proper overload is a bit of a surprise so when the expected behaviour changes 
the overload test can be adjusted.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87561/new/

https://reviews.llvm.org/D87561

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/CXX/drs/dr14xx.cpp
  clang/test/SemaCXX/overload-array-size.cpp
  clang/test/SemaObjCXX/overload.mm

Index: clang/test/SemaObjCXX/overload.mm
===
--- clang/test/SemaObjCXX/overload.mm
+++ clang/test/SemaObjCXX/overload.mm
@@ -201,3 +201,17 @@
 }
 
 }
+
+namespace StringLiterals {
+void f(const char(&&)[5]);
+void f(const wchar_t(&&)[5]);
+void f(const char16_t(&&)[5]);
+void f(const char32_t(&&)[5]);
+void g() {
+  f({"abc"});
+  f({(((@encode(int});
+  f({L"abc"});
+  f({uR"(abc)"});
+  f({(UR"(abc)")});
+}
+} // namespace StringLiterals
Index: clang/test/SemaCXX/overload-array-size.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/overload-array-size.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -ast-dump | FileCheck %s
+
+// When the array size is 4 the call will attempt to bind an lvalue to an
+// rvalue and fail. Therfore #2 will be called. (rsmith will bring this issue
+// to CWG)
+void f(const char(&&)[4]); // #1
+void f(const char(&&)[5]); // #2
+void g() {
+  f({"abc"});
+  // CHECK: ExprWithCleanups {{.*}}  'void'
+  // CHECK-NEXT: CallExpr
+  // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(const char (&&)[5])'
+}
Index: clang/test/CXX/drs/dr14xx.cpp
===
--- clang/test/CXX/drs/dr14xx.cpp
+++ clang/test/CXX/drs/dr14xx.cpp
@@ -334,6 +334,22 @@
 
 X x;
 X x2{x};
+
+void f1(int);
+void f1(std::initializer_list);
+void g1() { f1({42}); }
+
+template 
+struct Pair {
+  Pair(T, U);
+};
+struct String {
+  String(const char *);
+};
+
+void f2(Pair);
+void f2(std::initializer_list);
+void g2() { f2({"foo", "bar"}); }
   } // dr_example
 
   namespace nonaggregate {
@@ -379,6 +395,43 @@
 struct Value { Value(Pair); Value(TwoPairs); };
 void f() { Value{{{1,2},{3,4}}}; }
   }
+  namespace NonAmbiguous {
+  // The original implementation made this case ambigious due to the special
+  // handling of one element initialization lists.
+  void f(int(&&)[1]);
+  void f(unsigned(&&)[1]);
+
+  void g(unsigned i) {
+f({i});
+  }
+  } // namespace NonAmbiguous
+
+#if __cplusplus >= 201103L
+  namespace StringLiterals {
+  void f(const char(&&)[4]);
+  void f(const char(&&)[5]);
+  void f(const wchar_t(&&)[4]);
+  void f(const wchar_t(&&)[5]);
+#if __cplusplus >= 202002L
+  void f(const char8_t(&&)[4]);
+  void f(const char8_t(&&)[5]);
+#endif
+  void f(const char16_t(&&)[4]);
+  void f(const char16_t(&&)[5]);
+  void f(const char32_t(&&)[4]);
+  void f(const char32_t(&&)[5]);
+  void g() {
+f({"abc"});
+f({((("abc")))});
+f({L"abc"});
+#if __cplusplus >= 202002L
+f({u8"abc"});
+#endif
+f({uR"(abc)"});
+f({(UR"(abc)")});
+  }
+  } // namespace StringLiterals
+#endif
 } // dr1467
 
 namespace dr1490 {  // dr1490: 3.7 c++11
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -4984,20 +4984,20 @@
  InOverloadResolution,
  AllowObjCWritebackConversion);
 }
-// FIXME: Check the other conditions here: array of character type,
-// initializer is a string literal.
-if (ToType->isArrayType()) {
-  InitializedEntity Entity =
-InitializedEntity::InitializeParameter(S.Context, ToType,
-   /*Consumed=*/false);
-  if (S.CanPerformCopyInitialization(Entity, From)) {
-Result.setStandard();
-Result.Standard.setAsIdentityConversion();
-Result.Standard.setFromType(ToType);
-Result.Standard.setAllToTypes(ToType);
-return Result;
+
+if (const auto *AT = S.Context.getAsArrayType(ToType))
+  if (S.IsStringInit(From->getInit(0), AT)) {
+InitializedEntity Entity =
+  InitializedEntity::InitializeParameter(S.Context, ToType,
+ /*Consumed=*/false);
+if (S.CanPerformCopyInitialization(Entity, From)) {
+  Result.setStandard();
+  Result.Standard.setAsIdentityConversion();
+  Result.Standard.setFromType(ToType);
+  Result.Standard.setAllToTypes(ToType);
+  return Result;
+}
   }
-}
   }
 
   // C++14 [over.ics.list]p2

[PATCH] D88381: [Flang][Driver]Add PrintPreprocessedInput action `-E`

2020-09-27 Thread Caroline via Phabricator via cfe-commits
CarolineConcatto created this revision.
Herald added subscribers: cfe-commits, dang, mgorny.
Herald added a reviewer: DavidTruby.
Herald added a reviewer: sscalpone.
Herald added a project: clang.
CarolineConcatto requested review of this revision.

This patch runs Preprocess and PrintProcess actions for Fortran
files.

It makes use of Fortran::parser to run preprocessing for Fortran file and
print them. The two functions are:
`Fortran::parser::Prescan`  and
`Fortran::parser::DumpCookedChars`

This patch assumes that all files need to run preprocessing before running
other action. The PrintPreprocessedInput only prints the files. This is
compatible with the through away driver.

It does not map the driver options(clang::driver::options) to
Fortran::parser::options to be used by Fortran::parser::Prescan.
However, it sets Frotran::parser::options to:
`searchDirectories ` to the current directory
`encoding` to UTF_8
`isFixedForm`
These default settings are compatible with the trough away driver.
Further work needs to be done in CompilerInvocation to read and map
clang::driver::options to Fortran::parser::options.

Depends on D87989 


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D88381

Files:
  clang/include/clang/Driver/Options.td
  flang/include/flang/Frontend/CompilerInstance.h
  flang/include/flang/Frontend/CompilerInvocation.h
  flang/include/flang/Frontend/FrontendActions.h
  flang/include/flang/Frontend/FrontendOptions.h
  flang/lib/Frontend/CMakeLists.txt
  flang/lib/Frontend/CompilerInstance.cpp
  flang/lib/Frontend/CompilerInvocation.cpp
  flang/lib/Frontend/FrontendAction.cpp
  flang/lib/Frontend/FrontendActions.cpp
  flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
  flang/test/Flang-Driver/driver-help-hidden.f90
  flang/test/Flang-Driver/driver-help.f90
  flang/test/Frontend/Inputs/hello-world.c
  flang/test/Frontend/print-preprocess-C-file.f90
  flang/test/Frontend/print-preprocessed-file.f90
  flang/unittests/Frontend/CMakeLists.txt
  flang/unittests/Frontend/CompilerInstanceTest.cpp
  flang/unittests/Frontend/PrintPreprocessedTest.cpp

Index: flang/unittests/Frontend/PrintPreprocessedTest.cpp
===
--- /dev/null
+++ flang/unittests/Frontend/PrintPreprocessedTest.cpp
@@ -0,0 +1,69 @@
+//===- unittests/Frontend/PrintPreprocessedTest.cpp --- FrontendAction tests
+//--===//
+//
+// 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 "gtest/gtest.h"
+#include "flang/Frontend/CompilerInstance.h"
+#include "flang/Frontend/FrontendOptions.h"
+#include "flang/FrontendTool/Utils.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include 
+
+using namespace Fortran::frontend;
+
+namespace {
+
+TEST(PrintPreprocessedTests, TestPreprocessedOutputStreamOwned) {
+
+  // 1. Prepare the input source code
+  // Flang function 'SourceFile *Prescan' needs a physical file
+  // and the full path to work with
+  std::string inputFilename = "preprocessing-file-test.f";
+  std::error_code ec;
+  std::unique_ptr os{
+  new llvm::raw_fd_ostream(inputFilename, ec, llvm::sys::fs::OF_None)};
+  if (ec)
+llvm::errs() << "Fail to create the file need by the test";
+  *(os) << "! preprocessing-file-test.F:\n #ifdef NEW \n  Program A \n#else "
+   "\nProgram B \n #endif";
+  os.reset();
+  std::string getFileFullPath = std::filesystem::current_path().c_str();
+  getFileFullPath = getFileFullPath + "/" + inputFilename;
+
+  // 2. Set-up the output stream. Initialize buffer to be used to receive output
+  // file content
+  llvm::SmallVector outputFileBuffer;
+  std::unique_ptr outputFileStream(
+  new llvm::raw_svector_ostream(outputFileBuffer));
+
+  // 3. Prepare the compiler invocation with the preprocessing action
+  auto invocation = std::make_shared();
+  invocation->GetFrontendOpts().programAction_ = PrintPreprocessedInput;
+
+  // 4. Configure CompilerInstance and set the input file
+  CompilerInstance compInst;
+  compInst.CreateDiagnostics();
+  compInst.SetOutputStream(std::move(outputFileStream));
+  compInst.SetInvocation(std::move(invocation));
+  compInst.GetFrontendOpts().inputs_.push_back(
+  FrontendInputFile(getFileFullPath, Language::Fortran90));
+
+  // 5. Run the earlier defined FrontendAction
+  bool success = ExecuteCompilerInvocation(&compInst);
+
+  EXPECT_TRUE(success);
+  EXPECT_TRUE(!outputFileBuffer.empty());
+  EXPECT_TRUE(llvm::StringRef(outputFileBuffer.data()).startswith("program b"));
+
+  // 6. Delete output files in flight and the test file
+  llvm::sys::fs::remove(inputFilename);
+  compInst.ClearOutputFiles(/*EraseFiles=*/true);
+}
+} // namespace
Index: flang/unittests/Fron

[PATCH] D88381: [Flang][Driver]Add PrintPreprocessedInput action `-E`

2020-09-27 Thread Caroline via Phabricator via cfe-commits
CarolineConcatto updated this revision to Diff 294558.
CarolineConcatto added a comment.

Fix typos


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D88381/new/

https://reviews.llvm.org/D88381

Files:
  clang/include/clang/Driver/Options.td
  flang/include/flang/Frontend/CompilerInstance.h
  flang/include/flang/Frontend/CompilerInvocation.h
  flang/include/flang/Frontend/FrontendActions.h
  flang/include/flang/Frontend/FrontendOptions.h
  flang/lib/Frontend/CMakeLists.txt
  flang/lib/Frontend/CompilerInstance.cpp
  flang/lib/Frontend/CompilerInvocation.cpp
  flang/lib/Frontend/FrontendAction.cpp
  flang/lib/Frontend/FrontendActions.cpp
  flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
  flang/test/Flang-Driver/driver-help-hidden.f90
  flang/test/Flang-Driver/driver-help.f90
  flang/test/Frontend/Inputs/hello-world.c
  flang/test/Frontend/print-preprocess-C-file.f90
  flang/test/Frontend/print-preprocessed-file.f90
  flang/unittests/Frontend/CMakeLists.txt
  flang/unittests/Frontend/PrintPreprocessedTest.cpp

Index: flang/unittests/Frontend/PrintPreprocessedTest.cpp
===
--- /dev/null
+++ flang/unittests/Frontend/PrintPreprocessedTest.cpp
@@ -0,0 +1,69 @@
+//===- unittests/Frontend/PrintPreprocessedTest.cpp --- FrontendAction tests
+//--===//
+//
+// 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 "flang/Frontend/CompilerInstance.h"
+#include "flang/Frontend/FrontendOptions.h"
+#include "flang/FrontendTool/Utils.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+#include 
+
+using namespace Fortran::frontend;
+
+namespace {
+
+TEST(PrintPreprocessedTests, TestPreprocessedOutputStreamOwned) {
+
+  // 1. Prepare the input source code
+  // Flang function 'SourceFile *Prescan' needs a physical file
+  // and the full path to work with
+  std::string inputFilename = "preprocessing-file-test.f";
+  std::error_code ec;
+  std::unique_ptr os{
+  new llvm::raw_fd_ostream(inputFilename, ec, llvm::sys::fs::OF_None)};
+  if (ec)
+llvm::errs() << "Fail to create the file need by the test";
+  *(os) << "! preprocessing-file-test.F:\n #ifdef NEW \n  Program A \n#else "
+   "\nProgram B \n #endif";
+  os.reset();
+  std::string getFileFullPath = std::filesystem::current_path().c_str();
+  getFileFullPath = getFileFullPath + "/" + inputFilename;
+
+  // 2. Set-up the output stream. Initialize buffer to be used to receive output
+  // file content
+  llvm::SmallVector outputFileBuffer;
+  std::unique_ptr outputFileStream(
+  new llvm::raw_svector_ostream(outputFileBuffer));
+
+  // 3. Prepare the compiler invocation with the preprocessing action
+  auto invocation = std::make_shared();
+  invocation->GetFrontendOpts().programAction_ = PrintPreprocessedInput;
+
+  // 4. Configure CompilerInstance and set the input file
+  CompilerInstance compInst;
+  compInst.CreateDiagnostics();
+  compInst.SetOutputStream(std::move(outputFileStream));
+  compInst.SetInvocation(std::move(invocation));
+  compInst.GetFrontendOpts().inputs_.push_back(
+  FrontendInputFile(getFileFullPath, Language::Fortran90));
+
+  // 5. Run the earlier defined FrontendAction
+  bool success = ExecuteCompilerInvocation(&compInst);
+
+  EXPECT_TRUE(success);
+  EXPECT_TRUE(!outputFileBuffer.empty());
+  EXPECT_TRUE(llvm::StringRef(outputFileBuffer.data()).startswith("program b"));
+
+  // 6. Delete output files in flight and the test file
+  llvm::sys::fs::remove(inputFilename);
+  compInst.ClearOutputFiles(/*EraseFiles=*/true);
+}
+} // namespace
Index: flang/unittests/Frontend/CMakeLists.txt
===
--- flang/unittests/Frontend/CMakeLists.txt
+++ flang/unittests/Frontend/CMakeLists.txt
@@ -1,6 +1,7 @@
 add_flang_unittest(FlangFrontendTests
   CompilerInstanceTest.cpp
   InputOutputTest.cpp
+  PrintPreprocessedTest.cpp
 )
 
 target_link_libraries(FlangFrontendTests
Index: flang/test/Frontend/print-preprocessed-file.f90
===
--- /dev/null
+++ flang/test/Frontend/print-preprocessed-file.f90
@@ -0,0 +1,39 @@
+! Test printpreprocessed action
+
+! REQUIRES: new-flang-driver
+
+!--
+! FLANG DRIVER (flang-new)
+!--
+! RUN: %flang-new -E %s  2>&1 | FileCheck %s
+! RUN: %flang-new -E  -o - %s 2>&1 | FileCheck %s
+! RUN: %flang-new -E -o %t  %s 2>&1 && FileCheck %s --input-file=%t
+
+!-
+!   FRONTEND FLANG DRIVER (flang-new -fc1)
+!-
+! RUN: %flang-new -fc1 -E %s  2>&1 | FileCheck %s

[PATCH] D86559: [Sema, CodeGen] Allow [[likely]] and [[unlikely]] on labels

2020-09-27 Thread Mark de Wever via Phabricator via cfe-commits
Mordante added inline comments.



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:6454
 
+static bool validateLikelihoodAttr(Sema &S, Decl *D, const ParsedAttr &A) {
+  if (!isa(D)) {

aaron.ballman wrote:
> This is entering into somewhat novel territory for attributes, so some of 
> this feedback is me thinking out loud.
> 
> Attr.td lists these two attributes as being a `StmtAttr` and not any kind of 
> declaration attribute. We have `DeclOrTypeAttr` for attributes that can be 
> applied to declarations or types, but we do not have something similar for 
> statement attributes yet. We do have some custom semantic handling logic in 
> SemaDeclAttr.cpp for statement attributes, but you avoid hitting that code 
> path by adding a `case` for the two likelihood attributes. These attributes 
> only apply to label declarations currently, and labels cannot be redeclared, 
> so there aren't yet questions about whether this is inheritable or not. So we 
> *might* be okay with this, but I'm not 100% certain. For instance, I don't 
> recall if the pretty printer or AST dumpers will need to distinguish between 
> whether this attribute is written on the statement or the declaration (which 
> is itself a bit of an interesting question: should the attribute attach only 
> to the statement rather than trying to attach to the underlying decl? 
> http://eel.is/c++draft/stmt.stmt#stmt.label-1.sentence-2 is ambiguous, but I 
> don't think of `case` or `default` labels as being declarations so I tend to 
> not think of identifier labels as such either.). There's a part of me that 
> wonders if we have a different issue where the attribute is trying to attach 
> to the declaration rather than the statement and that this should be handled 
> purely as a statement attribute.
> 
> I'm curious what your thoughts are, but I'd also like to see some additional 
> tests for the random other bits that interact with attributes like AST 
> dumping and pretty printing to be sure the behavior is reasonable.
The labels in a switch are indeed different and the code in trunk already 
should allow the attribute there. (I'm still busy with the CodeGen patch.)
I agree that Standard isn't clear whether the attribute is attached to the 
statement or the declaration.

The `LabelDecl` expects a pointer to a `LabelStmt` and not to an 
`AttributedStmt`. Since declarations can already have attributes I used that 
feature. I just checked and the `LabelDecl` isn't shown in the AST and so the 
attributes also aren't shown. I can adjust that.

Another option would be to change the `LabelDecl` and have two overloads of 
`setStmt`
`void setStmt(LabelStmt *T) { TheStmt = T; }`
`void setStmt(AttributedStmt *T) { TheStmt = T; }`
Then `TheStmt` needs to be a `Stmt` and an extra getter would be required to 
get the generic statement.

I think both solutions aren't trivial changes. Currently the attribute has no 
effect on labels so it not being visible isn't a real issue. However I feel 
that's not a proper solution. I expect attributes will be used more in C and 
C++ in the future. For example, I can imagine a `[[cold]]` attribute becoming 
available for labels.

So I'm leaning towards biting the bullet and change the implementation of 
`LabelDecl` to allow an `AttributedStmt` instead of a `LabelStmt`.
WDYT?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86559/new/

https://reviews.llvm.org/D86559

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


[PATCH] D88383: [clangd] Add a tweak for filling in enumerators of a switch statement.

2020-09-27 Thread Tadeo Kondrak via Phabricator via cfe-commits
tdeo created this revision.
tdeo added a reviewer: sammccall.
tdeo added a project: clang-tools-extra.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, mgorny.
Herald added a project: clang.
tdeo requested review of this revision.
Herald added subscribers: MaskRay, ilya-biryukov.

Add a tweak that populates an empty switch statement of an enumeration type 
with all of the enumerators of that type.

Before:

  enum Color { RED, GREEN, BLUE };
  void f(Color color) {
switch (color) {}
  }

After:

  enum Color { RED, GREEN, BLUE };
  void f(Color color) {
switch (color) {
case RED:
case GREEN:
case BLUE:
  break;
}
  }


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D88383

Files:
  clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt
  clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp

Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -2802,6 +2802,96 @@
   }
 }
 
+TWEAK_TEST(PopulateSwitch);
+TEST_F(PopulateSwitchTest, Test) {
+  struct Case {
+CodeContext Context;
+llvm::StringRef TestSource;
+llvm::StringRef ExpectedSource;
+  };
+
+  Case Cases[]{
+  {
+  // No enumerators
+  Function,
+  R""(enum Enum {}; ^switch ((Enum)0) {})"",
+  "unavailable",
+  },
+  {
+  // Existing enumerators in switch
+  Function,
+  R""(enum Enum {A}; ^switch ((Enum)0) {case A:break;})"",
+  "unavailable",
+  },
+  {
+  // Body not CompoundStmt
+  Function,
+  R""(enum Enum {A}; ^switch (A);)"",
+  "unavailable",
+  },
+  {
+  // Selection on switch token
+  Function,
+  R""(enum Enum {A}; ^switch (A) {})"",
+  R""(enum Enum {A}; switch (A) {case A:break;})"",
+  },
+  {
+  // Selection on switch condition
+  Function,
+  R""(enum Enum {A}; switch (^A) {})"",
+  R""(enum Enum {A}; switch (A) {case A:break;})"",
+  },
+  {
+  // Selection in switch body
+  Function,
+  R""(enum Enum {A}; switch (A) {^})"",
+  R""(enum Enum {A}; switch (A) {case A:break;})"",
+  },
+  {
+  // Scoped enumeration
+  Function,
+  R""(enum class Enum {A}; ^switch (Enum::A) {})"",
+  R""(enum class Enum {A}; switch (Enum::A) {case Enum::A:break;})"",
+  },
+  {
+  // Scoped enumeration with multiple enumerators
+  Function,
+  R""(enum class Enum {A,B}; ^switch (Enum::A) {})"",
+  R""(enum class Enum {A,B}; )""
+  R""(switch (Enum::A) {case Enum::A:case Enum::B:break;})"",
+  },
+  {
+  // Scoped enumerations in namespace
+  File,
+  R""(
+namespace ns { enum class Enum {A}; }
+void function() { ^switch (ns::Enum::A) {} }
+  )"",
+  R""(
+namespace ns { enum class Enum {A}; }
+void function() { switch (ns::Enum::A) {case ns::Enum::A:break;} }
+  )"",
+  },
+  {
+  // Unscoped enumerations in namespace
+  File,
+  R""(
+namespace ns { enum Enum {A}; }
+void function() { ^switch (ns::A) {} }
+  )"",
+  R""(
+namespace ns { enum Enum {A}; }
+void function() { switch (ns::A) {case ns::A:break;} }
+  )"",
+  },
+  };
+
+  for (const auto &Case : Cases) {
+Context = Case.Context;
+EXPECT_EQ(apply(Case.TestSource), Case.ExpectedSource);
+  }
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp
===
--- /dev/null
+++ clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp
@@ -0,0 +1,145 @@
+//===--- PopulateSwitch.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
+//
+//===--===//
+//
+// Tweak that populates an empty switch statement of an enumeration type with
+// all of the enumerators of that type.
+//
+// Before:
+//   enum Color { RED, GREEN, BLUE };
+//
+//   void f(Color color) {
+// switch (color) {}
+//   }
+//
+// After:
+//   enum Color { RED, GREEN, BLUE };
+//
+//   void f(Color color) {
+// switch (color) {
+// case RED:
+// case GREEN:
+// case BLUE:
+//   break;
+// }
+//   }
+//
+//===

[PATCH] D88359: [analyzer][RFC] Complete rewrite of ArrayBoundCheckerV2

2020-09-27 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added a comment.

So, `ArrayBoundCheckerV3` then?

We already have a similar simplification facility in `SValBuilder` created to 
solve the similar problem with iterator checkers. It fires up when it knows 
that the values it works with are limited to roughly 1/4 of their type's range 
and therefore none of the individual operations over them can potentially 
overflow (cf. D35109 ). It's currently off by 
default because performance was not properly evaluated and none of the 
on-by-default checkers rely on it. This is currently the intended approach to 
such issues. It was decided that constructing a custom solver for 
"non-overflowing but still bounded" arithmetic was not the right thing to do, 
mostly because it absolutely doesn't correspond to the actual run-time behavior 
of the program that we're supposed to be modeling.

Separately, I'd like to once again bring up that the problem you're solving 
with this patch is relatively minor compared to bigger problems with this 
checker. One bigger problem is that this checker amplifies our lack of loop 
widening (i highly doubt that the existing alpha loop widening feature solves 
any of these, though i didn't try; it has to be really good loop widening in 
order to be effective). The checker has massive false positives because of just 
that. Like, it only deals with small concrete values, not much solving, but 
even then it's all wrong, just because the loop isn't executed the right number 
of times.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D88359/new/

https://reviews.llvm.org/D88359

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


[PATCH] D88384: [OpenMP][FIX] Verify compatible types for declare variant calls

2020-09-27 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert created this revision.
jdoerfert added reviewers: JonChesterfield, jhuber6, ABataev, aaron.ballman, 
ye-luo.
Herald added subscribers: guansong, bollu, yaxunl.
Herald added a project: clang.
jdoerfert requested review of this revision.
Herald added a subscriber: sstefan1.

Especially for templates we need to check at some point if the base
function matches the specialization we might call instead. Before this
lead to the replacement of `std::sqrt(int(2))` calls with one that
converts the argument to a `std::complex`, clearly not the desired
behavior.

Reported as PR47655


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D88384

Files:
  clang/lib/Sema/SemaOpenMP.cpp
  clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp

Index: clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp
===
--- /dev/null
+++ clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp
@@ -0,0 +1,241 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s
+// expected-no-diagnostics
+// PR47655
+
+template  struct S {
+  S(int) {}
+};
+
+template 
+int also_before(T s) {
+  return 0;
+}
+
+#pragma omp begin declare variant match(implementation = {extension(allow_templates)})
+template 
+int also_before(S s) {
+  return 1;
+}
+template 
+int special(S s) {
+  return 0;
+}
+template 
+int also_after(S s) {
+  return 2;
+}
+#pragma omp end declare variant
+
+template 
+int also_after(T s) {
+  return 0;
+}
+
+int test() {
+  // Should return 0.
+  return also_before(0) + also_after(0) + also_before(0.) + also_after(0.) + special(S(0));
+}
+
+// CHECK:  |-ClassTemplateDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:30 S
+// CHECK-NEXT: | |-TemplateTypeParmDecl [[ADDR_1:0x[a-z0-9]*]]  col:20 typename depth 0 index 0 T
+// CHECK-NEXT: | |-CXXRecordDecl [[ADDR_2:0x[a-z0-9]*]]  line:5:30 struct S definition
+// CHECK-NEXT: | | |-DefinitionData empty standard_layout trivially_copyable has_user_declared_ctor can_const_default_init
+// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
+// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
+// CHECK-NEXT: | | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | | | |-MoveAssignment exists simple trivial needs_implicit
+// CHECK-NEXT: | | | `-Destructor simple irrelevant trivial needs_implicit
+// CHECK-NEXT: | | |-CXXRecordDecl [[ADDR_3:0x[a-z0-9]*]]  col:30 implicit referenced struct S
+// CHECK-NEXT: | | `-CXXConstructorDecl [[ADDR_4:0x[a-z0-9]*]]  col:3 S 'void (int)'
+// CHECK-NEXT: | |   |-ParmVarDecl [[ADDR_5:0x[a-z0-9]*]]  col:8 'int'
+// CHECK-NEXT: | |   `-CompoundStmt [[ADDR_6:0x[a-z0-9]*]] 
+// CHECK-NEXT: | |-ClassTemplateSpecializationDecl [[ADDR_7:0x[a-z0-9]*]]  line:5:30 struct S definition
+// CHECK-NEXT: | | |-DefinitionData pass_in_registers empty standard_layout trivially_copyable has_user_declared_ctor can_const_default_init
+// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
+// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param implicit_has_const_param
+// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial
+// CHECK-NEXT: | | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | | | |-MoveAssignment exists simple trivial needs_implicit
+// CHECK-NEXT: | | | `-Destructor simple irrelevant trivial
+// CHECK-NEXT: | | |-TemplateArgument type 'int'
+// CHECK-NEXT: | | | `-BuiltinType [[ADDR_8:0x[a-z0-9]*]] 'int'
+// CHECK-NEXT: | | |-CXXRecordDecl [[ADDR_9:0x[a-z0-9]*]] prev [[ADDR_7]]  col:30 implicit struct S
+// CHECK-NEXT: | | |-CXXConstructorDecl [[ADDR_10:0x[a-z0-9]*]]  col:3 used S 'void (int)'
+// CHECK-NEXT: | | | |-ParmVarDecl [[ADDR_11:0x[a-z0-9]*]]  col:8 'int'
+// CHECK-NEXT: | | | `-CompoundStmt [[ADDR_6]] 
+// CHECK-NEXT: | | |-CXXConstructorDecl [[ADDR_12:0x[a-z0-9]*]]  col:30 implicit constexpr S 'void (const S &)' inline default trivial noexcept-unevaluated [[ADDR_12]]
+// CHECK-NEXT: | | | `-ParmVarDecl [[ADDR_13:0x[a-z0-9]*]]  col:30 'const S &'
+// CHECK-NEXT: | | |-CXXConstructorDecl [[ADDR_14:0x[a-z0-9]*]]  col:30 implicit used constexpr S 'void (S &&) noexcept' inline default trivial
+// CHECK-NEXT: | | | |-ParmVarDecl [[ADDR_15:0x[a-z0-9]*]]  col:30 'S &&'
+// CHECK-NEXT: | | | `-CompoundStmt [[ADDR_16:0x[a-z0-9]*]] 
+// CHECK-NEXT: | | `-CXXDestructorDecl [[ADDR_17:0x[a-z0-9]*]]  col:30 implicit referenced ~S 'void ({{.*}}) noexcept' inline default trivial
+// CHECK-NEXT: | `-ClassTemplateSpecializationDecl [[ADDR_18:0x[a-z0-9]*]]  line:5:30 struct S definition
+// CHECK-NEXT: |   |-DefinitionData pass_in_registers empty standard_layout trivially_copyable has_user_declared_ctor can

[PATCH] D88384: [OpenMP][FIX] Verify compatible types for declare variant calls

2020-09-27 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert updated this revision to Diff 294567.
jdoerfert added a comment.

Remove lefotver dump


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D88384/new/

https://reviews.llvm.org/D88384

Files:
  clang/lib/Sema/SemaOpenMP.cpp
  clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp

Index: clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp
===
--- /dev/null
+++ clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp
@@ -0,0 +1,241 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s
+// expected-no-diagnostics
+// PR47655
+
+template  struct S {
+  S(int) {}
+};
+
+template 
+int also_before(T s) {
+  return 0;
+}
+
+#pragma omp begin declare variant match(implementation = {extension(allow_templates)})
+template 
+int also_before(S s) {
+  return 1;
+}
+template 
+int special(S s) {
+  return 0;
+}
+template 
+int also_after(S s) {
+  return 2;
+}
+#pragma omp end declare variant
+
+template 
+int also_after(T s) {
+  return 0;
+}
+
+int test() {
+  // Should return 0.
+  return also_before(0) + also_after(0) + also_before(0.) + also_after(0.) + special(S(0));
+}
+
+// CHECK:  |-ClassTemplateDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:30 S
+// CHECK-NEXT: | |-TemplateTypeParmDecl [[ADDR_1:0x[a-z0-9]*]]  col:20 typename depth 0 index 0 T
+// CHECK-NEXT: | |-CXXRecordDecl [[ADDR_2:0x[a-z0-9]*]]  line:5:30 struct S definition
+// CHECK-NEXT: | | |-DefinitionData empty standard_layout trivially_copyable has_user_declared_ctor can_const_default_init
+// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
+// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
+// CHECK-NEXT: | | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | | | |-MoveAssignment exists simple trivial needs_implicit
+// CHECK-NEXT: | | | `-Destructor simple irrelevant trivial needs_implicit
+// CHECK-NEXT: | | |-CXXRecordDecl [[ADDR_3:0x[a-z0-9]*]]  col:30 implicit referenced struct S
+// CHECK-NEXT: | | `-CXXConstructorDecl [[ADDR_4:0x[a-z0-9]*]]  col:3 S 'void (int)'
+// CHECK-NEXT: | |   |-ParmVarDecl [[ADDR_5:0x[a-z0-9]*]]  col:8 'int'
+// CHECK-NEXT: | |   `-CompoundStmt [[ADDR_6:0x[a-z0-9]*]] 
+// CHECK-NEXT: | |-ClassTemplateSpecializationDecl [[ADDR_7:0x[a-z0-9]*]]  line:5:30 struct S definition
+// CHECK-NEXT: | | |-DefinitionData pass_in_registers empty standard_layout trivially_copyable has_user_declared_ctor can_const_default_init
+// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
+// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param implicit_has_const_param
+// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial
+// CHECK-NEXT: | | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | | | |-MoveAssignment exists simple trivial needs_implicit
+// CHECK-NEXT: | | | `-Destructor simple irrelevant trivial
+// CHECK-NEXT: | | |-TemplateArgument type 'int'
+// CHECK-NEXT: | | | `-BuiltinType [[ADDR_8:0x[a-z0-9]*]] 'int'
+// CHECK-NEXT: | | |-CXXRecordDecl [[ADDR_9:0x[a-z0-9]*]] prev [[ADDR_7]]  col:30 implicit struct S
+// CHECK-NEXT: | | |-CXXConstructorDecl [[ADDR_10:0x[a-z0-9]*]]  col:3 used S 'void (int)'
+// CHECK-NEXT: | | | |-ParmVarDecl [[ADDR_11:0x[a-z0-9]*]]  col:8 'int'
+// CHECK-NEXT: | | | `-CompoundStmt [[ADDR_6]] 
+// CHECK-NEXT: | | |-CXXConstructorDecl [[ADDR_12:0x[a-z0-9]*]]  col:30 implicit constexpr S 'void (const S &)' inline default trivial noexcept-unevaluated [[ADDR_12]]
+// CHECK-NEXT: | | | `-ParmVarDecl [[ADDR_13:0x[a-z0-9]*]]  col:30 'const S &'
+// CHECK-NEXT: | | |-CXXConstructorDecl [[ADDR_14:0x[a-z0-9]*]]  col:30 implicit used constexpr S 'void (S &&) noexcept' inline default trivial
+// CHECK-NEXT: | | | |-ParmVarDecl [[ADDR_15:0x[a-z0-9]*]]  col:30 'S &&'
+// CHECK-NEXT: | | | `-CompoundStmt [[ADDR_16:0x[a-z0-9]*]] 
+// CHECK-NEXT: | | `-CXXDestructorDecl [[ADDR_17:0x[a-z0-9]*]]  col:30 implicit referenced ~S 'void ({{.*}}) noexcept' inline default trivial
+// CHECK-NEXT: | `-ClassTemplateSpecializationDecl [[ADDR_18:0x[a-z0-9]*]]  line:5:30 struct S definition
+// CHECK-NEXT: |   |-DefinitionData pass_in_registers empty standard_layout trivially_copyable has_user_declared_ctor can_const_default_init
+// CHECK-NEXT: |   | |-DefaultConstructor defaulted_is_constexpr
+// CHECK-NEXT: |   | |-CopyConstructor simple trivial has_const_param implicit_has_const_param
+// CHECK-NEXT: |   | |-MoveConstructor exists simple trivial
+// CHECK-NEXT: |   | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: |   | |-MoveAssignment exists simple trivial needs_impl

[PATCH] D86841: [clang] Add mustprogress and llvm.loop.mustprogress attribute deduction

2020-09-27 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel updated this revision to Diff 294569.
atmnpatel added a comment.

Split them into pre and post forward progress requirement tests, now the 
difference is much easier to catch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86841/new/

https://reviews.llvm.org/D86841

Files:
  clang/lib/CodeGen/CGLoopInfo.cpp
  clang/lib/CodeGen/CGLoopInfo.h
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/test/CodeGen/address-safety-attr-flavors.cpp
  clang/test/CodeGen/address-safety-attr.cpp
  clang/test/CodeGen/attr-mustprogress-0.c
  clang/test/CodeGen/attr-mustprogress-0.cpp
  clang/test/CodeGen/attr-mustprogress-1.c
  clang/test/CodeGen/attr-mustprogress-1.cpp
  clang/test/CodeGen/memtag-attr.cpp
  clang/test/CodeGen/no-builtin.cpp
  clang/test/CodeGenCXX/cxx11-trivial-initializer-struct.cpp
  clang/test/CodeGenCXX/fno-unroll-loops-metadata.cpp
  clang/test/CodeGenCXX/thunks-ehspec.cpp
  clang/test/CodeGenCXX/thunks.cpp
  clang/test/OpenMP/simd_metadata.c
  clang/test/Profile/c-unprofiled-blocks.c
  clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
  
clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected

Index: clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected
===
--- clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected
+++ clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected
@@ -11,7 +11,7 @@
   struct RT Z;
 };
 
-// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK: Function Attrs: noinline nounwind optnone mustprogress
 // CHECK-LABEL: @_Z3fooP2ST(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:[[S_ADDR:%.*]] = alloca %struct.ST*, align 8
Index: clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
===
--- clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
+++ clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
@@ -44,7 +44,7 @@
 // CHECK-NEXT:[[THIS_ADDR:%.*]] = alloca %class.Foo*, align 8
 // CHECK-NEXT:store %class.Foo* [[THIS:%.*]], %class.Foo** [[THIS_ADDR]], align 8
 // CHECK-NEXT:[[THIS1:%.*]] = load %class.Foo*, %class.Foo** [[THIS_ADDR]], align 8
-// CHECK-NEXT:call void @_ZN3FooD2Ev(%class.Foo* [[THIS1]]) [[ATTR2:#.*]]
+// CHECK-NEXT:call void @_ZN3FooD2Ev(%class.Foo* [[THIS1]]) [[ATTR3:#.*]]
 // CHECK-NEXT:ret void
 //
 Foo::~Foo() {}
@@ -70,7 +70,7 @@
 // CHECK-NEXT:call void @_ZN3FooC1Ei(%class.Foo* [[F]], i32 1)
 // CHECK-NEXT:[[CALL:%.*]] = call i32 @_ZNK3Foo23function_defined_inlineEi(%class.Foo* [[F]], i32 2)
 // CHECK-NEXT:[[CALL1:%.*]] = call i32 @_ZNK3Foo28function_defined_out_of_lineEi(%class.Foo* [[F]], i32 3)
-// CHECK-NEXT:call void @_ZN3FooD1Ev(%class.Foo* [[F]]) [[ATTR2]]
+// CHECK-NEXT:call void @_ZN3FooD1Ev(%class.Foo* [[F]]) [[ATTR3]]
 // CHECK-NEXT:ret i32 0
 //
 int main() {
Index: clang/test/Profile/c-unprofiled-blocks.c
===
--- clang/test/Profile/c-unprofiled-blocks.c
+++ clang/test/Profile/c-unprofiled-blocks.c
@@ -16,7 +16,7 @@
   // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
   while (--i) {}
 
-  // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+  // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}, !llvm.loop [[LOOP1:!.*]]
   do {} while (i++ < 75);
 
   // PGOUSE: switch {{.*}} [
@@ -46,7 +46,7 @@
 // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
 while (--i) {}
 
-// PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+// PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}, !llvm.loop [[LOOP2:!.*]]
 do {} while (i++ < 75);
 
 // PGOUSE: switch {{.*}} [
Index: clang/test/OpenMP/simd_metadata.c
===
--- clang/test/OpenMP/simd_metadata.c
+++ clang/test/OpenMP/simd_metadata.c
@@ -137,7 +137,8 @@
 }
 // CHECK: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.access.group ![[ACCESS_GROUP_13:[0-9]+]]
   }
-// CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER:![0-9]+]]
+  // CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER_INNER:![0-9]+]]
+  // CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER:![0-9]+]]
 }
 
 // Metadata for h1:
Index: clang/test/CodeGenCXX/thunks.cpp
===
--- clang/test/CodeGenCXX/thunks.cpp
+++ clang/test/CodeGenCXX/thunks.cpp
@@ -529,7 +529,7 @@
 // CHECK-NONOPT-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv
 
 // Checking with opt
-// CHECK-OPT-LABEL: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(%"struct.Test4B::(anonymous na

[PATCH] D86841: [clang] Add mustprogress and llvm.loop.mustprogress attribute deduction

2020-09-27 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel added inline comments.



Comment at: clang/test/CodeGen/attr-mustprogress-0.cpp:2
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --check-attributes
+// RUN: %clang_cc1 -S -emit-llvm %s -o - | FileCheck %s
+

changing this asap.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86841/new/

https://reviews.llvm.org/D86841

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


[PATCH] D86841: [clang] Add mustprogress and llvm.loop.mustprogress attribute deduction

2020-09-27 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel updated this revision to Diff 294570.
atmnpatel added a comment.

All language standards (minus gnu extensions) are now tested.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86841/new/

https://reviews.llvm.org/D86841

Files:
  clang/lib/CodeGen/CGLoopInfo.cpp
  clang/lib/CodeGen/CGLoopInfo.h
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/test/CodeGen/address-safety-attr-flavors.cpp
  clang/test/CodeGen/address-safety-attr.cpp
  clang/test/CodeGen/attr-mustprogress-0.c
  clang/test/CodeGen/attr-mustprogress-0.cpp
  clang/test/CodeGen/attr-mustprogress-1.c
  clang/test/CodeGen/attr-mustprogress-1.cpp
  clang/test/CodeGen/memtag-attr.cpp
  clang/test/CodeGen/no-builtin.cpp
  clang/test/CodeGenCXX/cxx11-trivial-initializer-struct.cpp
  clang/test/CodeGenCXX/fno-unroll-loops-metadata.cpp
  clang/test/CodeGenCXX/thunks-ehspec.cpp
  clang/test/CodeGenCXX/thunks.cpp
  clang/test/OpenMP/simd_metadata.c
  clang/test/Profile/c-unprofiled-blocks.c
  clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
  
clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected

Index: clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected
===
--- clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected
+++ clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected
@@ -11,7 +11,7 @@
   struct RT Z;
 };
 
-// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK: Function Attrs: noinline nounwind optnone mustprogress
 // CHECK-LABEL: @_Z3fooP2ST(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:[[S_ADDR:%.*]] = alloca %struct.ST*, align 8
Index: clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
===
--- clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
+++ clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
@@ -44,7 +44,7 @@
 // CHECK-NEXT:[[THIS_ADDR:%.*]] = alloca %class.Foo*, align 8
 // CHECK-NEXT:store %class.Foo* [[THIS:%.*]], %class.Foo** [[THIS_ADDR]], align 8
 // CHECK-NEXT:[[THIS1:%.*]] = load %class.Foo*, %class.Foo** [[THIS_ADDR]], align 8
-// CHECK-NEXT:call void @_ZN3FooD2Ev(%class.Foo* [[THIS1]]) [[ATTR2:#.*]]
+// CHECK-NEXT:call void @_ZN3FooD2Ev(%class.Foo* [[THIS1]]) [[ATTR3:#.*]]
 // CHECK-NEXT:ret void
 //
 Foo::~Foo() {}
@@ -70,7 +70,7 @@
 // CHECK-NEXT:call void @_ZN3FooC1Ei(%class.Foo* [[F]], i32 1)
 // CHECK-NEXT:[[CALL:%.*]] = call i32 @_ZNK3Foo23function_defined_inlineEi(%class.Foo* [[F]], i32 2)
 // CHECK-NEXT:[[CALL1:%.*]] = call i32 @_ZNK3Foo28function_defined_out_of_lineEi(%class.Foo* [[F]], i32 3)
-// CHECK-NEXT:call void @_ZN3FooD1Ev(%class.Foo* [[F]]) [[ATTR2]]
+// CHECK-NEXT:call void @_ZN3FooD1Ev(%class.Foo* [[F]]) [[ATTR3]]
 // CHECK-NEXT:ret i32 0
 //
 int main() {
Index: clang/test/Profile/c-unprofiled-blocks.c
===
--- clang/test/Profile/c-unprofiled-blocks.c
+++ clang/test/Profile/c-unprofiled-blocks.c
@@ -16,7 +16,7 @@
   // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
   while (--i) {}
 
-  // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+  // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}, !llvm.loop [[LOOP1:!.*]]
   do {} while (i++ < 75);
 
   // PGOUSE: switch {{.*}} [
@@ -46,7 +46,7 @@
 // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
 while (--i) {}
 
-// PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+// PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}, !llvm.loop [[LOOP2:!.*]]
 do {} while (i++ < 75);
 
 // PGOUSE: switch {{.*}} [
Index: clang/test/OpenMP/simd_metadata.c
===
--- clang/test/OpenMP/simd_metadata.c
+++ clang/test/OpenMP/simd_metadata.c
@@ -110,7 +110,8 @@
 }
 // CHECK: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.access.group ![[ACCESS_GROUP_13:[0-9]+]]
   }
-// CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER:![0-9]+]]
+  // CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER_INNER:![0-9]+]]
+  // CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER:![0-9]+]]
 }
 
 // Metadata for h1:
Index: clang/test/CodeGenCXX/thunks.cpp
===
--- clang/test/CodeGenCXX/thunks.cpp
+++ clang/test/CodeGenCXX/thunks.cpp
@@ -529,7 +529,7 @@
 // CHECK-NONOPT-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv
 
 // Checking with opt
-// CHECK-OPT-LABEL: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(%"struct.Test4B::(anonymous namespace)::C"* %this) unnamed_addr #0 align 2
+//

[PATCH] D86841: [clang] Add mustprogress and llvm.loop.mustprogress attribute deduction

2020-09-27 Thread Atmn Patel via Phabricator via cfe-commits
atmnpatel updated this revision to Diff 294575.
atmnpatel added a comment.

rebase to hopefully fix buildbot


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86841/new/

https://reviews.llvm.org/D86841

Files:
  clang/lib/CodeGen/CGLoopInfo.cpp
  clang/lib/CodeGen/CGLoopInfo.h
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/test/CodeGen/address-safety-attr-flavors.cpp
  clang/test/CodeGen/address-safety-attr.cpp
  clang/test/CodeGen/attr-mustprogress-0.c
  clang/test/CodeGen/attr-mustprogress-0.cpp
  clang/test/CodeGen/attr-mustprogress-1.c
  clang/test/CodeGen/attr-mustprogress-1.cpp
  clang/test/CodeGen/memtag-attr.cpp
  clang/test/CodeGen/no-builtin.cpp
  clang/test/CodeGenCXX/cxx11-trivial-initializer-struct.cpp
  clang/test/CodeGenCXX/fno-unroll-loops-metadata.cpp
  clang/test/CodeGenCXX/thunks-ehspec.cpp
  clang/test/CodeGenCXX/thunks.cpp
  clang/test/OpenMP/simd_metadata.c
  clang/test/Profile/c-unprofiled-blocks.c
  clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
  
clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected

Index: clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected
===
--- clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected
+++ clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected
@@ -11,7 +11,7 @@
   struct RT Z;
 };
 
-// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK: Function Attrs: noinline nounwind optnone mustprogress
 // CHECK-LABEL: @_Z3fooP2ST(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:[[S_ADDR:%.*]] = alloca %struct.ST*, align 8
Index: clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
===
--- clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
+++ clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
@@ -44,7 +44,7 @@
 // CHECK-NEXT:[[THIS_ADDR:%.*]] = alloca %class.Foo*, align 8
 // CHECK-NEXT:store %class.Foo* [[THIS:%.*]], %class.Foo** [[THIS_ADDR]], align 8
 // CHECK-NEXT:[[THIS1:%.*]] = load %class.Foo*, %class.Foo** [[THIS_ADDR]], align 8
-// CHECK-NEXT:call void @_ZN3FooD2Ev(%class.Foo* [[THIS1]]) [[ATTR2:#.*]]
+// CHECK-NEXT:call void @_ZN3FooD2Ev(%class.Foo* [[THIS1]]) [[ATTR3:#.*]]
 // CHECK-NEXT:ret void
 //
 Foo::~Foo() {}
@@ -70,7 +70,7 @@
 // CHECK-NEXT:call void @_ZN3FooC1Ei(%class.Foo* [[F]], i32 1)
 // CHECK-NEXT:[[CALL:%.*]] = call i32 @_ZNK3Foo23function_defined_inlineEi(%class.Foo* [[F]], i32 2)
 // CHECK-NEXT:[[CALL1:%.*]] = call i32 @_ZNK3Foo28function_defined_out_of_lineEi(%class.Foo* [[F]], i32 3)
-// CHECK-NEXT:call void @_ZN3FooD1Ev(%class.Foo* [[F]]) [[ATTR2]]
+// CHECK-NEXT:call void @_ZN3FooD1Ev(%class.Foo* [[F]]) [[ATTR3]]
 // CHECK-NEXT:ret i32 0
 //
 int main() {
Index: clang/test/Profile/c-unprofiled-blocks.c
===
--- clang/test/Profile/c-unprofiled-blocks.c
+++ clang/test/Profile/c-unprofiled-blocks.c
@@ -16,7 +16,7 @@
   // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
   while (--i) {}
 
-  // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+  // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}, !llvm.loop [[LOOP1:!.*]]
   do {} while (i++ < 75);
 
   // PGOUSE: switch {{.*}} [
@@ -46,7 +46,7 @@
 // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
 while (--i) {}
 
-// PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+// PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}, !llvm.loop [[LOOP2:!.*]]
 do {} while (i++ < 75);
 
 // PGOUSE: switch {{.*}} [
Index: clang/test/OpenMP/simd_metadata.c
===
--- clang/test/OpenMP/simd_metadata.c
+++ clang/test/OpenMP/simd_metadata.c
@@ -110,7 +110,8 @@
 }
 // CHECK: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.access.group ![[ACCESS_GROUP_13:[0-9]+]]
   }
-// CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER:![0-9]+]]
+  // CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER_INNER:![0-9]+]]
+  // CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER:![0-9]+]]
 }
 
 // Metadata for h1:
Index: clang/test/CodeGenCXX/thunks.cpp
===
--- clang/test/CodeGenCXX/thunks.cpp
+++ clang/test/CodeGenCXX/thunks.cpp
@@ -529,7 +529,7 @@
 // CHECK-NONOPT-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv
 
 // Checking with opt
-// CHECK-OPT-LABEL: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(%"struct.Test4B::(anonymous namespace)::C"* %this) unnamed_addr #0 align 2
+// CHECK-OPT-LABEL: define inte

[PATCH] D87256: [clangd] Avoid relations being overwritten in a header shard

2020-09-27 Thread Nathan Ridge via Phabricator via cfe-commits
nridge updated this revision to Diff 294577.
nridge marked 5 inline comments as done.
nridge added a comment.

Address review comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87256/new/

https://reviews.llvm.org/D87256

Files:
  clang-tools-extra/clangd/index/FileIndex.cpp
  clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp
  clang-tools-extra/clangd/unittests/FileIndexTests.cpp

Index: clang-tools-extra/clangd/unittests/FileIndexTests.cpp
===
--- clang-tools-extra/clangd/unittests/FileIndexTests.cpp
+++ clang-tools-extra/clangd/unittests/FileIndexTests.cpp
@@ -547,6 +547,8 @@
   Sym2.CanonicalDeclaration.FileURI = BHeaderUri.c_str();
   Sym2.Definition.FileURI = BSourceUri.c_str();
 
+  auto Sym3 = symbol("3"); // not stored
+
   IndexFileIn IF;
   {
 SymbolSlab::Builder B;
@@ -562,12 +564,13 @@
   }
   {
 RelationSlab::Builder B;
-// Should be stored in a.h
+// Should be stored in a.h and b.h
 B.insert(Relation{Sym1.ID, RelationKind::BaseOf, Sym2.ID});
-// Should be stored in b.h
+// Should be stored in a.h and b.h
 B.insert(Relation{Sym2.ID, RelationKind::BaseOf, Sym1.ID});
-// Dangling relation should be dropped.
-B.insert(Relation{symbol("3").ID, RelationKind::BaseOf, Sym1.ID});
+// Should be stored in a.h (where Sym1 is stored) even though
+// the relation is dangling as Sym3 is unknown.
+B.insert(Relation{Sym3.ID, RelationKind::BaseOf, Sym1.ID});
 IF.Relations.emplace(std::move(B).build());
   }
 
@@ -605,7 +608,9 @@
 EXPECT_THAT(*Shard->Refs, IsEmpty());
 EXPECT_THAT(
 *Shard->Relations,
-UnorderedElementsAre(Relation{Sym1.ID, RelationKind::BaseOf, Sym2.ID}));
+UnorderedElementsAre(Relation{Sym1.ID, RelationKind::BaseOf, Sym2.ID},
+ Relation{Sym2.ID, RelationKind::BaseOf, Sym1.ID},
+ Relation{Sym3.ID, RelationKind::BaseOf, Sym1.ID}));
 ASSERT_THAT(Shard->Sources->keys(), UnorderedElementsAre(AHeaderUri));
 EXPECT_THAT(Shard->Sources->lookup(AHeaderUri).DirectIncludes, IsEmpty());
 EXPECT_TRUE(Shard->Cmd.hasValue());
@@ -617,7 +622,8 @@
 EXPECT_THAT(*Shard->Refs, IsEmpty());
 EXPECT_THAT(
 *Shard->Relations,
-UnorderedElementsAre(Relation{Sym2.ID, RelationKind::BaseOf, Sym1.ID}));
+UnorderedElementsAre(Relation{Sym1.ID, RelationKind::BaseOf, Sym2.ID},
+ Relation{Sym2.ID, RelationKind::BaseOf, Sym1.ID}));
 ASSERT_THAT(Shard->Sources->keys(),
 UnorderedElementsAre(BHeaderUri, AHeaderUri));
 EXPECT_THAT(Shard->Sources->lookup(BHeaderUri).DirectIncludes,
Index: clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp
===
--- clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp
+++ clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp
@@ -229,6 +229,49 @@
FileURI("unittest:///root/B.cc")}));
 }
 
+TEST_F(BackgroundIndexTest, RelationsMultiFile) {
+  MockFS FS;
+  FS.Files[testPath("root/RAV.h")] = "template  class RAV {};";
+  FS.Files[testPath("root/A.cc")] = R"cpp(
+#include "RAV.h"
+class A : public RAV {};
+  )cpp";
+  FS.Files[testPath("root/B.cc")] = R"cpp(
+#include "RAV.h"
+class B : public RAV {};
+  )cpp";
+
+  llvm::StringMap Storage;
+  size_t CacheHits = 0;
+  MemoryShardStorage MSS(Storage, CacheHits);
+  OverlayCDB CDB(/*Base=*/nullptr);
+  BackgroundIndex Index(FS, CDB, [&](llvm::StringRef) { return &MSS; },
+/*Opts=*/{});
+
+  tooling::CompileCommand Cmd;
+  Cmd.Filename = testPath("root/A.cc");
+  Cmd.Directory = testPath("root");
+  Cmd.CommandLine = {"clang++", Cmd.Filename};
+  CDB.setCompileCommand(testPath("root/A.cc"), Cmd);
+  ASSERT_TRUE(Index.blockUntilIdleForTest());
+
+  Cmd.Filename = testPath("root/B.cc");
+  Cmd.CommandLine = {"clang++", Cmd.Filename};
+  CDB.setCompileCommand(testPath("root/B.cc"), Cmd);
+  ASSERT_TRUE(Index.blockUntilIdleForTest());
+
+  auto HeaderShard = MSS.loadShard(testPath("root/RAV.h"));
+  EXPECT_NE(HeaderShard, nullptr);
+  SymbolID RAV = findSymbol(*HeaderShard->Symbols, "RAV").ID;
+
+  RelationsRequest Req;
+  Req.Subjects.insert(RAV);
+  Req.Predicate = RelationKind::BaseOf;
+  uint32_t Results = 0;
+  Index.relations(Req, [&](const SymbolID &, const Symbol &) { ++Results; });
+  EXPECT_EQ(Results, 2u);
+}
+
 TEST_F(BackgroundIndexTest, MainFileRefs) {
   MockFS FS;
   FS.Files[testPath("root/A.h")] = R"cpp(
@@ -345,14 +388,15 @@
 EXPECT_THAT(Ref.second,
 UnorderedElementsAre(FileURI("unittest:///root/A.cc")));
 
-  // The BaseOf relationship between A_CC and B_CC is stored in the file
-  // containing the definition of the subject (A_CC)
+  // The BaseOf relationship between A_CC and B_CC is stored in both the file
+  

[PATCH] D87561: [Sema] List conversion validate character array

2020-09-27 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith accepted this revision.
rsmith added a comment.
This revision is now accepted and ready to land.

Thanks, only nits here. Please feel free to submit after addressing them, or 
request another round of review if you prefer.




Comment at: clang/lib/Sema/SemaInit.cpp:3115-3118
+bool Sema::IsStringInit(Expr *Init, const ArrayType *AT) {
+  return ::IsStringInit(Init, AT, Context) == SIF_None;
+}
+

Consider moving this up to around line 144 (just after the definition of 
`::IsStringInit`).



Comment at: clang/lib/Sema/SemaOverload.cpp:4988
+
+if (const auto *AT = S.Context.getAsArrayType(ToType))
+  if (S.IsStringInit(From->getInit(0), AT)) {

Nit: the `if` body is long, please add braces.



Comment at: clang/test/CXX/drs/dr14xx.cpp:338-340
+void f1(int);
+void f1(std::initializer_list);
+void g1() { f1({42}); }

It would be useful to also test that the right overload is used here, and for 
`g2`.



Comment at: clang/test/CXX/drs/dr14xx.cpp:424-431
+f({"abc"});
+f({((("abc")))});
+f({L"abc"});
+#if __cplusplus >= 202002L
+f({u8"abc"});
+#endif
+f({uR"(abc)"});

Please test that the correct overload is called in each of these cases 
(especially considering the unintuitive outcome of these calls).



Comment at: clang/test/CXX/drs/dr14xx.cpp:411-414
+  void f(const char[4]);
+  void f(const wchar_t[4]);
+  void f(const char16_t[4]);
+  void f(const char32_t[4]);

Mordante wrote:
> rsmith wrote:
> > rsmith wrote:
> > > Mordante wrote:
> > > > rsmith wrote:
> > > > > These should presumably be references to arrays, rather than arrays, 
> > > > > or the parameter type is as if you wrote (for example) `void f(const 
> > > > > char *)`, which shouldn't get the special treatment here.
> > > > > 
> > > > > [over.ics.list]p4 mentions this in its footnote:
> > > > > 
> > > > > "Otherwise, if the parameter type is a character array [Footnote: 
> > > > > Since there are no parameters of array type, this will only occur as 
> > > > > the referenced type of a reference parameter.] and the initializer 
> > > > > list has a single element that is an appropriately-typed 
> > > > > string-literal (9.4.3), the implicit conversion sequence is the 
> > > > > identity conversion."
> > > > Ah I missed that footnote. I reread the standard and can you confirm 
> > > > some cases?
> > > > ```
> > > > namespace A { 
> > > >   void f(const char(&)[4]);
> > > >   void g() { f({"abc"}); }
> > > > }
> > > > namespace B { 
> > > >   void f(const char(&&)[4]);
> > > >   void g() { f({"abc"}); }
> > > > } 
> > > > ```
> > > > both should work and with P0388 the array without bounds will also work.
> > > > 
> > > > I ask since this is my interpretation of the standard, but it seems 
> > > > there's a difference between implementations and `void f(const 
> > > > char(&&)[4]);` fails for "abc" but works for "ab".
> > > > It seems ICC and consider "abc" an lvalue in this case and not when 
> > > > using "ab".
> > > > 
> > > > Here's a gotbolt link with the examples https://godbolt.org/z/r1TKfx
> > > That's a really interesting example :)
> > > 
> > > The initializer is a list containing an lvalue of type `const char[4]`. 
> > > Per [dcl.init.list]/3.9 and /3.10, the behavior depends on whether the 
> > > referenced type is reference-related to `const char[4]` -- if so, then 
> > > the reference can only bind directly and a `&&` reference will be 
> > > invalid, because it's binding an rvalue reference to an lvalue, and if 
> > > not, then we create an array temporary and the `&&` binding is fine.
> > > 
> > > Per [dcl.init.ref]/4, `const char[???]` is reference-related to `const 
> > > char[4]` if they are similar types, and per [conv.qual]/2, the types are 
> > > similar if `???` is omitted or `4`, and not similar otherwise.
> > > 
> > > So:
> > > * `const char (&&r)[4] = {"abc"}` is ill-formed (types are the same, 
> > > binds rvalue reference to lvalue)
> > > * `const char (&&)[] = {"abc"}` is ill-formed (types are similar, binds 
> > > rvalue reference to lvalue)
> > > * `const char (&&r)[5] = {"abc"}` is OK (types are not similar, creates 
> > > temporary)
> > > 
> > > That seems like a very surprising outcome to me. Perhaps we should 
> > > probably ignore array bounds entirely when determining whether two types 
> > > are reference-related. I'll take this to CWG for discussion.
> > I think that's only an answer to half of your question. The other half is 
> > that [over.ics.list]p4 does not apply (directly) to either of your 
> > testcases, because the "parameter type" is a reference type, not an array 
> > type. For:
> > 
> > ```
> > namespace A { 
> >   void f(const char(&)[4]);
> >   void g() { f({"abc"}); }
> > }
> > ```
> > 
> > ... we reach [over.ics.list]p9, which says to use the rules in 
> > [over.ics.ref]. Those rules say th

[PATCH] D87225: [clangd] When finding refs for a renaming alias, do not return refs to underlying decls

2020-09-27 Thread Nathan Ridge via Phabricator via cfe-commits
nridge updated this revision to Diff 294580.
nridge added a comment.

Address review comment


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87225/new/

https://reviews.llvm.org/D87225

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
@@ -1582,6 +1582,13 @@
   f.[[^~]]Foo();
 }
   )cpp",
+  R"cpp(// Renaming alias
+template  class Vector {};
+using [[^X]] = Vector;
+[[X]] x1;
+Vector x2;
+Vector y;
+  )cpp",
   };
   for (const char *Test : Tests) {
 Annotations T(Test);
Index: clang-tools-extra/clangd/XRefs.cpp
===
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -1140,11 +1140,22 @@
   } else {
 // Handle references to Decls.
 
-// We also show references to the targets of using-decls, so we include
-// DeclRelation::Underlying.
-DeclRelationSet Relations = DeclRelation::TemplatePattern |
-DeclRelation::Alias | DeclRelation::Underlying;
-auto Decls = getDeclAtPosition(AST, *CurLoc, Relations);
+DeclRelationSet Relations =
+DeclRelation::TemplatePattern | DeclRelation::Alias;
+std::vector Decls =
+getDeclAtPosition(AST, *CurLoc, Relations);
+std::vector AdditionalDecls;
+// If the results include a *non-renaming* alias, get its
+// underlying decls as well. (See similar logic in locateASTReferent()).
+for (const NamedDecl *D : Decls) {
+  if (llvm::isa(D) || llvm::isa(D)) {
+for (const NamedDecl *AD :
+ getDeclAtPosition(AST, *CurLoc, DeclRelation::Underlying))
+  AdditionalDecls.push_back(AD);
+break;
+  }
+}
+llvm::copy(AdditionalDecls, std::back_inserter(Decls));
 
 // We traverse the AST to find references in the main file.
 auto MainFileRefs = findRefs(Decls, AST);


Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -1582,6 +1582,13 @@
   f.[[^~]]Foo();
 }
   )cpp",
+  R"cpp(// Renaming alias
+template  class Vector {};
+using [[^X]] = Vector;
+[[X]] x1;
+Vector x2;
+Vector y;
+  )cpp",
   };
   for (const char *Test : Tests) {
 Annotations T(Test);
Index: clang-tools-extra/clangd/XRefs.cpp
===
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -1140,11 +1140,22 @@
   } else {
 // Handle references to Decls.
 
-// We also show references to the targets of using-decls, so we include
-// DeclRelation::Underlying.
-DeclRelationSet Relations = DeclRelation::TemplatePattern |
-DeclRelation::Alias | DeclRelation::Underlying;
-auto Decls = getDeclAtPosition(AST, *CurLoc, Relations);
+DeclRelationSet Relations =
+DeclRelation::TemplatePattern | DeclRelation::Alias;
+std::vector Decls =
+getDeclAtPosition(AST, *CurLoc, Relations);
+std::vector AdditionalDecls;
+// If the results include a *non-renaming* alias, get its
+// underlying decls as well. (See similar logic in locateASTReferent()).
+for (const NamedDecl *D : Decls) {
+  if (llvm::isa(D) || llvm::isa(D)) {
+for (const NamedDecl *AD :
+ getDeclAtPosition(AST, *CurLoc, DeclRelation::Underlying))
+  AdditionalDecls.push_back(AD);
+break;
+  }
+}
+llvm::copy(AdditionalDecls, std::back_inserter(Decls));
 
 // We traverse the AST to find references in the main file.
 auto MainFileRefs = findRefs(Decls, AST);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87225: [clangd] When finding refs for a renaming alias, do not return refs to underlying decls

2020-09-27 Thread Nathan Ridge via Phabricator via cfe-commits
nridge marked 3 inline comments as done.
nridge added inline comments.



Comment at: clang-tools-extra/clangd/XRefs.cpp:1150
+  if (llvm::isa(D) || llvm::isa(D)) {
+Decls = getDeclAtPosition(AST, *CurLoc,
+  Relations | DeclRelation::Underlying);

nridge wrote:
> hokein wrote:
> > I think it should not happen in practice (Decls just have 1 element in most 
> > cases), but the code feels hacky, we are throwing other decls if one of the 
> > `Decls` is a using decl.
> > 
> > I suppose if we're using the same workaround as `locateASTReferent`, then 
> > we should follow that way by only adjusting the 
> > UsingDecl/UnresolvedValueDecl results and keeping others.
> > 
> > 
> > In general, I think we probably need to remove this workaround (see the  
> > `FIXME` in `locateASTReferent`) by refining TargetDecl API. The current 
> > `DeclRelation::Underlying` enum is not enough to support our use case where 
> > we only want underlying decls for *non-renaming* alias. One rough idea to 
> > fix it is to split the `Underlying` to two `RenameAliasUnderlying` and 
> > `RemainingUnderlying` -- this would need some API design work, so no need 
> > to do it in this patch.
> > 
> > 
> > 
> I don't think we're actually throwing out the other results: by calling 
> `getDeclAtPosition()` with `Relations | Underlying`, where `Relations` is the 
> original flags, the call should find the other results again. If we only 
> replaced the UsingDecl/UnresolvedValueDecl results, I think the other results 
> would appear in duplicate.
Anyways, I've revised it as you suggested. I don't think it should make a 
difference in practice.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87225/new/

https://reviews.llvm.org/D87225

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


[PATCH] D88333: Better diagnostics for anonymous bit-fields with attributes or an initializer

2020-09-27 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticParseKinds.td:875-876
   "C++ standards before C++20">, InGroup, DefaultIgnore;
+def err_anon_bitfield_member_init : Error<
+  "anonymous bit-field cannot have an in-class initializer">;
 def err_incomplete_array_member_init: Error<

Please retain the diagnostic wording using proper standard terminology; the 
other diagnostics say "in-class initializer" because they predate the existence 
of the standard terminology and haven't been fixed yet. (Fixing them -- and 
renaming the corresponding functions throughout Clang -- would be great if you 
feel so inclined.)



Comment at: clang/lib/Parse/ParseDecl.cpp:4127-4129
+  // Anonymous bit-fields cannot specify attributes; the attributes
+  // appertain to the type specifier for the bit-field instead. Provide a
+  // kinder parsing error than if we just let parsing happen organically.

I think this will regress our diagnostics for this (probably more common) case:

```
struct X { 
  int a, [[attr]] b;
};
```

Instead, how about we unconditionally `DiagnoseAndSkipCXX11Attributes()` before 
and after we parse GNU attributes in the `if (!FirstDeclarator)` check up 
above? (Aside: we should probably be better about handling mixed sequences of 
GNU and C++11 attributes in general.)



Comment at: clang/lib/Parse/ParseDeclCXX.cpp:2311-2313
+  //   identifier attribute-specifier-seq[opt] ':' constant-expression
+  //   brace-or-equal-initializer[opt]
+  //   ':' constant-expression

Please mention that this is a proposed bugfix, not the standard grammar.



Comment at: clang/lib/Parse/ParseDeclCXX.cpp:2318-2320
+// Anonymous bit-fields cannot specify attributes; the attributes appertain
+// to the type specifier for the bit-field instead. Provide a kinder
+// parsing error than if we just let parsing happen organically.

(Same comment as for the C side of things.)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D88333/new/

https://reviews.llvm.org/D88333

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


[clang] 9dcd96f - Canonicalize declaration pointers when forming APValues.

2020-09-27 Thread Richard Smith via cfe-commits

Author: Richard Smith
Date: 2020-09-27T19:05:26-07:00
New Revision: 9dcd96f728863d40d6f5922ed52732fdd728fb5f

URL: 
https://github.com/llvm/llvm-project/commit/9dcd96f728863d40d6f5922ed52732fdd728fb5f
DIFF: 
https://github.com/llvm/llvm-project/commit/9dcd96f728863d40d6f5922ed52732fdd728fb5f.diff

LOG: Canonicalize declaration pointers when forming APValues.

References to different declarations of the same entity aren't different
values, so shouldn't have different representations.

Recommit of e6393ee813178e9d3306b8e3c6949a4f32f8a2cb with fixed handling
for weak declarations. We now look for attributes on the most recent
declaration when determining whether a declaration is weak. (Second
recommit with further fixes for mishandling of weak declarations. Our
behavior here is fundamentally unsound -- see PR47663 -- but this
approach attempts to not make things worse.)

Added: 


Modified: 
clang/include/clang/AST/APValue.h
clang/lib/AST/APValue.cpp
clang/lib/AST/Decl.cpp
clang/lib/AST/DeclBase.cpp
clang/lib/AST/ExprConstant.cpp
clang/lib/CodeGen/CGExprConstant.cpp
clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp
clang/test/CodeGenCXX/weak-external.cpp
clang/test/OpenMP/ordered_messages.cpp

Removed: 




diff  --git a/clang/include/clang/AST/APValue.h 
b/clang/include/clang/AST/APValue.h
index 5103cfa8604e..6307f8a92e5a 100644
--- a/clang/include/clang/AST/APValue.h
+++ b/clang/include/clang/AST/APValue.h
@@ -174,6 +174,7 @@ class APValue {
   return !(LHS == RHS);
 }
 friend llvm::hash_code hash_value(const LValueBase &Base);
+friend struct llvm::DenseMapInfo;
 
   private:
 PtrTy Ptr;
@@ -201,8 +202,7 @@ class APValue {
 
   public:
 LValuePathEntry() : Value() {}
-LValuePathEntry(BaseOrMemberType BaseOrMember)
-: Value{reinterpret_cast(BaseOrMember.getOpaqueValue())} {}
+LValuePathEntry(BaseOrMemberType BaseOrMember);
 static LValuePathEntry ArrayIndex(uint64_t Index) {
   LValuePathEntry Result;
   Result.Value = Index;

diff  --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
index 08ae0ff3c67d..32d3ff7ce1d0 100644
--- a/clang/lib/AST/APValue.cpp
+++ b/clang/lib/AST/APValue.cpp
@@ -38,7 +38,7 @@ static_assert(
 "Type is insufficiently aligned");
 
 APValue::LValueBase::LValueBase(const ValueDecl *P, unsigned I, unsigned V)
-: Ptr(P), Local{I, V} {}
+: Ptr(P ? cast(P->getCanonicalDecl()) : nullptr), Local{I, V} {}
 APValue::LValueBase::LValueBase(const Expr *P, unsigned I, unsigned V)
 : Ptr(P), Local{I, V} {}
 
@@ -82,13 +82,19 @@ bool operator==(const APValue::LValueBase &LHS,
 const APValue::LValueBase &RHS) {
   if (LHS.Ptr != RHS.Ptr)
 return false;
-  if (LHS.is())
+  if (LHS.is() || LHS.is())
 return true;
   return LHS.Local.CallIndex == RHS.Local.CallIndex &&
  LHS.Local.Version == RHS.Local.Version;
 }
 }
 
+APValue::LValuePathEntry::LValuePathEntry(BaseOrMemberType BaseOrMember) {
+  if (const Decl *D = BaseOrMember.getPointer())
+BaseOrMember.setPointer(D->getCanonicalDecl());
+  Value = reinterpret_cast(BaseOrMember.getOpaqueValue());
+}
+
 namespace {
   struct LVBase {
 APValue::LValueBase Base;
@@ -113,14 +119,16 @@ APValue::LValueBase::operator bool () const {
 
 clang::APValue::LValueBase
 llvm::DenseMapInfo::getEmptyKey() {
-  return clang::APValue::LValueBase(
-  DenseMapInfo::getEmptyKey());
+  clang::APValue::LValueBase B;
+  B.Ptr = DenseMapInfo::getEmptyKey();
+  return B;
 }
 
 clang::APValue::LValueBase
 llvm::DenseMapInfo::getTombstoneKey() {
-  return clang::APValue::LValueBase(
-  DenseMapInfo::getTombstoneKey());
+  clang::APValue::LValueBase B;
+  B.Ptr = DenseMapInfo::getTombstoneKey();
+  return B;
 }
 
 namespace clang {
@@ -773,8 +781,10 @@ void APValue::MakeMemberPointer(const ValueDecl *Member, 
bool IsDerivedMember,
   assert(isAbsent() && "Bad state change");
   MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
   Kind = MemberPointer;
-  MPD->MemberAndIsDerivedMember.setPointer(Member);
+  MPD->MemberAndIsDerivedMember.setPointer(
+  Member ? cast(Member->getCanonicalDecl()) : nullptr);
   MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
   MPD->resizePath(Path.size());
-  memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const 
CXXRecordDecl*));
+  for (unsigned I = 0; I != Path.size(); ++I)
+MPD->getPath()[I] = Path[I]->getCanonicalDecl();
 }

diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 0ee1399d42df..c96450b8a377 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -4686,11 +4686,9 @@ char *Buffer = new (getASTContext(), 1) char[Name.size() 
+ 1];
 void ValueDecl::anchor() {}
 
 bool ValueDecl::isWeak() const {
-  for (const auto *I : attrs())
-if (isa(I) || isa(I))
-  return true;
-
-  return isWeakImported();
+  auto *

Re: [clang] 15d94a7 - Revert "Canonicalize declaration pointers when forming APValues."

2020-09-27 Thread Richard Smith via cfe-commits
On Tue, 22 Sep 2020 at 17:42, Leonard Chan via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> Author: Leonard Chan
> Date: 2020-09-22T17:40:53-07:00
> New Revision: 15d94a7d0f8f0d6b3b5308fff51b286957e45650
>
> URL:
> https://github.com/llvm/llvm-project/commit/15d94a7d0f8f0d6b3b5308fff51b286957e45650
> DIFF:
> https://github.com/llvm/llvm-project/commit/15d94a7d0f8f0d6b3b5308fff51b286957e45650.diff
>
> LOG: Revert "Canonicalize declaration pointers when forming APValues."
>
> This reverts commit 905b9ca26c94fa86339451a528cedde5004fc1bb.
>
> Reverting because this strips `weak` attributes off function
> declarations, leading to the linker error we see at
>
> https://ci.chromium.org/p/fuchsia/builders/ci/clang_toolchain.fuchsia-arm64-debug-subbuild/b8868932035091473008
> .
>
> See https://reviews.llvm.org/rG905b9ca26c94 for reproducer details.
>

Thanks, re-committed with a fix in 9dcd96f728863d40d6f5922ed52732fdd728fb5f.


> Added:
>
>
> Modified:
> clang/include/clang/AST/APValue.h
> clang/lib/AST/APValue.cpp
> clang/lib/AST/Decl.cpp
> clang/lib/AST/DeclBase.cpp
> clang/lib/AST/ExprConstant.cpp
> clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp
> clang/test/OpenMP/ordered_messages.cpp
>
> Removed:
>
>
>
>
> 
> diff  --git a/clang/include/clang/AST/APValue.h
> b/clang/include/clang/AST/APValue.h
> index 6307f8a92e5a..5103cfa8604e 100644
> --- a/clang/include/clang/AST/APValue.h
> +++ b/clang/include/clang/AST/APValue.h
> @@ -174,7 +174,6 @@ class APValue {
>return !(LHS == RHS);
>  }
>  friend llvm::hash_code hash_value(const LValueBase &Base);
> -friend struct llvm::DenseMapInfo;
>
>private:
>  PtrTy Ptr;
> @@ -202,7 +201,8 @@ class APValue {
>
>public:
>  LValuePathEntry() : Value() {}
> -LValuePathEntry(BaseOrMemberType BaseOrMember);
> +LValuePathEntry(BaseOrMemberType BaseOrMember)
> +:
> Value{reinterpret_cast(BaseOrMember.getOpaqueValue())} {}
>  static LValuePathEntry ArrayIndex(uint64_t Index) {
>LValuePathEntry Result;
>Result.Value = Index;
>
> diff  --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
> index 32d3ff7ce1d0..08ae0ff3c67d 100644
> --- a/clang/lib/AST/APValue.cpp
> +++ b/clang/lib/AST/APValue.cpp
> @@ -38,7 +38,7 @@ static_assert(
>  "Type is insufficiently aligned");
>
>  APValue::LValueBase::LValueBase(const ValueDecl *P, unsigned I, unsigned
> V)
> -: Ptr(P ? cast(P->getCanonicalDecl()) : nullptr), Local{I,
> V} {}
> +: Ptr(P), Local{I, V} {}
>  APValue::LValueBase::LValueBase(const Expr *P, unsigned I, unsigned V)
>  : Ptr(P), Local{I, V} {}
>
> @@ -82,19 +82,13 @@ bool operator==(const APValue::LValueBase &LHS,
>  const APValue::LValueBase &RHS) {
>if (LHS.Ptr != RHS.Ptr)
>  return false;
> -  if (LHS.is() || LHS.is())
> +  if (LHS.is())
>  return true;
>return LHS.Local.CallIndex == RHS.Local.CallIndex &&
>   LHS.Local.Version == RHS.Local.Version;
>  }
>  }
>
> -APValue::LValuePathEntry::LValuePathEntry(BaseOrMemberType BaseOrMember) {
> -  if (const Decl *D = BaseOrMember.getPointer())
> -BaseOrMember.setPointer(D->getCanonicalDecl());
> -  Value = reinterpret_cast(BaseOrMember.getOpaqueValue());
> -}
> -
>  namespace {
>struct LVBase {
>  APValue::LValueBase Base;
> @@ -119,16 +113,14 @@ APValue::LValueBase::operator bool () const {
>
>  clang::APValue::LValueBase
>  llvm::DenseMapInfo::getEmptyKey() {
> -  clang::APValue::LValueBase B;
> -  B.Ptr = DenseMapInfo::getEmptyKey();
> -  return B;
> +  return clang::APValue::LValueBase(
> +  DenseMapInfo::getEmptyKey());
>  }
>
>  clang::APValue::LValueBase
>  llvm::DenseMapInfo::getTombstoneKey() {
> -  clang::APValue::LValueBase B;
> -  B.Ptr = DenseMapInfo::getTombstoneKey();
> -  return B;
> +  return clang::APValue::LValueBase(
> +  DenseMapInfo::getTombstoneKey());
>  }
>
>  namespace clang {
> @@ -781,10 +773,8 @@ void APValue::MakeMemberPointer(const ValueDecl
> *Member, bool IsDerivedMember,
>assert(isAbsent() && "Bad state change");
>MemberPointerData *MPD = new ((void*)(char*)Data.buffer)
> MemberPointerData;
>Kind = MemberPointer;
> -  MPD->MemberAndIsDerivedMember.setPointer(
> -  Member ? cast(Member->getCanonicalDecl()) : nullptr);
> +  MPD->MemberAndIsDerivedMember.setPointer(Member);
>MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
>MPD->resizePath(Path.size());
> -  for (unsigned I = 0; I != Path.size(); ++I)
> -MPD->getPath()[I] = Path[I]->getCanonicalDecl();
> +  memcpy(MPD->getPath(), Path.data(), Path.size()*sizeof(const
> CXXRecordDecl*));
>  }
>
> diff  --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
> index ae38e3dd2a72..0ee1399d42df 100644
> --- a/clang/lib/AST/Decl.cpp
> +++ b/clang/lib/AST/Decl.cpp
> @@ -4686,7 +4686,7 @@ char *Buffer = new (getASTContext(), 1)
> char[Name.size() + 1];
>  v

[PATCH] D78938: Make LLVM build in C++20 mode

2020-09-27 Thread Barry Revzin via Phabricator via cfe-commits
BRevzin added inline comments.



Comment at: llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h:167-171
-
-inline bool operator!=(const DWARFExpression::iterator &LHS,
-   const DWARFExpression::iterator &RHS) {
-  return !(LHS == RHS);
-}

dblaikie wrote:
> Why are some being removed? That seems harder to justify. Even if they're not 
> called, it may be more valuable to have the symmetry to reduce friction 
> if/when they are needed. (iterators seem pretty common to compare for 
> inequality - such as in a loop condition testing I != E)
They're not being removed. These functions still exist - it's just that now 
they're being injected by the base class template with this exact signature 
(rather than before where they were slightly different), so that now these are 
redefinition issues. 

There's no loss of functionality here. 



Comment at: llvm/include/llvm/IR/BasicBlock.h:324-325
+template ::value>>
 phi_iterator_impl(const phi_iterator_impl &Arg)

dblaikie wrote:
> What tripped over/required this SFINAE?
There's somewhere which compared a const iterator to a non-const iterator, that 
ends up doing conversions in both directions under C++20 rules, one direction 
of which is perfectly fine and the other was a hard error. Need to make the 
non-const iterator not constructible from a const iterator.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78938/new/

https://reviews.llvm.org/D78938

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


[clang] df2a1f2 - Add profiling support for APValues.

2020-09-27 Thread Richard Smith via cfe-commits

Author: Richard Smith
Date: 2020-09-27T20:05:39-07:00
New Revision: df2a1f2aabf6692daa83e849f0fdc37f9e402fca

URL: 
https://github.com/llvm/llvm-project/commit/df2a1f2aabf6692daa83e849f0fdc37f9e402fca
DIFF: 
https://github.com/llvm/llvm-project/commit/df2a1f2aabf6692daa83e849f0fdc37f9e402fca.diff

LOG: Add profiling support for APValues.

For C++20 P0732R2; unused so far. Will be used and tested by a follow-on
commit.

Added: 


Modified: 
clang/include/clang/AST/APValue.h
clang/lib/AST/APValue.cpp

Removed: 




diff  --git a/clang/include/clang/AST/APValue.h 
b/clang/include/clang/AST/APValue.h
index 6307f8a92e5a..ac8ed0818af0 100644
--- a/clang/include/clang/AST/APValue.h
+++ b/clang/include/clang/AST/APValue.h
@@ -19,6 +19,7 @@
 #include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/FoldingSet.h"
 
 namespace clang {
   class AddrLabelExpr;
@@ -149,6 +150,8 @@ class APValue {
 static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type);
 static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
 
+void profile(llvm::FoldingSetNodeID &ID) const;
+
 template 
 bool is() const { return Ptr.is(); }
 
@@ -215,6 +218,8 @@ class APValue {
 }
 uint64_t getAsArrayIndex() const { return Value; }
 
+void profile(llvm::FoldingSetNodeID &ID) const;
+
 friend bool operator==(LValuePathEntry A, LValuePathEntry B) {
   return A.Value == B.Value;
 }
@@ -357,6 +362,11 @@ class APValue {
   /// Swaps the contents of this and the given APValue.
   void swap(APValue &RHS);
 
+  /// Profile this value. There is no guarantee that values of 
diff erent
+  /// types will not produce the same profiled value, so the type should
+  /// typically also be profiled if it's not implied by the context.
+  void profile(llvm::FoldingSetNodeID &ID) const;
+
   ValueKind getKind() const { return Kind; }
 
   bool isAbsent() const { return Kind == None; }

diff  --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
index 32d3ff7ce1d0..7efd0caf3f1d 100644
--- a/clang/lib/AST/APValue.cpp
+++ b/clang/lib/AST/APValue.cpp
@@ -77,6 +77,14 @@ QualType APValue::LValueBase::getDynamicAllocType() const {
   return QualType::getFromOpaquePtr(DynamicAllocType);
 }
 
+void APValue::LValueBase::profile(llvm::FoldingSetNodeID &ID) const {
+  ID.AddPointer(Ptr.getOpaqueValue());
+  if (is() || is())
+return;
+  ID.AddInteger(Local.CallIndex);
+  ID.AddInteger(Local.Version);
+}
+
 namespace clang {
 bool operator==(const APValue::LValueBase &LHS,
 const APValue::LValueBase &RHS) {
@@ -95,6 +103,10 @@ APValue::LValuePathEntry::LValuePathEntry(BaseOrMemberType 
BaseOrMember) {
   Value = reinterpret_cast(BaseOrMember.getOpaqueValue());
 }
 
+void APValue::LValuePathEntry::profile(llvm::FoldingSetNodeID &ID) const {
+  ID.AddInteger(Value);
+}
+
 namespace {
   struct LVBase {
 APValue::LValueBase Base;
@@ -402,6 +414,147 @@ void APValue::swap(APValue &RHS) {
   std::swap(Data, RHS.Data);
 }
 
+void APValue::profile(llvm::FoldingSetNodeID &ID) const {
+  ID.AddInteger(Kind);
+
+  switch (Kind) {
+  case None:
+  case Indeterminate:
+return;
+
+  case AddrLabelDiff:
+ID.AddPointer(getAddrLabelDiffLHS()->getLabel()->getCanonicalDecl());
+ID.AddPointer(getAddrLabelDiffRHS()->getLabel()->getCanonicalDecl());
+return;
+
+  case Struct:
+ID.AddInteger(getStructNumBases());
+for (unsigned I = 0, N = getStructNumBases(); I != N; ++I)
+  getStructBase(I).profile(ID);
+ID.AddInteger(getStructNumFields());
+for (unsigned I = 0, N = getStructNumFields(); I != N; ++I)
+  getStructField(I).profile(ID);
+return;
+
+  case Union:
+if (!getUnionField()) {
+  ID.AddPointer(nullptr);
+  return;
+}
+ID.AddPointer(getUnionField()->getCanonicalDecl());
+getUnionValue().profile(ID);
+return;
+
+  case Array: {
+ID.AddInteger(getArraySize());
+if (getArraySize() == 0)
+  return;
+
+// The profile should not depend on whether the array is expanded or
+// not, but we don't want to profile the array filler many times for
+// a large array. So treat all equal trailing elements as the filler.
+// Elements are profiled in reverse order to support this, and the
+// first profiled element is followed by a count. For example:
+//
+//   ['a', 'c', 'x', 'x', 'x'] is profiled as
+//   [5, 'x', 3, 'c', 'a']
+llvm::FoldingSetNodeID FillerID;
+(hasArrayFiller() ? getArrayFiller() :
+ getArrayInitializedElt(getArrayInitializedElts() -
+   1)).profile(FillerID);
+ID.AddNodeID(FillerID);
+unsigned NumFillers = getArraySize() - getArrayInitializedElts();
+unsigned N = getArrayInitializedElts();
+
+// Count the number of elements equal to the last one. This loop ends
+// by adding an integer i

[PATCH] D87888: [X86] Use inlineasm flag output for the _bittest* intrinsics.

2020-09-27 Thread Craig Topper via Phabricator via cfe-commits
craig.topper updated this revision to Diff 294593.
craig.topper added a comment.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Rebase and add a backend test file


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87888/new/

https://reviews.llvm.org/D87888

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/bittest-intrin.c
  llvm/test/CodeGen/X86/bittest-intrin.ll

Index: llvm/test/CodeGen/X86/bittest-intrin.ll
===
--- /dev/null
+++ llvm/test/CodeGen/X86/bittest-intrin.ll
@@ -0,0 +1,101 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown-windows-msvc19.11.0 | FileCheck %s
+
+; This matches the code produced by clang/lib/CodeGen/bittest-intrin.c
+
+@sink = global i8 0, align 1
+
+define void @test32(i32* %base, i32 %idx) {
+; CHECK-LABEL: test32:
+; CHECK:   # %bb.0: # %entry
+; CHECK-NEXT:#APP
+; CHECK-NEXT:btl %edx, (%rcx)
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:setb {{.*}}(%rip)
+; CHECK-NEXT:#APP
+; CHECK-NEXT:btcl %edx, (%rcx)
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:setb {{.*}}(%rip)
+; CHECK-NEXT:#APP
+; CHECK-NEXT:btrl %edx, (%rcx)
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:setb {{.*}}(%rip)
+; CHECK-NEXT:#APP
+; CHECK-NEXT:btsl %edx, (%rcx)
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:setb {{.*}}(%rip)
+; CHECK-NEXT:#APP
+; CHECK-NEXT:lock btrl %edx, (%rcx)
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:setb {{.*}}(%rip)
+; CHECK-NEXT:#APP
+; CHECK-NEXT:lock btsl %edx, (%rcx)
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:setb {{.*}}(%rip)
+; CHECK-NEXT:#APP
+; CHECK-NEXT:lock btsl %edx, (%rcx)
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:setb {{.*}}(%rip)
+; CHECK-NEXT:retq
+entry:
+  %0 = tail call i8 asm sideeffect "btl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %base, i32 %idx)
+  store volatile i8 %0, i8* @sink, align 1
+  %1 = tail call i8 asm sideeffect "btcl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %base, i32 %idx)
+  store volatile i8 %1, i8* @sink, align 1
+  %2 = tail call i8 asm sideeffect "btrl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %base, i32 %idx)
+  store volatile i8 %2, i8* @sink, align 1
+  %3 = tail call i8 asm sideeffect "btsl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %base, i32 %idx)
+  store volatile i8 %3, i8* @sink, align 1
+  %4 = tail call i8 asm sideeffect "lock btrl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %base, i32 %idx)
+  store volatile i8 %4, i8* @sink, align 1
+  %5 = tail call i8 asm sideeffect "lock btsl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %base, i32 %idx)
+  store volatile i8 %5, i8* @sink, align 1
+  %6 = tail call i8 asm sideeffect "lock btsl $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %base, i32 %idx)
+  store volatile i8 %6, i8* @sink, align 1
+  ret void
+}
+
+; Function Attrs: nounwind uwtable
+define void @test64(i64* %base, i64 %idx) {
+; CHECK-LABEL: test64:
+; CHECK:   # %bb.0: # %entry
+; CHECK-NEXT:#APP
+; CHECK-NEXT:btq %rdx, (%rcx)
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:setb {{.*}}(%rip)
+; CHECK-NEXT:#APP
+; CHECK-NEXT:btcq %rdx, (%rcx)
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:setb {{.*}}(%rip)
+; CHECK-NEXT:#APP
+; CHECK-NEXT:btrq %rdx, (%rcx)
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:setb {{.*}}(%rip)
+; CHECK-NEXT:#APP
+; CHECK-NEXT:btsq %rdx, (%rcx)
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:setb {{.*}}(%rip)
+; CHECK-NEXT:#APP
+; CHECK-NEXT:lock btrq %rdx, (%rcx)
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:setb {{.*}}(%rip)
+; CHECK-NEXT:#APP
+; CHECK-NEXT:lock btsq %rdx, (%rcx)
+; CHECK-NEXT:#NO_APP
+; CHECK-NEXT:setb {{.*}}(%rip)
+; CHECK-NEXT:retq
+entry:
+  %0 = tail call i8 asm sideeffect "btq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %base, i64 %idx)
+  store volatile i8 %0, i8* @sink, align 1
+  %1 = tail call i8 asm sideeffect "btcq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %base, i64 %idx)
+  store volatile i8 %1, i8* @sink, align 1
+  %2 = tail call i8 asm sideeffect "btrq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %base, i64 %idx)
+  store volatile i8 %2, i8* @sink, align 1
+  %3 = tail call i8 asm sideeffect "btsq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %base, i64 %idx)
+  store volatile i8 %3, i8* @sink, align 1
+  %4 = tail call i8 asm sideeffect "lock btrq $2, ($1)", "={@ccc},r,r,~{cc},~{memory},~{dirflag},~{fpsr},~{flags}"(i64* %base, i64 %idx)
+  store volatile i8 %4, i8* @sink, align 1
+  %5 = tail call i8 asm sideeffect 

[PATCH] D86649: Fix for assertion failure on PR46865

2020-09-27 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith requested changes to this revision.
rsmith added a comment.
This revision now requires changes to proceed.

I think the assertion is correct: if we reach this point, then we have a 
`DeclRefExpr` that is not value-dependent and refers to a declaration whose 
initializer is value-dependent. That should never happen if the variable's type 
satisfies the requirements for use in a constant expression, which is what 
`mightBeUsableInConstantExpressions` checks.

The bug here appears to be that the dependency bits on a `DeclRefExpr` are 
computed too early when it refers to a templated variable -- before we 
instantiate the initializer -- and don't get "fixed" later when the initializer 
is instantiated. `DoMarkVarDeclReferenced` would be the right place to handle 
this -- after we trigger instantiation of the initializer, we should recompute 
the dependence bits on the `DeclRefExpr`, because they can depend on the 
initializer.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D86649/new/

https://reviews.llvm.org/D86649

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


[PATCH] D88384: [OpenMP][FIX] Verify compatible types for declare variant calls

2020-09-27 Thread Johannes Doerfert via Phabricator via cfe-commits
jdoerfert updated this revision to Diff 294596.
jdoerfert added a comment.

Add instantiation check and expand test case


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D88384/new/

https://reviews.llvm.org/D88384

Files:
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp

Index: clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp
===
--- /dev/null
+++ clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp
@@ -0,0 +1,258 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s
+// expected-no-diagnostics
+// PR47655
+
+template  struct S {
+  S(int, T*) {}
+};
+
+template 
+int also_before(T s) {
+  return 0;
+}
+
+#pragma omp begin declare variant match(implementation = {extension(allow_templates)})
+template 
+int also_before(S s) {
+  // Ensure there is no error because this is never instantiated.
+  double t;
+  S q(1, &t);
+  return 1;
+}
+template 
+int special(S s) {
+  T t;
+  S q(0, &t);
+  return 0;
+}
+template 
+int also_after(S s) {
+  // Ensure there is no error because this is never instantiated.
+  double t;
+  S q(2.0, &t);
+  return 2;
+}
+#pragma omp end declare variant
+
+template 
+int also_after(T s) {
+  return 0;
+}
+
+int test() {
+  // Should return 0.
+  return also_before(0) + also_after(0) + also_before(0.) + also_after(0.) + special(S(0, 0));
+}
+
+// CHECK:  |-ClassTemplateDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:30 S
+// CHECK-NEXT: | |-TemplateTypeParmDecl [[ADDR_1:0x[a-z0-9]*]]  col:20 referenced typename depth 0 index 0 T
+// CHECK-NEXT: | |-CXXRecordDecl [[ADDR_2:0x[a-z0-9]*]]  line:5:30 struct S definition
+// CHECK-NEXT: | | |-DefinitionData empty standard_layout trivially_copyable has_user_declared_ctor can_const_default_init
+// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
+// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
+// CHECK-NEXT: | | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | | | |-MoveAssignment exists simple trivial needs_implicit
+// CHECK-NEXT: | | | `-Destructor simple irrelevant trivial needs_implicit
+// CHECK-NEXT: | | |-CXXRecordDecl [[ADDR_3:0x[a-z0-9]*]]  col:30 implicit referenced struct S
+// CHECK-NEXT: | | `-CXXConstructorDecl [[ADDR_4:0x[a-z0-9]*]]  col:3 S 'void (int, T *)'
+// CHECK-NEXT: | |   |-ParmVarDecl [[ADDR_5:0x[a-z0-9]*]]  col:8 'int'
+// CHECK-NEXT: | |   |-ParmVarDecl [[ADDR_6:0x[a-z0-9]*]]  col:12 'T *'
+// CHECK-NEXT: | |   `-CompoundStmt [[ADDR_7:0x[a-z0-9]*]] 
+// CHECK-NEXT: | |-ClassTemplateSpecializationDecl [[ADDR_8:0x[a-z0-9]*]]  line:5:30 struct S definition
+// CHECK-NEXT: | | |-DefinitionData pass_in_registers empty standard_layout trivially_copyable has_user_declared_ctor can_const_default_init
+// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
+// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param implicit_has_const_param
+// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial
+// CHECK-NEXT: | | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
+// CHECK-NEXT: | | | |-MoveAssignment exists simple trivial needs_implicit
+// CHECK-NEXT: | | | `-Destructor simple irrelevant trivial
+// CHECK-NEXT: | | |-TemplateArgument type 'int'
+// CHECK-NEXT: | | | `-BuiltinType [[ADDR_9:0x[a-z0-9]*]] 'int'
+// CHECK-NEXT: | | |-CXXRecordDecl [[ADDR_10:0x[a-z0-9]*]] prev [[ADDR_8]]  col:30 implicit struct S
+// CHECK-NEXT: | | |-CXXConstructorDecl [[ADDR_11:0x[a-z0-9]*]]  col:3 used S 'void (int, int *)'
+// CHECK-NEXT: | | | |-ParmVarDecl [[ADDR_12:0x[a-z0-9]*]]  col:8 'int'
+// CHECK-NEXT: | | | |-ParmVarDecl [[ADDR_13:0x[a-z0-9]*]]  col:12 'int *'
+// CHECK-NEXT: | | | `-CompoundStmt [[ADDR_7]] 
+// CHECK-NEXT: | | |-CXXConstructorDecl [[ADDR_14:0x[a-z0-9]*]]  col:30 implicit constexpr S 'void (const S &)' inline default trivial noexcept-unevaluated [[ADDR_14]]
+// CHECK-NEXT: | | | `-ParmVarDecl [[ADDR_15:0x[a-z0-9]*]]  col:30 'const S &'
+// CHECK-NEXT: | | |-CXXConstructorDecl [[ADDR_16:0x[a-z0-9]*]]  col:30 implicit used constexpr S 'void (S &&) noexcept' inline default trivial
+// CHECK-NEXT: | | | |-ParmVarDecl [[ADDR_17:0x[a-z0-9]*]]  col:30 'S &&'
+// CHECK-NEXT: | | | `-CompoundStmt [[ADDR_18:0x[a-z0-9]*]] 
+// CHECK-NEXT: | | `-CXXDestructorDecl [[ADDR_19:0x[a-z0-9]*]]  col:30 implicit referenced ~S 'void ({{.*}}) noexcept' inline default trivial
+// CHECK-NEXT: | `-ClassTemplateSpecializationDecl [[ADDR_20:0x[a-z0-9]*]]  line:5:30 struct S
+// CHECK-NEXT: |   `-TemplateArgument type 'double'
+// CHECK-NEXT: | `-BuiltinType [

[PATCH] D88393: [cfe][M68K] (Patch 7/8) Basic Clang support

2020-09-27 Thread Min-Yih Hsu via Phabricator via cfe-commits
myhsu created this revision.
Herald added subscribers: cfe-commits, mgorny.
Herald added a reviewer: aaron.ballman.
Herald added a project: clang.
myhsu requested review of this revision.

1. Add M68K as new Clang target
2. Add new attribute to support M68K's ISR (Interrupt Service Routine)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D88393

Files:
  clang/include/clang/Basic/Attr.td
  clang/lib/Basic/CMakeLists.txt
  clang/lib/Basic/Targets.cpp
  clang/lib/Basic/Targets/M680x0.cpp
  clang/lib/Basic/Targets/M680x0.h
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/Sema/SemaDeclAttr.cpp

Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -5797,6 +5797,39 @@
   D->addAttr(::new (S.Context) MipsInterruptAttr(S.Context, AL, Kind));
 }
 
+static void handleM680x0InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+  if (!checkAttributeNumArgs(S, AL, 1))
+return;
+
+  if (!AL.isArgExpr(0)) {
+S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
+<< AL << AANT_ArgumentIntegerConstant;
+return;
+  }
+
+  // FIXME: Check for decl - it should be void ()(void).
+
+  Expr *NumParamsExpr = static_cast(AL.getArgAsExpr(0));
+  auto MaybeNumParams = NumParamsExpr->getIntegerConstantExpr(S.Context);
+  if (!MaybeNumParams) {
+S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
+<< AL << AANT_ArgumentIntegerConstant
+<< NumParamsExpr->getSourceRange();
+return;
+  }
+
+  unsigned Num = MaybeNumParams->getLimitedValue(255);
+  if ((Num & 1) || Num > 30) {
+S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
+<< AL << (int)MaybeNumParams->getSExtValue()
+<< NumParamsExpr->getSourceRange();
+return;
+  }
+
+  D->addAttr(::new (S.Context) M680x0InterruptAttr(S.Context, AL, Num));
+  D->addAttr(UsedAttr::CreateImplicit(S.Context));
+}
+
 static void handleAnyX86InterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   // Semantic checks for a function with the 'interrupt' attribute.
   // a) Must be a function.
@@ -6069,6 +6102,9 @@
   case llvm::Triple::mips:
 handleMipsInterruptAttr(S, D, AL);
 break;
+  case llvm::Triple::m680x0:
+handleM680x0InterruptAttr(S, D, AL);
+break;
   case llvm::Triple::x86:
   case llvm::Triple::x86_64:
 handleAnyX86InterruptAttr(S, D, AL);
Index: clang/lib/CodeGen/TargetInfo.cpp
===
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -8064,6 +8064,46 @@
   return false;
 }
 
+//===--===//
+// M680x0 ABI Implementation
+//===--===//
+
+namespace {
+
+class M680x0TargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  M680x0TargetCodeGenInfo(CodeGenTypes &CGT)
+: TargetCodeGenInfo(std::make_unique(CGT)) {}
+  void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+   CodeGen::CodeGenModule &M) const override;
+};
+
+}
+
+// TODO Does not actually work right now
+void M680x0TargetCodeGenInfo::
+setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+CodeGen::CodeGenModule &M) const {
+  if (const FunctionDecl *FD = dyn_cast_or_null(D)) {
+if (const M680x0InterruptAttr *attr = FD->getAttr()) {
+  // Handle 'interrupt' attribute:
+  llvm::Function *F = cast(GV);
+
+  // Step 1: Set ISR calling convention.
+  F->setCallingConv(llvm::CallingConv::M680x0_INTR);
+
+  // Step 2: Add attributes goodness.
+  F->addFnAttr(llvm::Attribute::NoInline);
+
+  // ??? is this right
+  // Step 3: Emit ISR vector alias.
+  unsigned Num = attr->getNumber() / 2;
+  llvm::GlobalAlias::create(llvm::Function::ExternalLinkage,
+"__isr_" + Twine(Num), F);
+}
+  }
+}
+
 //===--===//
 // AVR ABI Implementation.
 //===--===//
Index: clang/lib/Basic/Targets/M680x0.h
===
--- /dev/null
+++ clang/lib/Basic/Targets/M680x0.h
@@ -0,0 +1,58 @@
+//===--- M680x0.h - Declare M680x0 target feature support ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// This file declares M680x0 TargetInfo objects.
+//
+//===--===//
+
+#ifndef M680X0_H_LTNCIPAD
+#define M680X0_H_LTNCIPAD
+
+#include "OSTargets.h"
+#include "clang/Basi

[PATCH] D88394: [Driver][M68K] (Patch 8/8) Add driver support for M68K

2020-09-27 Thread Min-Yih Hsu via Phabricator via cfe-commits
myhsu created this revision.
Herald added subscribers: cfe-commits, dang, mgorny.
Herald added a project: clang.
myhsu requested review of this revision.
Herald added a subscriber: ormris.

Add new toolchain and driver options for the M680x0 target


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D88394

Files:
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/CMakeLists.txt
  clang/lib/Driver/ToolChains/Arch/M680x0.cpp
  clang/lib/Driver/ToolChains/Arch/M680x0.h
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  clang/lib/Driver/ToolChains/Gnu.cpp
  clang/lib/Driver/ToolChains/Linux.cpp
  clang/test/Driver/m680x0-features.cpp
  clang/test/Driver/m680x0-sub-archs.cpp

Index: clang/test/Driver/m680x0-sub-archs.cpp
===
--- /dev/null
+++ clang/test/Driver/m680x0-sub-archs.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang -### -target m680x0-unknown-linux -mcpu=68000 %s 2>&1 | FileCheck --check-prefix=CHECK-MX00 %s
+// RUN: %clang -### -target m680x0-unknown-linux -m68000 %s 2>&1 | FileCheck --check-prefix=CHECK-MX00 %s
+// CHECK-MX00: "-target-cpu" "68000"
+
+// RUN: %clang -### -target m680x0-unknown-linux -mcpu=68010 %s 2>&1 | FileCheck --check-prefix=CHECK-MX10 %s
+// RUN: %clang -### -target m680x0-unknown-linux -m68010 %s 2>&1 | FileCheck --check-prefix=CHECK-MX10 %s
+// CHECK-MX10: "-target-cpu" "68010"
+
+// RUN: %clang -### -target m680x0-unknown-linux -mcpu=68020 %s 2>&1 | FileCheck --check-prefix=CHECK-MX20 %s
+// RUN: %clang -### -target m680x0-unknown-linux -m68020 %s 2>&1 | FileCheck --check-prefix=CHECK-MX20 %s
+// CHECK-MX20: "-target-cpu" "68020"
+
+// RUN: %clang -### -target m680x0-unknown-linux -mcpu=68030 %s 2>&1 | FileCheck --check-prefix=CHECK-MX30 %s
+// RUN: %clang -### -target m680x0-unknown-linux -m68030 %s 2>&1 | FileCheck --check-prefix=CHECK-MX30 %s
+// CHECK-MX30: "-target-cpu" "68030"
+
+// RUN: %clang -### -target m680x0-unknown-linux -mcpu=68040 %s 2>&1 | FileCheck --check-prefix=CHECK-MX40 %s
+// RUN: %clang -### -target m680x0-unknown-linux -m68040 %s 2>&1 | FileCheck --check-prefix=CHECK-MX40 %s
+// CHECK-MX40: "-target-cpu" "68040"
+
+// RUN: %clang -### -target m680x0-unknown-linux -mcpu=68060 %s 2>&1 | FileCheck --check-prefix=CHECK-MX60 %s
+// RUN: %clang -### -target m680x0-unknown-linux -m68060 %s 2>&1 | FileCheck --check-prefix=CHECK-MX60 %s
+// CHECK-MX60: "-target-cpu" "68060"
Index: clang/test/Driver/m680x0-features.cpp
===
--- /dev/null
+++ clang/test/Driver/m680x0-features.cpp
@@ -0,0 +1,45 @@
+// Check macro definitions
+// RUN: %clang -target m680x0-unknown-linux -m68000 -dM -E %s | FileCheck --check-prefix=CHECK-MX %s
+// CHECK-MX: #define __mc68000 1
+// CHECK-MX: #define __mc68000__ 1
+// CHECK-MX: #define mc68000 1
+
+// RUN: %clang -target m680x0-unknown-linux -m68010 -dM -E %s | FileCheck --check-prefix=CHECK-MX10 %s
+// CHECK-MX10: #define __mc68000 1
+// CHECK-MX10: #define __mc68000__ 1
+// CHECK-MX10: #define __mc68010 1
+// CHECK-MX10: #define __mc68010__ 1
+// CHECK-MX10: #define mc68000 1
+// CHECK-MX10: #define mc68010 1
+
+// RUN: %clang -target m680x0-unknown-linux -m68020 -dM -E %s | FileCheck --check-prefix=CHECK-MX20 %s
+// CHECK-MX20: #define __mc68000 1
+// CHECK-MX20: #define __mc68000__ 1
+// CHECK-MX20: #define __mc68020 1
+// CHECK-MX20: #define __mc68020__ 1
+// CHECK-MX20: #define mc68000 1
+// CHECK-MX20: #define mc68020 1
+
+// RUN: %clang -target m680x0-unknown-linux -m68030 -dM -E %s | FileCheck --check-prefix=CHECK-MX30 %s
+// CHECK-MX30: #define __mc68000 1
+// CHECK-MX30: #define __mc68000__ 1
+// CHECK-MX30: #define __mc68030 1
+// CHECK-MX30: #define __mc68030__ 1
+// CHECK-MX30: #define mc68000 1
+// CHECK-MX30: #define mc68030 1
+
+// RUN: %clang -target m680x0-unknown-linux -m68040 -dM -E %s | FileCheck --check-prefix=CHECK-MX40 %s
+// CHECK-MX40: #define __mc68000 1
+// CHECK-MX40: #define __mc68000__ 1
+// CHECK-MX40: #define __mc68040 1
+// CHECK-MX40: #define __mc68040__ 1
+// CHECK-MX40: #define mc68000 1
+// CHECK-MX40: #define mc68040 1
+
+// RUN: %clang -target m680x0-unknown-linux -m68060 -dM -E %s | FileCheck --check-prefix=CHECK-MX60 %s
+// CHECK-MX60: #define __mc68000 1
+// CHECK-MX60: #define __mc68000__ 1
+// CHECK-MX60: #define __mc68060 1
+// CHECK-MX60: #define __mc68060__ 1
+// CHECK-MX60: #define mc68000 1
+// CHECK-MX60: #define mc68060 1
Index: clang/lib/Driver/ToolChains/Linux.cpp
===
--- clang/lib/Driver/ToolChains/Linux.cpp
+++ clang/lib/Driver/ToolChains/Linux.cpp
@@ -102,6 +102,12 @@
 if (D.getVFS().exists(SysRoot + "/lib/aarch64_be-linux-gnu"))
   return "aarch64_be-linux-gnu";
 break;
+
+  case llvm::Triple::m680x0:
+if (D.getVFS().exists(SysRoot + "/lib/m68k-linux-gnu"))
+  return "m68k-linux-gnu";
+break;
+
   case llvm::Triple::mi

[PATCH] D87974: [Builtin] Add __builtin_zero_non_value_bits.

2020-09-27 Thread Zoe Carver via Phabricator via cfe-commits
zoecarver updated this revision to Diff 294603.
zoecarver marked 3 inline comments as done.
zoecarver added a comment.

- Add UnsizedTail codegen test


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87974/new/

https://reviews.llvm.org/D87974

Files:
  clang/include/clang/Basic/Builtins.def
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGenCXX/builtin-zero-non-value-bits-codegen.cpp
  clang/test/CodeGenCXX/builtin-zero-non-value-bits.cpp
  clang/test/SemaCXX/builtin-zero-non-value-bits.cpp

Index: clang/test/SemaCXX/builtin-zero-non-value-bits.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/builtin-zero-non-value-bits.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Foo { };
+
+struct Incomplete; // expected-note {{forward declaration of 'Incomplete'}}
+
+void test(int a, Foo b, void* c, int *d, Foo *e, const Foo *f, Incomplete *g) {
+  __builtin_zero_non_value_bits(a); // expected-error {{passing 'int' to parameter of incompatible type structure pointer: type mismatch at 1st parameter ('int' vs structure pointer)}}
+  __builtin_zero_non_value_bits(b); // expected-error {{passing 'Foo' to parameter of incompatible type structure pointer: type mismatch at 1st parameter ('Foo' vs structure pointer)}}
+  __builtin_zero_non_value_bits(c); // expected-error {{passing 'void *' to parameter of incompatible type structure pointer: type mismatch at 1st parameter ('void *' vs structure pointer)}}
+  __builtin_zero_non_value_bits(d); // expected-error {{passing 'int *' to parameter of incompatible type structure pointer: type mismatch at 1st parameter ('int *' vs structure pointer)}}
+  __builtin_zero_non_value_bits(e); // This should not error.
+  __builtin_zero_non_value_bits(f); // expected-error {{read-only variable is not assignable}}
+  __builtin_zero_non_value_bits(g); // expected-error {{variable has incomplete type 'Incomplete'}}
+}
Index: clang/test/CodeGenCXX/builtin-zero-non-value-bits.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/builtin-zero-non-value-bits.cpp
@@ -0,0 +1,249 @@
+// RUN: mkdir -p %t
+// RUN: %clang++ %s -o %t/run
+// RUN: %t/run
+
+#include 
+#include 
+#include 
+#include 
+
+template
+struct alignas(A1) BasicWithPadding {
+  T x;
+  alignas(A2) T y;
+};
+
+template
+struct alignas(A1) SpacedArrayMembers {
+  T x[N];
+  alignas(A2) char c;
+  T y[N];
+};
+
+template
+struct alignas(A1) PaddedPointerMembers {
+  T *x;
+  alignas(A2) T *y;
+};
+
+template
+struct alignas(A1) ThreeMembers {
+  T x;
+  alignas(A2) T y;
+  alignas(A3) T z;
+};
+
+template
+struct Normal {
+  T a;
+  T b;
+};
+
+template
+struct X {
+  T x;
+};
+
+template
+struct Z {
+  T z;
+};
+
+template
+struct YZ : public Z {
+  alignas(A) T y;
+};
+
+template
+struct alignas(A1) HasBase : public X, public YZ {
+  T a;
+  alignas(A2) T b;
+};
+
+template
+void testAllForType(T a, T b, T c, T d) {
+  using B = BasicWithPadding;
+  B basic1;
+  memset(&basic1, 0, sizeof(B));
+  basic1.x = a;
+  basic1.y = b;
+  B basic2;
+  memset(&basic2, 42, sizeof(B));
+  basic2.x = a;
+  basic2.y = b;
+  assert(memcmp(&basic1, &basic2, sizeof(B)) != 0);
+  __builtin_zero_non_value_bits(&basic2);
+  assert(memcmp(&basic1, &basic2, sizeof(B)) == 0);
+
+  using A = SpacedArrayMembers;
+  A arr1;
+  memset(&arr1, 0, sizeof(A));
+  arr1.x[0] = a;
+  arr1.x[1] = b;
+  arr1.y[0] = c;
+  arr1.y[1] = d;
+  A arr2;
+  memset(&arr2, 42, sizeof(A));
+  arr2.x[0] = a;
+  arr2.x[1] = b;
+  arr2.y[0] = c;
+  arr2.y[1] = d;
+  arr2.c = 0;
+  assert(memcmp(&arr1, &arr2, sizeof(A)) != 0);
+  __builtin_zero_non_value_bits(&arr2);
+  assert(memcmp(&arr1, &arr2, sizeof(A)) == 0);
+
+  using P = PaddedPointerMembers;
+  P ptr1;
+  memset(&ptr1, 0, sizeof(P));
+  ptr1.x = &a;
+  ptr1.y = &b;
+  P ptr2;
+  memset(&ptr2, 42, sizeof(P));
+  ptr2.x = &a;
+  ptr2.y = &b;
+  assert(memcmp(&ptr1, &ptr2, sizeof(P)) != 0);
+  __builtin_zero_non_value_bits(&ptr2);
+  assert(memcmp(&ptr1, &ptr2, sizeof(P)) == 0);
+
+  using Three = ThreeMembers;
+  Three three1;
+  memset(&three1, 0, sizeof(Three));
+  three1.x = a;
+  three1.y = b;
+  three1.z = c;
+  Three three2;
+  memset(&three2, 42, sizeof(Three));
+  three2.x = a;
+  three2.y = b;
+  three2.z = c;
+  __builtin_zero_non_value_bits(&three2);
+  assert(memcmp(&three1, &three2, sizeof(Three)) == 0);
+
+  using N = Normal;
+  N normal1;
+  memset(&normal1, 0, sizeof(N));
+  normal1.a = a;
+  normal1.b = b;
+  N normal2;
+  memset(&normal2, 42, sizeof(N));
+  normal2.a = a;
+  normal2.b = b;
+  __builtin_zero_non_value_bits(&normal2);
+  assert(memcmp(&normal1, &normal2, sizeof(N)) == 0);
+
+  using H = HasBase;
+  H base1;
+  memset(&base1, 0, sizeof(H));
+  base1.a = a;
+  base1.b = b;
+  base1.x = c;
+  base1.y = d;
+  base1.z = a;
+  H base2;
+  memset(&base2, 42, sizeof(H));
+ 

[PATCH] D87974: [Builtin] Add __builtin_zero_non_value_bits.

2020-09-27 Thread Zoe Carver via Phabricator via cfe-commits
zoecarver marked 3 inline comments as done.
zoecarver added inline comments.



Comment at: clang/test/CodeGenCXX/builtin-zero-non-value-bits-codegen.cpp:16
+  Bar f;
+};
+

jfb wrote:
> It would be helpful to have a comment with the final layout of the struct, 
> including padding. Give each padding field a name, and reference them in the 
> IR check below.
Done. I've named each padding field as "PAD_X" so below it should be clear what 
fields are being stored without a comment. 



Comment at: clang/test/CodeGenCXX/builtin-zero-non-value-bits-codegen.cpp:26
+// CHECK: [[FOO_RAW_PTR:%.*]] = bitcast %struct.Foo* [[FOO_BASE]] to i8*
+// CHECK: [[PAD_1:%.*]] = getelementptr i8, i8* [[FOO_RAW_PTR]], i32 1
+// CHECK: store i8 0, i8* [[PAD_1]]

jfb wrote:
> It would help read the tests if you had a comment on top of each store, for 
> example here "padding byte X".
See above comment. 



Comment at: clang/test/CodeGenCXX/builtin-zero-non-value-bits-codegen.cpp:46
+void test(Baz *baz) {
+  __builtin_zero_non_value_bits(baz);
+}

jfb wrote:
> It would be useful to see a test for arrays with a type that contains tail 
> padding.
Hmm, this test case doesn't seem to be working. I'll investigate further. 



Comment at: clang/test/CodeGenCXX/builtin-zero-non-value-bits.cpp:160
+
+int main() {
+  testAllForType<32, 16, char>(11, 22, 33, 44);

jfb wrote:
> zoecarver wrote:
> > jfb wrote:
> > > Usually CodeGen tests will use lit to check the emitted IR matches 
> > > expectations. I think that's what you want to do here.
> > > 
> > > Remember to test `volatile` qualified pointers, as well as address spaces 
> > > too.
> > What's a good place for me to put this end-to-end test?
> I'm not sure, I don't usually add this type of test :)
Even if it's a bit unconventional, I think it would be good to have this type 
of test. I think we should try to cover as many test cases as possible because 
it's important that this builtin both doesn't zero non-padding bits and does 
zero all padding bits. And it wouldn't be practical to add the 100+ test cases 
covered here as codegen tests. 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87974/new/

https://reviews.llvm.org/D87974

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


[PATCH] D77229: [Analyzer][NFC] Avoid handling of LazyCompundVals in IteratorModeling

2020-09-27 Thread Balogh , Ádám via Phabricator via cfe-commits
baloghadamsoftware added a comment.

Now I completely know what the source of our misunderstanding is. You thought 
that this patch will **fix** an issue, namely that we store iterator positions 
for both the iterator values and the locations of the iterator variables. While 
this is definitely a wrong approach, it could not be fixed until we got rid 
from the hack with `LazyCompoundVal`s. These functions **keep this existing 
issue** unfixed. However, I could not understand you because I was completely 
focusing on how these functions could **introduce a new issue** and I could not 
find it. No wonder. Thus all my efforts were focused on finding a test cases 
which passed in the earlier versions but fail in this one because of these 
functions. Of course I could not find any and I was continuously proving that 
my patch is correct in the sense that it does not make things worse than they 
were. That is why I implemented the pointer-based iterators (it would have been 
better after this patch and a subsequent one that fixes this issue) where I was 
facing problems because of this wrong approach. In the same time you 
continuously came with new examples which tried to prove the issue, but I could 
not understand it because all these new test cases failed in the master version 
as well. We talked about two very different things because we had very 
different perceptions about the goal of this patch. That was all.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77229/new/

https://reviews.llvm.org/D77229

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


[PATCH] D87225: [clangd] When finding refs for a renaming alias, do not return refs to underlying decls

2020-09-27 Thread Haojian Wu via Phabricator via cfe-commits
hokein accepted this revision.
hokein added a comment.
This revision is now accepted and ready to land.

thanks.




Comment at: clang-tools-extra/clangd/XRefs.cpp:1147
+getDeclAtPosition(AST, *CurLoc, Relations);
+std::vector AdditionalDecls;
+// If the results include a *non-renaming* alias, get its

nit: name it `NonrenamingAliasUnderlyingDecls`?



Comment at: clang-tools-extra/clangd/XRefs.cpp:1155
+  AdditionalDecls.push_back(AD);
+break;
+  }

I think the `break` is not necessarily needed. In practice we should just have 
one non-renaming alias at the current position. If not, that probably means we 
likely have a bug, `break` seems to just hide the bug.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87225/new/

https://reviews.llvm.org/D87225

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


[PATCH] D87962: [clang] Change the multi-character character constants from extension to implementation-defined.

2020-09-27 Thread Chuyang Chen via Phabricator via cfe-commits
nomanous added a comment.

Ping @rsmith


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87962/new/

https://reviews.llvm.org/D87962

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