[PATCH] D60934: [clang] adding explicit(bool) from c++2a

2019-04-28 Thread Tyker via Phabricator via cfe-commits
Tyker marked an inline comment as done.
Tyker added a comment.

Fixed based on Feedback from @rsmith @martong @Rakete.

feedback that weren't fixed have comment explaining why.




Comment at: clang/include/clang/AST/DeclCXX.h:2033
+
+  void setExplicitSpecifier(ExplicitSpecInfo ESI);
+

Tyker wrote:
> rsmith wrote:
> > Generally we don't want to have setters in the AST; the AST is intended to 
> > be immutable after creation. Is this necessary?
> this is used in 2 cases:
> - for deserialization.
> - for in `Sema::ActOnFunctionDeclarator` to make every declaration of the 
> same function have the same explicit specifier as the canonical one. there is 
> probably a better way to do this but i didn't find how.
> 
> the second use case will need to be changed because the constructor's 
> explicit specifier will be tail-allocated so the explicit specifier from the 
> canonical declaration will need to be recovered before construction to 
> allocate storage. 
> 
> how can we find the canonical declaration of a function before it is 
> constructed ?
i found a solution around that issue.
now setExplicitSpecifier is only used for deserialization.



Comment at: clang/include/clang/Basic/DiagnosticParseKinds.td:40
+def note_explicit_bool_breaking_change_cxx2a : Note<
+  "this expression is parsed as explicit(bool) since C++2a">;
+

rsmith wrote:
> This should be a warning in the `CXXPre2aCompat` group, phrased as 
> "explicit(bool) is incompatible with C++ standards before C++2a".
explicit(bool) can only be parse with the c++2a option because code like:
```
 struct C {
  explicit(C)(int);
 };
```
is correct before c++2a but is parsed as explicit(bool) and fail to complie in 
c++2a.
so i don't think this warning can be fired in any case. so i removed it.



Comment at: clang/lib/Parse/ParseDecl.cpp:3533
+  if (ExplicitExpr.isInvalid()) {
+Diag(ParenLoc, diag::note_explicit_bool_breaking_change_cxx2a)
+<< FixItHint::CreateReplacement(

rsmith wrote:
> Rakete wrote:
> > This is a useful diagnostic but you'll need to fix (a lot) of false 
> > positives:
> > 
> > ```
> > template  struct Foo { explicit(T{} +) Foo(); };
> > ```
> > 
> > gets me:
> > 
> > ```
> > main.cpp:1:50: error: expected expression
> > template  struct Foo { explicit(T{} +) Foo(); };
> >  ^
> > main.cpp:1:44: note: this expression is parsed as explicit(bool) since C++2a
> > template  struct Foo { explicit(T{} +) Foo(); };
> >^
> >explicit(true)
> > ```
> > 
> > Fixit hints should only be used when it is 100% the right fix that works, 
> > always.
> This "add a note after an error" construct is an anti-pattern, and will fail 
> in a bunch of cases (for example: if multiple diagnostics are produced, it 
> gets attached to the last one rather than the first; if a disabled warning / 
> remark is produced last, the note is not displayed at all).
> 
> As noted above, the conventional way to handle this is to unconditionally 
> produce a `-Wc++17-compat` warning when we see `explicit(`. Attaching a 
> context note to the diagnostic if building the expression fails (catching 
> both `Parse` and `Sema` diagnostics) will require more invasive changes and 
> I'd prefer to see that left to a separate patch (if we do it at all).
after the comment from rsmith i will remove it at least for now.



Comment at: clang/lib/Sema/SemaInit.cpp:9361
 // Only consider converting constructors.
-if (GD->isExplicit())
+if (!GD->isMaybeNotExplicit())
   continue;

rsmith wrote:
> We need to substitute into the deduction guide first to detect whether it 
> forms a "converting constructor", and that will need to be done inside 
> `AddTemplateOverloadCandidate`.
similarly as the previous if. this check removes deduction guide that are 
already resolve to be explicit when we are in a context that doesn't allow 
explicit.
every time the explicitness was checked before my change i replaced it by a 
check that removes already resolved explicit specifiers.



Comment at: clang/test/SemaCXX/cxx2a-compat.cpp:51
+#else
+// expected-error@-8 {{does not refer to a value}}
+// expected-error@-9 {{expected member name or ';'}}

Rakete wrote:
> A fixit hint for this would be great. Also it would be nice if there was a 
> nicer error message.
this had a fix it in the previous patch with the "this expression is parsed as 
explicit(bool) since C++2a" note. but i removed it because to much false 
positive and fixing it would make the patch even bigger.


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

https://reviews.llvm.org/D60934



___
cfe-commits mailing list
cfe-commit

[PATCH] D60934: [clang] adding explicit(bool) from c++2a

2019-04-30 Thread Tyker via Phabricator via cfe-commits
Tyker marked 2 inline comments as done.
Tyker added inline comments.



Comment at: clang/include/clang/AST/DeclBase.h:1539-1541
+uint64_t NumCtorInitializers : 64 - NumDeclContextBits -
+NumFunctionDeclBits -
+/*Other used bits in CXXConstructorDecl*/ 3;

rsmith wrote:
> I would prefer that we keep an explicit number here so that we can ensure 
> that this field has the range we desire.
couldn't we compute the value and static_assert on it. having to modify this 
each time we modify DeclContextBits or FunctionDeclBits is sad. and there isn't 
anything reminding us to do so in some cases.
what would be a reasonable minimum ?



Comment at: clang/lib/Sema/SemaInit.cpp:3817-3831
+if (AllowExplicit || !Conv->isExplicit()) {
   if (ConvTemplate)
-S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(),
- ActingDC, Initializer, DestType,
- CandidateSet, AllowExplicit,
- /*AllowResultConversion*/false);
+S.AddTemplateConversionCandidate(
+ConvTemplate, I.getPair(), ActingDC, Initializer, DestType,
+CandidateSet, AllowExplicit, AllowExplicit,
+/*AllowResultConversion*/ false);
   else

rsmith wrote:
> We no longer pass `false` for `AllowExplicit` to `Add*Candidate` when 
> `CopyInitializing` is `true`. Is that an intentional change?
yes. i didn't found any cases in which AllowExplicit was false but 
CopyInitializing was true. so i assumed that relying only on AllowExplicit is 
better. the regression tests passes after the change.


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

https://reviews.llvm.org/D60934



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


[PATCH] D60934: [clang] adding explicit(bool) from c++2a

2019-04-30 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/include/clang/AST/DeclCXX.h:2033
+
+  void setExplicitSpecifier(ExplicitSpecInfo ESI);
+

Tyker wrote:
> Tyker wrote:
> > rsmith wrote:
> > > Generally we don't want to have setters in the AST; the AST is intended 
> > > to be immutable after creation. Is this necessary?
> > this is used in 2 cases:
> > - for deserialization.
> > - for in `Sema::ActOnFunctionDeclarator` to make every declaration of the 
> > same function have the same explicit specifier as the canonical one. there 
> > is probably a better way to do this but i didn't find how.
> > 
> > the second use case will need to be changed because the constructor's 
> > explicit specifier will be tail-allocated so the explicit specifier from 
> > the canonical declaration will need to be recovered before construction to 
> > allocate storage. 
> > 
> > how can we find the canonical declaration of a function before it is 
> > constructed ?
> i found a solution around that issue.
> now setExplicitSpecifier is only used for deserialization.
as it is only used by deserialization and ASTDeclReader is friend to all class 
with a setExplicitSpecifier.
I made setExplicitSpecifier private.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:6174
 CXXConversionDecl)) {
-  return Node.isExplicit();
+  return Node.getExplicitSpecifier().isSpecified();
 }

rsmith wrote:
> This will match `explicit(false)` constructors. I think 
> `getExplicitSpecifier().isExplicit()` would be better, but please also add a 
> FIXME here: it's not clear whether this should match a dependent 
> `explicit()`.
shouldn't this be able to match with deduction guides too ?



Comment at: clang/lib/Sema/SemaInit.cpp:9361
 // Only consider converting constructors.
-if (GD->isExplicit())
+if (!GD->isMaybeNotExplicit())
   continue;

rsmith wrote:
> Tyker wrote:
> > rsmith wrote:
> > > We need to substitute into the deduction guide first to detect whether it 
> > > forms a "converting constructor", and that will need to be done inside 
> > > `AddTemplateOverloadCandidate`.
> > similarly as the previous if. this check removes deduction guide that are 
> > already resolve to be explicit when we are in a context that doesn't allow 
> > explicit.
> > every time the explicitness was checked before my change i replaced it by a 
> > check that removes already resolved explicit specifiers.
> Unlike in the previous case, we do //not// yet pass an `AllowExplicit` flag 
> into `AddTemplateOverloadCandidate` here, so this will incorrectly allow 
> dependent //explicit-specifier//s that evaluate to `true` in 
> copy-initialization contexts.
the default value for `AllowExplicit` is false. so the conversion will be 
removed in `AddTemplateOverloadCandidate`.


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

https://reviews.llvm.org/D60934



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


[PATCH] D60934: [clang] adding explicit(bool) from c++2a

2019-05-01 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/include/clang/AST/DeclCXX.h:2579
+assert(
+!ES.getExpr() ||
+CXXConstructorDeclBits.HasTrailingExplicitSpecifier &&

Rakete wrote:
> Your or needs parens or the disambiguation is wrong.
i don't understand. but there is no need for disambiguation, `a && true == a` 
so this will work regardless of operator priority.



Comment at: clang/include/clang/Serialization/ASTReader.h:2435
+uint64_t Kind = readInt();
+bool hasExpr = Kind & 0x1;
+Kind = Kind >> 1;

Rakete wrote:
> same here.
what is the issue



Comment at: clang/lib/Sema/SemaInit.cpp:9361
 // Only consider converting constructors.
-if (GD->isExplicit())
+if (!GD->isMaybeNotExplicit())
   continue;

rsmith wrote:
> Tyker wrote:
> > rsmith wrote:
> > > Tyker wrote:
> > > > rsmith wrote:
> > > > > We need to substitute into the deduction guide first to detect 
> > > > > whether it forms a "converting constructor", and that will need to be 
> > > > > done inside `AddTemplateOverloadCandidate`.
> > > > similarly as the previous if. this check removes deduction guide that 
> > > > are already resolve to be explicit when we are in a context that 
> > > > doesn't allow explicit.
> > > > every time the explicitness was checked before my change i replaced it 
> > > > by a check that removes already resolved explicit specifiers.
> > > Unlike in the previous case, we do //not// yet pass an `AllowExplicit` 
> > > flag into `AddTemplateOverloadCandidate` here, so this will incorrectly 
> > > allow dependent //explicit-specifier//s that evaluate to `true` in 
> > > copy-initialization contexts.
> > the default value for `AllowExplicit` is false. so the conversion will be 
> > removed in `AddTemplateOverloadCandidate`.
> That doesn't sound right: that'd mean we never use explicit deduction guides 
> (we never pass `AllowExplicit = true` to `AddTemplateOverloadCandidate`). Do 
> we have any test coverage that demonstrates that conditionally-explicit 
> deduction guides are handled properly?
my mistake. the default value for AllowExplicit is false. but 
AddTemplateOverloadCandidate will only remove conversions and constructors. 
dependent explicit specifier that are resolved to true on deduction guides are 
removed at line 9480. they are not removed from the overload set. CTAD just 
fails if a explicit deduction guide is selected in a CopyInitList. i agree this 
is weird but the behavior is the same as before the patch.
the result on clang is:
```
template
struct A {
  explicit A(T);
};
A a = 0; // error with explicit constructor meaning CTAD succeed.
A a = { 0 }; // error with explicit deduction guide
```
all compiler don't agree on this https://godbolt.org/z/ElHlkE. icc and clang 
have this behavior, gcc and msvc fail at CTAD time on both initialization. as 
of what the standard say from what i read, it isn't clear, the standard is 
clear when calling an explicit constructor should fail. but it doesn't appear 
to say for deduction guides.
as this was the previous behavior i did not change it with explicit(bool).



Comment at: clang/test/CXX/temp/temp.deduct.guide/p1.cpp:74
 virtual A(int(&)[28]) -> A; // expected-error {{'virtual' can only appear 
on non-static member functions}}
-const A(int(&)[28]) -> A; // expected-error {{deduction guide cannot be 
declared 'const'}}
+const A(int(&)[31]) -> A; // expected-error {{deduction guide cannot be 
declared 'const'}}
 

Rakete wrote:
> Is there a reason why you changed this?
yes. One of change that was made is making deduction guide redeclaration be an 
error. Without this change, this line was a redeclartion so the test didn't 
serve its purpose.


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

https://reviews.llvm.org/D60934



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


[PATCH] D60934: [clang] adding explicit(bool) from c++2a

2019-05-02 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/lib/Sema/SemaInit.cpp:9361
 // Only consider converting constructors.
-if (GD->isExplicit())
+if (!GD->isMaybeNotExplicit())
   continue;

rsmith wrote:
> Tyker wrote:
> > rsmith wrote:
> > > Tyker wrote:
> > > > rsmith wrote:
> > > > > Tyker wrote:
> > > > > > rsmith wrote:
> > > > > > > We need to substitute into the deduction guide first to detect 
> > > > > > > whether it forms a "converting constructor", and that will need 
> > > > > > > to be done inside `AddTemplateOverloadCandidate`.
> > > > > > similarly as the previous if. this check removes deduction guide 
> > > > > > that are already resolve to be explicit when we are in a context 
> > > > > > that doesn't allow explicit.
> > > > > > every time the explicitness was checked before my change i replaced 
> > > > > > it by a check that removes already resolved explicit specifiers.
> > > > > Unlike in the previous case, we do //not// yet pass an 
> > > > > `AllowExplicit` flag into `AddTemplateOverloadCandidate` here, so 
> > > > > this will incorrectly allow dependent //explicit-specifier//s that 
> > > > > evaluate to `true` in copy-initialization contexts.
> > > > the default value for `AllowExplicit` is false. so the conversion will 
> > > > be removed in `AddTemplateOverloadCandidate`.
> > > That doesn't sound right: that'd mean we never use explicit deduction 
> > > guides (we never pass `AllowExplicit = true` to 
> > > `AddTemplateOverloadCandidate`). Do we have any test coverage that 
> > > demonstrates that conditionally-explicit deduction guides are handled 
> > > properly?
> > my mistake. the default value for AllowExplicit is false. but 
> > AddTemplateOverloadCandidate will only remove conversions and constructors. 
> > dependent explicit specifier that are resolved to true on deduction guides 
> > are removed at line 9480. they are not removed from the overload set. CTAD 
> > just fails if a explicit deduction guide is selected in a CopyInitList. i 
> > agree this is weird but the behavior is the same as before the patch.
> > the result on clang is:
> > ```
> > template
> > struct A {
> >   explicit A(T);
> > };
> > A a = 0; // error with explicit constructor meaning CTAD succeed.
> > A a = { 0 }; // error with explicit deduction guide
> > ```
> > all compiler don't agree on this https://godbolt.org/z/ElHlkE. icc and 
> > clang have this behavior, gcc and msvc fail at CTAD time on both 
> > initialization. as of what the standard say from what i read, it isn't 
> > clear, the standard is clear when calling an explicit constructor should 
> > fail. but it doesn't appear to say for deduction guides.
> > as this was the previous behavior i did not change it with explicit(bool).
> > the standard is clear when calling an explicit constructor should fail. but 
> > it doesn't appear to say for deduction guides
> 
> The standard says that you take the set of deduction guides and notionally 
> form a set of constructors from them (see [over.match.class.deduct]). So the 
> constructor rules apply to deduction guides too.
> 
> > as this was the previous behavior i did not change it with explicit(bool).
> 
> I don't think that's correct. We filter out explicit deduction guides for 
> non-list copy-initialization on line ~9239 (prior to this change). Today we 
> get this result:
> 
> ```
> template struct X { X(int); };
> 
> explicit X(int) -> X; // #1
> 
> X a = 0; // error: no viable deduction guide, #1 is not a candidate
> X b = {0}; // error: selected explicit deduction guide #1
> X c{0}; // ok
> X d(0); // ok
> ```
> 
> ... which is correct. If we change the deduction guide to have a dependent 
> `explicit(bool)` specifier:
> 
> ```
> template
> explicit(E) X(int) -> X;
> ```
> 
> ... we should get the same result, but I think we won't get that result with 
> this patch: I think we'll incorrectly select an explicit deduction guide for 
> the declaration of `a`, because we never filter out explicit deduction guides.
> 
> `DeduceTemplateSpecializationFromInitializer` should compute an 
> `AllowExplicit` flag (`= !Kind.isCopyInit() || ListInit`), pass it into 
> `AddTemplateOverloadCandidate`, and that should filter out explicit deduction 
> guide specializations if it's `true`.
there was an issue. now fixed.



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

https://reviews.llvm.org/D60934



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


[PATCH] D61552: [clang] Adapt ASTMatcher to explicit(bool) specifier

2019-05-04 Thread Tyker via Phabricator via cfe-commits
Tyker created this revision.
Tyker added a reviewer: klimek.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Changes:

- add an ast matcher for deductiong guide.
- allow isExplicit matcher for deductiong guide.
- add hasExplicitSpecifier matcher which matches for declarations that have an 
explicit specifier even if it is unresolved or resolved to false.
- added test for all of the above.


Repository:
  rC Clang

https://reviews.llvm.org/D61552

Files:
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -810,6 +810,31 @@
   cxxConversionDecl(isExplicit(;
   EXPECT_TRUE(notMatches("struct S { operator int(); };",
  cxxConversionDecl(isExplicit(;
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) operator int(); };",
+  cxxConversionDecl(isExplicit()), false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(true) operator int(); };",
+  cxxConversionDecl(isExplicit()), true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(false) operator int(); };",
+  cxxConversionDecl(isExplicit()), false, "-std=c++2a"));
+}
+
+TEST(ConversionDeclaration, HasExplicitSpecifier) {
+  EXPECT_TRUE(matches("struct S { explicit operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier(;
+  EXPECT_TRUE(notMatches("struct S { operator int(); };",
+ cxxConversionDecl(hasExplicitSpecifier(;
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier()), true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(true) operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier()), true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(false) operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier()), true, "-std=c++2a"));
 }
 
 TEST(Matcher, ArgumentCount) {
@@ -1129,6 +1154,77 @@
   cxxConstructorDecl(isExplicit(;
   EXPECT_TRUE(notMatches("struct S { S(int); };",
  cxxConstructorDecl(isExplicit(;
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) S(int);};",
+  cxxConstructorDecl(isExplicit()), false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("struct S { explicit(true) S(int);};",
+   cxxConstructorDecl(isExplicit()), true,
+   "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("struct S { explicit(false) S(int);};",
+   cxxConstructorDecl(isExplicit()), false,
+   "-std=c++2a"));
+}
+
+TEST(ConstructorDeclaration, HasExplicitSpecifier) {
+  EXPECT_TRUE(matches("struct S { explicit S(int); };",
+  cxxConstructorDecl(hasExplicitSpecifier(;
+  EXPECT_TRUE(notMatches("struct S { S(int); };",
+ cxxConstructorDecl(hasExplicitSpecifier(;
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) S(int);};",
+  cxxConstructorDecl(hasExplicitSpecifier()), true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("struct S { explicit(true) S(int);};",
+   cxxConstructorDecl(hasExplicitSpecifier()),
+   true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("struct S { explicit(false) S(int);};",
+   cxxConstructorDecl(hasExplicitSpecifier()),
+   true, "-std=c++2a"));
+}
+
+TEST(DeductionGuideDeclaration, IsExplicit) {
+  EXPECT_TRUE(matchesConditionally("template struct S { S(int);};"
+   "S(int) -> S;",
+   cxxDeductionGuideDecl(isExplicit()), false,
+   "-std=c++17"));
+  EXPECT_TRUE(matchesConditionally("template struct S { S(int);};"
+   "explicit S(int) -> S;",
+   cxxDeductionGuideDecl(isExplicit()), true,
+   "-std=c++17"));
+  EXPECT_TRUE(matchesConditionally("template struct S { S(int);};"
+   "explicit(true) S(int) -> S;",
+   cxxDeductionGuideDecl(isExplicit()), true,
+   "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("template struct S { S(int);};"
+   

[PATCH] D61556: [clang] fixing -ast-print for variadic parameter pack in lambda capture

2019-05-05 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

could you commit it for me please ?


Repository:
  rC Clang

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

https://reviews.llvm.org/D61556



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


[PATCH] D60934: [clang] adding explicit(bool) from c++2a

2019-05-06 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

yes i am on it.


Repository:
  rC Clang

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

https://reviews.llvm.org/D60934



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


[PATCH] D60934: [clang] adding explicit(bool) from c++2a

2019-05-07 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

could you commit this for me ?


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

https://reviews.llvm.org/D60934



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


[PATCH] D60934: [clang] adding explicit(bool) from c++2a

2019-05-09 Thread Tyker via Phabricator via cfe-commits
Tyker marked an inline comment as done.
Tyker added inline comments.



Comment at: cfe/trunk/lib/Parse/ParseDecl.cpp:3939
+ "both or neither of isAlreadyConsumed and 
"
+ "RangeEnd needs to be set");
+DS.SetRangeEnd(isAlreadyConsumed ? RangeEnd : Tok.getLocation());

RKSimon wrote:
> @Tyker @rsmith We're seeing -Wparentheses warnings because of this - please 
> can you take a look? The logic looks a little dodgy for a both/neither 
> assertion as well.
> 
> http://lab.llvm.org:8011/builders/clang-ppc64be-linux-lnt/builds/27322/steps/build%20stage%201/logs/warnings%20%281%29
i made a revision that fixes this: https://reviews.llvm.org/D61731


Repository:
  rL LLVM

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

https://reviews.llvm.org/D60934



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


[PATCH] D62399: [clang] Add storage for APValue in ConstantExpr

2019-05-31 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.
Herald added a subscriber: rnkovacs.

ping @rsmith


Repository:
  rC Clang

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

https://reviews.llvm.org/D62399



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


[PATCH] D61790: [C++20] add Basic consteval specifier

2019-06-03 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

@rsmith ping


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

https://reviews.llvm.org/D61790



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


[PATCH] D59467: [clang] Adding the Likelihood Attribute from C++2a

2019-06-04 Thread Tyker via Phabricator via cfe-commits
Tyker reclaimed this revision.
Tyker added a comment.

I closed it originally because it was inactive and i was working on other 
reviews. but i learned this is not how it is supposed to be done.


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

https://reviews.llvm.org/D59467



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


[PATCH] D61552: [clang] Adapt ASTMatcher to explicit(bool) specifier

2019-06-05 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 203115.
Tyker marked an inline comment as done.
Tyker edited the summary of this revision.
Tyker added a comment.

changed as requested.

hasExplicitSpecifier now gives access to the expression if present.


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

https://reviews.llvm.org/D61552

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1735,6 +1735,56 @@
 llvm::make_unique>("x", 3)));
 }
 
+TEST(Declaration, HasExplicitExpr) {
+  EXPECT_TRUE(matchesConditionally(
+  "void f();", functionDecl(hasExplicitExpr(constantExpr())), false,
+  "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit operator int(); };",
+  cxxConversionDecl(hasExplicitExpr(constantExpr(has(cxxBoolLiteral(),
+  false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) operator int(); };",
+  cxxConversionDecl(hasExplicitExpr(constantExpr(has(cxxBoolLiteral(),
+  false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(true) operator int(); };",
+  cxxConversionDecl(hasExplicitExpr(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(false) operator int(); };",
+  cxxConversionDecl(hasExplicitExpr(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) S(int); };",
+  cxxConstructorDecl(hasExplicitExpr(constantExpr(has(cxxBoolLiteral(),
+  false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(true) S(int); };",
+  cxxConstructorDecl(hasExplicitExpr(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(false) S(int); };",
+  cxxConstructorDecl(hasExplicitExpr(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { S(int); };"
+  "template explicit(b) S(int) -> S;",
+  cxxDeductionGuideDecl(
+  hasExplicitExpr(constantExpr(has(cxxBoolLiteral(),
+  false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("template struct S { S(int); };"
+   "explicit(true) S(int) -> S;",
+   cxxDeductionGuideDecl(hasExplicitExpr(
+   constantExpr(has(cxxBoolLiteral(),
+   true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("template struct S { S(int); };"
+   "explicit(false) S(int) -> S;",
+   cxxDeductionGuideDecl(hasExplicitExpr(
+   constantExpr(has(cxxBoolLiteral(),
+   true, "-std=c++2a"));
+}
+
 TEST(ForEachConstructorInitializer, MatchesInitializers) {
   EXPECT_TRUE(matches(
 "struct X { X() : i(42), j(42) {} int i, j; };",
Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -810,6 +810,15 @@
   cxxConversionDecl(isExplicit(;
   EXPECT_TRUE(notMatches("struct S { operator int(); };",
  cxxConversionDecl(isExplicit(;
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) operator int(); };",
+  cxxConversionDecl(isExplicit()), false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(true) operator int(); };",
+  cxxConversionDecl(isExplicit()), true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(false) operator int(); };",
+  cxxConversionDecl(isExplicit()), false, "-std=c++2a"));
 }
 
 TEST(Matcher, ArgumentCount) {
@@ -1129,6 +1138,38 @@
   cxxConstructorDecl(isExplicit(;
   EXPECT_TRUE(notMatches("struct S { S(int); };",
  cxxConstructorDecl(isExplicit(;
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) S(int);};",
+  cxxConstructorDecl(isExplicit()), false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("struct S { explicit(true) S(int);};",
+  

[PATCH] D61790: [C++20] add Basic consteval specifier

2019-06-07 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/lib/Parse/ParseDecl.cpp:2491
+  if (DS.hasConstexprSpecifier() && DSC != DeclSpecContext::DSC_condition) {
 Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr);
 DS.ClearConstexprSpec();

rsmith wrote:
> Should this say which specifier was used? Or do we somehow reject eg. 
> `sizeof(consteval int)` before we get here?
`sizeof(consteval int)` was rejected before this point but the diagnostics was 
bad. so i improved it.



Comment at: clang/lib/Parse/ParseExprCXX.cpp:1152-1154
 P.Diag(ConstexprLoc, !P.getLangOpts().CPlusPlus17
  ? diag::ext_constexpr_on_lambda_cxx17
  : diag::warn_cxx14_compat_constexpr_on_lambda);

rsmith wrote:
> We should produce a `-Wc++17-compat` diagnostic similar to this for uses of 
> `consteval`.
a consteval keyword can only be lexed when we are in C++2a because it is a 
C++2a keyword so the warning would never fire.



Comment at: clang/lib/Sema/DeclSpec.cpp:1296-1297
   << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t");
-  if (Constexpr_specified)
+  if (hasConstexprSpecifier())
 S.Diag(ConstexprLoc, diag::warn_cxx98_compat_constexpr);
 

rsmith wrote:
> For `consteval` we should produce an "incompatible with C++ standards before 
> C++2a" diagnostic, not an "incompatible with C++98" diagnostic.
same as previous comment. the consteval keyword cannot be lexed unless we are 
in c++2a mode so the warning would never fire.


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

https://reviews.llvm.org/D61790



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


[PATCH] D61790: [C++20] add Basic consteval specifier

2019-06-07 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 203551.
Tyker marked 9 inline comments as done.
Tyker added a comment.

fixed requested changes except some i commented upon.


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

https://reviews.llvm.org/D61790

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/DeclPrinter.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Parse/ParseCXXInlineMethods.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaCoroutine.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/test/SemaCXX/cxx2a-compat.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp

Index: clang/test/SemaCXX/cxx2a-consteval.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+
+namespace basic_sema {
+
+consteval int f1(int i) {
+  return i;
+}
+
+consteval constexpr int f2(int i) { 
+  //expected-error@-1 {{cannot combine}}
+  return i;
+}
+
+constexpr auto l_eval = [](int i) consteval {
+
+  return i;
+};
+
+constexpr consteval int f3(int i) {
+  //expected-error@-1 {{cannot combine}}
+  return i;
+}
+
+struct A {
+  consteval int f1(int i) const {
+return i;
+  }
+  consteval A(int i);
+  consteval A() = default;
+  consteval ~A() = default; // expected-error {{destructor cannot be marked consteval}}
+};
+
+consteval struct B {}; // expected-error {{struct cannot be marked consteval}}
+
+consteval typedef B b; // expected-error {{typedef cannot be consteval}}
+
+consteval int redecl() {return 0;} // expected-note {{previous declaration is here}}
+constexpr int redecl() {return 0;} // expected-error {{constexpr declaration of 'redecl' follows consteval declaration}}
+
+consteval int i = 0; // expected-error {{consteval can only be used in function declarations}}
+
+consteval int; // expected-error {{consteval can only be used in function declarations}}
+
+consteval int f1() {} // expected-error {{no return statement in consteval function}}
+
+struct C {
+  C() {}
+};
+
+struct D {
+  C c;
+  consteval D() = default; // expected-error {{cannot be consteval}}
+};
+}
+
+consteval int main() { // expected-error {{'main' is not allowed to be declared consteval}}
+  return 0;
+}
Index: clang/test/SemaCXX/cxx2a-compat.cpp
===
--- clang/test/SemaCXX/cxx2a-compat.cpp
+++ clang/test/SemaCXX/cxx2a-compat.cpp
@@ -56,4 +56,13 @@
 #if !defined(__cpp_conditional_explicit) || __cpp_conditional_explicit != 201806L
 #error "the feature test macro __cpp_conditional_explicit isn't correct"
 #endif
+#endif
+
+auto l = []() consteval {};
+int consteval();
+#if __cplusplus <= 201703L
+// expected-warning@-3 {{'consteval' is a keyword in C++2a}}
+// expected-error@-4 {{expected body of lambda expression}}
+#else
+// expected-error@-5 {{expected unqualified-id}}
 #endif
\ No newline at end of file
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -868,7 +868,7 @@
   FD->setDefaulted(Record.readInt());
   FD->setExplicitlyDefaulted(Record.readInt());
   FD->setHasImplicitReturnZero(Record.readInt());
-  FD->setConstexpr(Record.readInt());
+  FD->setConstexprKind(static_cast(Record.readInt()));
   FD->setUsesSEHTry(Record.readInt());
   FD->setHasSkippedBody(Record.readInt());
   FD->setIsMultiVersion(Record.readInt());
Index: clang/lib/Sema/TreeTransform.h
===
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -11337,7 +11337,7 @@
   Class, E->getIntroducerRange(), NewCallOpTSI,
   E->getCallOperator()->getEndLoc(),
   NewCallOpTSI->getTypeLoc().castAs().getParams(),
-  E->getCallOperator()->isConstexpr(), Mangling);
+  E->getCallOperator()->getConstexprKind(), Mangling);
 
   LSI->CallOperator = NewCallOperator;
 
Index: clang/lib/Sema/SemaType.cpp
===

[PATCH] D62009: [clang] perform semantic checking in constant context

2019-06-07 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

@rsmith ping.


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

https://reviews.llvm.org/D62009



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


[PATCH] D62399: [clang] Add storage for APValue in ConstantExpr

2019-06-09 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 203723.
Tyker marked 4 inline comments as done.
Tyker edited the summary of this revision.
Tyker added a comment.

fixed requested changes.
i will commit it when i have access.


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

https://reviews.llvm.org/D62399

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/AST/TextNodeDumper.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/AST/ast-dump-color.cpp
  llvm/include/llvm/ADT/APFloat.h
  llvm/lib/Support/APFloat.cpp

Index: llvm/lib/Support/APFloat.cpp
===
--- llvm/lib/Support/APFloat.cpp
+++ llvm/lib/Support/APFloat.cpp
@@ -113,6 +113,42 @@
   static const fltSemantics semPPCDoubleDoubleLegacy = {1023, -1022 + 53,
 53 + 53, 128};
 
+  const llvm::fltSemantics &APFloatBase::EnumToSemantics(Semantics S) {
+switch (S) {
+case S_IEEEhalf:
+  return IEEEhalf();
+case S_IEEEsingle:
+  return IEEEsingle();
+case S_IEEEdouble:
+  return IEEEdouble();
+case S_x87DoubleExtended:
+  return x87DoubleExtended();
+case S_IEEEquad:
+  return IEEEquad();
+case S_PPCDoubleDouble:
+  return PPCDoubleDouble();
+}
+llvm_unreachable("Unrecognised floating semantics");
+  }
+
+  APFloatBase::Semantics
+  APFloatBase::SemanticsToEnum(const llvm::fltSemantics &Sem) {
+if (&Sem == &llvm::APFloat::IEEEhalf())
+  return S_IEEEhalf;
+else if (&Sem == &llvm::APFloat::IEEEsingle())
+  return S_IEEEsingle;
+else if (&Sem == &llvm::APFloat::IEEEdouble())
+  return S_IEEEdouble;
+else if (&Sem == &llvm::APFloat::x87DoubleExtended())
+  return S_x87DoubleExtended;
+else if (&Sem == &llvm::APFloat::IEEEquad())
+  return S_IEEEquad;
+else if (&Sem == &llvm::APFloat::PPCDoubleDouble())
+  return S_PPCDoubleDouble;
+else
+  llvm_unreachable("Unknown floating semantics");
+  }
+
   const fltSemantics &APFloatBase::IEEEhalf() {
 return semIEEEhalf;
   }
Index: llvm/include/llvm/ADT/APFloat.h
===
--- llvm/include/llvm/ADT/APFloat.h
+++ llvm/include/llvm/ADT/APFloat.h
@@ -147,6 +147,17 @@
 
   /// \name Floating Point Semantics.
   /// @{
+  enum Semantics {
+S_IEEEhalf,
+S_IEEEsingle,
+S_IEEEdouble,
+S_x87DoubleExtended,
+S_IEEEquad,
+S_PPCDoubleDouble
+  };
+
+  static const llvm::fltSemantics &EnumToSemantics(Semantics S);
+  static Semantics SemanticsToEnum(const llvm::fltSemantics &Sem);
 
   static const fltSemantics &IEEEhalf() LLVM_READNONE;
   static const fltSemantics &IEEEsingle() LLVM_READNONE;
Index: clang/test/AST/ast-dump-color.cpp
===
--- clang/test/AST/ast-dump-color.cpp
+++ clang/test/AST/ast-dump-color.cpp
@@ -49,13 +49,13 @@
 //CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:11[[RESET]]> [[Green]]'int'[[RESET]][[Cyan:.\[0;36m]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:3[[RESET]], [[Yellow]]line:12:27[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| | | | `-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]AttributedStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:12:5[[RESET]], [[Yellow]]col:27[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | |   |-[[RESET]][[BLUE]]FallThroughAttr[[RESET]][[Yellow]] 0x{{

[PATCH] D61790: [C++20] add Basic consteval specifier

2019-06-09 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 203725.
Tyker marked 5 inline comments as done.
Tyker added a comment.

fixed requested changes.
also adapted lldb to AST change.
I will commit this when i have access.


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

https://reviews.llvm.org/D61790

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/Basic/DiagnosticCommonKinds.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/DeclPrinter.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Parse/ParseCXXInlineMethods.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaCoroutine.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/lib/Serialization/ASTWriterDecl.cpp
  clang/test/SemaCXX/cxx2a-compat.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp
  lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
  lldb/source/Symbol/ClangASTContext.cpp

Index: lldb/source/Symbol/ClangASTContext.cpp
===
--- lldb/source/Symbol/ClangASTContext.cpp
+++ lldb/source/Symbol/ClangASTContext.cpp
@@ -2170,7 +2170,7 @@
   *ast, decl_ctx, SourceLocation(), SourceLocation(), declarationName,
   ClangUtil::GetQualType(function_clang_type), nullptr,
   (clang::StorageClass)storage, is_inline, hasWrittenPrototype,
-  isConstexprSpecified);
+  isConstexprSpecified ? CSK_constexpr : CSK_unspecified);
   if (func_decl)
 decl_ctx->addDecl(func_decl);
 
@@ -8210,7 +8210,7 @@
 clang::SourceLocation()),
 method_qual_type,
 nullptr, // TypeSourceInfo *
-explicit_spec, is_inline, is_artificial, false /*is_constexpr*/);
+explicit_spec, is_inline, is_artificial, CSK_unspecified);
 cxx_method_decl = cxx_ctor_decl;
   } else {
 clang::StorageClass SC = is_static ? clang::SC_Static : clang::SC_None;
@@ -8233,7 +8233,7 @@
 clang::SourceLocation()),
 method_qual_type,
 nullptr, // TypeSourceInfo *
-SC, is_inline, false /*is_constexpr*/, clang::SourceLocation());
+SC, is_inline, CSK_unspecified, clang::SourceLocation());
   } else if (num_params == 0) {
 // Conversion operators don't take params...
 cxx_method_decl = clang::CXXConversionDecl::Create(
@@ -8245,7 +8245,7 @@
 clang::SourceLocation()),
 method_qual_type,
 nullptr, // TypeSourceInfo *
-is_inline, explicit_spec, false /*is_constexpr*/,
+is_inline, explicit_spec, CSK_unspecified,
 clang::SourceLocation());
   }
 }
@@ -8256,7 +8256,7 @@
   clang::DeclarationNameInfo(decl_name, clang::SourceLocation()),
   method_qual_type,
   nullptr, // TypeSourceInfo *
-  SC, is_inline, false /*is_constexpr*/, clang::SourceLocation());
+  SC, is_inline, CSK_unspecified, clang::SourceLocation());
 }
   }
 
Index: lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
===
--- lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -2127,7 +2127,7 @@
   clang::FunctionDecl *func_decl = FunctionDecl::Create(
   *ast, context, SourceLocation(), SourceLocation(), decl_name, qual_type,
   nullptr, SC_Extern, isInlineSpecified, hasWrittenPrototype,
-  isConstexprSpecified);
+  isConstexprSpecified ? CSK_constexpr : CSK_unspecified);
 
   // We have to do more than just synthesize the FunctionDecl.  We have to
   // synthesize ParmVarDecls for all of the FunctionDecl's arguments.  To do
Index: clang/test/SemaCXX/cxx2a-consteval.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+
+namespace basic_sema {
+
+consteval int f1(int i) {
+  return i;
+}
+
+consteval constexpr int f2(int i) { 
+  //expected-error@-1 {{cannot combine}}
+  return i;
+}
+
+constexpr auto l_eval = [](int i) consteval {
+
+  return i;
+};
+
+constexpr conste

[PATCH] D63072: [clang] Fixing incorrect implicit deduction guides (PR41549)

2019-06-10 Thread Tyker via Phabricator via cfe-commits
Tyker created this revision.
Tyker added a reviewer: rsmith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

bug report 

Before this patch, implicit deduction guides were generated from the first 
declaration found by lookup.
With this patch implicit deduction guides are generated from the definition of 
the class template.
Also added test that was previously failing.


Repository:
  rC Clang

https://reviews.llvm.org/D63072

Files:
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp


Index: clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
===
--- clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -489,6 +489,21 @@
 }
 #pragma clang diagnostic pop
 
+namespace PR41549 {
+
+template  struct umm;
+
+template 
+struct umm {
+  umm(H h = 0, P p = 0);
+};
+
+template  struct umm;
+
+umm<> m(1);
+
+}
+
 #else
 
 // expected-no-diagnostics
Index: clang/lib/Sema/SemaTemplate.cpp
===
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -2052,6 +2052,12 @@
 
 void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
   SourceLocation Loc) {
+  if (CXXRecordDecl *DefRecord =
+  cast(Template->getTemplatedDecl())->getDefinition()) {
+TemplateDecl *DescribedTemplate = DefRecord->getDescribedClassTemplate();
+Template = DescribedTemplate ? DescribedTemplate : Template;
+  }
+
   DeclContext *DC = Template->getDeclContext();
   if (DC->isDependentContext())
 return;


Index: clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
===
--- clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -489,6 +489,21 @@
 }
 #pragma clang diagnostic pop
 
+namespace PR41549 {
+
+template  struct umm;
+
+template 
+struct umm {
+  umm(H h = 0, P p = 0);
+};
+
+template  struct umm;
+
+umm<> m(1);
+
+}
+
 #else
 
 // expected-no-diagnostics
Index: clang/lib/Sema/SemaTemplate.cpp
===
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -2052,6 +2052,12 @@
 
 void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
   SourceLocation Loc) {
+  if (CXXRecordDecl *DefRecord =
+  cast(Template->getTemplatedDecl())->getDefinition()) {
+TemplateDecl *DescribedTemplate = DefRecord->getDescribedClassTemplate();
+Template = DescribedTemplate ? DescribedTemplate : Template;
+  }
+
   DeclContext *DC = Template->getDeclContext();
   if (DC->isDependentContext())
 return;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63072: [clang] Fixing incorrect implicit deduction guides (PR41549)

2019-06-10 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 203862.
Tyker added a comment.

fixed the issue.


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

https://reviews.llvm.org/D63072

Files:
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp


Index: clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
===
--- clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -489,6 +489,21 @@
 }
 #pragma clang diagnostic pop
 
+namespace PR41549 {
+
+template  struct umm;
+
+template 
+struct umm {
+  umm(H h = 0, P p = 0);
+};
+
+template  struct umm;
+
+umm m(1);
+
+}
+
 #else
 
 // expected-no-diagnostics
Index: clang/lib/Sema/SemaTemplate.cpp
===
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -2052,6 +2052,12 @@
 
 void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
   SourceLocation Loc) {
+  if (CXXRecordDecl *DefRecord =
+  cast(Template->getTemplatedDecl())->getDefinition()) {
+TemplateDecl *DescribedTemplate = DefRecord->getDescribedClassTemplate();
+Template = DescribedTemplate ? DescribedTemplate : Template;
+  }
+
   DeclContext *DC = Template->getDeclContext();
   if (DC->isDependentContext())
 return;


Index: clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
===
--- clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -489,6 +489,21 @@
 }
 #pragma clang diagnostic pop
 
+namespace PR41549 {
+
+template  struct umm;
+
+template 
+struct umm {
+  umm(H h = 0, P p = 0);
+};
+
+template  struct umm;
+
+umm m(1);
+
+}
+
 #else
 
 // expected-no-diagnostics
Index: clang/lib/Sema/SemaTemplate.cpp
===
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -2052,6 +2052,12 @@
 
 void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
   SourceLocation Loc) {
+  if (CXXRecordDecl *DefRecord =
+  cast(Template->getTemplatedDecl())->getDefinition()) {
+TemplateDecl *DescribedTemplate = DefRecord->getDescribedClassTemplate();
+Template = DescribedTemplate ? DescribedTemplate : Template;
+  }
+
   DeclContext *DC = Template->getDeclContext();
   if (DC->isDependentContext())
 return;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63134: [clang] improving diagnotics for invalid constexpr defaulted special membres

2019-06-11 Thread Tyker via Phabricator via cfe-commits
Tyker created this revision.
Tyker added a reviewer: rsmith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

this patch improves diagnostic for invalid constexpr defaulted special members 
by adding notes explaining why the special member cannot be constexpr.

example
input:

  01 struct B {};
  02 
  03 struct C : virtual B {
  04 };
  05 
  06 struct D {
  07   C c;
  08 };
  09 
  10 struct A : D {
  11   constexpr A() = default;
  12 };
  13 
  14 union U {
  15   A a;
  16   int b;
  17   constexpr U() = default;
  18 };
  19 
  20 struct E {
  21   ~E() {}
  22 };
  23 
  24 struct F {
  25   E e;
  26   constexpr F& operator=(const F&) =default;
  27 };

output with patch:

  test.cpp:11:3: error: defaulted definition of default constructor is not 
constexpr because:
constexpr A() = default;
^
  test.cpp:10:12: note: base class 'D' of 'A' has a non-constexpr implicit 
default constructor
  struct A : D {
 ^
  test.cpp:7:5: note: non-static data member 'c' of 'D' has a non-constexpr 
implicit default constructor
C c;
  ^
  test.cpp:3:12: note: 'C' inherits virtually from 'B'
  struct C : virtual B {
 ^
  test.cpp:17:3: error: defaulted definition of default constructor is not 
constexpr because:
constexpr U() = default;
^
  note: unions require exactly one non-static data member initializer to have a 
constexpr default constructor
  test.cpp:26:3: error: defaulted definition of copy assignment operator is not 
constexpr because:
constexpr F& operator=(const F&) =default;
^
  note: 'F' is not a literal type
  3 errors generated.

I didn't adapt exitsing tests yet because the diagnostics emitted are likely be 
adapted during review.


Repository:
  rC Clang

https://reviews.llvm.org/D63134

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp

Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -6366,19 +6366,26 @@
  Sema::CXXSpecialMember CSM, unsigned Quals,
  bool ConstRHS,
  CXXConstructorDecl *InheritedCtor = nullptr,
- Sema::InheritedConstructorInfo *Inherited = nullptr) {
+ Sema::InheritedConstructorInfo *Inherited = nullptr,
+ SourceLocation* SMLoc = nullptr) {
   // If we're inheriting a constructor, see if we need to call it for this base
   // class.
   if (InheritedCtor) {
 assert(CSM == Sema::CXXDefaultConstructor);
 auto BaseCtor =
 Inherited->findConstructorForBase(ClassDecl, InheritedCtor).first;
-if (BaseCtor)
+if (BaseCtor) {
+  if (SMLoc && !BaseCtor->isImplicit())
+*SMLoc = BaseCtor->getLocation();
   return BaseCtor->isConstexpr();
+}
   }
 
-  if (CSM == Sema::CXXDefaultConstructor)
-return ClassDecl->hasConstexprDefaultConstructor();
+  if (CSM == Sema::CXXDefaultConstructor) {
+bool IsConstexprCtor = ClassDecl->hasConstexprDefaultConstructor();
+if (IsConstexprCtor || !SMLoc)
+  return IsConstexprCtor;
+  }
 
   Sema::SpecialMemberOverloadResult SMOR =
   lookupCallFromSpecialMember(S, ClassDecl, CSM, Quals, ConstRHS);
@@ -6386,21 +6393,96 @@
 // A constructor we wouldn't select can't be "involved in initializing"
 // anything.
 return true;
+  if (SMLoc && !SMOR.getMethod()->isImplicit())
+*SMLoc = SMOR.getMethod()->getLocation();
   return SMOR.getMethod()->isConstexpr();
 }
 
 /// Determine whether the specified special member function would be constexpr
 /// if it were implicitly defined.
 static bool defaultedSpecialMemberIsConstexpr(
-Sema &S, CXXRecordDecl *ClassDecl, Sema::CXXSpecialMember CSM,
-bool ConstArg, CXXConstructorDecl *InheritedCtor = nullptr,
-Sema::InheritedConstructorInfo *Inherited = nullptr) {
+Sema &S, const CXXRecordDecl *ClassDecl, Sema::CXXSpecialMember CSM,
+bool ConstArg,
+CXXConstructorDecl *InheritedCtor = nullptr,
+Sema::InheritedConstructorInfo *Inherited = nullptr,
+SmallVectorImpl* DiagNotes = nullptr) {
   if (!S.getLangOpts().CPlusPlus11)
 return false;
 
+  SourceLocation SMLoc;
+  SourceLocation DiagLoc;
+  enum class FailKind {
+Subobject,
+Union,
+VirtualBase,
+NonLiteral,
+  };
+  /// This lambda will gathering all information and add notes for diagnostics.
+  auto Fail = [&](FailKind FailureKind, const Decl *FaillingDecl = nullptr) {
+if (DiagNotes) {
+  switch (FailureKind) {
+  case FailKind::Subobject: {
+PartialDiagnostic PDiag(diag::note_constexpr_defaulted_special_member, S.Context.getDiagAllocator());
+auto *Field = dyn_cast(FaillingDecl);
+auto *Record = dyn_cast(FaillingDecl);
+SourceLocation Loc = FaillingDecl->getLocation();
+if (!Record)
+  Record = Fiel

[PATCH] D63134: [clang] improving diagnotics for invalid constexpr defaulted special membres

2019-06-11 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 204041.

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

https://reviews.llvm.org/D63134

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp

Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -6361,24 +6361,29 @@
 
 /// Is the special member function which would be selected to perform the
 /// specified operation on the specified class type a constexpr constructor?
-static bool
-specialMemberIsConstexpr(Sema &S, CXXRecordDecl *ClassDecl,
- Sema::CXXSpecialMember CSM, unsigned Quals,
- bool ConstRHS,
- CXXConstructorDecl *InheritedCtor = nullptr,
- Sema::InheritedConstructorInfo *Inherited = nullptr) {
+static bool specialMemberIsConstexpr(
+Sema &S, CXXRecordDecl *ClassDecl, Sema::CXXSpecialMember CSM,
+unsigned Quals, bool ConstRHS, CXXConstructorDecl *InheritedCtor = nullptr,
+Sema::InheritedConstructorInfo *Inherited = nullptr,
+SourceLocation *SMLoc = nullptr) {
   // If we're inheriting a constructor, see if we need to call it for this base
   // class.
   if (InheritedCtor) {
 assert(CSM == Sema::CXXDefaultConstructor);
 auto BaseCtor =
 Inherited->findConstructorForBase(ClassDecl, InheritedCtor).first;
-if (BaseCtor)
+if (BaseCtor) {
+  if (SMLoc && !BaseCtor->isImplicit())
+*SMLoc = BaseCtor->getLocation();
   return BaseCtor->isConstexpr();
+}
   }
 
-  if (CSM == Sema::CXXDefaultConstructor)
-return ClassDecl->hasConstexprDefaultConstructor();
+  if (CSM == Sema::CXXDefaultConstructor) {
+bool IsConstexprCtor = ClassDecl->hasConstexprDefaultConstructor();
+if (IsConstexprCtor || !SMLoc)
+  return IsConstexprCtor;
+  }
 
   Sema::SpecialMemberOverloadResult SMOR =
   lookupCallFromSpecialMember(S, ClassDecl, CSM, Quals, ConstRHS);
@@ -6386,21 +6391,96 @@
 // A constructor we wouldn't select can't be "involved in initializing"
 // anything.
 return true;
+  if (SMLoc && !SMOR.getMethod()->isImplicit())
+*SMLoc = SMOR.getMethod()->getLocation();
   return SMOR.getMethod()->isConstexpr();
 }
 
 /// Determine whether the specified special member function would be constexpr
 /// if it were implicitly defined.
 static bool defaultedSpecialMemberIsConstexpr(
-Sema &S, CXXRecordDecl *ClassDecl, Sema::CXXSpecialMember CSM,
+Sema &S, const CXXRecordDecl *ClassDecl, Sema::CXXSpecialMember CSM,
 bool ConstArg, CXXConstructorDecl *InheritedCtor = nullptr,
-Sema::InheritedConstructorInfo *Inherited = nullptr) {
+Sema::InheritedConstructorInfo *Inherited = nullptr,
+SmallVectorImpl *DiagNotes = nullptr) {
   if (!S.getLangOpts().CPlusPlus11)
 return false;
 
+  SourceLocation SMLoc;
+  SourceLocation DiagLoc;
+  enum class FailKind {
+Subobject,
+Union,
+VirtualBase,
+NonLiteral,
+  };
+  /// This lambda will gathering all information and add notes for diagnostics.
+  auto Fail = [&](FailKind FailureKind, const Decl *FaillingDecl = nullptr) {
+if (DiagNotes) {
+  switch (FailureKind) {
+  case FailKind::Subobject: {
+PartialDiagnostic PDiag(diag::note_constexpr_defaulted_special_member,
+S.Context.getDiagAllocator());
+auto *Field = dyn_cast(FaillingDecl);
+auto *Record = dyn_cast(FaillingDecl);
+SourceLocation Loc = FaillingDecl->getLocation();
+if (!Record)
+  Record = Field->getType()->getAsCXXRecordDecl();
+if (DiagLoc.isValid())
+  Loc = DiagLoc;
+PDiag << CSM << isa(FaillingDecl);
+if (Field)
+  PDiag << Field;
+else
+  PDiag << Record;
+PDiag << ClassDecl << SMLoc.isInvalid()
+  << (Field ? Field->getDeclName().isEmpty() : false);
+DiagNotes->emplace_back(Loc, PDiag);
+if (SMLoc.isValid()) {
+  DiagNotes->emplace_back(
+  SMLoc, PartialDiagnostic(diag::note_special_member_declared_here,
+   S.Context.getDiagAllocator())
+ << CSM);
+  return false;
+}
+if (!Record)
+  return false;
+defaultedSpecialMemberIsConstexpr(S, Record, CSM, ConstArg, nullptr,
+  nullptr, DiagNotes);
+return false;
+  }
+  case FailKind::VirtualBase: {
+PartialDiagnostic PDiag(diag::note_constexpr_defaulted_virtual_base,
+S.Context.getDiagAllocator());
+const CXXBaseSpecifier &Base = *ClassDecl->bases_begin();
+PDiag << ClassDecl << Base.getType();
+DiagNotes->emplace_back(Base.getBeginLoc(), PDiag);
+return false;
+  }
+  case FailKind::Union:
+ 

[PATCH] D60523: [clang] Don't segfault on incorrect using directive (PR41400)

2019-06-14 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL363360: [clang] Don't segfault on incorrect using 
directive (PR41400) (authored by Tyker, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D60523?vs=194552&id=204720#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D60523

Files:
  cfe/trunk/lib/Sema/SemaExprCXX.cpp
  cfe/trunk/test/SemaCXX/using-decl-1.cpp


Index: cfe/trunk/test/SemaCXX/using-decl-1.cpp
===
--- cfe/trunk/test/SemaCXX/using-decl-1.cpp
+++ cfe/trunk/test/SemaCXX/using-decl-1.cpp
@@ -396,3 +396,10 @@
   using N::Y;
   using N::Z;
 }
+
+// expected-error@+5 {{requires a qualified name}}
+// expected-error@+4 {{expected ';'}}
+// expected-error@+3 {{expected '}'}}
+// expected-note@+2 {{to match this '{'}}
+// expected-error@+1 {{expected ';'}}
+template struct S { using S
\ No newline at end of file
Index: cfe/trunk/lib/Sema/SemaExprCXX.cpp
===
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp
@@ -90,7 +90,7 @@
   // When naming a constructor as a member of a dependent context (eg, in a
   // friend declaration or an inherited constructor declaration), form an
   // unresolved "typename" type.
-  if (CurClass->isDependentContext() && !EnteringContext) {
+  if (CurClass->isDependentContext() && !EnteringContext && SS.getScopeRep()) {
 QualType T = Context.getDependentNameType(ETK_None, SS.getScopeRep(), &II);
 return ParsedType::make(T);
   }


Index: cfe/trunk/test/SemaCXX/using-decl-1.cpp
===
--- cfe/trunk/test/SemaCXX/using-decl-1.cpp
+++ cfe/trunk/test/SemaCXX/using-decl-1.cpp
@@ -396,3 +396,10 @@
   using N::Y;
   using N::Z;
 }
+
+// expected-error@+5 {{requires a qualified name}}
+// expected-error@+4 {{expected ';'}}
+// expected-error@+3 {{expected '}'}}
+// expected-note@+2 {{to match this '{'}}
+// expected-error@+1 {{expected ';'}}
+template struct S { using S
\ No newline at end of file
Index: cfe/trunk/lib/Sema/SemaExprCXX.cpp
===
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp
@@ -90,7 +90,7 @@
   // When naming a constructor as a member of a dependent context (eg, in a
   // friend declaration or an inherited constructor declaration), form an
   // unresolved "typename" type.
-  if (CurClass->isDependentContext() && !EnteringContext) {
+  if (CurClass->isDependentContext() && !EnteringContext && SS.getScopeRep()) {
 QualType T = Context.getDependentNameType(ETK_None, SS.getScopeRep(), &II);
 return ParsedType::make(T);
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63072: [clang] Fixing incorrect implicit deduction guides (PR41549)

2019-06-14 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL363361: [clang] Fixing incorrect implicit deduction guides 
(PR41549) (authored by Tyker, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D63072?vs=203862&id=204721#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D63072

Files:
  cfe/trunk/lib/Sema/SemaTemplate.cpp
  cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp


Index: cfe/trunk/lib/Sema/SemaTemplate.cpp
===
--- cfe/trunk/lib/Sema/SemaTemplate.cpp
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp
@@ -2052,6 +2052,12 @@
 
 void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
   SourceLocation Loc) {
+  if (CXXRecordDecl *DefRecord =
+  cast(Template->getTemplatedDecl())->getDefinition()) {
+TemplateDecl *DescribedTemplate = DefRecord->getDescribedClassTemplate();
+Template = DescribedTemplate ? DescribedTemplate : Template;
+  }
+
   DeclContext *DC = Template->getDeclContext();
   if (DC->isDependentContext())
 return;
Index: cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
===
--- cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -489,6 +489,21 @@
 }
 #pragma clang diagnostic pop
 
+namespace PR41549 {
+
+template  struct umm;
+
+template 
+struct umm {
+  umm(H h = 0, P p = 0);
+};
+
+template  struct umm;
+
+umm m(1);
+
+}
+
 #else
 
 // expected-no-diagnostics


Index: cfe/trunk/lib/Sema/SemaTemplate.cpp
===
--- cfe/trunk/lib/Sema/SemaTemplate.cpp
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp
@@ -2052,6 +2052,12 @@
 
 void Sema::DeclareImplicitDeductionGuides(TemplateDecl *Template,
   SourceLocation Loc) {
+  if (CXXRecordDecl *DefRecord =
+  cast(Template->getTemplatedDecl())->getDefinition()) {
+TemplateDecl *DescribedTemplate = DefRecord->getDescribedClassTemplate();
+Template = DescribedTemplate ? DescribedTemplate : Template;
+  }
+
   DeclContext *DC = Template->getDeclContext();
   if (DC->isDependentContext())
 return;
Index: cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
===
--- cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ cfe/trunk/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -489,6 +489,21 @@
 }
 #pragma clang diagnostic pop
 
+namespace PR41549 {
+
+template  struct umm;
+
+template 
+struct umm {
+  umm(H h = 0, P p = 0);
+};
+
+template  struct umm;
+
+umm m(1);
+
+}
+
 #else
 
 // expected-no-diagnostics
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61790: [C++20] add Basic consteval specifier

2019-06-14 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL363362: [C++20] add Basic consteval specifier (authored by 
Tyker, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D61790?vs=203725&id=204723#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D61790

Files:
  cfe/trunk/include/clang/AST/Decl.h
  cfe/trunk/include/clang/AST/DeclBase.h
  cfe/trunk/include/clang/AST/DeclCXX.h
  cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
  cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
  cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/include/clang/Basic/Specifiers.h
  cfe/trunk/include/clang/Basic/TokenKinds.def
  cfe/trunk/include/clang/Sema/DeclSpec.h
  cfe/trunk/include/clang/Sema/Sema.h
  cfe/trunk/lib/AST/ASTImporter.cpp
  cfe/trunk/lib/AST/Decl.cpp
  cfe/trunk/lib/AST/DeclCXX.cpp
  cfe/trunk/lib/AST/DeclPrinter.cpp
  cfe/trunk/lib/AST/TextNodeDumper.cpp
  cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
  cfe/trunk/lib/Parse/ParseDecl.cpp
  cfe/trunk/lib/Parse/ParseExprCXX.cpp
  cfe/trunk/lib/Parse/ParseTentative.cpp
  cfe/trunk/lib/Sema/DeclSpec.cpp
  cfe/trunk/lib/Sema/SemaCoroutine.cpp
  cfe/trunk/lib/Sema/SemaDecl.cpp
  cfe/trunk/lib/Sema/SemaDeclAttr.cpp
  cfe/trunk/lib/Sema/SemaDeclCXX.cpp
  cfe/trunk/lib/Sema/SemaExpr.cpp
  cfe/trunk/lib/Sema/SemaLambda.cpp
  cfe/trunk/lib/Sema/SemaStmt.cpp
  cfe/trunk/lib/Sema/SemaTemplate.cpp
  cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
  cfe/trunk/lib/Sema/SemaType.cpp
  cfe/trunk/lib/Sema/TreeTransform.h
  cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
  cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
  cfe/trunk/test/SemaCXX/cxx2a-compat.cpp
  cfe/trunk/test/SemaCXX/cxx2a-consteval.cpp
  lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
  lldb/trunk/source/Symbol/ClangASTContext.cpp

Index: cfe/trunk/include/clang/AST/DeclBase.h
===
--- cfe/trunk/include/clang/AST/DeclBase.h
+++ cfe/trunk/include/clang/AST/DeclBase.h
@@ -1500,7 +1500,9 @@
 uint64_t IsExplicitlyDefaulted : 1;
 uint64_t HasImplicitReturnZero : 1;
 uint64_t IsLateTemplateParsed : 1;
-uint64_t IsConstexpr : 1;
+
+/// Kind of contexpr specifier as defined by ConstexprSpecKind.
+uint64_t ConstexprKind : 2;
 uint64_t InstantiationIsPending : 1;
 
 /// Indicates if the function uses __try.
@@ -1528,7 +1530,7 @@
   };
 
   /// Number of non-inherited bits in FunctionDeclBitfields.
-  enum { NumFunctionDeclBits = 24 };
+  enum { NumFunctionDeclBits = 25 };
 
   /// Stores the bits used by CXXConstructorDecl. If modified
   /// NumCXXConstructorDeclBits and the accessor
@@ -1545,7 +1547,7 @@
 /// exactly 64 bits and thus the width of NumCtorInitializers
 /// will need to be shrunk if some bit is added to NumDeclContextBitfields,
 /// NumFunctionDeclBitfields or CXXConstructorDeclBitfields.
-uint64_t NumCtorInitializers : 24;
+uint64_t NumCtorInitializers : 23;
 uint64_t IsInheritingConstructor : 1;
 
 /// Whether this constructor has a trail-allocated explicit specifier.
Index: cfe/trunk/include/clang/AST/Decl.h
===
--- cfe/trunk/include/clang/AST/Decl.h
+++ cfe/trunk/include/clang/AST/Decl.h
@@ -1861,7 +1861,7 @@
   FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified,
-   bool isConstexprSpecified);
+   ConstexprSpecKind ConstexprKind);
 
   using redeclarable_base = Redeclarable;
 
@@ -1891,29 +1891,24 @@
   using redeclarable_base::getMostRecentDecl;
   using redeclarable_base::isFirstDecl;
 
-  static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
-  SourceLocation StartLoc, SourceLocation NLoc,
-  DeclarationName N, QualType T,
-  TypeSourceInfo *TInfo,
-  StorageClass SC,
-  bool isInlineSpecified = false,
-  bool hasWrittenPrototype = true,
-  bool isConstexprSpecified = false) {
+  static FunctionDecl *
+  Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation NLoc, DeclarationName N, QualType T,
+ TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified = false,
+ bool hasWrittenPrototype = true,
+ ConstexprSpecKind ConstexprKind = CSK_unspecified) {
 DeclarationNameInfo NameInfo(N, NLoc);
-return FunctionDecl::Create(C, DC, StartLoc, NameInfo, T, TInfo,
-SC,
+return FunctionDe

[PATCH] D62009: [clang] perform semantic checking in constant context

2019-06-15 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL363488: [clang] perform semantic checking in constant 
context (authored by Tyker, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D62009?vs=200662&id=204906#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D62009

Files:
  cfe/trunk/include/clang/AST/Expr.h
  cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
  cfe/trunk/include/clang/Sema/Sema.h
  cfe/trunk/lib/AST/ExprConstant.cpp
  cfe/trunk/lib/Sema/Sema.cpp
  cfe/trunk/lib/Sema/SemaChecking.cpp
  cfe/trunk/test/SemaCXX/attr-nonnull.cpp
  cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp

Index: cfe/trunk/include/clang/AST/Expr.h
===
--- cfe/trunk/include/clang/AST/Expr.h
+++ cfe/trunk/include/clang/AST/Expr.h
@@ -599,7 +599,8 @@
   /// which we can fold and convert to a boolean condition using
   /// any crazy technique that we want to, even if the expression has
   /// side-effects.
-  bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const;
+  bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx,
+  bool InConstantContext = false) const;
 
   enum SideEffectsKind {
 SE_NoSideEffects,  ///< Strictly evaluate the expression.
@@ -611,20 +612,21 @@
   /// EvaluateAsInt - Return true if this is a constant which we can fold and
   /// convert to an integer, using any crazy technique that we want to.
   bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx,
- SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
+ SideEffectsKind AllowSideEffects = SE_NoSideEffects,
+ bool InConstantContext = false) const;
 
   /// EvaluateAsFloat - Return true if this is a constant which we can fold and
   /// convert to a floating point value, using any crazy technique that we
   /// want to.
-  bool
-  EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx,
-  SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
+  bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx,
+   SideEffectsKind AllowSideEffects = SE_NoSideEffects,
+   bool InConstantContext = false) const;
 
   /// EvaluateAsFloat - Return true if this is a constant which we can fold and
   /// convert to a fixed point value.
-  bool EvaluateAsFixedPoint(
-  EvalResult &Result, const ASTContext &Ctx,
-  SideEffectsKind AllowSideEffects = SE_NoSideEffects) const;
+  bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx,
+SideEffectsKind AllowSideEffects = SE_NoSideEffects,
+bool InConstantContext = false) const;
 
   /// isEvaluatable - Call EvaluateAsRValue to see if this expression can be
   /// constant folded without side-effects, but discard the result.
@@ -660,7 +662,8 @@
 
   /// EvaluateAsLValue - Evaluate an expression to see if we can fold it to an
   /// lvalue with link time known address, with no side-effects.
-  bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const;
+  bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx,
+bool InConstantContext = false) const;
 
   /// EvaluateAsInitializer - Evaluate an expression as if it were the
   /// initializer of the given declaration. Returns true if the initializer
Index: cfe/trunk/include/clang/Sema/Sema.h
===
--- cfe/trunk/include/clang/Sema/Sema.h
+++ cfe/trunk/include/clang/Sema/Sema.h
@@ -797,6 +797,15 @@
 }
   };
 
+  /// Used to change context to isConstantEvaluated without pushing a heavy
+  /// ExpressionEvaluationContextRecord object.
+  bool isConstantEvaluatedOverride;
+
+  bool isConstantEvaluated() {
+return ExprEvalContexts.back().isConstantEvaluated() ||
+   isConstantEvaluatedOverride;
+  }
+
   /// RAII object to handle the state changes required to synthesize
   /// a function body.
   class SynthesizedFunctionScope {
Index: cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
===
--- cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
+++ cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
@@ -85,6 +85,8 @@
   "access array element of|ERROR|"
   "access real component of|access imaginary component of}0 "
   "pointer past the end of object">;
+def note_non_null_attribute_failed : Note<
+  "null passed to a callee that requires a non-null argument">;
 def note_constexpr_null_subobject : Note<
   "cannot %select{access base class of|access derived class of|access field of|"
   "access array element of|perform pointer arith

[PATCH] D62399: [clang] Add storage for APValue in ConstantExpr

2019-06-15 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL363493: [clang] Add storage for APValue in ConstantExpr 
(authored by Tyker, committed by ).
Herald added a subscriber: kristina.

Changed prior to commit:
  https://reviews.llvm.org/D62399?vs=203723&id=204911#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D62399

Files:
  cfe/trunk/include/clang/AST/APValue.h
  cfe/trunk/include/clang/AST/ASTContext.h
  cfe/trunk/include/clang/AST/Expr.h
  cfe/trunk/include/clang/AST/Stmt.h
  cfe/trunk/include/clang/AST/TextNodeDumper.h
  cfe/trunk/include/clang/Serialization/ASTReader.h
  cfe/trunk/include/clang/Serialization/ASTWriter.h
  cfe/trunk/lib/AST/APValue.cpp
  cfe/trunk/lib/AST/ASTContext.cpp
  cfe/trunk/lib/AST/ASTImporter.cpp
  cfe/trunk/lib/AST/Expr.cpp
  cfe/trunk/lib/AST/TextNodeDumper.cpp
  cfe/trunk/lib/Sema/SemaOverload.cpp
  cfe/trunk/lib/Serialization/ASTReader.cpp
  cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
  cfe/trunk/lib/Serialization/ASTWriter.cpp
  cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
  cfe/trunk/test/AST/ast-dump-color.cpp
  llvm/trunk/include/llvm/ADT/APFloat.h
  llvm/trunk/lib/Support/APFloat.cpp

Index: llvm/trunk/lib/Support/APFloat.cpp
===
--- llvm/trunk/lib/Support/APFloat.cpp
+++ llvm/trunk/lib/Support/APFloat.cpp
@@ -113,6 +113,42 @@
   static const fltSemantics semPPCDoubleDoubleLegacy = {1023, -1022 + 53,
 53 + 53, 128};
 
+  const llvm::fltSemantics &APFloatBase::EnumToSemantics(Semantics S) {
+switch (S) {
+case S_IEEEhalf:
+  return IEEEhalf();
+case S_IEEEsingle:
+  return IEEEsingle();
+case S_IEEEdouble:
+  return IEEEdouble();
+case S_x87DoubleExtended:
+  return x87DoubleExtended();
+case S_IEEEquad:
+  return IEEEquad();
+case S_PPCDoubleDouble:
+  return PPCDoubleDouble();
+}
+llvm_unreachable("Unrecognised floating semantics");
+  }
+
+  APFloatBase::Semantics
+  APFloatBase::SemanticsToEnum(const llvm::fltSemantics &Sem) {
+if (&Sem == &llvm::APFloat::IEEEhalf())
+  return S_IEEEhalf;
+else if (&Sem == &llvm::APFloat::IEEEsingle())
+  return S_IEEEsingle;
+else if (&Sem == &llvm::APFloat::IEEEdouble())
+  return S_IEEEdouble;
+else if (&Sem == &llvm::APFloat::x87DoubleExtended())
+  return S_x87DoubleExtended;
+else if (&Sem == &llvm::APFloat::IEEEquad())
+  return S_IEEEquad;
+else if (&Sem == &llvm::APFloat::PPCDoubleDouble())
+  return S_PPCDoubleDouble;
+else
+  llvm_unreachable("Unknown floating semantics");
+  }
+
   const fltSemantics &APFloatBase::IEEEhalf() {
 return semIEEEhalf;
   }
Index: llvm/trunk/include/llvm/ADT/APFloat.h
===
--- llvm/trunk/include/llvm/ADT/APFloat.h
+++ llvm/trunk/include/llvm/ADT/APFloat.h
@@ -147,6 +147,17 @@
 
   /// \name Floating Point Semantics.
   /// @{
+  enum Semantics {
+S_IEEEhalf,
+S_IEEEsingle,
+S_IEEEdouble,
+S_x87DoubleExtended,
+S_IEEEquad,
+S_PPCDoubleDouble
+  };
+
+  static const llvm::fltSemantics &EnumToSemantics(Semantics S);
+  static Semantics SemanticsToEnum(const llvm::fltSemantics &Sem);
 
   static const fltSemantics &IEEEhalf() LLVM_READNONE;
   static const fltSemantics &IEEEsingle() LLVM_READNONE;
Index: cfe/trunk/lib/AST/ASTImporter.cpp
===
--- cfe/trunk/lib/AST/ASTImporter.cpp
+++ cfe/trunk/lib/AST/ASTImporter.cpp
@@ -6376,6 +6376,13 @@
   Expr *ToSubExpr;
   std::tie(ToSubExpr) = *Imp;
 
+  // TODO : Handle APValue::ValueKind that require importing.
+  APValue::ValueKind Kind = E->getResultAPValueKind();
+  if (Kind == APValue::Int || Kind == APValue::Float ||
+  Kind == APValue::FixedPoint || Kind == APValue::ComplexFloat ||
+  Kind == APValue::ComplexInt)
+return ConstantExpr::Create(Importer.getToContext(), ToSubExpr,
+E->getAPValueResult());
   return ConstantExpr::Create(Importer.getToContext(), ToSubExpr);
 }
 
Index: cfe/trunk/lib/AST/APValue.cpp
===
--- cfe/trunk/lib/AST/APValue.cpp
+++ cfe/trunk/lib/AST/APValue.cpp
@@ -456,7 +456,8 @@
   llvm_unreachable("Unknown APValue kind!");
 }
 
-void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
+void APValue::printPretty(raw_ostream &Out, const ASTContext &Ctx,
+  QualType Ty) const {
   switch (getKind()) {
   case APValue::None:
 Out << "";
@@ -675,7 +676,7 @@
   llvm_unreachable("Unknown APValue kind!");
 }
 
-std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
+std::string APValue::getAsString(const ASTContext &Ctx, QualType Ty) const {
   std::string Result;
 

[PATCH] D63376: [clang] Small improvments after Adding APValue to ConstantExpr

2019-06-15 Thread Tyker via Phabricator via cfe-commits
Tyker created this revision.
Tyker added a reviewer: rsmith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

this patch has multiple small improvements related to the APValue in 
ConstantExpr.

changes:

- APValue in ConstantExpr are now cleaned up using ASTContext::addDestruction 
instead of there own system.
- ConstantExprBits Stores the ValueKind of the result beaing stored.
- VerifyIntegerConstantExpression now stores the evaluated value in 
ConstantExpr.
- the Constant Evaluator uses the stored value of ConstantExpr when available.


Repository:
  rC Clang

https://reviews.llvm.org/D63376

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaOverload.cpp

Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -5514,7 +5514,12 @@
 
 if (Notes.empty()) {
   // It's a constant expression.
-  return ConstantExpr::Create(S.Context, Result.get(), Value);
+
+  // ExplicitBool wouldn't use the value stored in ConstantExpr.
+  if (CCE != Sema::CCEK_ExplicitBool)
+return ConstantExpr::Create(S.Context, Result.get(), Value);
+  else
+return ConstantExpr::Create(S.Context, Result.get());
 }
   }
 
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -14467,10 +14467,10 @@
   S.Diag(Loc, diag::ext_expr_not_ice) << SR << S.LangOpts.CPlusPlus;
 }
 
-ExprResult
-Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
-  VerifyICEDiagnoser &Diagnoser,
-  bool AllowFold) {
+ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
+ VerifyICEDiagnoser &Diagnoser,
+ bool AllowFold,
+ bool StoreResult) {
   SourceLocation DiagLoc = E->getBeginLoc();
 
   if (getLangOpts().CPlusPlus11) {
@@ -14538,14 +14538,13 @@
 return ExprError();
   }
 
-  if (!isa(E))
-E = ConstantExpr::Create(Context, E);
-
   // Circumvent ICE checking in C++11 to avoid evaluating the expression twice
   // in the non-ICE case.
   if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {
 if (Result)
   *Result = E->EvaluateKnownConstIntCheckOverflow(Context);
+if (!isa(E))
+  E = ConstantExpr::Create(Context, E);
 return E;
   }
 
@@ -14555,8 +14554,13 @@
 
   // Try to evaluate the expression, and produce diagnostics explaining why it's
   // not a constant expression as a side-effect.
-  bool Folded = E->EvaluateAsRValue(EvalResult, Context) &&
-EvalResult.Val.isInt() && !EvalResult.HasSideEffects;
+  bool Folded =
+  E->EvaluateAsRValue(EvalResult, Context, /*isConstantContext*/ true) &&
+  EvalResult.Val.isInt() && !EvalResult.HasSideEffects;
+
+  if (!isa(E))
+if (StoreResult)
+  E = ConstantExpr::Create(Context, E, EvalResult.Val);
 
   // In C++11, we can rely on diagnostics being produced for any expression
   // which is not a constant expression. If no diagnostics were produced, then
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -14006,8 +14006,6 @@
 ExprResult Converted = PerformContextuallyConvertToBool(AssertExpr);
 if (Converted.isInvalid())
   Failed = true;
-else
-  Converted = ConstantExpr::Create(Context, Converted.get());
 
 llvm::APSInt Cond;
 if (!Failed && VerifyIntegerConstantExpression(Converted.get(), &Cond,
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -8963,6 +8963,8 @@
 
 bool IntExprEvaluator::VisitConstantExpr(const ConstantExpr *E) {
   llvm::SaveAndRestore InConstantContext(Info.InConstantContext, true);
+  if (E->getResultStorageKind() != ConstantExpr::RSK_None)
+return Success(E->getAPValueResult(), E);
   return ExprEvaluatorBaseTy::VisitConstantExpr(E);
 }
 
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -239,6 +239,7 @@
 ConstantExpr::getStorageKind(const APValue &Value) {
   switch (Value.getKind()) {
   case APValue::None:
+  case APValue::Indeterminate:
 return ConstantExpr::RSK_None;
   case APValue::Int:
 if (!Value

[PATCH] D63376: [clang] Small improvments after Adding APValue to ConstantExpr

2019-06-15 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 204916.

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

https://reviews.llvm.org/D63376

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaOverload.cpp

Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -5514,7 +5514,12 @@
 
 if (Notes.empty()) {
   // It's a constant expression.
-  return ConstantExpr::Create(S.Context, Result.get(), Value);
+
+  // ExplicitBool wouldn't use the value stored in ConstantExpr.
+  if (CCE != Sema::CCEK_ExplicitBool)
+return ConstantExpr::Create(S.Context, Result.get(), Value);
+  else
+return ConstantExpr::Create(S.Context, Result.get());
 }
   }
 
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -14467,10 +14467,10 @@
   S.Diag(Loc, diag::ext_expr_not_ice) << SR << S.LangOpts.CPlusPlus;
 }
 
-ExprResult
-Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
-  VerifyICEDiagnoser &Diagnoser,
-  bool AllowFold) {
+ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
+ VerifyICEDiagnoser &Diagnoser,
+ bool AllowFold,
+ bool StoreResult) {
   SourceLocation DiagLoc = E->getBeginLoc();
 
   if (getLangOpts().CPlusPlus11) {
@@ -14538,14 +14538,13 @@
 return ExprError();
   }
 
-  if (!isa(E))
-E = ConstantExpr::Create(Context, E);
-
   // Circumvent ICE checking in C++11 to avoid evaluating the expression twice
   // in the non-ICE case.
   if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {
 if (Result)
   *Result = E->EvaluateKnownConstIntCheckOverflow(Context);
+if (!isa(E))
+  E = ConstantExpr::Create(Context, E);
 return E;
   }
 
@@ -14555,8 +14554,13 @@
 
   // Try to evaluate the expression, and produce diagnostics explaining why it's
   // not a constant expression as a side-effect.
-  bool Folded = E->EvaluateAsRValue(EvalResult, Context) &&
-EvalResult.Val.isInt() && !EvalResult.HasSideEffects;
+  bool Folded =
+  E->EvaluateAsRValue(EvalResult, Context, /*isConstantContext*/ true) &&
+  EvalResult.Val.isInt() && !EvalResult.HasSideEffects;
+
+  if (!isa(E))
+if (StoreResult)
+  E = ConstantExpr::Create(Context, E, EvalResult.Val);
 
   // In C++11, we can rely on diagnostics being produced for any expression
   // which is not a constant expression. If no diagnostics were produced, then
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -14006,8 +14006,6 @@
 ExprResult Converted = PerformContextuallyConvertToBool(AssertExpr);
 if (Converted.isInvalid())
   Failed = true;
-else
-  Converted = ConstantExpr::Create(Context, Converted.get());
 
 llvm::APSInt Cond;
 if (!Failed && VerifyIntegerConstantExpression(Converted.get(), &Cond,
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -8963,6 +8963,8 @@
 
 bool IntExprEvaluator::VisitConstantExpr(const ConstantExpr *E) {
   llvm::SaveAndRestore InConstantContext(Info.InConstantContext, true);
+  if (E->getResultStorageKind() != ConstantExpr::RSK_None)
+return Success(E->getAPValueResult(), E);
   return ExprEvaluatorBaseTy::VisitConstantExpr(E);
 }
 
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -239,6 +239,7 @@
 ConstantExpr::getStorageKind(const APValue &Value) {
   switch (Value.getKind()) {
   case APValue::None:
+  case APValue::Indeterminate:
 return ConstantExpr::RSK_None;
   case APValue::Int:
 if (!Value.getInt().needsCleanup())
@@ -249,9 +250,18 @@
   }
 }
 
+ConstantExpr::ResultStorageKind
+ConstantExpr::getStorageKind(const Type *T, const ASTContext &Context) {
+  if (T->isIntegralOrEnumerationType() && Context.getTypeInfo(T).Width <= 64)
+return ConstantExpr::RSK_Int64;
+  return ConstantExpr::RSK_APValue;
+}
+
 void ConstantExpr::DefaultInit(ResultStorageKind StorageKind) {
   ConstantExprBits.ResultKind = StorageKind;
-  if (StorageKind == RSK_APValue)
+  ConstantExp

[PATCH] D63376: [clang] Small improvments after Adding APValue to ConstantExpr

2019-06-17 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 204992.

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

https://reviews.llvm.org/D63376

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaOverload.cpp

Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -5514,7 +5514,12 @@
 
 if (Notes.empty()) {
   // It's a constant expression.
-  return ConstantExpr::Create(S.Context, Result.get(), Value);
+
+  // ExplicitBool wouldn't use the value stored in ConstantExpr.
+  if (CCE != Sema::CCEK_ExplicitBool)
+return ConstantExpr::Create(S.Context, Result.get(), Value);
+  else
+return ConstantExpr::Create(S.Context, Result.get());
 }
   }
 
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -14467,10 +14467,10 @@
   S.Diag(Loc, diag::ext_expr_not_ice) << SR << S.LangOpts.CPlusPlus;
 }
 
-ExprResult
-Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
-  VerifyICEDiagnoser &Diagnoser,
-  bool AllowFold) {
+ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
+ VerifyICEDiagnoser &Diagnoser,
+ bool AllowFold,
+ bool StoreResult) {
   SourceLocation DiagLoc = E->getBeginLoc();
 
   if (getLangOpts().CPlusPlus11) {
@@ -14538,14 +14538,13 @@
 return ExprError();
   }
 
-  if (!isa(E))
-E = ConstantExpr::Create(Context, E);
-
   // Circumvent ICE checking in C++11 to avoid evaluating the expression twice
   // in the non-ICE case.
   if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {
 if (Result)
   *Result = E->EvaluateKnownConstIntCheckOverflow(Context);
+if (!isa(E))
+  E = ConstantExpr::Create(Context, E);
 return E;
   }
 
@@ -14555,8 +14554,13 @@
 
   // Try to evaluate the expression, and produce diagnostics explaining why it's
   // not a constant expression as a side-effect.
-  bool Folded = E->EvaluateAsRValue(EvalResult, Context) &&
-EvalResult.Val.isInt() && !EvalResult.HasSideEffects;
+  bool Folded =
+  E->EvaluateAsRValue(EvalResult, Context, /*isConstantContext*/ true) &&
+  EvalResult.Val.isInt() && !EvalResult.HasSideEffects;
+
+  if (!isa(E))
+if (StoreResult)
+  E = ConstantExpr::Create(Context, E, EvalResult.Val);
 
   // In C++11, we can rely on diagnostics being produced for any expression
   // which is not a constant expression. If no diagnostics were produced, then
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -14006,8 +14006,6 @@
 ExprResult Converted = PerformContextuallyConvertToBool(AssertExpr);
 if (Converted.isInvalid())
   Failed = true;
-else
-  Converted = ConstantExpr::Create(Context, Converted.get());
 
 llvm::APSInt Cond;
 if (!Failed && VerifyIntegerConstantExpression(Converted.get(), &Cond,
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -8963,6 +8963,8 @@
 
 bool IntExprEvaluator::VisitConstantExpr(const ConstantExpr *E) {
   llvm::SaveAndRestore InConstantContext(Info.InConstantContext, true);
+  if (E->getResultAPValueKind() != APValue::None)
+return Success(E->getAPValueResult(), E);
   return ExprEvaluatorBaseTy::VisitConstantExpr(E);
 }
 
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -239,6 +239,7 @@
 ConstantExpr::getStorageKind(const APValue &Value) {
   switch (Value.getKind()) {
   case APValue::None:
+  case APValue::Indeterminate:
 return ConstantExpr::RSK_None;
   case APValue::Int:
 if (!Value.getInt().needsCleanup())
@@ -249,9 +250,18 @@
   }
 }
 
+ConstantExpr::ResultStorageKind
+ConstantExpr::getStorageKind(const Type *T, const ASTContext &Context) {
+  if (T->isIntegralOrEnumerationType() && Context.getTypeInfo(T).Width <= 64)
+return ConstantExpr::RSK_Int64;
+  return ConstantExpr::RSK_APValue;
+}
+
 void ConstantExpr::DefaultInit(ResultStorageKind StorageKind) {
   ConstantExprBits.ResultKind = StorageKind;
-  if (StorageKind == RSK_APValue)
+  ConstantExprBits.APV

[PATCH] D63376: [clang] Small improvments after Adding APValue to ConstantExpr

2019-06-19 Thread Tyker via Phabricator via cfe-commits
Tyker marked an inline comment as done.
Tyker added inline comments.



Comment at: clang/include/clang/Sema/Sema.h:10298
+ bool AllowFold = true,
+ bool StoreResult = true);
   ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,

rsmith wrote:
> Do you need this new flag? No callers are passing it.
the idea behind it is that not all integral constant expression benefit from 
storing the result. i have not analyzed which benefit from it and which don't. 
adding a FIXME would have probably be more appropriate.


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

https://reviews.llvm.org/D63376



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


[PATCH] D61552: [clang] Adapt ASTMatcher to explicit(bool) specifier

2019-06-19 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 205559.
Tyker marked 3 inline comments as done.
Tyker added a comment.

fixed requested changes.

> Are you getting errors from running it, or just incorrect output?

the issue happens to me even on master so i suppose the input is correct.
here is the error report:

  [tyker@tyker tools]$ ./dump_ast_matchers.py 
  *** Unparsable: " #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H #define 
LLVM_CLANG_ASTMATCHERS_ASTMATCHERS_H " ***
  *** Unparsable: " #include "clang/AST/ASTContext.h" #include 
"clang/AST/ASTTypeTraits.h" #include "clang/AST/Attr.h" #include 
"clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include 
"clang/AST/DeclFriend.h" #include "clang/AST/DeclObjC.h" #include 
"clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include 
"clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include 
"clang/AST/NestedNameSpecifier.h" #include "clang/AST/OpenMPClause.h" #include 
"clang/AST/OperationKinds.h" #include "clang/AST/Stmt.h" #include 
"clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" #include 
"clang/AST/StmtOpenMP.h" #include "clang/AST/TemplateBase.h" #include 
"clang/AST/TemplateName.h" #include "clang/AST/Type.h" #include 
"clang/AST/TypeLoc.h" #include "clang/ASTMatchers/ASTMatchersInternal.h" 
#include "clang/ASTMatchers/ASTMatchersMacros.h" #include 
"clang/Basic/AttrKinds.h" #include "clang/Basic/ExceptionSpecificationType.h" 
#include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include 
"clang/Basic/SourceManager.h" #include "clang/Basic/Specifiers.h" #include 
"clang/Basic/TypeTraits.h" #include "llvm/ADT/ArrayRef.h" #include 
"llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include 
"llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include 
"llvm/Support/ErrorHandling.h" #include "llvm/Support/Regex.h" #include 
 #include  #include  #include  #include 
 #include  #include  " ***
  *** Unparsable: " namespace clang {" ***
  *** Unparsable: " using DeclarationMatcher = internal::Matcher;" ***
  *** Unparsable: " using StatementMatcher = internal::Matcher;" ***
  *** Unparsable: " using TypeMatcher = internal::Matcher;" ***
  *** Unparsable: " using TypeLocMatcher = internal::Matcher;" ***
  *** Unparsable: " using NestedNameSpecifierMatcher = 
internal::Matcher;" ***
  *** Unparsable: " using NestedNameSpecifierLocMatcher = 
internal::Matcher;" ***
  *** Unparsable: " using CXXCtorInitializerMatcher = 
internal::Matcher;" ***
  Probing https://clang.llvm.org/doxygen/classclang_1_1Decl.html...

after this the script keep probing with no issues.
i tested using python 2.7 and python 3.7 the same error occurs


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

https://reviews.llvm.org/D61552

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1735,6 +1735,56 @@
 llvm::make_unique>("x", 3)));
 }
 
+TEST(Declaration, HasExplicitSpecifier) {
+  EXPECT_TRUE(matchesConditionally(
+  "void f();", functionDecl(hasExplicitSpecifier(constantExpr())), false,
+  "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(true) operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(false) operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) S(int); };",
+  cxxConstructorDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(true) S(int); };",
+  cxxConstructorDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(false) S(int); };",
+  cxxConstructorDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "tem

[PATCH] D61552: [clang] Adapt ASTMatcher to explicit(bool) specifier

2019-06-19 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 205602.
Tyker added a comment.

i was confuse because the log seemed like an error and it was happening in 
python2.7 and python3.7
but the actual error that was preventing generating the documentation only 
occurs in 3.7.

it works in python2.7.


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

https://reviews.llvm.org/D61552

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1735,6 +1735,56 @@
 llvm::make_unique>("x", 3)));
 }
 
+TEST(Declaration, HasExplicitSpecifier) {
+  EXPECT_TRUE(matchesConditionally(
+  "void f();", functionDecl(hasExplicitSpecifier(constantExpr())), false,
+  "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(true) operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(false) operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) S(int); };",
+  cxxConstructorDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(true) S(int); };",
+  cxxConstructorDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(false) S(int); };",
+  cxxConstructorDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { S(int); };"
+  "template explicit(b) S(int) -> S;",
+  cxxDeductionGuideDecl(
+  hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("template struct S { S(int); };"
+   "explicit(true) S(int) -> S;",
+   cxxDeductionGuideDecl(hasExplicitSpecifier(
+   constantExpr(has(cxxBoolLiteral(),
+   true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("template struct S { S(int); };"
+   "explicit(false) S(int) -> S;",
+   cxxDeductionGuideDecl(hasExplicitSpecifier(
+   constantExpr(has(cxxBoolLiteral(),
+   true, "-std=c++2a"));
+}
+
 TEST(ForEachConstructorInitializer, MatchesInitializers) {
   EXPECT_TRUE(matches(
 "struct X { X() : i(42), j(42) {} int i, j; };",
Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -878,6 +878,15 @@
   cxxConversionDecl(isExplicit(;
   EXPECT_TRUE(notMatches("struct S { operator int(); };",
  cxxConversionDecl(isExplicit(;
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) operator int(); };",
+  cxxConversionDecl(isExplicit()), false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(true) operator int(); };",
+  cxxConversionDecl(isExplicit()), true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(false) operator int(); };",
+  cxxConversionDecl(isExplicit()), false, "-std=c++2a"));
 }
 
 TEST(Matcher, ArgumentCount) {
@@ -1197,6 +1206,38 @@
   cxxConstructorDecl(isExplicit(;
   EXPECT_TRUE(notMatches("struct S { S(int); };",
  cxxConstructorDecl(isExplicit(;
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) S(int);};",
+  cxxConstructorDecl(isExp

[PATCH] D61552: [clang] Adapt ASTMatcher to explicit(bool) specifier

2019-06-19 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:6190
+/// cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5.
+/// cxxConstructorDecl(isExplicit()) will match #8, but not #7 or #9.
+AST_POLYMORPHIC_MATCHER(isExplicit, AST_POLYMORPHIC_SUPPORTED_TYPES(

aaron.ballman wrote:
> Why won't it match #2?
#2 matches.


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

https://reviews.llvm.org/D61552



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


[PATCH] D61552: [clang] Adapt ASTMatcher to explicit(bool) specifier

2019-06-19 Thread Tyker via Phabricator via cfe-commits
Tyker marked an inline comment as done.
Tyker added inline comments.



Comment at: clang/include/clang/ASTMatchers/ASTMatchers.h:6190
+/// cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5.
+/// cxxConstructorDecl(isExplicit()) will match #8, but not #7 or #9.
+AST_POLYMORPHIC_MATCHER(isExplicit, AST_POLYMORPHIC_SUPPORTED_TYPES(

aaron.ballman wrote:
> Tyker wrote:
> > aaron.ballman wrote:
> > > Why won't it match #2?
> > #2 matches.
> I figured it would -- the comment should be updated to correct that (and then 
> generate the docs again).
but the comment says it matches

> cxxConstructorDecl(isExplicit()) will match #2, but not #1.




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

https://reviews.llvm.org/D61552



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


[PATCH] D61552: [clang] Adapt ASTMatcher to explicit(bool) specifier

2019-06-19 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 205645.
Tyker marked an inline comment as done.

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

https://reviews.llvm.org/D61552

Files:
  clang/docs/LibASTMatchersReference.html
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/ASTMatchers/ASTMatchers.h
  clang/lib/ASTMatchers/Dynamic/Registry.cpp
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
  clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1735,6 +1735,56 @@
 llvm::make_unique>("x", 3)));
 }
 
+TEST(Declaration, HasExplicitSpecifier) {
+  EXPECT_TRUE(matchesConditionally(
+  "void f();", functionDecl(hasExplicitSpecifier(constantExpr())), false,
+  "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(true) operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(false) operator int(); };",
+  cxxConversionDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) S(int); };",
+  cxxConstructorDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(true) S(int); };",
+  cxxConstructorDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(false) S(int); };",
+  cxxConstructorDecl(hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { S(int); };"
+  "template explicit(b) S(int) -> S;",
+  cxxDeductionGuideDecl(
+  hasExplicitSpecifier(constantExpr(has(cxxBoolLiteral(),
+  false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("template struct S { S(int); };"
+   "explicit(true) S(int) -> S;",
+   cxxDeductionGuideDecl(hasExplicitSpecifier(
+   constantExpr(has(cxxBoolLiteral(),
+   true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("template struct S { S(int); };"
+   "explicit(false) S(int) -> S;",
+   cxxDeductionGuideDecl(hasExplicitSpecifier(
+   constantExpr(has(cxxBoolLiteral(),
+   true, "-std=c++2a"));
+}
+
 TEST(ForEachConstructorInitializer, MatchesInitializers) {
   EXPECT_TRUE(matches(
 "struct X { X() : i(42), j(42) {} int i, j; };",
Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -878,6 +878,15 @@
   cxxConversionDecl(isExplicit(;
   EXPECT_TRUE(notMatches("struct S { operator int(); };",
  cxxConversionDecl(isExplicit(;
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) operator int(); };",
+  cxxConversionDecl(isExplicit()), false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(true) operator int(); };",
+  cxxConversionDecl(isExplicit()), true, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally(
+  "struct S { explicit(false) operator int(); };",
+  cxxConversionDecl(isExplicit()), false, "-std=c++2a"));
 }
 
 TEST(Matcher, ArgumentCount) {
@@ -1197,6 +1206,38 @@
   cxxConstructorDecl(isExplicit(;
   EXPECT_TRUE(notMatches("struct S { S(int); };",
  cxxConstructorDecl(isExplicit(;
+  EXPECT_TRUE(matchesConditionally(
+  "template struct S { explicit(b) S(int);};",
+  cxxConstructorDecl(isExplicit()), false, "-std=c++2a"));
+  EXPECT_TRUE(matchesConditionally("struct S { explicit(true) S(int);};",
+   cxxConstructorDecl(isExplicit()), true,
+   

[PATCH] D61552: [clang] Adapt ASTMatcher to explicit(bool) specifier

2019-06-19 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL363855: [clang] Adapt ASTMatcher to explicit(bool) specifier 
(authored by Tyker, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D61552?vs=205645&id=205650#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D61552

Files:
  cfe/trunk/docs/LibASTMatchersReference.html
  cfe/trunk/include/clang/AST/DeclCXX.h
  cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
  cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
  cfe/trunk/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
  cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: cfe/trunk/docs/LibASTMatchersReference.html
===
--- cfe/trunk/docs/LibASTMatchersReference.html
+++ cfe/trunk/docs/LibASTMatchersReference.html
@@ -194,6 +194,16 @@
 
 
 
+MatcherDecl>cxxDeductionGuideDeclMatcherCXXDeductionGuideDecl>...
+Matches user-defined and implicitly generated deduction guide.
+
+Example matches the deduction guide.
+  template
+  class X { X(int) };
+  X(int) -> X;
+
+
+
 MatcherDecl>cxxDestructorDeclMatcherCXXDestructorDecl>...
 Matches explicit C++ destructor declarations.
 
@@ -,18 +2232,26 @@
 
 
 MatcherCXXConstructorDecl>isExplicit
-Matches constructor and conversion declarations that are marked with
-the explicit keyword.
+Matches constructor, conversion function, and deduction guide declarations
+that have an explicit specifier if this explicit specifier is resolved to
+true.
 
 Given
+  template
   struct S {
 S(int); // #1
 explicit S(double); // #2
 operator int(); // #3
 explicit operator bool(); // #4
-  };
-cxxConstructorDecl(isExplicit()) will match #2, but not #1.
+explicit(false) S(bool) // # 7
+explicit(true) S(char) // # 8
+explicit(b) S(S) // # 9
+  };
+  S(int) -> S // #5
+  explicit S(double) -> S // #6
+cxxConstructorDecl(isExplicit()) will match #2 and #8, but not #1, #7 or #9.
 cxxConversionDecl(isExplicit()) will match #4, but not #3.
+cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5.
 
 
 
@@ -2251,18 +2269,26 @@
 
 
 MatcherCXXConversionDecl>isExplicit
-Matches constructor and conversion declarations that are marked with
-the explicit keyword.
+Matches constructor, conversion function, and deduction guide declarations
+that have an explicit specifier if this explicit specifier is resolved to
+true.
 
 Given
+  template
   struct S {
 S(int); // #1
 explicit S(double); // #2
 operator int(); // #3
 explicit operator bool(); // #4
-  };
-cxxConstructorDecl(isExplicit()) will match #2, but not #1.
+explicit(false) S(bool) // # 7
+explicit(true) S(char) // # 8
+explicit(b) S(S) // # 9
+  };
+  S(int) -> S // #5
+  explicit S(double) -> S // #6
+cxxConstructorDecl(isExplicit()) will match #2 and #8, but not #1, #7 or #9.
 cxxConversionDecl(isExplicit()) will match #4, but not #3.
+cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5.
 
 
 
@@ -2317,6 +2343,30 @@
 
 
 
+MatcherCXXDeductionGuideDecl>isExplicit
+Matches constructor, conversion function, and deduction guide declarations
+that have an explicit specifier if this explicit specifier is resolved to
+true.
+
+Given
+  template
+  struct S {
+S(int); // #1
+explicit S(double); // #2
+operator int(); // #3
+explicit operator bool(); // #4
+explicit(false) S(bool) // # 7
+explicit(true) S(char) // # 8
+explicit(b) S(S) // # 9
+  };
+  S(int) -> S // #5
+  explicit S(double) -> S // #6
+cxxConstructorDecl(isExplicit()) will match #2 and #8, but not #1, #7 or #9.
+cxxConversionDecl(isExplicit()) will match #4, but not #3.
+cxxDeductionGuideDecl(isExplicit()) will match #6, but not #5.
+
+
+
 MatcherCXXDependentScopeMemberExpr>isArrow
 Matches member expressions that are called with '->' as opposed
 to '.'.
@@ -6007,6 +6057,29 @@
 
 
 
+MatcherFunctionDecl>hasExplicitSpecifierMatcherExpr> InnerMatcher
+Matches the expression in an explicit specifier if present in the given
+declaration.
+
+Given
+  templat

[PATCH] D63960: [C++20] Add consteval-specifique semantic

2019-07-20 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

@rsmith ping


Repository:
  rC Clang

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

https://reviews.llvm.org/D63960



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


[PATCH] D63960: [C++20] Add consteval-specifique semantic

2019-08-03 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

ping @rsmith


Repository:
  rC Clang

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

https://reviews.llvm.org/D63960



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


[PATCH] D63134: [clang] improving diagnotics for invalid constexpr defaulted special membres

2019-08-03 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

ping @rsmith


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

https://reviews.llvm.org/D63134



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


[PATCH] D63376: [clang] Small improvments after Adding APValue to ConstantExpr

2019-06-20 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/include/clang/Sema/Sema.h:10298
+ bool AllowFold = true,
+ bool StoreResult = true);
   ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,

rsmith wrote:
> Tyker wrote:
> > rsmith wrote:
> > > Do you need this new flag? No callers are passing it.
> > the idea behind it is that not all integral constant expression benefit 
> > from storing the result. i have not analyzed which benefit from it and 
> > which don't. adding a FIXME would have probably be more appropriate.
> It's useful to have a consistent AST representation, so I'd be inclined to at 
> least always create a `ConstantExpr` node. Also, once we start allowing 
> `consteval` evaluations that have side effects (for example, 
> reflection-related actions that modify the AST), I think we'll need to always 
> store the result to ensure we never evaluate a constant expression twice (and 
> trigger its side-effects to occur twice).
I removed the StoreResult flag.
evaluating expression only once is going to be mandatory in the future but i 
think it is hard to reach, semantic checking often needs intermediate values. 
so we will need probably need to integrate semantic checking to the expression 
evaluator to use its intermediate value. and do so without code duplication 
with the non-constant context checking.


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

https://reviews.llvm.org/D63376



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


[PATCH] D63376: [clang] Small improvments after Adding APValue to ConstantExpr

2019-06-20 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 205944.
Tyker marked an inline comment as done.
Tyker added a comment.

made the requested changes.


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

https://reviews.llvm.org/D63376

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp

Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -14538,14 +14538,13 @@
 return ExprError();
   }
 
-  if (!isa(E))
-E = ConstantExpr::Create(Context, E);
-
   // Circumvent ICE checking in C++11 to avoid evaluating the expression twice
   // in the non-ICE case.
   if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {
 if (Result)
   *Result = E->EvaluateKnownConstIntCheckOverflow(Context);
+if (!isa(E))
+  E = ConstantExpr::Create(Context, E);
 return E;
   }
 
@@ -14555,8 +14554,12 @@
 
   // Try to evaluate the expression, and produce diagnostics explaining why it's
   // not a constant expression as a side-effect.
-  bool Folded = E->EvaluateAsRValue(EvalResult, Context) &&
-EvalResult.Val.isInt() && !EvalResult.HasSideEffects;
+  bool Folded =
+  E->EvaluateAsRValue(EvalResult, Context, /*isConstantContext*/ true) &&
+  EvalResult.Val.isInt() && !EvalResult.HasSideEffects;
+
+  if (!isa(E))
+E = ConstantExpr::Create(Context, E, EvalResult.Val);
 
   // In C++11, we can rely on diagnostics being produced for any expression
   // which is not a constant expression. If no diagnostics were produced, then
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -14013,8 +14013,6 @@
 ExprResult Converted = PerformContextuallyConvertToBool(AssertExpr);
 if (Converted.isInvalid())
   Failed = true;
-else
-  Converted = ConstantExpr::Create(Context, Converted.get());
 
 llvm::APSInt Cond;
 if (!Failed && VerifyIntegerConstantExpression(Converted.get(), &Cond,
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -8963,6 +8963,8 @@
 
 bool IntExprEvaluator::VisitConstantExpr(const ConstantExpr *E) {
   llvm::SaveAndRestore InConstantContext(Info.InConstantContext, true);
+  if (E->getResultAPValueKind() != APValue::None)
+return Success(E->getAPValueResult(), E);
   return ExprEvaluatorBaseTy::VisitConstantExpr(E);
 }
 
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -239,6 +239,7 @@
 ConstantExpr::getStorageKind(const APValue &Value) {
   switch (Value.getKind()) {
   case APValue::None:
+  case APValue::Indeterminate:
 return ConstantExpr::RSK_None;
   case APValue::Int:
 if (!Value.getInt().needsCleanup())
@@ -249,9 +250,18 @@
   }
 }
 
+ConstantExpr::ResultStorageKind
+ConstantExpr::getStorageKind(const Type *T, const ASTContext &Context) {
+  if (T->isIntegralOrEnumerationType() && Context.getTypeInfo(T).Width <= 64)
+return ConstantExpr::RSK_Int64;
+  return ConstantExpr::RSK_APValue;
+}
+
 void ConstantExpr::DefaultInit(ResultStorageKind StorageKind) {
   ConstantExprBits.ResultKind = StorageKind;
-  if (StorageKind == RSK_APValue)
+  ConstantExprBits.APValueKind = APValue::None;
+  ConstantExprBits.HasCleanup = false;
+  if (StorageKind == ConstantExpr::RSK_APValue)
 ::new (getTrailingObjects()) APValue();
 }
 
@@ -269,8 +279,6 @@
   StorageKind == ConstantExpr::RSK_Int64);
   void *Mem = Context.Allocate(Size, alignof(ConstantExpr));
   ConstantExpr *Self = new (Mem) ConstantExpr(E, StorageKind);
-  if (StorageKind == ConstantExpr::RSK_APValue)
-Context.AddAPValueCleanup(&Self->APValueResult());
   return Self;
 }
 
@@ -278,7 +286,7 @@
const APValue &Result) {
   ResultStorageKind StorageKind = getStorageKind(Result);
   ConstantExpr *Self = Create(Context, E, StorageKind);
-  Self->SetResult(Result);
+  Self->SetResult(Result, Context);
   return Self;
 }
 
@@ -296,14 +304,13 @@
   StorageKind == ConstantExpr::RSK_Int64);
   void *Mem = Context.Allocate(Size, alignof(ConstantExpr));
   ConstantExpr *Self = new (Mem) ConstantExpr(StorageKind, Empty);
-  if (StorageKind == ConstantExpr::RSK_APValue)
-Context.AddAPValueCleanup(&Self->APValueResult());
   return Self;
 }
 
-void ConstantExpr::MoveIntoResult(APValue &Value) {
+void ConstantExpr::MoveIntoResult(APValue &Value, const ASTContext &Context) {
   assert(getStorageKind(Value) == ConstantExprBits.ResultKind &&

[PATCH] D63376: [clang] Small improvments after Adding APValue to ConstantExpr

2019-06-21 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL364011: [clang] Small improvments after Adding APValue to 
ConstantExpr (authored by Tyker, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D63376?vs=205944&id=205948#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D63376

Files:
  cfe/trunk/include/clang/AST/ASTContext.h
  cfe/trunk/include/clang/AST/Expr.h
  cfe/trunk/include/clang/AST/Stmt.h
  cfe/trunk/lib/AST/ASTContext.cpp
  cfe/trunk/lib/AST/Expr.cpp
  cfe/trunk/lib/AST/ExprConstant.cpp
  cfe/trunk/lib/Sema/SemaDeclCXX.cpp
  cfe/trunk/lib/Sema/SemaExpr.cpp

Index: cfe/trunk/include/clang/AST/Stmt.h
===
--- cfe/trunk/include/clang/AST/Stmt.h
+++ cfe/trunk/include/clang/AST/Stmt.h
@@ -332,6 +332,9 @@
 /// The kind of result that is trail-allocated.
 unsigned ResultKind : 2;
 
+/// Kind of Result as defined by APValue::Kind
+unsigned APValueKind : 4;
+
 /// When ResultKind == RSK_Int64. whether the trail-allocated integer is
 /// signed.
 unsigned IsUnsigned : 1;
@@ -340,6 +343,10 @@
 /// integer. 7 bits because it is the minimal number of bit to represent a
 /// value from 0 to 64 (the size of the trail-allocated number).
 unsigned BitWidth : 7;
+
+/// When ResultKind == RSK_APValue. Wether the ASTContext will cleanup the
+/// destructor on the trail-allocated APValue.
+unsigned HasCleanup : 1;
   };
 
   class PredefinedExprBitfields {
Index: cfe/trunk/include/clang/AST/Expr.h
===
--- cfe/trunk/include/clang/AST/Expr.h
+++ cfe/trunk/include/clang/AST/Expr.h
@@ -998,6 +998,9 @@
EmptyShell Empty);
 
   static ResultStorageKind getStorageKind(const APValue &Value);
+  static ResultStorageKind getStorageKind(const Type *T,
+  const ASTContext &Context);
+
   SourceLocation getBeginLoc() const LLVM_READONLY {
 return SubExpr->getBeginLoc();
   }
@@ -1009,25 +1012,20 @@
 return T->getStmtClass() == ConstantExprClass;
   }
 
-  void SetResult(APValue Value) { MoveIntoResult(Value); }
-  void MoveIntoResult(APValue &Value);
+  void SetResult(APValue Value, const ASTContext &Context) {
+MoveIntoResult(Value, Context);
+  }
+  void MoveIntoResult(APValue &Value, const ASTContext &Context);
 
   APValue::ValueKind getResultAPValueKind() const {
-switch (ConstantExprBits.ResultKind) {
-case ConstantExpr::RSK_APValue:
-  return APValueResult().getKind();
-case ConstantExpr::RSK_Int64:
-  return APValue::Int;
-case ConstantExpr::RSK_None:
-  return APValue::None;
-}
-llvm_unreachable("invalid ResultKind");
+return static_cast(ConstantExprBits.APValueKind);
   }
   ResultStorageKind getResultStorageKind() const {
 return static_cast(ConstantExprBits.ResultKind);
   }
   APValue getAPValueResult() const;
-
+  const APValue &getResultAsAPValue() const { return APValueResult(); }
+  llvm::APSInt getResultAsAPSInt() const;
   // Iterators
   child_range children() { return child_range(&SubExpr, &SubExpr+1); }
   const_child_range children() const {
Index: cfe/trunk/include/clang/AST/ASTContext.h
===
--- cfe/trunk/include/clang/AST/ASTContext.h
+++ cfe/trunk/include/clang/AST/ASTContext.h
@@ -2751,12 +2751,11 @@
   ///
   /// \param Data Pointer data that will be provided to the callback function
   /// when it is called.
-  void AddDeallocation(void (*Callback)(void*), void *Data);
+  void AddDeallocation(void (*Callback)(void *), void *Data) const;
 
   /// If T isn't trivially destructible, calls AddDeallocation to register it
   /// for destruction.
-  template 
-  void addDestruction(T *Ptr) {
+  template  void addDestruction(T *Ptr) const {
 if (!std::is_trivially_destructible::value) {
   auto DestroyPtr = [](void *V) { static_cast(V)->~T(); };
   AddDeallocation(DestroyPtr, Ptr);
@@ -2819,10 +2818,6 @@
   APValue *getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,
  bool MayCreate);
 
-  /// Adds an APValue that will be destructed during the destruction of the
-  /// ASTContext.
-  void AddAPValueCleanup(APValue *Ptr) const { APValueCleanups.push_back(Ptr); }
-
   /// Return a string representing the human readable name for the specified
   /// function declaration or file name. Used by SourceLocExpr and
   /// PredefinedExpr to cache evaluated results.
@@ -2989,7 +2984,7 @@
   // in order to track and run destructors while we're tearing things down.
   using DeallocationFunctionsAndArguments =
   llvm::SmallVector, 16>;
-  DeallocationFunctionsAndArguments Deallocations;
+

[PATCH] D63640: [clang] Improve Serialization/Imporing of APValues

2019-06-21 Thread Tyker via Phabricator via cfe-commits
Tyker created this revision.
Tyker added a reviewer: rsmith.
Herald added a reviewer: martong.
Herald added a reviewer: shafik.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Tyker edited the summary of this revision.
Herald added a subscriber: rnkovacs.

Changes:

- initializer expressions of constexpr variable are now wraped in a 
ConstantExpr. this is mainly used for testing purposes. the old caching system 
has not yet been removed.
- Add Serialization and Importing of APValues for Struct, Array and Vectors.
- Cleanup leftover from last patch.
- Add Tests.


Repository:
  rC Clang

https://reviews.llvm.org/D63640

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/ASTImporter.h
  clang/include/clang/AST/Expr.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/PCH/APValue.cpp

Index: clang/test/PCH/APValue.cpp
===
--- /dev/null
+++ clang/test/PCH/APValue.cpp
@@ -0,0 +1,91 @@
+
+// RUN: %clang_cc1 -std=gnu++17 -emit-pch %s -o %t.pch
+// RUN: %clang_cc1 -std=gnu++17 -x c++ -include-pch %t.pch -ast-dump-all | FileCheck %s
+
+#ifndef EMIT
+#define EMIT
+
+namespace Integer {
+
+constexpr int Unique_Int = int(6789);
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int' 6789
+
+constexpr __uint128_t Unique_Int128 = ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+//CHECK:  VarDecl {{.*}} Unique_Int128 
+//CHECK-NEXT: ConstantExpr {{.*}} 'unsigned __int128' 156773562844924187900898496343692168785
+
+}
+
+namespace FloatingPoint {
+
+constexpr double Unique_Double = double(567890.67890);
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}} 'double' 5.678907e+05
+
+}
+
+// FIXME: Add test for FixePoint, ComplexInt, ComplexFloat.
+// as they are C features they need to be treated differently.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+constexpr B Basic_Struct = B{1, 0.7};
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::B' {1, 7.00e-01}
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  int i;
+  double d;
+  C c;
+};
+
+constexpr A Advanced_Struct = A{Basic_Struct, 1, 79.789, {}};
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::A' {{[{][{]}}1, 7.00e-01}, 1, 7.978900e+01, {9}}
+
+}
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Vector_Int = (v4si){8, 2, 3};
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'Vector::v4si':'__attribute__((__vector_size__(4 * sizeof(int int' {8, 2, 3, 0}
+
+}
+
+namespace Array {
+
+constexpr int Array_Int[] = {1, 2, 3, 4, 5, 6};
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int [6]' {1, 2, 3, 4, 5, 6}
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+constexpr A Array2_Struct[][3] = {{{}, {-45678, 9.8}, {9}}, {{}}};
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'Array::A const [2][3]' {{[{][{]}}{789, 6.789010e+04}, {-45678, 9.80e+00}, {9, 6.789010e+04}}, {{[{][{]}}789, 6.789010e+04}, {789, 6.789010e+04}, {789, 6.789010e+04}}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Array_Vector[] = {{1, 2, 3, 4}, {4, 5, 6, 7}};
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Array::v4si [2]' {{[{][{]}}1, 2, 3, 4}, {4, 5, 6, 7}}
+
+}
+
+#endif
\ No newline at end of file
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -5441,10 +5441,26 @@
 AddAPFloat(Value.getComplexFloatImag());
 return;
   }
-  case APValue::LValue:
   case APValue::Vector:
+push_back(Value.getVectorLength());
+for (unsigned Idx = 0; Idx < Value.getVectorLength(); Idx++)
+  AddAPValue(Value.getVectorElt(Idx));
+return;
   case APValue::Array:
+push_back(Value.getArrayInitializedElts());
+push_back(Value.getArraySize());
+for (unsigned Idx = 0; Idx < Value.getArrayInitializedElts(); Idx++)
+  AddAPValue(Value.getArrayInitializedElt(Idx));
+return;
   case APValue::Struct:
+push_back(Value.getStructNumBases());
+push_back(Value.getStructNumFields());
+for (unsigned Idx = 0; Idx < Value.getStructNumBases(); Idx++)
+  AddAPValue(Value.getStructBase(Idx));
+for (unsigned Idx = 0; Idx < Value.getStructNumFields(); Idx++)
+  AddAPValue(Value.getStructField(Idx));
+return;
+  case APValue::LValue:
   case APValue::Union:
   case APValue::MemberPointer:
   case APVa

[PATCH] D63134: [clang] improving diagnotics for invalid constexpr defaulted special membres

2019-06-21 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

ping @rsmith


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

https://reviews.llvm.org/D63134



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


[PATCH] D63640: [clang] Improve Serialization/Imporing of APValues

2019-06-22 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 206121.
Tyker edited the summary of this revision.

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

https://reviews.llvm.org/D63640

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/ASTImporter.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/PCH/APValue.cpp

Index: clang/test/PCH/APValue.cpp
===
--- /dev/null
+++ clang/test/PCH/APValue.cpp
@@ -0,0 +1,113 @@
+
+// RUN: %clang_cc1 -std=gnu++17 -emit-pch %s -o %t.pch
+// RUN: %clang_cc1 -std=gnu++17 -x c++ -include-pch %t.pch -ast-dump-all | FileCheck %s
+
+#ifndef EMIT
+#define EMIT
+
+namespace Integer {
+
+constexpr int Unique_Int = int(6789);
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int' 6789
+
+constexpr __uint128_t Unique_Int128 = ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+//CHECK:  VarDecl {{.*}} Unique_Int128 
+//CHECK-NEXT: ConstantExpr {{.*}} 'unsigned __int128' 156773562844924187900898496343692168785
+
+}
+
+namespace FloatingPoint {
+
+constexpr double Unique_Double = double(567890.67890);
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}} 'double' 5.678907e+05
+
+}
+
+// FIXME: Add test for FixePoint, ComplexInt, ComplexFloat.
+// as they are C features they need to be treated differently.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+constexpr B Basic_Struct = B{1, 0.7};
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::B' {1, 7.00e-01}
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  int i;
+  double d;
+  C c;
+};
+
+constexpr A Advanced_Struct = A{Basic_Struct, 1, 79.789, {}};
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::A' {{[{][{]}}1, 7.00e-01}, 1, 7.978900e+01, {9}}
+
+}
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Vector_Int = (v4si){8, 2, 3};
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'Vector::v4si':'__attribute__((__vector_size__(4 * sizeof(int int' {8, 2, 3, 0}
+
+}
+
+namespace Array {
+
+constexpr int Array_Int[] = {1, 2, 3, 4, 5, 6};
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int [6]' {1, 2, 3, 4, 5, 6}
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+constexpr A Array2_Struct[][3] = {{{}, {-45678, 9.8}, {9}}, {{}}};
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'Array::A const [2][3]' {{[{][{]}}{789, 6.789010e+04}, {-45678, 9.80e+00}, {9, 6.789010e+04}}, {{[{][{]}}789, 6.789010e+04}, {789, 6.789010e+04}, {789, 6.789010e+04}}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Array_Vector[] = {{1, 2, 3, 4}, {4, 5, 6, 7}};
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Array::v4si [2]' {{[{][{]}}1, 2, 3, 4}, {4, 5, 6, 7}}
+
+}
+
+namespace Union {
+
+struct A {
+  int i = 6789;
+  float f = 987.9876;
+};
+
+union U {
+  int i;
+  A a{567890, 9876.5678f};
+};
+
+constexpr U Unique_Union1 = U{0};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.i = 0}
+
+constexpr U Unique_Union2 = U{};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.a = {567890, 9.876567e+03}}
+
+}
+
+#endif
\ No newline at end of file
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -5441,13 +5441,32 @@
 AddAPFloat(Value.getComplexFloatImag());
 return;
   }
-  case APValue::LValue:
   case APValue::Vector:
+push_back(Value.getVectorLength());
+for (unsigned Idx = 0; Idx < Value.getVectorLength(); Idx++)
+  AddAPValue(Value.getVectorElt(Idx));
+return;
   case APValue::Array:
+push_back(Value.getArrayInitializedElts());
+push_back(Value.getArraySize());
+for (unsigned Idx = 0; Idx < Value.getArrayInitializedElts(); Idx++)
+  AddAPValue(Value.getArrayInitializedElt(Idx));
+return;
   case APValue::Struct:
+push_back(Value.getStructNumBases());
+push_back(Value.getStructNumFields());
+for (unsigned Idx = 0; Idx < Value.getStructNumBases(); Idx++)
+  AddAPValue(Value.getStructBase(Idx));
+for (unsigned Idx = 0; Idx < Value.getStructNumFields(); Idx++)
+  AddAPValue(Value.getStructField(Idx));

[PATCH] D63640: [clang] Improve Serialization/Imporing of APValues

2019-06-25 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 206464.
Tyker edited the summary of this revision.
Tyker added a comment.

Change:

- Add support for LValue, MemberPointer and AddrDiffExpr.
- Add tests for importing.

i wasn't able to test for some APValueKinds: FixePoint, ComplexInt, 
ComplexFloat, AddrLabelDiff.
LValue could need more tests. i am not sure all edges cases are covered.


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

https://reviews.llvm.org/D63640

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/ASTImporter.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/TextNodeDumper.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/ASTMerge/APValue/Inputs/APValue.cpp
  clang/test/ASTMerge/APValue/test.cpp
  clang/test/PCH/APValue.cpp

Index: clang/test/PCH/APValue.cpp
===
--- /dev/null
+++ clang/test/PCH/APValue.cpp
@@ -0,0 +1,210 @@
+
+// RUN: %clang_cc1 -std=gnu++2a -emit-pch %s -o %t.pch
+// RUN: %clang_cc1 -std=gnu++2a -x c++ -include-pch %t.pch -ast-dump-all | FileCheck %s
+
+#ifndef EMIT
+#define EMIT
+
+namespace Integer {
+
+constexpr int Unique_Int = int(6789);
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int' 6789
+
+constexpr __uint128_t Unique_Int128 = ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+//CHECK:  VarDecl {{.*}} Unique_Int128 
+//CHECK-NEXT: ConstantExpr {{.*}} 'unsigned __int128' 156773562844924187900898496343692168785
+
+}
+
+namespace FloatingPoint {
+
+constexpr double Unique_Double = double(567890.67890);
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}} 'double' 5.678907e+05
+
+}
+
+// FIXME: Add test for FixePoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+constexpr B Basic_Struct = B{1, 0.7};
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::B' {1, 7.00e-01}
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  int i;
+  double d;
+  C c;
+};
+
+constexpr A Advanced_Struct = A{Basic_Struct, 1, 79.789, {}};
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::A' {{[{][{]}}1, 7.00e-01}, 1, 7.978900e+01, {9}}
+
+}
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Vector_Int = (v4si){8, 2, 3};
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'Vector::v4si':'__attribute__((__vector_size__(4 * sizeof(int int' {8, 2, 3, 0}
+
+}
+
+namespace Array {
+
+constexpr int Array_Int[] = {1, 2, 3, 4, 5, 6};
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int [6]' {1, 2, 3, 4, 5, 6}
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+constexpr A Array2_Struct[][3] = {{{}, {-45678, 9.8}, {9}}, {{}}};
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'Array::A const [2][3]' {{[{][{]}}{789, 6.789010e+04}, {-45678, 9.80e+00}, {9, 6.789010e+04}}, {{[{][{]}}789, 6.789010e+04}, {789, 6.789010e+04}, {789, 6.789010e+04}}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Array_Vector[] = {{1, 2, 3, 4}, {4, 5, 6, 7}};
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Array::v4si [2]' {{[{][{]}}1, 2, 3, 4}, {4, 5, 6, 7}}
+
+}
+
+namespace Union {
+
+struct A {
+  int i = 6789;
+  float f = 987.9876;
+};
+
+union U {
+  int i;
+  A a{567890, 9876.5678f};
+};
+
+constexpr U Unique_Union1 = U{0};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.i = 0}
+
+constexpr U Unique_Union2 = U{};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.a = {567890, 9.876567e+03}}
+
+}
+
+namespace MemberPointer{
+
+struct A {
+  struct B {
+struct C {
+  struct D {
+struct E {
+  struct F {
+struct G {
+  int i;
+};
+  };
+};
+  };
+};
+  };
+};
+
+constexpr auto MemberPointer1 = &A::B::C::D::E::F::G::i;
+//CHECK:  VarDecl {{.*}} MemberPointer1
+//CHECK-NEXT: ConstantExpr {{.*}} 'int MemberPointer::A::B::C::D::E::F::G::*' &G::i
+
+struct A1 {
+  struct B1 {
+int f() const {
+  return 0;
+}
+  };
+
+};
+
+constexpr auto MemberPointer2 = &A1::B1::f;
+//CHECK:  VarDecl {{.*}} MemberPointer2
+//CHECK-NEXT: ConstantExpr {{.*}} 'int (MemberPointer::A1::B1::*)() const' &B1::f
+
+}
+
+namespace std {
+  s

[PATCH] D63640: [clang] Improve Serialization/Imporing of APValues

2019-06-25 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 206467.

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

https://reviews.llvm.org/D63640

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/ASTImporter.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/TextNodeDumper.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/PCH/APValue.cpp

Index: clang/test/PCH/APValue.cpp
===
--- /dev/null
+++ clang/test/PCH/APValue.cpp
@@ -0,0 +1,211 @@
+
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -emit-pch %s -o %t.pch
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -include-pch %t.pch -ast-dump-all | FileCheck %s
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -ast-merge %t.pch -ast-dump-all | FileCheck %s
+
+#ifndef EMIT
+#define EMIT
+
+namespace Integer {
+
+constexpr int Unique_Int = int(6789);
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int' 6789
+
+constexpr __uint128_t Unique_Int128 = ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+//CHECK:  VarDecl {{.*}} Unique_Int128 
+//CHECK-NEXT: ConstantExpr {{.*}} 'unsigned __int128' 156773562844924187900898496343692168785
+
+}
+
+namespace FloatingPoint {
+
+constexpr double Unique_Double = double(567890.67890);
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}} 'double' 5.678907e+05
+
+}
+
+// FIXME: Add test for FixePoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+constexpr B Basic_Struct = B{1, 0.7};
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::B' {1, 7.00e-01}
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  int i;
+  double d;
+  C c;
+};
+
+constexpr A Advanced_Struct = A{Basic_Struct, 1, 79.789, {}};
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::A' {{[{][{]}}1, 7.00e-01}, 1, 7.978900e+01, {9}}
+
+}
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Vector_Int = (v4si){8, 2, 3};
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'Vector::v4si':'__attribute__((__vector_size__(4 * sizeof(int int' {8, 2, 3, 0}
+
+}
+
+namespace Array {
+
+constexpr int Array_Int[] = {1, 2, 3, 4, 5, 6};
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int [6]' {1, 2, 3, 4, 5, 6}
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+constexpr A Array2_Struct[][3] = {{{}, {-45678, 9.8}, {9}}, {{}}};
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'Array::A const [2][3]' {{[{][{]}}{789, 6.789010e+04}, {-45678, 9.80e+00}, {9, 6.789010e+04}}, {{[{][{]}}789, 6.789010e+04}, {789, 6.789010e+04}, {789, 6.789010e+04}}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Array_Vector[] = {{1, 2, 3, 4}, {4, 5, 6, 7}};
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Array::v4si [2]' {{[{][{]}}1, 2, 3, 4}, {4, 5, 6, 7}}
+
+}
+
+namespace Union {
+
+struct A {
+  int i = 6789;
+  float f = 987.9876;
+};
+
+union U {
+  int i;
+  A a{567890, 9876.5678f};
+};
+
+constexpr U Unique_Union1 = U{0};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.i = 0}
+
+constexpr U Unique_Union2 = U{};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.a = {567890, 9.876567e+03}}
+
+}
+
+namespace MemberPointer{
+
+struct A {
+  struct B {
+struct C {
+  struct D {
+struct E {
+  struct F {
+struct G {
+  int i;
+};
+  };
+};
+  };
+};
+  };
+};
+
+constexpr auto MemberPointer1 = &A::B::C::D::E::F::G::i;
+//CHECK:  VarDecl {{.*}} MemberPointer1
+//CHECK-NEXT: ConstantExpr {{.*}} 'int MemberPointer::A::B::C::D::E::F::G::*' &G::i
+
+struct A1 {
+  struct B1 {
+int f() const {
+  return 0;
+}
+  };
+
+};
+
+constexpr auto MemberPointer2 = &A1::B1::f;
+//CHECK:  VarDecl {{.*}} MemberPointer2
+//CHECK-NEXT: ConstantExpr {{.*}} 'int (MemberPointer::A1::B1::*)() const' &B1::f
+
+}
+
+namespace std {
+  struct type_info;
+};
+
+namespace LValue {
+
+constexpr int LValueInt = 0;
+constexpr const int& ConstIntRef = LValueInt;
+//CHECK:  VarDecl {{.*}} ConstIntRef
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int' lvalue &LValueInt
+constexpr const int* IntPtr = &LValueInt;
+//CHECK:  VarDecl {{.*}} IntPtr
+//CHECK-NEXT: Cons

[PATCH] D63960: [C++20] Add consteval-specifique semantic

2019-06-28 Thread Tyker via Phabricator via cfe-commits
Tyker created this revision.
Tyker added a reviewer: rsmith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Changes:

- Calls to consteval function and constructors are not evaluated as soon as 
they are reached.
- Add diagnostic for taking address of a consteval function in non-constexpr 
context.
- Add diagnostic for address of consteval function accessible at runtime.
- Add tests

Serialization and importing depends on https://reviews.llvm.org/D63640


Repository:
  rC Clang

https://reviews.llvm.org/D63960

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp

Index: clang/test/SemaCXX/cxx2a-consteval.cpp
===
--- clang/test/SemaCXX/cxx2a-consteval.cpp
+++ clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -56,3 +56,276 @@
 consteval int main() { // expected-error {{'main' is not allowed to be declared consteval}}
   return 0;
 }
+
+int i_runtime; // expected-note+ {{declared here}}
+constexpr int i_constexpr = 0;
+
+consteval int f_eval(int i) {
+// expected-note@-1+ {{declared here}}
+  return i;
+}
+
+constexpr auto l_eval = [](int i) consteval {
+// expected-note@-1+ {{declared here}}
+  return i;
+};
+
+struct A {
+  int I = 0;
+  consteval int f_eval(int i) const {
+// expected-note@-1+ {{declared here}}
+return I + i;
+// expected-note@-1 {{is not allowed in a constant expression}}
+  }
+};
+
+constexpr A a;
+
+namespace invalid_call {
+
+int d2 = f_eval(i_runtime);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{is not allowed in a constant expression}}
+int l2 = l_eval(i_runtime);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{is not allowed in a constant expression}}
+int m2 = a.f_eval(i_runtime);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{is not allowed in a constant expression}}
+int d4 = f_eval(i_constexpr);
+int l4 = l_eval(i_constexpr);
+int m4 = a.f_eval(i_constexpr);
+
+constexpr int f1(int i) { // expected-note+ {{declared here}}
+  int d0 = f_eval(0);
+  int l0 = l_eval(0);
+  int m0 = a.f_eval(0);
+  int d2 = f_eval(i);
+  // expected-error@-1 {{could not be evaluated}}
+  // expected-error@-2 {{must be initialized}}
+  // FIXME: the error above should not appear when the initializer present but is invalid.
+  // expected-note@-4 {{is not allowed in a constant expression}}
+
+  int l2 = l_eval(i);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{is not allowed in a constant expression}}
+  int m2 = a.f_eval(i);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{is not allowed in a constant expression}}
+  int d6 = f_eval(i_constexpr);
+  int l6 = l_eval(i_constexpr);
+  int m6 = a.f_eval(i_constexpr);
+  int d8 = f_eval(i_runtime);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{is not allowed in a constant expression}}
+  int l8 = l_eval(i_runtime);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{is not allowed in a constant expression}}
+  int m8 = a.f_eval(i_runtime);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{is not allowed in a constant expression}}
+  return 0;
+}
+
+consteval int f2(int i) {
+// expected-error@-1 {{never produces a constant expression}}
+  int d0 = f_eval(i);
+  int l0 = l_eval(i);
+  int m0 = a.f_eval(i);
+  int d1 = f_eval(i_runtime);
+// expected-note@-1 {{is not allowed in a constant expression}}
+  int l1 = l_eval(i_runtime);
+  int m1 = a.f_eval(i_runtime);
+  return 0;
+}
+
+void test() {
+  A a_dependent;
+  // expected-note@-1+ {{declared here}}
+
+  int Int = 0;
+  auto l_dependent = [Int](int i) consteval {
+// expected-note@-1+ {{declared here}}
+return Int + i;
+// expected-note@-1 {{is not allowed in a constant expression}}
+  };
+
+  int i_l = l_dependent(0);
+  // expected-error@-1 {{could not be evaluated}}
+  // expected-note@-2 {{in call}}
+
+  int i_m = a_dependent.f_eval(0);
+  // expected-error@-1 {{could not be evaluated}}
+  // expected-note@-2 {{in call}}
+}
+
+}
+
+namespace taking_address {
+
+using func_type = int(int);
+using mem_ptr_type = int(A::*)(int);
+
+func_type* p1 = (&f_eval);
+// expected-error@-1 {{take address}}
+func_type* p2= &(((f_eval)));
+// expected-error@-1 {{take address}}
+func_type* p3 = (func_type*)f_eval;
+// expected-error@-1 {{take address}}
+func_type* p4 = static_cast(f_eval);
+// expected-error@-1 {{take address}}
+func_type* p5 = reinterpret_cast(f_eval);
+// expected-error@-1 {{take address}}
+func_type* p6 = reinterpret_cast(&reinterpret_cast(f_eval));
+// expected-error@-1 {{take address}}
+func_type* p7 = __builtin_addressof(f_eval);
+// expected-error@-1 {{take address}}
+

[PATCH] D63640: [clang] Improve Serialization/Imporing of APValues

2019-07-04 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 207977.
Tyker marked 2 inline comments as done.
Tyker set the repository for this revision to rC Clang.
Tyker added a comment.

fixed comment typo.


Repository:
  rC Clang

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

https://reviews.llvm.org/D63640

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/ASTImporter.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/TextNodeDumper.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/PCH/APValue.cpp

Index: clang/test/PCH/APValue.cpp
===
--- /dev/null
+++ clang/test/PCH/APValue.cpp
@@ -0,0 +1,211 @@
+
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -emit-pch %s -o %t.pch
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -include-pch %t.pch -ast-dump-all | FileCheck %s
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -ast-merge %t.pch -ast-dump-all | FileCheck %s
+
+#ifndef EMIT
+#define EMIT
+
+namespace Integer {
+
+constexpr int Unique_Int = int(6789);
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int' 6789
+
+constexpr __uint128_t Unique_Int128 = ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+//CHECK:  VarDecl {{.*}} Unique_Int128 
+//CHECK-NEXT: ConstantExpr {{.*}} 'unsigned __int128' 156773562844924187900898496343692168785
+
+}
+
+namespace FloatingPoint {
+
+constexpr double Unique_Double = double(567890.67890);
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}} 'double' 5.678907e+05
+
+}
+
+// FIXME: Add test for FixePoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+constexpr B Basic_Struct = B{1, 0.7};
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::B' {1, 7.00e-01}
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  int i;
+  double d;
+  C c;
+};
+
+constexpr A Advanced_Struct = A{Basic_Struct, 1, 79.789, {}};
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::A' {{[{][{]}}1, 7.00e-01}, 1, 7.978900e+01, {9}}
+
+}
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Vector_Int = (v4si){8, 2, 3};
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'Vector::v4si':'__attribute__((__vector_size__(4 * sizeof(int int' {8, 2, 3, 0}
+
+}
+
+namespace Array {
+
+constexpr int Array_Int[] = {1, 2, 3, 4, 5, 6};
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int [6]' {1, 2, 3, 4, 5, 6}
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+constexpr A Array2_Struct[][3] = {{{}, {-45678, 9.8}, {9}}, {{}}};
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'Array::A const [2][3]' {{[{][{]}}{789, 6.789010e+04}, {-45678, 9.80e+00}, {9, 6.789010e+04}}, {{[{][{]}}789, 6.789010e+04}, {789, 6.789010e+04}, {789, 6.789010e+04}}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Array_Vector[] = {{1, 2, 3, 4}, {4, 5, 6, 7}};
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Array::v4si [2]' {{[{][{]}}1, 2, 3, 4}, {4, 5, 6, 7}}
+
+}
+
+namespace Union {
+
+struct A {
+  int i = 6789;
+  float f = 987.9876;
+};
+
+union U {
+  int i;
+  A a{567890, 9876.5678f};
+};
+
+constexpr U Unique_Union1 = U{0};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.i = 0}
+
+constexpr U Unique_Union2 = U{};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.a = {567890, 9.876567e+03}}
+
+}
+
+namespace MemberPointer{
+
+struct A {
+  struct B {
+struct C {
+  struct D {
+struct E {
+  struct F {
+struct G {
+  int i;
+};
+  };
+};
+  };
+};
+  };
+};
+
+constexpr auto MemberPointer1 = &A::B::C::D::E::F::G::i;
+//CHECK:  VarDecl {{.*}} MemberPointer1
+//CHECK-NEXT: ConstantExpr {{.*}} 'int MemberPointer::A::B::C::D::E::F::G::*' &G::i
+
+struct A1 {
+  struct B1 {
+int f() const {
+  return 0;
+}
+  };
+
+};
+
+constexpr auto MemberPointer2 = &A1::B1::f;
+//CHECK:  VarDecl {{.*}} MemberPointer2
+//CHECK-NEXT: ConstantExpr {{.*}} 'int (MemberPointer::A1::B1::*)() const' &B1::f
+
+}
+
+namespace std {
+  struct type_info;
+};
+
+namespace LValue {
+
+constexpr int LValueInt = 0;
+constexpr const int& ConstIntRef = LValueInt;
+//CHECK:  VarDecl {{.*}} ConstIntRef

[PATCH] D63640: [clang] Improve Serialization/Imporing of APValues

2019-07-04 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/lib/AST/ASTImporter.cpp:8503
 
+llvm::Expected ASTImporter::Import(const APValue &FromValue) {
+  APValue Result;

martong wrote:
> Looks okay, but could we have unit tests for this in ASTImporterTest.cpp?
I tested importing using the same test file as serialization 
`clang/test/PCH/APValue.cpp` with `-ast-merge` which uses importing. this 
prevent duplicating the test code for importing and serializing. is the 
unit-test in ASTImporterTest.cpp necessary anyway ?


Repository:
  rC Clang

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

https://reviews.llvm.org/D63640



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


[PATCH] D63640: [clang] Improve Serialization/Imporing of APValues

2019-07-04 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 208015.
Tyker added a comment.

fixed the comment for good, sorry for that.


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

https://reviews.llvm.org/D63640

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/ASTImporter.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/TextNodeDumper.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/PCH/APValue.cpp

Index: clang/test/PCH/APValue.cpp
===
--- /dev/null
+++ clang/test/PCH/APValue.cpp
@@ -0,0 +1,211 @@
+
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -emit-pch %s -o %t.pch
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -include-pch %t.pch -ast-dump-all | FileCheck %s
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -ast-merge %t.pch -ast-dump-all | FileCheck %s
+
+#ifndef EMIT
+#define EMIT
+
+namespace Integer {
+
+constexpr int Unique_Int = int(6789);
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int' 6789
+
+constexpr __uint128_t Unique_Int128 = ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+//CHECK:  VarDecl {{.*}} Unique_Int128 
+//CHECK-NEXT: ConstantExpr {{.*}} 'unsigned __int128' 156773562844924187900898496343692168785
+
+}
+
+namespace FloatingPoint {
+
+constexpr double Unique_Double = double(567890.67890);
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}} 'double' 5.678907e+05
+
+}
+
+// FIXME: Add test for FixePoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+constexpr B Basic_Struct = B{1, 0.7};
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::B' {1, 7.00e-01}
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  int i;
+  double d;
+  C c;
+};
+
+constexpr A Advanced_Struct = A{Basic_Struct, 1, 79.789, {}};
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::A' {{[{][{]}}1, 7.00e-01}, 1, 7.978900e+01, {9}}
+
+}
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Vector_Int = (v4si){8, 2, 3};
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'Vector::v4si':'__attribute__((__vector_size__(4 * sizeof(int int' {8, 2, 3, 0}
+
+}
+
+namespace Array {
+
+constexpr int Array_Int[] = {1, 2, 3, 4, 5, 6};
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int [6]' {1, 2, 3, 4, 5, 6}
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+constexpr A Array2_Struct[][3] = {{{}, {-45678, 9.8}, {9}}, {{}}};
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'Array::A const [2][3]' {{[{][{]}}{789, 6.789010e+04}, {-45678, 9.80e+00}, {9, 6.789010e+04}}, {{[{][{]}}789, 6.789010e+04}, {789, 6.789010e+04}, {789, 6.789010e+04}}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Array_Vector[] = {{1, 2, 3, 4}, {4, 5, 6, 7}};
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Array::v4si [2]' {{[{][{]}}1, 2, 3, 4}, {4, 5, 6, 7}}
+
+}
+
+namespace Union {
+
+struct A {
+  int i = 6789;
+  float f = 987.9876;
+};
+
+union U {
+  int i;
+  A a{567890, 9876.5678f};
+};
+
+constexpr U Unique_Union1 = U{0};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.i = 0}
+
+constexpr U Unique_Union2 = U{};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.a = {567890, 9.876567e+03}}
+
+}
+
+namespace MemberPointer{
+
+struct A {
+  struct B {
+struct C {
+  struct D {
+struct E {
+  struct F {
+struct G {
+  int i;
+};
+  };
+};
+  };
+};
+  };
+};
+
+constexpr auto MemberPointer1 = &A::B::C::D::E::F::G::i;
+//CHECK:  VarDecl {{.*}} MemberPointer1
+//CHECK-NEXT: ConstantExpr {{.*}} 'int MemberPointer::A::B::C::D::E::F::G::*' &G::i
+
+struct A1 {
+  struct B1 {
+int f() const {
+  return 0;
+}
+  };
+
+};
+
+constexpr auto MemberPointer2 = &A1::B1::f;
+//CHECK:  VarDecl {{.*}} MemberPointer2
+//CHECK-NEXT: ConstantExpr {{.*}} 'int (MemberPointer::A1::B1::*)() const' &B1::f
+
+}
+
+namespace std {
+  struct type_info;
+};
+
+namespace LValue {
+
+constexpr int LValueInt = 0;
+constexpr const int& ConstIntRef = LValueInt;
+//CHECK:  VarDecl {{.*}} ConstIntRef
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int' lvalue &LValueInt
+constexpr const int* IntPtr =

[PATCH] D63640: [clang] Improve Serialization/Imporing of APValues

2019-07-04 Thread Tyker via Phabricator via cfe-commits
Tyker marked 2 inline comments as done.
Tyker added inline comments.



Comment at: clang/lib/AST/ASTImporter.cpp:8503
 
+llvm::Expected ASTImporter::Import(const APValue &FromValue) {
+  APValue Result;

martong wrote:
> Tyker wrote:
> > martong wrote:
> > > Looks okay, but could we have unit tests for this in ASTImporterTest.cpp?
> > I tested importing using the same test file as serialization 
> > `clang/test/PCH/APValue.cpp` with `-ast-merge` which uses importing. this 
> > prevent duplicating the test code for importing and serializing. is the 
> > unit-test in ASTImporterTest.cpp necessary anyway ?
> Okay, that's fine I missed that previously, so there is no need for the 
> unit-tests in this case.
> Though maybe the `-ast-merge` part of the test should reside in the  
> `clang/test/ASTMerge` directory, because that is where all the other 
> `-ast-merge` tests are. 
> I am not sure how to solve that nicely, because i see you use the same file 
> for both the serialization and for the import.
> Perhaps there should be a common header file which is included both in 
> `test/PCH/APValue.cpp` and in `test/ASTMerge/apvalue/test.cpp`?
> 
> 
we can have a common header,  but i don't know where to put it. having a in 
`PCH` that includes a header form `ASTMerge` seems weird and vice versa. 


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

https://reviews.llvm.org/D63640



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


[PATCH] D63960: [C++20] Add consteval-specifique semantic

2019-07-07 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

ping @rsmith


Repository:
  rC Clang

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

https://reviews.llvm.org/D63960



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


[PATCH] D61790: [C++20] add consteval specifier

2019-05-10 Thread Tyker via Phabricator via cfe-commits
Tyker created this revision.
Tyker added a reviewer: rsmith.
Herald added a reviewer: martong.
Herald added a reviewer: shafik.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

this revision adds the consteval specifier as specified by 
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1073r3.html

Changes:

- add the consteval keyword.
- add parsing of consteval specifier for normal declarations and lambdas 
expressions.
- add the a bit to FunctionDeclBits for consteval.
- adapt creation of FunctionDecl and some classes inheriting from it to take an 
extra bool for consteval.
- change most calls to FunctionDecl::isConstexpr into call to 
FunctionDecl::isConstexprOrConsteval.
- add semantic checking to prevent call to consteval function that cannot be 
constant evaluated.
- add semantic checking to prevent taking address from consteval function.
- add semantic checking to prevent consteval specified allocation function.
- add tests for semantic.

The code-gen has not yet been adapted, but it will need to be change to not 
emit consteval function and ensure calls to consteval function are folded 
correctly.


Repository:
  rC Clang

https://reviews.llvm.org/D61790

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/DeclPrinter.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Analysis/ReachableCode.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaCoroutine.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/lib/Serialization/ASTWriterDecl.cpp
  clang/test/SemaCXX/cxx2a-compat.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp

Index: clang/test/SemaCXX/cxx2a-consteval.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -0,0 +1,224 @@
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+
+int i_global; // expected-note+ {{declared here}}
+extern int i_extern; // expected-note+ {{declared here}}
+const int i_const = 0;
+constexpr int i_constexpr = 0;
+
+consteval int f_eval(int i) {
+// expected-note@-1+ {{consteval function declared here}}
+  return i;
+}
+
+constexpr auto l_eval = [](int i) consteval {
+// expected-note@-1+ {{consteval operator declared here}}
+  return i;
+};
+
+constexpr int f_expr(int i) {
+  return i;
+}
+
+struct A {
+  consteval int f_eval(int i) const {
+// expected-note@-1+ {{consteval function declared here}}
+return i;
+  }
+};
+
+constexpr A a;
+
+namespace invalid_call_args {
+
+int d0 = f_eval(0);
+int l0 = l_eval(0);
+int m0 = a.f_eval(0);
+int d2 = f_eval(i_extern);
+// expected-error@-1 {{call to consteval function cannot be constant evaluated}}
+// expected-note@-2 {{argument 0 cannot be constant evaluated}}
+// expected-note@-3 {{not allowed in a constant expression}}
+int l2 = l_eval(i_extern);
+// expected-error@-1 {{call to consteval operator cannot be constant evaluated}}
+// expected-note@-2 {{argument 0 cannot be constant evaluated}}
+// expected-note@-3 {{not allowed in a constant expression}}
+int m2 = a.f_eval(i_extern);
+// expected-error@-1 {{call to consteval function cannot be constant evaluated}}
+// expected-note@-2 {{argument 0 cannot be constant evaluated}}
+// expected-note@-3 {{not allowed in a constant expression}}
+int d4 = f_eval(i_const);
+int l4 = l_eval(i_const);
+int m4 = a.f_eval(i_const);
+int d6 = f_eval(i_constexpr);
+int l6 = l_eval(i_constexpr);
+int m6 = a.f_eval(i_constexpr);
+int d8 = f_eval(i_global);
+// expected-error@-1 {{call to consteval function cannot be constant evaluated}}
+// expected-note@-2 {{argument 0 cannot be constant evaluated}}
+// expected-note@-3 {{not allowed in a constant expression}}
+int l8 = l_eval(i_global);
+// expected-error@-1 {{call to consteval operator cannot be constant evaluated}}
+// expected-note@-2 {{argument 0 cannot be constant evaluated}}
+// expected-note@-3 {{not allowed in a constant expression}}
+int m8 = a.f_eval(i_global);
+// expected-error@-1 {{call to consteval function cannot be constant evaluated}}
+// expected-note@-2 {{argument 0 cannot be constant evaluated}}
+// expected-note@-3 {{not allowed in a constant expression}}
+
+const

[PATCH] D62009: [clang] perform semantic checking in constant context

2019-05-16 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 199830.

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

https://reviews.llvm.org/D62009

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/SemaCXX/builtin-is-constant-evaluated.cpp

Index: clang/test/SemaCXX/builtin-is-constant-evaluated.cpp
===
--- clang/test/SemaCXX/builtin-is-constant-evaluated.cpp
+++ clang/test/SemaCXX/builtin-is-constant-evaluated.cpp
@@ -119,3 +119,11 @@
 };
 TestConditionalExplicit e = 42;
 #endif
+
+constexpr int i = (long long)__builtin_is_constant_evaluated() * (1ll << 33);
+// expected-warning@-1 {{implicit conversion}}
+
+void f() {
+  if constexpr ((long long)__builtin_is_constant_evaluated() * (1ll << 33))
+ ;// expected-error@-1 {{cannot be narrowed to type 'bool'}}
+}
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -5408,6 +5408,7 @@
   if (checkPlaceholderForOverload(S, From))
 return ExprError();
 
+  From->setIsConstantContext();
   // C++1z [expr.const]p3:
   //  A converted constant expression of type T is an expression,
   //  implicitly converted to type T, where the converted
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11100,6 +11100,10 @@
   return;
   }
 
+  Init->setIsConstantContext(
+  VDecl->isConstexpr() ||
+  (VDecl->getType().isConstQualified() && !Init->isValueDependent()));
+
   // dllimport cannot be used on variable definitions.
   if (VDecl->hasAttr() && !VDecl->isStaticDataMember()) {
 Diag(VDecl->getLocation(), diag::err_attribute_dllimport_data_definition);
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -11439,7 +11439,7 @@
 bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx,
 bool InConstantContext) const {
   EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
-  Info.InConstantContext = InConstantContext;
+  Info.InConstantContext = InConstantContext || IsConstantContext();
   return ::EvaluateAsRValue(this, Result, Ctx, Info);
 }
 
@@ -11453,12 +11453,14 @@
 bool Expr::EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx,
  SideEffectsKind AllowSideEffects) const {
   EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
+  Info.InConstantContext = IsConstantContext();
   return ::EvaluateAsInt(this, Result, Ctx, AllowSideEffects, Info);
 }
 
 bool Expr::EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx,
 SideEffectsKind AllowSideEffects) const {
   EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
+  Info.InConstantContext = IsConstantContext();
   return ::EvaluateAsFixedPoint(this, Result, Ctx, AllowSideEffects, Info);
 }
 
@@ -11478,7 +11480,7 @@
 
 bool Expr::EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx) const {
   EvalInfo Info(Ctx, Result, EvalInfo::EM_ConstantFold);
-
+  Info.InConstantContext = IsConstantContext();
   LValue LV;
   if (!EvaluateLValue(this, LV, Info) || Result.HasSideEffects ||
   !CheckLValueConstantExpression(Info, getExprLoc(),
@@ -11588,6 +11590,7 @@
   EvalResult EVResult;
   if (!FastEvaluateAsRValue(this, EVResult, Ctx, IsConst)) {
 EvalInfo Info(Ctx, EVResult, EvalInfo::EM_EvaluateForOverflow);
+Info.InConstantContext = IsConstantContext();
 (void)::EvaluateAsRValue(Info, this, EVResult.Val);
   }
 }
@@ -12115,6 +12118,7 @@
   SmallVector Diags;
   Status.Diag = &Diags;
   EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression);
+  Info.InConstantContext = IsConstantContext();
 
   APValue Scratch;
   bool IsConstExpr = ::EvaluateAsRValue(Info, this, Result ? *Result : Scratch);
Index: clang/include/clang/AST/Stmt.h
===
--- clang/include/clang/AST/Stmt.h
+++ clang/include/clang/AST/Stmt.h
@@ -318,8 +318,9 @@
 unsigned ValueDependent : 1;
 unsigned InstantiationDependent : 1;
 unsigned ContainsUnexpandedParameterPack : 1;
+unsigned IsConstantContext : 1;
   };
-  enum { NumExprBits = NumStmtBits + 9 };
+  enum { NumExprBits = NumStmtBits + 10 };
 
   class PredefinedExprBitfields {
 friend class ASTStmtReader;
Index: clang/include/clang/AST/Expr.h
===
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -223,6 +223,18 @@
 ExprBits.ContainsUnexpandedParameterPack = PP;
   }
 
+  /// Wether this expressi

[PATCH] D62009: [clang] perform semantic checking in constant context

2019-05-16 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

i added this bit because when we eventually store the result of evaluation in 
ConstantExpr we will probably want to trail-allocate the APValue's possible 
representations separately to limit memory consumption. but if we do this the 
ConstantExpr node will need to be created after evaluation of the value, so we 
cannot use it to mark that the expression should be evaluated in constant 
context.
if we won't store APValue's possible representations separately in 
trail-allocate space, wrapping the expression in a ConstantExpr is the right 
solution.


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

https://reviews.llvm.org/D62009



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


[PATCH] D62009: [clang] perform semantic checking in constant context

2019-05-17 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

I checked how we can propagate the information about constant context through 
semantic checking.
there are issues with using ConstantExpr to mark expressions as constant for 
semantic checking:

- #1 multpile Expr::Ignore* operation remove ConstantExpr from the expression.
- #2 Semantic checking Traverses the AST so all methods that only mark the 
top-level Node not will fail.
- #3 at short term: adding ConstantExpr modifies the AST structure, so adding 
it everywhere it is needed for semantic checking will require changing a lot of 
code that depend closely on the AST structure.

Note: the limitation #2 also applies to the bit in ExprBitfield solution in its 
current form.

propagating constant context to the expression evaluator via a boolean value 
will be a lot of boilerplate and in my opinion this should be propagated more 
"automatically".
 so I think the best solutions are:

- push a ExpressionEvaluationContext::ConstantEvaluated so Sema will propagate 
it and propagate from Sema to the expression evaluator via boolean values.
- put all semantic checking function's in a SemaCheckContext class and 
propagate via this class to the expression evaluator. this class will be usable 
to propagate Sema and probably other informations.
- keep the bit in ExprBitfield but make all nodes created in 
ExpressionEvaluationContext::ConstantEvaluated marked for constant evaluation 
to fixes limitation #2.


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

https://reviews.llvm.org/D62009



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


[PATCH] D62009: [clang] perform semantic checking in constant context

2019-05-20 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 200231.
Tyker edited the summary of this revision.

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

https://reviews.llvm.org/D62009

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CXX/expr/expr.const/p3-0x.cpp
  clang/test/Sema/integer-overflow.c
  clang/test/Sema/switch.c
  clang/test/SemaCXX/builtin-is-constant-evaluated.cpp
  clang/test/SemaCXX/constant-expression-cxx11.cpp
  clang/test/SemaCXX/integer-overflow.cpp

Index: clang/test/SemaCXX/integer-overflow.cpp
===
--- clang/test/SemaCXX/integer-overflow.cpp
+++ clang/test/SemaCXX/integer-overflow.cpp
@@ -92,6 +92,7 @@
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 'int'}}
   case ((1ULL * ((4608) * ((1024) * (1024))) + 2ULL)):
 return 9;
+// expected-warning@+3 {{implicit conversion}}
 // expected-warning@+2 2{{overflow in expression; result is 536870912 with type 'int'}}
 // expected-warning@+1 {{overflow converting case value to switch condition type (288230376151711744 to 0)}}
   case ((uint64_t)((uint64_t)(4608 * 1024 * 1024) * (uint64_t)(4608 * 1024 * 1024))):
Index: clang/test/SemaCXX/constant-expression-cxx11.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -438,8 +438,8 @@
 
 constexpr char c0 = "nought index"[0];
 constexpr char c1 = "nice index"[10];
-constexpr char c2 = "nasty index"[12]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is past the end}} expected-note {{read of dereferenced one-past-the-end pointer}}
-constexpr char c3 = "negative index"[-1]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is before the beginning}} expected-note {{cannot refer to element -1 of array of 15 elements}}
+constexpr char c2 = "nasty index"[12]; // expected-error {{must be initialized by a constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}}
+constexpr char c3 = "negative index"[-1]; // expected-error {{must be initialized by a constant expression}} expected-note {{cannot refer to element -1 of array of 15 elements}}
 constexpr char c4 = ((char*)(int*)"no reinterpret_casts allowed")[14]; // expected-error {{must be initialized by a constant expression}} expected-note {{cast that performs the conversions of a reinterpret_cast}}
 
 constexpr const char *p = "test" + 2;
@@ -547,7 +547,7 @@
 constexpr int xs0 = p[-3]; // ok
 constexpr int xs_1 = p[-4]; // expected-error {{constant expression}} expected-note {{cannot refer to element -1}}
 
-constexpr int zs[2][2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; // expected-note {{array 'zs' declared here}}
+constexpr int zs[2][2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
 static_assert(zs[0][0][0][0] == 1, "");
 static_assert(zs[1][1][1][1] == 16, "");
 static_assert(zs[0][0][0][2] == 3, ""); // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}}
@@ -557,8 +557,7 @@
 static_assert(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2) == 11, "");
 constexpr int err_zs_1_2_0_0 = zs[1][2][0][0]; // \
 expected-error {{constant expression}} \
-expected-note {{cannot access array element of pointer past the end}} \
-expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
+expected-note {{cannot access array element of pointer past the end}}
 
 constexpr int fail(const int &p) {
   return (&p)[64]; // expected-note {{cannot refer to element 64 of array of 2 elements}}
Index: clang/test/SemaCXX/builtin-is-constant-evaluated.cpp
===
--- clang/test/SemaCXX/builtin-is-constant-evaluated.cpp
+++ clang/test/SemaCXX/builtin-is-constant-evaluated.cpp
@@ -119,3 +119,15 @@
 };
 TestConditionalExplicit e = 42;
 #endif
+
+constexpr int i1 = (long long)__builtin_is_constant_evaluated() * (1ll << 33);
+// expected-warning@-1 {{implicit conversion}}
+
+constexpr int i2 = (long long)!__builtin_is_constant_evaluated() * (1ll << 33);
+
+ void f(int i) {
+   switch (i) {
+   case (long long)__builtin_is_constant_evaluated() * (1ll << 33):;
+// expected-warning@-1 {{implicit conversion}}
+   }
+ }
Index: clang/test/Sema/switch.c
===
--- clang/test/Sema/switch.c
+++ clang/test/Sema/switch.c
@@ -8,7 +8,7 @@
 void foo(int X) {
   switch (X) {
   case 42: ; // expected-note {{previous case}}
-  case 50LL: // expected-warning {{overflow}}
+  case 50LL: // expected-warning {{overflow}} expected-warning {{implicit conversion}} 
   case 42:

[PATCH] D62009: [clang] perform semantic checking in constant context

2019-05-20 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

I changed the approach in the last revision. the information is now propagated 
using the expression evaluation context and then via booleans. I should have 
added a comment to make it clear.


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

https://reviews.llvm.org/D62009



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


[PATCH] D62009: [clang] perform semantic checking in constant context

2019-05-22 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 200662.
Tyker added a comment.

most comments were fixed. but there is a few point on which the direction isn't 
clear.

> I think all of the new warnings in the test cases here are undesirable (they 
> duplicate errors produced by the constant evaluator)

in the last revision `warn_impcast_integer_precision_constant` was always 
diagnosed in constant expression and diagnosed if reachable otherwise. this 
warning was responsible of all new warnings but isn't diagnosed by the constant 
evaluator. which is correct because AFAIK integral casts have implementation 
defined behavior and not undefined behavior.

> For code patterns that are suspicious but defined (eg, we think they might do 
> something other than what the programmer intended), we should typically 
> diagnose using Diag, regardless of whether they appear in a constant context.

this is not currently done even in non constant context. for example 
`warn_impcast_integer_precision_constant` is diagnosed via 
`DiagRuntimeBehavior`.

in this revision

  constexpr int i0 = (long long)__builtin_is_constant_evaluated() * (1ll << 
33); //#1

is diagnosed as it should by the reason it is diagnosed isn't correct. it is 
diagnosed only because `CheckCompletedExpr` doesn't push an 
`ExpressionEvaluationContextRecord` but just set isConstantEvaluatedOverride. 
so `DiagRuntimeBehavior` doesn't see the context as constant context. This 
means that other context that are correctly in constant context like:

  case (long long)__builtin_is_constant_evaluated() * (1ll << 33):; //#1

will not be diagnosed even thought they probably should.


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

https://reviews.llvm.org/D62009

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/include/clang/Basic/DiagnosticIDs.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/SemaCXX/attr-nonnull.cpp
  clang/test/SemaCXX/constant-expression-cxx11.cpp

Index: clang/test/SemaCXX/constant-expression-cxx11.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -438,8 +438,8 @@
 
 constexpr char c0 = "nought index"[0];
 constexpr char c1 = "nice index"[10];
-constexpr char c2 = "nasty index"[12]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is past the end}} expected-note {{read of dereferenced one-past-the-end pointer}}
-constexpr char c3 = "negative index"[-1]; // expected-error {{must be initialized by a constant expression}} expected-warning {{is before the beginning}} expected-note {{cannot refer to element -1 of array of 15 elements}}
+constexpr char c2 = "nasty index"[12]; // expected-error {{must be initialized by a constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}}
+constexpr char c3 = "negative index"[-1]; // expected-error {{must be initialized by a constant expression}} expected-note {{cannot refer to element -1 of array of 15 elements}}
 constexpr char c4 = ((char*)(int*)"no reinterpret_casts allowed")[14]; // expected-error {{must be initialized by a constant expression}} expected-note {{cast that performs the conversions of a reinterpret_cast}}
 
 constexpr const char *p = "test" + 2;
@@ -547,7 +547,7 @@
 constexpr int xs0 = p[-3]; // ok
 constexpr int xs_1 = p[-4]; // expected-error {{constant expression}} expected-note {{cannot refer to element -1}}
 
-constexpr int zs[2][2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; // expected-note {{array 'zs' declared here}}
+constexpr int zs[2][2][2][2] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
 static_assert(zs[0][0][0][0] == 1, "");
 static_assert(zs[1][1][1][1] == 16, "");
 static_assert(zs[0][0][0][2] == 3, ""); // expected-error {{constant expression}} expected-note {{read of dereferenced one-past-the-end pointer}}
@@ -557,8 +557,7 @@
 static_assert(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][2] - 2) == 11, "");
 constexpr int err_zs_1_2_0_0 = zs[1][2][0][0]; // \
 expected-error {{constant expression}} \
-expected-note {{cannot access array element of pointer past the end}} \
-expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}}
+expected-note {{cannot access array element of pointer past the end}}
 
 constexpr int fail(const int &p) {
   return (&p)[64]; // expected-note {{cannot refer to element 64 of array of 2 elements}}
Index: clang/test/SemaCXX/attr-nonnull.cpp
===
--- clang/test/SemaCXX/attr-nonnull.cpp
+++ clang/test/SemaCXX/attr-nonnull.cpp
@@ -52,3 +52,35 @@
   (void)(x != 0);  // expected-warning{{null passed}}
 }
 }
+
+namespace test5 {
+
+constexpr int c = 0;
+
+__attribute__((nonnull))
+c

[PATCH] D62399: [clang] Add storage for APValue in ConstantExpr

2019-05-24 Thread Tyker via Phabricator via cfe-commits
Tyker created this revision.
Tyker added a reviewer: rsmith.
Herald added subscribers: llvm-commits, cfe-commits, dexonsmith, hiraditya.
Herald added a reviewer: martong.
Herald added a reviewer: shafik.
Herald added projects: clang, LLVM.

When using ConstantExpr we often need the result of the expression to be kept 
in the AST. Currently this is done on a by the node that needs the result and 
has been done multiple times for enumerator, for constexpr variables... . This 
patch adds to ConstantExpr the ability to store the result of evaluating the 
expression. no functional changes expected.

Changes:

- Add trailling object to ConstantExpr that can hold an APValue or an APSInt. 
the APSInt is here because most ConstantExpr yield integral values so they will 
only take enough memory to store an integral values in this case.
- Add basic* serialization support for the trailing result.
- Move conversion functions from an enum to a fltSemantics from 
clang::FloatingLiteral to llvm::APFloatBase. this change is to make it usable 
for serializing APValues.
- Add basic* Import support for the trailing result.
- ConstantExpr created in CheckConvertedConstantExpression now stores the 
result in the ConstantExpr Node.
- Adapt AST dump to print the result when present.

basic* : Uninitialized, Int, Float, FixedPoint, ComplexInt, ComplexFloat,
the result is not yet used anywhere but for -ast-dump.


Repository:
  rC Clang

https://reviews.llvm.org/D62399

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/AST/TextNodeDumper.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/AST/ast-dump-color.cpp
  llvm/include/llvm/ADT/APFloat.h
  llvm/lib/Support/APFloat.cpp

Index: llvm/lib/Support/APFloat.cpp
===
--- llvm/lib/Support/APFloat.cpp
+++ llvm/lib/Support/APFloat.cpp
@@ -113,6 +113,42 @@
   static const fltSemantics semPPCDoubleDoubleLegacy = {1023, -1022 + 53,
 53 + 53, 128};
 
+  const llvm::fltSemantics &APFloatBase::EnumToSemantics(Semantics S) {
+switch (S) {
+case S_IEEEhalf:
+  return IEEEhalf();
+case S_IEEEsingle:
+  return IEEEsingle();
+case S_IEEEdouble:
+  return IEEEdouble();
+case S_x87DoubleExtended:
+  return x87DoubleExtended();
+case S_IEEEquad:
+  return IEEEquad();
+case S_PPCDoubleDouble:
+  return PPCDoubleDouble();
+}
+llvm_unreachable("Unrecognised floating semantics");
+  }
+
+  APFloatBase::Semantics
+  APFloatBase::SemanticsToEnum(const llvm::fltSemantics &Sem) {
+if (&Sem == &llvm::APFloat::IEEEhalf())
+  return S_IEEEhalf;
+else if (&Sem == &llvm::APFloat::IEEEsingle())
+  return S_IEEEsingle;
+else if (&Sem == &llvm::APFloat::IEEEdouble())
+  return S_IEEEdouble;
+else if (&Sem == &llvm::APFloat::x87DoubleExtended())
+  return S_x87DoubleExtended;
+else if (&Sem == &llvm::APFloat::IEEEquad())
+  return S_IEEEquad;
+else if (&Sem == &llvm::APFloat::PPCDoubleDouble())
+  return S_PPCDoubleDouble;
+else
+  llvm_unreachable("Unknown floating semantics");
+  }
+
   const fltSemantics &APFloatBase::IEEEhalf() {
 return semIEEEhalf;
   }
Index: llvm/include/llvm/ADT/APFloat.h
===
--- llvm/include/llvm/ADT/APFloat.h
+++ llvm/include/llvm/ADT/APFloat.h
@@ -147,6 +147,17 @@
 
   /// \name Floating Point Semantics.
   /// @{
+  enum Semantics {
+S_IEEEhalf,
+S_IEEEsingle,
+S_IEEEdouble,
+S_x87DoubleExtended,
+S_IEEEquad,
+S_PPCDoubleDouble
+  };
+
+  static const llvm::fltSemantics &EnumToSemantics(Semantics S);
+  static Semantics SemanticsToEnum(const llvm::fltSemantics &Sem);
 
   static const fltSemantics &IEEEhalf() LLVM_READNONE;
   static const fltSemantics &IEEEsingle() LLVM_READNONE;
Index: clang/test/AST/ast-dump-color.cpp
===
--- clang/test/AST/ast-dump-color.cpp
+++ clang/test/AST/ast-dump-color.cpp
@@ -49,13 +49,13 @@
 //CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:11[[RESET]]> [[Green]]'int'[[RESET]][[Cyan:.\[0;36m]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RES

[PATCH] D61790: [C++20] add Basic consteval specifier

2019-05-27 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 201535.
Tyker marked 13 inline comments as done.
Tyker retitled this revision from "[C++20] add consteval specifier" to "[C++20] 
add Basic consteval specifier".
Tyker edited the summary of this revision.
Tyker added a comment.
Herald added a subscriber: eraman.

previous revision was spitted in multiple part as requested
consteval specific semantic and code-gen have been removed from the patch.
other parts:

- fixing semantic checking in constant context : https://reviews.llvm.org/D62009
- adding storage for APValue in ConstantExpr : https://reviews.llvm.org/D62399

some remarks weren't fixed because the changes are not present in this patch.


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

https://reviews.llvm.org/D61790

Files:
  clang/include/clang/AST/Decl.h
  clang/include/clang/AST/DeclBase.h
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Sema/DeclSpec.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/DeclPrinter.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Parse/ParseCXXInlineMethods.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaCoroutine.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaStmt.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/test/SemaCXX/cxx2a-compat.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp

Index: clang/test/SemaCXX/cxx2a-consteval.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+
+namespace basic_sema {
+
+consteval int f1(int i) {
+  return i;
+}
+
+consteval constexpr int f2(int i) { 
+  //expected-error@-1 {{cannot combine}}
+  return i;
+}
+
+constexpr auto l_eval = [](int i) consteval {
+
+  return i;
+};
+
+constexpr consteval int f3(int i) {
+  //expected-error@-1 {{cannot combine}}
+  return i;
+}
+
+struct A {
+  consteval int f1(int i) const {
+return i;
+  }
+  consteval A(int i);
+  consteval A() = default;
+  consteval ~A() = default; // expected-error {{destructor cannot be marked consteval}}
+};
+
+consteval struct B {}; // expected-error {{struct cannot be marked consteval}}
+
+consteval typedef B b; // expected-error {{typedef cannot be consteval}}
+
+consteval int redecl() {return 0;} // expected-note {{previous declaration is here}}
+constexpr int redecl() {return 0;} // expected-error {{constexpr declaration of 'redecl' follows consteval declaration}}
+
+consteval int i = 0; // expected-error {{consteval can only be used in function declarations}}
+
+consteval int; // expected-error {{consteval can only be used in function declarations}}
+
+consteval int f1() {} // expected-error {{no return statement in consteval function}}
+consteval int main() {
+  return 0;
+}
+
+}
Index: clang/test/SemaCXX/cxx2a-compat.cpp
===
--- clang/test/SemaCXX/cxx2a-compat.cpp
+++ clang/test/SemaCXX/cxx2a-compat.cpp
@@ -56,4 +56,13 @@
 #if !defined(__cpp_conditional_explicit) || __cpp_conditional_explicit != 201806L
 #error "the feature test macro __cpp_conditional_explicit isn't correct"
 #endif
+#endif
+
+auto l = []() consteval {};
+int consteval();
+#if __cplusplus <= 201703L
+// expected-warning@-3 {{'consteval' is a keyword in C++2a}}
+// expected-error@-4 {{expected body of lambda expression}}
+#else
+// expected-error@-5 {{expected unqualified-id}}
 #endif
\ No newline at end of file
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -868,7 +868,7 @@
   FD->setDefaulted(Record.readInt());
   FD->setExplicitlyDefaulted(Record.readInt());
   FD->setHasImplicitReturnZero(Record.readInt());
-  FD->setConstexpr(Record.readInt());
+  FD->setConstexprKind(static_cast(Record.readInt()));
   FD->setUsesSEHTry(Record.readInt());
   FD->setHasSkippedBody(Record.readInt());
   FD->setIsMultiVersion(Record.readInt());
Index: clang/lib/Sema/TreeTransform.h
===
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -11301,7 +11301,7 @@
   Class, E->getIntroducerRange(), NewCallOpTSI,
   E->getCallOperator()->getEndLoc(),
  

[PATCH] D61790: [C++20] add Basic consteval specifier

2019-05-27 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/lib/Sema/SemaChecking.cpp:10471
 
+  bool IsConstantContext = S.ExprEvalContexts.back().isConstantEvaluated();
+

rsmith wrote:
> Are the changes to this file really specific to `consteval` evaluation? They 
> look more general than that; I think this would fix the evaluation of 
> `std::is_constant_evaluated()` in any constant-evaluated context that we 
> analyzed. Can this be split out of this patch into a separate change?
this can be splited in and other patch. https://reviews.llvm.org/D62009.



Comment at: clang/lib/Sema/SemaExpr.cpp:5720-5769
+bool Sema::CheckInvalidConstevalCall(FunctionDecl *FDecl, SourceLocation Loc,
+ ArrayRef Args, Expr *This) {
+  bool Failed = false;
+  if (FDecl && FDecl->isConsteval() &&
+  !ExprEvalContexts.back().isConstantEvaluated()) {
+
+SmallVector Diags;

rsmith wrote:
> This checking doesn't make sense: we should be checking that the invocation 
> as a whole is a constant expression, not whether the arguments (evaluated in 
> isolation) are constant expressions. This check should be applied to the 
> `Expr` representing the call, and should wrap it in a `ConstantExpr` holding 
> the evaluated value if evaluation succeeds.
the idea behind this check was "if the function satisfies the rules of 
constexpr and all it arguments can be constant evaluated. this function call 
can be constant evaluated". this was a easy way of checking that the call could 
be evaluated without evaluating it.

this will be added in later patch after https://reviews.llvm.org/D62399.



Comment at: clang/lib/Sema/SemaExpr.cpp:13417-13435
+bool Sema::CheckInvalidConstevalTakeAddress(Expr *Input) {
+  if (Input) {
+if (auto *DeclRef = dyn_cast(Input->IgnoreParens())) {
+  if (auto *Function = dyn_cast(DeclRef->getDecl())) {
+if (Function->isConsteval()) {
+  const char *DeclName = Function->isOverloadedOperator()
+ ? "consteval operator"

rsmith wrote:
> This isn't correct: you can take the address of a `consteval` function within 
> an immediate invocation. In general, we need to delay this checking until 
> we've finished processing any potentially-enclosing immediate invocations. 
> Trying to capture all of the places where we might form a reference to a 
> `consteval` function name without forming an immediate invocation is also 
> fragile: you'll miss some, and as Clang is extended, there'll be more cases 
> introduced that you miss.
> 
> Here's how I was intending to handle this:
> 
>  * Change `Sema::MarkFunctionReferenced` to take an `Expr*` instead of a 
> location, and update all of its callers. (We'll need a separate function for 
> marking destructors referenced, because destructor calls typically don't have 
> expressions, but destructors can't be `consteval` so that's OK.)
>  * In `Sema::MarkFunctionReferenced`, if `Func` is a `consteval` function and 
> our current context is not a `consteval` function, add it to a list on the 
> `ExpressionEvaluationContext`.
>  * When forming an immediate invocation, walk all of its subexpressions and 
> remove them all from the list on the `ExpressionEvaluationContext`
>  * When popping the `ExpressionEvaluationContext`, diagnose any remaining 
> expressions in its list.
> 
> (The first step should be done in a separate patch to keep the diffs smaller 
> and easier to review.)
delayed to later patch.


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

https://reviews.llvm.org/D61790



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


[PATCH] D62009: [clang] perform semantic checking in constant context

2019-05-28 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

@rsmith friendly ping.


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

https://reviews.llvm.org/D62009



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


[PATCH] D63960: [C++20] Add consteval-specific semantic for functions

2019-09-14 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

@rsmith Ping


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

https://reviews.llvm.org/D63960



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


[PATCH] D63640: [clang] Improve Serialization/Imporing of APValues

2019-09-21 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 221166.
Tyker marked 24 inline comments as done.
Tyker added a comment.

Fixed most changes requested by @aaron.ballman
test are currently no valid anymore see comments for why.


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

https://reviews.llvm.org/D63640

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/ASTImporter.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/ASTMerge/APValue/APValue.cpp
  clang/test/PCH/APValue.cpp

Index: clang/test/PCH/APValue.cpp
===
--- /dev/null
+++ clang/test/PCH/APValue.cpp
@@ -0,0 +1,210 @@
+
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -emit-pch %s -o %t.pch
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -include-pch %t.pch -ast-dump-all | FileCheck %s
+
+#ifndef EMIT
+#define EMIT
+
+namespace Integer {
+
+constexpr int Unique_Int = int(6789);
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int' 6789
+
+constexpr __uint128_t Unique_Int128 = ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+//CHECK:  VarDecl {{.*}} Unique_Int128 
+//CHECK-NEXT: ConstantExpr {{.*}} 'unsigned __int128' 156773562844924187900898496343692168785
+
+}
+
+namespace FloatingPoint {
+
+constexpr double Unique_Double = double(567890.67890);
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}} 'double' 5.678907e+05
+
+}
+
+// FIXME: Add test for FixePoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+constexpr B Basic_Struct = B{1, 0.7};
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::B' {1, 7.00e-01}
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  int i;
+  double d;
+  C c;
+};
+
+constexpr A Advanced_Struct = A{Basic_Struct, 1, 79.789, {}};
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::A' {{[{][{]}}1, 7.00e-01}, 1, 7.978900e+01, {9}}
+
+}
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Vector_Int = (v4si){8, 2, 3};
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'Vector::v4si':'__attribute__((__vector_size__(4 * sizeof(int int' {8, 2, 3, 0}
+
+}
+
+namespace Array {
+
+constexpr int Array_Int[] = {1, 2, 3, 4, 5, 6};
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int [6]' {1, 2, 3, 4, 5, 6}
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+constexpr A Array2_Struct[][3] = {{{}, {-45678, 9.8}, {9}}, {{}}};
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'Array::A const [2][3]' {{[{][{]}}{789, 6.789010e+04}, {-45678, 9.80e+00}, {9, 6.789010e+04}}, {{[{][{]}}789, 6.789010e+04}, {789, 6.789010e+04}, {789, 6.789010e+04}}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Array_Vector[] = {{1, 2, 3, 4}, {4, 5, 6, 7}};
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Array::v4si [2]' {{[{][{]}}1, 2, 3, 4}, {4, 5, 6, 7}}
+
+}
+
+namespace Union {
+
+struct A {
+  int i = 6789;
+  float f = 987.9876;
+};
+
+union U {
+  int i;
+  A a{567890, 9876.5678f};
+};
+
+constexpr U Unique_Union1 = U{0};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.i = 0}
+
+constexpr U Unique_Union2 = U{};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.a = {567890, 9.876567e+03}}
+
+}
+
+namespace MemberPointer{
+
+struct A {
+  struct B {
+struct C {
+  struct D {
+struct E {
+  struct F {
+struct G {
+  int i;
+};
+  };
+};
+  };
+};
+  };
+};
+
+constexpr auto MemberPointer1 = &A::B::C::D::E::F::G::i;
+//CHECK:  VarDecl {{.*}} MemberPointer1
+//CHECK-NEXT: ConstantExpr {{.*}} 'int MemberPointer::A::B::C::D::E::F::G::*' &G::i
+
+struct A1 {
+  struct B1 {
+int f() const {
+  return 0;
+}
+  };
+
+};
+
+constexpr auto MemberPointer2 = &A1::B1::f;
+//CHECK:  VarDecl {{.*}} MemberPointer2
+//CHECK-NEXT: ConstantExpr {{.*}} 'int (MemberPointer::A1::B1::*)() const' &B1::f
+
+}
+
+namespace std {
+  struct type_info;
+};
+
+namespace LValue {
+
+constexpr int LValueInt = 0;
+constexpr const int& ConstIntRef = LValueInt;
+//CHECK:  VarDecl {{.*}} ConstIntRef
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int' lvalue &LValueInt
+conste

[PATCH] D63640: [clang] Improve Serialization/Imporing of APValues

2019-09-21 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/include/clang/AST/ASTContext.h:275
-  /// Used to cleanups APValues stored in the AST.
-  mutable llvm::SmallVector APValueCleanups;
-

aaron.ballman wrote:
> Why are you getting rid of this? It seems like we would still want these 
> cleaned up.
when i added APValueCleanups i wasn't aware that there were a generic system to 
handle this. but with this patch APValue a cleaned up using the generic 
ASTContext::addDestruction.



Comment at: clang/include/clang/AST/TextNodeDumper.h:149
 
-  const ASTContext *Context;
+  const ASTContext *Context = nullptr;
 

aaron.ballman wrote:
> Good catch -- this pointed out a bug in the class that I've fixed in r372323, 
> so you'll need to rebase.
i took a look at the revision. there is a big difference is the quality of 
output between APValue::dump and APValue::printPretty. i think it is possible 
to come quite close to printPretty's output even without the ASTContext. this 
would require having a default PrintingPolicy and improving dump

in this patch i was relying on the -ast-dump output for testing. i would need 
to find an other testing strategy or make the improvement to APValue::dump 
first.



Comment at: clang/lib/AST/APValue.cpp:176
+  (DataSize - sizeof(MemberPointerBase)) / sizeof(CXXRecordDecl *);
+  typedef CXXRecordDecl *PathElem;
   union {

aaron.ballman wrote:
> Why is this no longer a pointer to `const`?
when imporing or deserializing, we reserve the space for elements and then 
import/deserialize element directly in place. so the buffer storing them is not 
const. that said i saw that the normal construction cast away the const.



Comment at: clang/lib/AST/APValue.cpp:748
 
+APValue::LValuePathEntry *APValue::getLValuePathPtr() {
+  return ((LV *)(char *)Data.buffer)->getPath();

aaron.ballman wrote:
> Can this function be marked `const`?
this function gives access to non-const internal data. this function is private 
so the impact is quite limited.


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

https://reviews.llvm.org/D63640



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


[PATCH] D63640: [clang] Improve Serialization/Imporing of APValues

2019-09-21 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 221169.

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

https://reviews.llvm.org/D63640

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/ASTImporter.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/ASTMerge/APValue/APValue.cpp
  clang/test/PCH/APValue.cpp

Index: clang/test/PCH/APValue.cpp
===
--- /dev/null
+++ clang/test/PCH/APValue.cpp
@@ -0,0 +1,210 @@
+
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -emit-pch %s -o %t.pch
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -include-pch %t.pch -ast-dump-all | FileCheck %s
+
+#ifndef EMIT
+#define EMIT
+
+namespace Integer {
+
+constexpr int Unique_Int = int(6789);
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int' 6789
+
+constexpr __uint128_t Unique_Int128 = ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+//CHECK:  VarDecl {{.*}} Unique_Int128 
+//CHECK-NEXT: ConstantExpr {{.*}} 'unsigned __int128' 156773562844924187900898496343692168785
+
+}
+
+namespace FloatingPoint {
+
+constexpr double Unique_Double = double(567890.67890);
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}} 'double' 5.678907e+05
+
+}
+
+// FIXME: Add test for FixePoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+constexpr B Basic_Struct = B{1, 0.7};
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::B' {1, 7.00e-01}
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  int i;
+  double d;
+  C c;
+};
+
+constexpr A Advanced_Struct = A{Basic_Struct, 1, 79.789, {}};
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::A' {{[{][{]}}1, 7.00e-01}, 1, 7.978900e+01, {9}}
+
+}
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Vector_Int = (v4si){8, 2, 3};
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'Vector::v4si':'__attribute__((__vector_size__(4 * sizeof(int int' {8, 2, 3, 0}
+
+}
+
+namespace Array {
+
+constexpr int Array_Int[] = {1, 2, 3, 4, 5, 6};
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int [6]' {1, 2, 3, 4, 5, 6}
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+constexpr A Array2_Struct[][3] = {{{}, {-45678, 9.8}, {9}}, {{}}};
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'Array::A const [2][3]' {{[{][{]}}{789, 6.789010e+04}, {-45678, 9.80e+00}, {9, 6.789010e+04}}, {{[{][{]}}789, 6.789010e+04}, {789, 6.789010e+04}, {789, 6.789010e+04}}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Array_Vector[] = {{1, 2, 3, 4}, {4, 5, 6, 7}};
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Array::v4si [2]' {{[{][{]}}1, 2, 3, 4}, {4, 5, 6, 7}}
+
+}
+
+namespace Union {
+
+struct A {
+  int i = 6789;
+  float f = 987.9876;
+};
+
+union U {
+  int i;
+  A a{567890, 9876.5678f};
+};
+
+constexpr U Unique_Union1 = U{0};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.i = 0}
+
+constexpr U Unique_Union2 = U{};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.a = {567890, 9.876567e+03}}
+
+}
+
+namespace MemberPointer{
+
+struct A {
+  struct B {
+struct C {
+  struct D {
+struct E {
+  struct F {
+struct G {
+  int i;
+};
+  };
+};
+  };
+};
+  };
+};
+
+constexpr auto MemberPointer1 = &A::B::C::D::E::F::G::i;
+//CHECK:  VarDecl {{.*}} MemberPointer1
+//CHECK-NEXT: ConstantExpr {{.*}} 'int MemberPointer::A::B::C::D::E::F::G::*' &G::i
+
+struct A1 {
+  struct B1 {
+int f() const {
+  return 0;
+}
+  };
+
+};
+
+constexpr auto MemberPointer2 = &A1::B1::f;
+//CHECK:  VarDecl {{.*}} MemberPointer2
+//CHECK-NEXT: ConstantExpr {{.*}} 'int (MemberPointer::A1::B1::*)() const' &B1::f
+
+}
+
+namespace std {
+  struct type_info;
+};
+
+namespace LValue {
+
+constexpr int LValueInt = 0;
+constexpr const int& ConstIntRef = LValueInt;
+//CHECK:  VarDecl {{.*}} ConstIntRef
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int' lvalue &LValueInt
+constexpr const int* IntPtr = &LValueInt;
+//CHECK:  VarDecl {{.*}} IntPtr
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int *' &LValueInt
+
+constexpr const int* NullPtr = null

[PATCH] D63640: [clang] Improve Serialization/Imporing of APValues

2019-09-21 Thread Tyker via Phabricator via cfe-commits
Tyker marked 2 inline comments as done.
Tyker added inline comments.



Comment at: clang/lib/AST/APValue.cpp:176
+  (DataSize - sizeof(MemberPointerBase)) / sizeof(CXXRecordDecl *);
+  typedef CXXRecordDecl *PathElem;
   union {

Tyker wrote:
> aaron.ballman wrote:
> > Why is this no longer a pointer to `const`?
> when imporing or deserializing, we reserve the space for elements and then 
> import/deserialize element directly in place. so the buffer storing them is 
> not const. that said i saw that the normal construction cast away the const.
never mind this change wasn't needed.


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

https://reviews.llvm.org/D63640



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


[PATCH] D63960: [C++20] Add consteval-specific semantic for functions

2019-09-22 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

ping @rsmith


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

https://reviews.llvm.org/D63960



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


[PATCH] D67889: [clang] fixing conditional explicit for out-of-line definition PR42980

2019-09-22 Thread Tyker via Phabricator via cfe-commits
Tyker created this revision.
Tyker added reviewers: rsmith, aaron.ballman.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

not every read in CXXConstructorDecl::getExplicitSpecifierInternal() was made 
on the canonical declaration.


Repository:
  rC Clang

https://reviews.llvm.org/D67889

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/test/SemaCXX/cxx2a-explicit-bool.cpp


Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -717,3 +717,21 @@
 A d3 = {0.0, 0.0};// expected-error {{explicit deduction guide}}
 
 }
+
+namespace PR42980 {
+using size_t = decltype(sizeof(0));
+
+struct Str {// expected-note+ {{candidate constructor}}
+  template 
+  explicit(N > 7)// expected-note {{resolved to true}}
+  Str(char const (&str)[N]);
+};
+
+template 
+Str::Str(char const(&str)[N]) { }
+// expected-note@-1 {{candidate constructor}}
+
+Str a = "short";
+Str b = "not so short";// expected-error {{no viable conversion}}
+
+}
\ No newline at end of file
Index: clang/include/clang/AST/DeclCXX.h
===
--- clang/include/clang/AST/DeclCXX.h
+++ clang/include/clang/AST/DeclCXX.h
@@ -2555,9 +2555,9 @@
 
   ExplicitSpecifier getExplicitSpecifierInternal() const {
 if (CXXConstructorDeclBits.HasTrailingExplicitSpecifier)
-  return *getCanonicalDecl()->getTrailingObjects();
+  return *getTrailingObjects();
 return ExplicitSpecifier(
-nullptr, getCanonicalDecl()->CXXConstructorDeclBits.IsSimpleExplicit
+nullptr, CXXConstructorDeclBits.IsSimpleExplicit
  ? ExplicitSpecKind::ResolvedTrue
  : ExplicitSpecKind::ResolvedFalse);
   }
@@ -2598,10 +2598,10 @@
  InheritedConstructor Inherited = InheritedConstructor());
 
   ExplicitSpecifier getExplicitSpecifier() {
-return getExplicitSpecifierInternal();
+return getCanonicalDecl()->getExplicitSpecifierInternal();
   }
   const ExplicitSpecifier getExplicitSpecifier() const {
-return getExplicitSpecifierInternal();
+return getCanonicalDecl()->getExplicitSpecifierInternal();
   }
 
   /// Return true if the declartion is already resolved to be explicit.


Index: clang/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- clang/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ clang/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -717,3 +717,21 @@
 A d3 = {0.0, 0.0};// expected-error {{explicit deduction guide}}
 
 }
+
+namespace PR42980 {
+using size_t = decltype(sizeof(0));
+
+struct Str {// expected-note+ {{candidate constructor}}
+  template 
+  explicit(N > 7)// expected-note {{resolved to true}}
+  Str(char const (&str)[N]);
+};
+
+template 
+Str::Str(char const(&str)[N]) { }
+// expected-note@-1 {{candidate constructor}}
+
+Str a = "short";
+Str b = "not so short";// expected-error {{no viable conversion}}
+
+}
\ No newline at end of file
Index: clang/include/clang/AST/DeclCXX.h
===
--- clang/include/clang/AST/DeclCXX.h
+++ clang/include/clang/AST/DeclCXX.h
@@ -2555,9 +2555,9 @@
 
   ExplicitSpecifier getExplicitSpecifierInternal() const {
 if (CXXConstructorDeclBits.HasTrailingExplicitSpecifier)
-  return *getCanonicalDecl()->getTrailingObjects();
+  return *getTrailingObjects();
 return ExplicitSpecifier(
-nullptr, getCanonicalDecl()->CXXConstructorDeclBits.IsSimpleExplicit
+nullptr, CXXConstructorDeclBits.IsSimpleExplicit
  ? ExplicitSpecKind::ResolvedTrue
  : ExplicitSpecKind::ResolvedFalse);
   }
@@ -2598,10 +2598,10 @@
  InheritedConstructor Inherited = InheritedConstructor());
 
   ExplicitSpecifier getExplicitSpecifier() {
-return getExplicitSpecifierInternal();
+return getCanonicalDecl()->getExplicitSpecifierInternal();
   }
   const ExplicitSpecifier getExplicitSpecifier() const {
-return getExplicitSpecifierInternal();
+return getCanonicalDecl()->getExplicitSpecifierInternal();
   }
 
   /// Return true if the declartion is already resolved to be explicit.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67889: [clang] fixing conditional explicit for out-of-line definition PR42980

2019-09-22 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL372530: [clang] fixing conditional explicit for out-of-line 
definition PR42980 (authored by Tyker, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D67889?vs=221216&id=221241#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D67889

Files:
  cfe/trunk/include/clang/AST/DeclCXX.h
  cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp


Index: cfe/trunk/include/clang/AST/DeclCXX.h
===
--- cfe/trunk/include/clang/AST/DeclCXX.h
+++ cfe/trunk/include/clang/AST/DeclCXX.h
@@ -2555,9 +2555,9 @@
 
   ExplicitSpecifier getExplicitSpecifierInternal() const {
 if (CXXConstructorDeclBits.HasTrailingExplicitSpecifier)
-  return *getCanonicalDecl()->getTrailingObjects();
+  return *getTrailingObjects();
 return ExplicitSpecifier(
-nullptr, getCanonicalDecl()->CXXConstructorDeclBits.IsSimpleExplicit
+nullptr, CXXConstructorDeclBits.IsSimpleExplicit
  ? ExplicitSpecKind::ResolvedTrue
  : ExplicitSpecKind::ResolvedFalse);
   }
@@ -2598,10 +2598,10 @@
  InheritedConstructor Inherited = InheritedConstructor());
 
   ExplicitSpecifier getExplicitSpecifier() {
-return getExplicitSpecifierInternal();
+return getCanonicalDecl()->getExplicitSpecifierInternal();
   }
   const ExplicitSpecifier getExplicitSpecifier() const {
-return getExplicitSpecifierInternal();
+return getCanonicalDecl()->getExplicitSpecifierInternal();
   }
 
   /// Return true if the declartion is already resolved to be explicit.
Index: cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -717,3 +717,21 @@
 A d3 = {0.0, 0.0};// expected-error {{explicit deduction guide}}
 
 }
+
+namespace PR42980 {
+using size_t = decltype(sizeof(0));
+
+struct Str {// expected-note+ {{candidate constructor}}
+  template 
+  explicit(N > 7)// expected-note {{resolved to true}}
+  Str(char const (&str)[N]);
+};
+
+template 
+Str::Str(char const(&str)[N]) { }
+// expected-note@-1 {{candidate constructor}}
+
+Str a = "short";
+Str b = "not so short";// expected-error {{no viable conversion}}
+
+}
\ No newline at end of file


Index: cfe/trunk/include/clang/AST/DeclCXX.h
===
--- cfe/trunk/include/clang/AST/DeclCXX.h
+++ cfe/trunk/include/clang/AST/DeclCXX.h
@@ -2555,9 +2555,9 @@
 
   ExplicitSpecifier getExplicitSpecifierInternal() const {
 if (CXXConstructorDeclBits.HasTrailingExplicitSpecifier)
-  return *getCanonicalDecl()->getTrailingObjects();
+  return *getTrailingObjects();
 return ExplicitSpecifier(
-nullptr, getCanonicalDecl()->CXXConstructorDeclBits.IsSimpleExplicit
+nullptr, CXXConstructorDeclBits.IsSimpleExplicit
  ? ExplicitSpecKind::ResolvedTrue
  : ExplicitSpecKind::ResolvedFalse);
   }
@@ -2598,10 +2598,10 @@
  InheritedConstructor Inherited = InheritedConstructor());
 
   ExplicitSpecifier getExplicitSpecifier() {
-return getExplicitSpecifierInternal();
+return getCanonicalDecl()->getExplicitSpecifierInternal();
   }
   const ExplicitSpecifier getExplicitSpecifier() const {
-return getExplicitSpecifierInternal();
+return getCanonicalDecl()->getExplicitSpecifierInternal();
   }
 
   /// Return true if the declartion is already resolved to be explicit.
Index: cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp
===
--- cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp
+++ cfe/trunk/test/SemaCXX/cxx2a-explicit-bool.cpp
@@ -717,3 +717,21 @@
 A d3 = {0.0, 0.0};// expected-error {{explicit deduction guide}}
 
 }
+
+namespace PR42980 {
+using size_t = decltype(sizeof(0));
+
+struct Str {// expected-note+ {{candidate constructor}}
+  template 
+  explicit(N > 7)// expected-note {{resolved to true}}
+  Str(char const (&str)[N]);
+};
+
+template 
+Str::Str(char const(&str)[N]) { }
+// expected-note@-1 {{candidate constructor}}
+
+Str a = "short";
+Str b = "not so short";// expected-error {{no viable conversion}}
+
+}
\ No newline at end of file
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63640: [clang] Improve Serialization/Imporing/Dumping of APValues

2019-09-23 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/include/clang/AST/APValue.h:618
   }
+  const CXXRecordDecl **getMemberPointerPathPtr();
 };

aaron.ballman wrote:
> We're horribly inconsistent in this class, but because the other private 
> member functions go with it, this should probably be 
> `GetMemberPointerPathPtr()`. Maybe rename the get/setLValue methods from 
> above as well?
> We're horribly inconsistent in this class

this class has many flaws. but is far too broadly used to fix.



Comment at: clang/include/clang/AST/APValue.h:512
   }
-  void setVector(const APValue *E, unsigned N) {
+  void ReserveVector(unsigned N) {
 assert(isVector() && "Invalid accessor");

aaron.ballman wrote:
> aaron.ballman wrote:
> > `reserveVector` per naming conventions
> This was marked as done but is still an issue.
sorry



Comment at: clang/include/clang/AST/ASTContext.h:275
-  /// Used to cleanups APValues stored in the AST.
-  mutable llvm::SmallVector APValueCleanups;
-

aaron.ballman wrote:
> Tyker wrote:
> > aaron.ballman wrote:
> > > Why are you getting rid of this? It seems like we would still want these 
> > > cleaned up.
> > when i added APValueCleanups i wasn't aware that there were a generic 
> > system to handle this. but with this patch APValue a cleaned up using the 
> > generic ASTContext::addDestruction.
> I don't see any new calls to `addDestruction()` though. Have I missed 
> something?
the modification to use `addDestruction()` was made in a previous revision 
(https://reviews.llvm.org/D63376).
the use is currently on master in `ConstantExpr::MoveIntoResult` in the 
RSK_APValue case of the switch.
this is just a removing an unused member.




Comment at: clang/include/clang/AST/TextNodeDumper.h:149
 
-  const ASTContext *Context;
+  const ASTContext *Context = nullptr;
 

aaron.ballman wrote:
> Tyker wrote:
> > aaron.ballman wrote:
> > > Good catch -- this pointed out a bug in the class that I've fixed in 
> > > r372323, so you'll need to rebase.
> > i took a look at the revision. there is a big difference is the quality of 
> > output between APValue::dump and APValue::printPretty. i think it is 
> > possible to come quite close to printPretty's output even without the 
> > ASTContext. this would require having a default PrintingPolicy and 
> > improving dump
> > 
> > in this patch i was relying on the -ast-dump output for testing. i would 
> > need to find an other testing strategy or make the improvement to 
> > APValue::dump first.
> > there is a big difference is the quality of output between APValue::dump 
> > and APValue::printPretty.
> 
> Yes, there is.
> 
> > i think it is possible to come quite close to printPretty's output even 
> > without the ASTContext. this would require having a default PrintingPolicy 
> > and improving dump
> 
> That would be much-appreciated! When I looked at it, it seemed like it may 
> not be plausible because `Stmt` does not track which `ASTContext` it is 
> associated with the same way that `Decl` does, and changing that seemed 
> likely to cause a huge amount of interface churn.
> 
> > in this patch i was relying on the -ast-dump output for testing. i would 
> > need to find an other testing strategy or make the improvement to 
> > APValue::dump first.
> 
> The issue resolved by r372323 was that we would crash on certain kinds of AST 
> dumps. Specifically, the default AST dumper is often used during a debugging 
> session to dump AST node information within the debugger. It was trivial to 
> get that to crash before r372323, but with that revision, we no longer crash 
> but get slightly uglier output (which is acceptable because it's still 
> human-readable output).
> 
> I'm sorry for causing extra pain for you here, but I didn't want the fix from 
> this review to accidentally become an enshrined part of the API because it's 
> very easy to forget about this use case when working on AST dumping 
> functionality.
no worries, i wrote the original bug. i added APValue::dumpPretty which has 
almost the same output as APValue::printPretty but doesn't need an ASTContext. 
and is used for TextNodeDumper.



Comment at: clang/lib/AST/APValue.cpp:748
 
+APValue::LValuePathEntry *APValue::getLValuePathPtr() {
+  return ((LV *)(char *)Data.buffer)->getPath();

aaron.ballman wrote:
> Tyker wrote:
> > aaron.ballman wrote:
> > > Can this function be marked `const`?
> > this function gives access to non-const internal data. this function is 
> > private so the impact is quite limited.
> That makes it harder to call this helper from a constant context. I think 
> there should be overloads (one `const`, one not) to handle this.
this helper is not intended to be used outside of importing and serialization. 
it is logically part of initialization.
normal users are intended to use `ArrayRef 
APValue::getLValu

[PATCH] D63640: [clang] Improve Serialization/Imporing/Dumping of APValues

2019-09-23 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 221384.
Tyker marked 12 inline comments as done.
Tyker retitled this revision from "[clang] Improve Serialization/Imporing of 
APValues" to "[clang] Improve Serialization/Imporing/Dumping of APValues".
Tyker edited the summary of this revision.
Tyker added a comment.

fixed some changes.
see comments for others.


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

https://reviews.llvm.org/D63640

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/ASTImporter.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/AST/ast-dump-color.cpp
  clang/test/ASTMerge/APValue/APValue.cpp

Index: clang/test/ASTMerge/APValue/APValue.cpp
===
--- /dev/null
+++ clang/test/ASTMerge/APValue/APValue.cpp
@@ -0,0 +1,209 @@
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -emit-pch %s -o %t.pch
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -ast-merge %t.pch -ast-dump-all | FileCheck %s
+
+#ifndef EMIT
+#define EMIT
+
+namespace Integer {
+
+constexpr int Unique_Int = int(6789);
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int' 6789
+
+constexpr __uint128_t Unique_Int128 = ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+//CHECK:  VarDecl {{.*}} Unique_Int128 
+//CHECK-NEXT: ConstantExpr {{.*}} 'unsigned __int128' 156773562844924187900898496343692168785
+
+}
+
+namespace FloatingPoint {
+
+constexpr double Unique_Double = double(567890.67890);
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}} 'double' 5.678907e+05
+
+}
+
+// FIXME: Add test for FixedPoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+constexpr B Basic_Struct = B{1, 0.7};
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::B' {1, 7.00e-01}
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  int i;
+  double d;
+  C c;
+};
+
+constexpr A Advanced_Struct = A{Basic_Struct, 1, 79.789, {}};
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::A' {{[{][{]}}1, 7.00e-01}, 1, 7.978900e+01, {9}}
+
+}
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Vector_Int = (v4si){8, 2, 3};
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'Vector::v4si':'__attribute__((__vector_size__(4 * sizeof(int int' {8, 2, 3, 0}
+
+}
+
+namespace Array {
+
+constexpr int Array_Int[] = {1, 2, 3, 4, 5, 6};
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int [6]' {1, 2, 3, 4, 5, 6}
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+constexpr A Array2_Struct[][3] = {{{}, {-45678, 9.8}, {9}}, {{}}};
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'Array::A const [2][3]' {{[{][{]}}{789, 6.789010e+04}, {-45678, 9.80e+00}, {9, 6.789010e+04}}, {{[{][{]}}789, 6.789010e+04}, {789, 6.789010e+04}, {789, 6.789010e+04}}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Array_Vector[] = {{1, 2, 3, 4}, {4, 5, 6, 7}};
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Array::v4si [2]' {{[{][{]}}1, 2, 3, 4}, {4, 5, 6, 7}}
+
+}
+
+namespace Union {
+
+struct A {
+  int i = 6789;
+  float f = 987.9876;
+};
+
+union U {
+  int i;
+  A a{567890, 9876.5678f};
+};
+
+constexpr U Unique_Union1 = U{0};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.i = 0}
+
+constexpr U Unique_Union2 = U{};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.a = {567890, 9.876567e+03}}
+
+}
+
+namespace MemberPointer{
+
+struct A {
+  struct B {
+struct C {
+  struct D {
+struct E {
+  struct F {
+struct G {
+  int i;
+};
+  };
+};
+  };
+};
+  };
+};
+
+constexpr auto MemberPointer1 = &A::B::C::D::E::F::G::i;
+//CHECK:  VarDecl {{.*}} MemberPointer1
+//CHECK-NEXT: ConstantExpr {{.*}} 'int MemberPointer::A::B::C::D::E::F::G::*' &G::i
+
+struct A1 {
+  struct B1 {
+int f() const {
+  return 0;
+}
+  };
+
+};
+
+constexpr auto MemberPointer2 = &A1::B1::f;
+//CHECK:  VarDecl {{.*}} MemberPointer2
+//CHECK-NEXT: ConstantExpr {{.*}} 'int (MemberPointer::A1::B1::*)() const' &B1::f
+
+}
+
+namespace std

[PATCH] D63640: [clang] Improve Serialization/Imporing/Dumping of APValues

2019-09-24 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 221568.
Tyker marked 7 inline comments as done.
Tyker added a comment.

fixed most comments


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

https://reviews.llvm.org/D63640

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/ASTImporter.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/AST/ast-dump-color.cpp
  clang/test/ASTMerge/APValue/APValue.cpp

Index: clang/test/ASTMerge/APValue/APValue.cpp
===
--- /dev/null
+++ clang/test/ASTMerge/APValue/APValue.cpp
@@ -0,0 +1,209 @@
+// RUN: %clang_cc1 -std=gnu++2a -emit-pch %s -o %t.pch
+// RUN: %clang_cc1 -std=gnu++2a %s -DEMIT -ast-merge %t.pch -ast-dump-all | FileCheck %s
+
+#ifndef EMIT
+#define EMIT
+
+namespace Integer {
+
+constexpr int Unique_Int = int(6789);
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int' 6789
+
+constexpr __uint128_t Unique_Int128 = ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+//CHECK:  VarDecl {{.*}} Unique_Int128 
+//CHECK-NEXT: ConstantExpr {{.*}} 'unsigned __int128' 156773562844924187900898496343692168785
+
+}
+
+namespace FloatingPoint {
+
+constexpr double Unique_Double = double(567890.67890);
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}} 'double' 5.678907e+05
+
+}
+
+// FIXME: Add test for FixedPoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+constexpr B Basic_Struct = B{1, 0.7};
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::B' {1, 7.00e-01}
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  int i;
+  double d;
+  C c;
+};
+
+constexpr A Advanced_Struct = A{Basic_Struct, 1, 79.789, {}};
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::A' {{[{][{]}}1, 7.00e-01}, 1, 7.978900e+01, {9}}
+
+}
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Vector_Int = (v4si){8, 2, 3};
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'Vector::v4si':'__attribute__((__vector_size__(4 * sizeof(int int' {8, 2, 3, 0}
+
+}
+
+namespace Array {
+
+constexpr int Array_Int[] = {1, 2, 3, 4, 5, 6};
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int [6]' {1, 2, 3, 4, 5, 6}
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+constexpr A Array2_Struct[][3] = {{{}, {-45678, 9.8}, {9}}, {{}}};
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'Array::A const [2][3]' {{[{][{]}}{789, 6.789010e+04}, {-45678, 9.80e+00}, {9, 6.789010e+04}}, {{[{][{]}}789, 6.789010e+04}, {789, 6.789010e+04}, {789, 6.789010e+04}}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Array_Vector[] = {{1, 2, 3, 4}, {4, 5, 6, 7}};
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Array::v4si [2]' {{[{][{]}}1, 2, 3, 4}, {4, 5, 6, 7}}
+
+}
+
+namespace Union {
+
+struct A {
+  int i = 6789;
+  float f = 987.9876;
+};
+
+union U {
+  int i;
+  A a{567890, 9876.5678f};
+};
+
+constexpr U Unique_Union1 = U{0};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.i = 0}
+
+constexpr U Unique_Union2 = U{};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.a = {567890, 9.876567e+03}}
+
+}
+
+namespace MemberPointer{
+
+struct A {
+  struct B {
+struct C {
+  struct D {
+struct E {
+  struct F {
+struct G {
+  int i;
+};
+  };
+};
+  };
+};
+  };
+};
+
+constexpr auto MemberPointer1 = &A::B::C::D::E::F::G::i;
+//CHECK:  VarDecl {{.*}} MemberPointer1
+//CHECK-NEXT: ConstantExpr {{.*}} 'int MemberPointer::A::B::C::D::E::F::G::*' &G::i
+
+struct A1 {
+  struct B1 {
+int f() const {
+  return 0;
+}
+  };
+
+};
+
+constexpr auto MemberPointer2 = &A1::B1::f;
+//CHECK:  VarDecl {{.*}} MemberPointer2
+//CHECK-NEXT: ConstantExpr {{.*}} 'int (MemberPointer::A1::B1::*)() const' &B1::f
+
+}
+
+namespace std {
+  struct type_info;
+};
+
+namespace LValue {
+
+constexpr int LValueInt = 0;
+constexpr const int& ConstIntRef = LValueInt;
+//CHECK:  VarDecl {{.*}} ConstIntRef
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int' lvalue &

[PATCH] D63640: [clang] Improve Serialization/Imporing/Dumping of APValues

2019-09-24 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/lib/AST/APValue.cpp:599
 Out << '[' << Path[I].getAsArrayIndex() << ']';
-ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType();
+ElemTy = cast(ElemTy)->getElementType();
   }

aaron.ballman wrote:
> Are you sure this doesn't change behavior? See the implementation of 
> `ASTContext::getAsArrayType()`. Same question applies below.
i ran the test suite after the change it there wasn't any test failures. but 
the test on dumping APValue are probably not as thorough as we would like them 
to be.
from analysis of `ASTContext::getAsArrayType()` the only effect i see on the 
element type is de-sugaring and canonicalization which shouldn't affect 
correctness of the output.  de-sugaring requires the ASTContext but 
canonicalization doesn't.

i think the best way the have higher confidence is to ask rsmith what he thinks.



Comment at: clang/test/ASTMerge/APValue/APValue.cpp:28
+
+// FIXME: Add test for FixePoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+

aaron.ballman wrote:
> Tyker wrote:
> > aaron.ballman wrote:
> > > Are you planning to address this in this patch? Also, I think it's 
> > > FixedPoint and not FixePoint.
> > i don't intend to add them in this patch or subsequent patches. i don't 
> > know how to use the features that have these representations, i don't even 
> > know if they can be stored stored in that AST. so this is untested code.
> > that said theses representations aren't complex. the imporing for 
> > FixePoint, ComplexInt, ComplexFloat is a no-op and for AddrLabelDiff it is 
> > trivial. for serialization, I can put an llvm_unreachable to mark them as 
> > untested if you want ?
> I don't think `llvm_unreachable` makes a whole lot of sense unless the code 
> is truly unreachable because there's no way to get an AST with that 
> representation. By code inspection, the code looks reasonable but it does 
> make me a bit uncomfortable to adopt it without tests. I suppose the FIXME is 
> a reasonable compromise in this case, but if you have some spare cycles to 
> investigate ways to get those representations, it would be appreciated.
the reason i proposed `llvm_unreachable` was because it passes the tests and 
prevents future developer from depending on the code that depend on it assuming 
it works.


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

https://reviews.llvm.org/D63640



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


[PATCH] D63640: [clang] Improve Serialization/Imporing/Dumping of APValues

2019-09-27 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 222169.
Tyker marked 3 inline comments as done.
Tyker added a comment.

made renamings


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

https://reviews.llvm.org/D63640

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/ASTImporter.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Decl.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/AST/ast-dump-color.cpp
  clang/test/ASTMerge/APValue/APValue.cpp

Index: clang/test/ASTMerge/APValue/APValue.cpp
===
--- /dev/null
+++ clang/test/ASTMerge/APValue/APValue.cpp
@@ -0,0 +1,209 @@
+// RUN: %clang_cc1 -std=gnu++2a -emit-pch %s -o %t.pch
+// RUN: %clang_cc1 -std=gnu++2a %s -DEMIT -ast-merge %t.pch -ast-dump-all | FileCheck %s
+
+#ifndef EMIT
+#define EMIT
+
+namespace Integer {
+
+constexpr int Unique_Int = int(6789);
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int' 6789
+
+constexpr __uint128_t Unique_Int128 = ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+//CHECK:  VarDecl {{.*}} Unique_Int128 
+//CHECK-NEXT: ConstantExpr {{.*}} 'unsigned __int128' 156773562844924187900898496343692168785
+
+}
+
+namespace FloatingPoint {
+
+constexpr double Unique_Double = double(567890.67890);
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}} 'double' 5.678907e+05
+
+}
+
+// FIXME: Add test for FixedPoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+constexpr B Basic_Struct = B{1, 0.7};
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::B' {1, 7.00e-01}
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  int i;
+  double d;
+  C c;
+};
+
+constexpr A Advanced_Struct = A{Basic_Struct, 1, 79.789, {}};
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Struct::A' {{[{][{]}}1, 7.00e-01}, 1, 7.978900e+01, {9}}
+
+}
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Vector_Int = (v4si){8, 2, 3};
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'Vector::v4si':'__attribute__((__vector_size__(4 * sizeof(int int' {8, 2, 3, 0}
+
+}
+
+namespace Array {
+
+constexpr int Array_Int[] = {1, 2, 3, 4, 5, 6};
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int [6]' {1, 2, 3, 4, 5, 6}
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+constexpr A Array2_Struct[][3] = {{{}, {-45678, 9.8}, {9}}, {{}}};
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}} 'Array::A const [2][3]' {{[{][{]}}{789, 6.789010e+04}, {-45678, 9.80e+00}, {9, 6.789010e+04}}, {{[{][{]}}789, 6.789010e+04}, {789, 6.789010e+04}, {789, 6.789010e+04}}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+constexpr v4si Array_Vector[] = {{1, 2, 3, 4}, {4, 5, 6, 7}};
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Array::v4si [2]' {{[{][{]}}1, 2, 3, 4}, {4, 5, 6, 7}}
+
+}
+
+namespace Union {
+
+struct A {
+  int i = 6789;
+  float f = 987.9876;
+};
+
+union U {
+  int i;
+  A a{567890, 9876.5678f};
+};
+
+constexpr U Unique_Union1 = U{0};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.i = 0}
+
+constexpr U Unique_Union2 = U{};
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr {{.*}} 'const Union::U' {.a = {567890, 9.876567e+03}}
+
+}
+
+namespace MemberPointer{
+
+struct A {
+  struct B {
+struct C {
+  struct D {
+struct E {
+  struct F {
+struct G {
+  int i;
+};
+  };
+};
+  };
+};
+  };
+};
+
+constexpr auto MemberPointer1 = &A::B::C::D::E::F::G::i;
+//CHECK:  VarDecl {{.*}} MemberPointer1
+//CHECK-NEXT: ConstantExpr {{.*}} 'int MemberPointer::A::B::C::D::E::F::G::*' &G::i
+
+struct A1 {
+  struct B1 {
+int f() const {
+  return 0;
+}
+  };
+
+};
+
+constexpr auto MemberPointer2 = &A1::B1::f;
+//CHECK:  VarDecl {{.*}} MemberPointer2
+//CHECK-NEXT: ConstantExpr {{.*}} 'int (MemberPointer::A1::B1::*)() const' &B1::f
+
+}
+
+namespace std {
+  struct type_info;
+};
+
+namespace LValue {
+
+constexpr int LValueInt = 0;
+constexpr const int& ConstIntRef = LValueInt;
+//CHECK:  VarDecl {{.*}} ConstIntRef
+//CHECK-NEXT: ConstantExpr {{.*}} 'const int' lvalue &LValu

[PATCH] D63960: [C++20] Add consteval-specific semantic for functions

2019-10-03 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 223021.
Tyker marked 16 inline comments as done.
Tyker added a comment.

i addressed almost all comments.


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

https://reviews.llvm.org/D63960

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp

Index: clang/test/SemaCXX/cxx2a-consteval.cpp
===
--- clang/test/SemaCXX/cxx2a-consteval.cpp
+++ clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -12,6 +12,7 @@
 }
 
 constexpr auto l_eval = [](int i) consteval {
+// expected-note@-1+ {{declared here}}
 
   return i;
 };
@@ -23,6 +24,7 @@
 
 struct A {
   consteval int f1(int i) const {
+// expected-note@-1 {{declared here}}
 return i;
   }
   consteval A(int i);
@@ -62,3 +64,203 @@
 consteval int main() { // expected-error {{'main' is not allowed to be declared consteval}}
   return 0;
 }
+
+consteval int f_eval(int i) {
+// expected-note@-1+ {{declared here}}
+  return i;
+}
+
+namespace taking_address {
+
+using func_type = int(int);
+
+func_type* p1 = (&f_eval);
+// expected-error@-1 {{take address}}
+func_type* p7 = __builtin_addressof(f_eval);
+// expected-error@-1 {{take address}}
+
+auto p = f_eval;
+// expected-error@-1 {{take address}}
+
+auto m1 = &basic_sema::A::f1;
+// expected-error@-1 {{take address}}
+auto l1 = &decltype(basic_sema::l_eval)::operator();
+// expected-error@-1 {{take address}}
+
+consteval int f(int i) {
+// expected-note@-1+ {{declared here}}
+  return i;
+}
+
+auto ptr = &f;
+// expected-error@-1 {{take address}}
+
+auto f1() {
+  return &f;
+// expected-error@-1 {{take address}}
+}
+
+}
+
+namespace invalid_function {
+using size_t = unsigned long;
+struct A {
+  consteval void *operator new(size_t count);
+  // expected-error@-1 {{'operator new' cannot be declared consteval}}
+  consteval void *operator new[](size_t count);
+  // expected-error@-1 {{'operator new[]' cannot be declared consteval}}
+  consteval void operator delete(void* ptr);
+  // expected-error@-1 {{'operator delete' cannot be declared consteval}}
+  consteval void operator delete[](void* ptr);
+  // expected-error@-1 {{'operator delete[]' cannot be declared consteval}}
+};
+
+}
+
+namespace nested {
+consteval int f() {
+  return 0;
+}
+
+consteval int f1(...) {
+  return 1;
+}
+
+enum E {};
+
+using T = int(&)();
+
+consteval auto operator+ (E, int(*a)()) {
+  return 0;
+}
+
+void d() {
+  auto i = f1(E() + &f);
+}
+
+auto l0 = [](auto) consteval {
+  return 0;
+};
+
+int i0 = l0(&f1);
+
+int i1 = f1(l0(4));
+
+int i2 = f1(&f1, &f1, &f1, &f1, &f1, &f1, &f1);
+
+int i3 = f1(f1(f1(&f1, &f1), f1(&f1, &f1), f1(f1(&f1, &f1), &f1)));
+
+}
+
+namespace user_defined_literal {
+
+consteval int operator"" _test(unsigned long long i) {
+// expected-note@-1+ {{declared here}}
+  return 0;
+}
+
+int i = 0_test;
+
+auto ptr = &operator"" _test;
+// expected-error@-1 {{take address}}
+
+}
+
+namespace return_address {
+
+consteval int f() {
+  return 0;
+}
+
+consteval int(*ret1(int i))() {
+  return &f;
+}
+
+auto ptr = ret1(0);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{pointer to a consteval}}
+
+struct A {
+  consteval int f(int) {
+return 0;
+  }
+};
+
+using mem_ptr_type = int (A::*)(int);
+
+template
+struct C {};
+
+C<&A::f> c;
+// expected-error@-1 {{is not a constant expression}}
+// expected-note@-2 {{pointer to a consteval}}
+
+consteval mem_ptr_type ret2() {
+  return &A::f;
+}
+
+C c1;
+// expected-error@-1 {{is not a constant expression}}
+// expected-note@-2 {{pointer to a consteval}}
+
+}
+
+namespace context {
+
+int g_i;
+// expected-note@-1 {{declared here}}
+
+consteval int f(int) {
+  return 0;
+}
+
+constexpr int c_i = 0;
+
+int t1 = f(g_i);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{read of non-const variable}}
+int t3 = f(c_i);
+
+constexpr int f_c(int i) {
+// expected-note@-1 {{declared here}}
+  int t = f(i);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{read of non-const variable}}
+  return f(0);  
+}
+
+consteval int f_eval(int i) {
+  return f(i);
+}
+
+auto l0 = [](int i) consteval {
+  return f(i);
+};
+
+auto l1 = [](int i) constexpr {
+// expected-note@-1 {{declared here}}
+  int t = f(i);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{read of non-const variable}}
+  return f(0);  
+};
+
+}
+
+namespace cleanup {
+
+struct A {
+  int *p = new int(42);
+  consteval int get() { ret

[PATCH] D63960: [C++20] Add consteval-specific semantic for functions

2019-10-03 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/lib/Sema/SemaDeclCXX.cpp:11188-11189
 
+  ConstexprSpecKind ConstexprKind = DetermineSpecialMemberConstexprKind(
+  Constexpr, ClassDecl->hasDefaultedConstevalDefaultCtor());
+

rsmith wrote:
> I don't think this is necessary: implicit special members are never 
> `consteval`. (We use `DeclareImplicitDefaultConstructor` when there is no 
> user-declared default constructor, in which case there can't possibly be a 
> defaulted consteval default constructor.) I don't think you need any of the 
> `DetermineSpecialMemberConstexprKind` machinery, nor the tracking of 
> `DefaultedSpecialMemberIsConsteval` in `CXXRecordDecl`.
all the code you mention is to fixe an issue i saw while working on consteval.
the AST of
```
struct A {
consteval A() = default;
consteval A(int) { }
};
```
is
```
TranslationUnitDecl
`-CXXRecordDecl  line:1:8 struct A definition
  |-DefinitionData pass_in_registers empty standard_layout trivially_copyable 
trivial literal has_user_declared_ctor has_constexpr_non_copy_move_ctor 
can_const_default_init
  | |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr
  | |-CopyConstructor simple trivial has_const_param needs_implicit 
implicit_has_const_param
  | |-MoveConstructor exists simple trivial needs_implicit
  | |-CopyAssignment trivial has_const_param needs_implicit 
implicit_has_const_param
  | |-MoveAssignment exists simple trivial needs_implicit
  | `-Destructor simple irrelevant trivial needs_implicit
  |-CXXRecordDecl  col:8 implicit referenced struct A
  |-CXXConstructorDecl  col:15 constexpr A 'void ()' default 
trivial noexcept-unevaluated 0x55585ae25160
  `-CXXConstructorDecl  col:15 consteval A 'void (int)'
|-ParmVarDecl  col:20 'int'
`-CompoundStmt 
```
[[ https://godbolt.org/z/oRx0Ss | godbolt ]]
notice that `A::A()` is marked as constexpr instead of consteval.
and `A::A(int)` is marked correctly.

this is because consteval defaulted special members are not marked as consteval.
those code changes are intended to fix that. with this patch both constructor 
are marked as consteval




Comment at: clang/lib/Sema/SemaExpr.cpp:15071
+llvm::PointerIntPair RHS) {
+  return LHS.getPointer()->getBeginLoc() < RHS.getPointer()->getBeginLoc();
+}

rsmith wrote:
> `<` on `SourceLocation` doesn't really mean anything. It's not correct to use 
> it here. Also, using source locations will not give you outer expressions 
> before inner ones. Consider:
> 
> ```
> enum E {};
> consteval E f();
> consteval int operator+(E, int);
> void g() {
>   f() + 1;
> }
> ```
> 
>  Here, the begin location of both the call to `f()` and the call to 
> `operator+` are in the same place: at the `f` token.
> 
> I don't think you need this sort at all: instead, you can process immediate 
> invocations in `ImmediateInvocationCandidates` in reverse order: 
> subexpressions must have been built before their enclosing expressions, so 
> walking in reverse order will guarantee that you process an outer candidate 
> before any inner ones.
the sort is used in combination with a lower_bounds in 
`ComplexRemove::TransformConstantExpr` to lookup in 
`ImmediateInvocationsCandidates` using binary search.
but i think your proposition is more efficient except in some very rare cases.




Comment at: clang/lib/Sema/SemaExpr.cpp:15102
+ExprCompType{});
+if (It != IISet.end()) {
+  It->setInt(1); // Mark as deleted

rsmith wrote:
> We should look for an exact match here, not merely for something nearby. 
> (Maybe: form a pointer set of immediate invocation pointer expressions, and 
> remove things from the set when you encounter them in this walk; then when 
> iterating over the immediate invocations, skip ones that have already been 
> erased from the set.)
the issue i had with a set is that we can't remove element during iteration as 
removing element invalidate iterators.
but to get an exact match we can use the pointer as "key", they are unique.


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

https://reviews.llvm.org/D63960



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


[PATCH] D63640: [clang] Improve Serialization/Imporing/Dumping of APValues

2019-10-06 Thread Tyker via Phabricator via cfe-commits
Tyker marked 10 inline comments as done.
Tyker added a comment.

update done tasks.




Comment at: clang/lib/AST/APValue.cpp:599
 Out << '[' << Path[I].getAsArrayIndex() << ']';
-ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType();
+ElemTy = cast(ElemTy)->getElementType();
   }

aaron.ballman wrote:
> Tyker wrote:
> > aaron.ballman wrote:
> > > Are you sure this doesn't change behavior? See the implementation of 
> > > `ASTContext::getAsArrayType()`. Same question applies below.
> > i ran the test suite after the change it there wasn't any test failures. 
> > but the test on dumping APValue are probably not as thorough as we would 
> > like them to be.
> > from analysis of `ASTContext::getAsArrayType()` the only effect i see on 
> > the element type is de-sugaring and canonicalization which shouldn't affect 
> > correctness of the output.  de-sugaring requires the ASTContext but 
> > canonicalization doesn't.
> > 
> > i think the best way the have higher confidence is to ask rsmith what he 
> > thinks.
> Yeah, I doubt we have good test coverage for all the various behaviors here. 
> I was wondering if the qualifiers bit was handled properly with a simple 
> cast. @rsmith is a good person to weigh in.
the original question we had is whether it is correct to replace 
`Ctx.ASTContext::getAsArrayType(ElemTy)` by 
`cast(ElemTy.getCanonicalType())` in this context and the other 
comment below.



Comment at: clang/lib/AST/Expr.cpp:319
   case RSK_None:
 return;
   case RSK_Int64:

rsmith wrote:
> Can you use `llvm_unreachable` here? (Are there cases where we use `RSK_None` 
> and then later find we actually have a value to store into the 
> `ConstantExpr`?)
we can put `llvm_unreachable` in the switch because of `if (!Value.hasValue())` 
above the switch but we can't remove `if (!Value.hasValue())`.
all cases i have seen where `if (!Value.hasValue())` is taken occur after a 
semantic error occured. 



Comment at: clang/lib/Serialization/ASTReader.cpp:9635
+if (IsExpr) {
+  Base = APValue::LValueBase(ReadExpr(F), CallIndex, Version);
+  ElemTy = Base.get()->getType();

rsmith wrote:
> This is problematic.
> 
> `ReadExpr` will read a new copy of the expression, creating a distinct 
> object. But in the case where we reach this when deserializing (for a 
> `MaterializeTemporaryExpr`), we need to refer to the existing 
> `MaterializeTemporaryExpr` in the initializer of its lifetime-extending 
> declaration. We will also need to serialize the `ASTContext`'s 
> `MaterializedTemporaryValues` collection so that the temporaries 
> lifetime-extended in a constant initializer get properly handled.
> 
> That all sounds very messy, so I think we should reconsider the model that we 
> use for lifetime-extended materialized temporaries. As a half-baked idea:
> 
>  * When we lifetime-extend a temporary, create a `MaterializedTemporaryDecl` 
> to hold its value, and modify `MaterializeTemporaryExpr` to refer to the 
> `MaterializedTemporaryDecl` rather than to just hold the subexpression for 
> the temporary.
>  * Change the `LValueBase` representation to denote the declaration rather 
> than the expression.
>  * Store the constant evaluated value for a materialized temporary on the 
> `MaterializedTemporaryDecl` rather than on a side-table in the `ASTContext`.
> 
> With that done, we should verify that all remaining `Expr*`s used as 
> `LValueBase`s are either only transiently used during evaluation or don't 
> have these kinds of identity problems.
Would it be possible to adapt serialization/deserialization so that they make 
sure that `MaterializeTemporaryExpr` are unique.
by:

  - When serializing `MaterializeTemporaryExpr` serialize a key obtained from 
the pointer to the expression as it is unique.
  - When deserializing `MaterializeTemporaryExpr` deserializing the key, and 
than have a cache for previously deserialized expression that need to be unique.

This would make easier adding new `Expr` that require uniqueness and seem less 
complicated.
What do you think ?


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

https://reviews.llvm.org/D63640



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


[PATCH] D63960: [C++20] Add consteval-specific semantic for functions

2019-10-07 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 223624.

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

https://reviews.llvm.org/D63960

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp

Index: clang/test/SemaCXX/cxx2a-consteval.cpp
===
--- clang/test/SemaCXX/cxx2a-consteval.cpp
+++ clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -12,6 +12,7 @@
 }
 
 constexpr auto l_eval = [](int i) consteval {
+// expected-note@-1+ {{declared here}}
 
   return i;
 };
@@ -23,6 +24,7 @@
 
 struct A {
   consteval int f1(int i) const {
+// expected-note@-1 {{declared here}}
 return i;
   }
   consteval A(int i);
@@ -62,3 +64,203 @@
 consteval int main() { // expected-error {{'main' is not allowed to be declared consteval}}
   return 0;
 }
+
+consteval int f_eval(int i) {
+// expected-note@-1+ {{declared here}}
+  return i;
+}
+
+namespace taking_address {
+
+using func_type = int(int);
+
+func_type* p1 = (&f_eval);
+// expected-error@-1 {{take address}}
+func_type* p7 = __builtin_addressof(f_eval);
+// expected-error@-1 {{take address}}
+
+auto p = f_eval;
+// expected-error@-1 {{take address}}
+
+auto m1 = &basic_sema::A::f1;
+// expected-error@-1 {{take address}}
+auto l1 = &decltype(basic_sema::l_eval)::operator();
+// expected-error@-1 {{take address}}
+
+consteval int f(int i) {
+// expected-note@-1+ {{declared here}}
+  return i;
+}
+
+auto ptr = &f;
+// expected-error@-1 {{take address}}
+
+auto f1() {
+  return &f;
+// expected-error@-1 {{take address}}
+}
+
+}
+
+namespace invalid_function {
+using size_t = unsigned long;
+struct A {
+  consteval void *operator new(size_t count);
+  // expected-error@-1 {{'operator new' cannot be declared consteval}}
+  consteval void *operator new[](size_t count);
+  // expected-error@-1 {{'operator new[]' cannot be declared consteval}}
+  consteval void operator delete(void* ptr);
+  // expected-error@-1 {{'operator delete' cannot be declared consteval}}
+  consteval void operator delete[](void* ptr);
+  // expected-error@-1 {{'operator delete[]' cannot be declared consteval}}
+};
+
+}
+
+namespace nested {
+consteval int f() {
+  return 0;
+}
+
+consteval int f1(...) {
+  return 1;
+}
+
+enum E {};
+
+using T = int(&)();
+
+consteval auto operator+ (E, int(*a)()) {
+  return 0;
+}
+
+void d() {
+  auto i = f1(E() + &f);
+}
+
+auto l0 = [](auto) consteval {
+  return 0;
+};
+
+int i0 = l0(&f1);
+
+int i1 = f1(l0(4));
+
+int i2 = f1(&f1, &f1, &f1, &f1, &f1, &f1, &f1);
+
+int i3 = f1(f1(f1(&f1, &f1), f1(&f1, &f1), f1(f1(&f1, &f1), &f1)));
+
+}
+
+namespace user_defined_literal {
+
+consteval int operator"" _test(unsigned long long i) {
+// expected-note@-1+ {{declared here}}
+  return 0;
+}
+
+int i = 0_test;
+
+auto ptr = &operator"" _test;
+// expected-error@-1 {{take address}}
+
+}
+
+namespace return_address {
+
+consteval int f() {
+  return 0;
+}
+
+consteval int(*ret1(int i))() {
+  return &f;
+}
+
+auto ptr = ret1(0);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{pointer to a consteval}}
+
+struct A {
+  consteval int f(int) {
+return 0;
+  }
+};
+
+using mem_ptr_type = int (A::*)(int);
+
+template
+struct C {};
+
+C<&A::f> c;
+// expected-error@-1 {{is not a constant expression}}
+// expected-note@-2 {{pointer to a consteval}}
+
+consteval mem_ptr_type ret2() {
+  return &A::f;
+}
+
+C c1;
+// expected-error@-1 {{is not a constant expression}}
+// expected-note@-2 {{pointer to a consteval}}
+
+}
+
+namespace context {
+
+int g_i;
+// expected-note@-1 {{declared here}}
+
+consteval int f(int) {
+  return 0;
+}
+
+constexpr int c_i = 0;
+
+int t1 = f(g_i);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{read of non-const variable}}
+int t3 = f(c_i);
+
+constexpr int f_c(int i) {
+// expected-note@-1 {{declared here}}
+  int t = f(i);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{read of non-const variable}}
+  return f(0);  
+}
+
+consteval int f_eval(int i) {
+  return f(i);
+}
+
+auto l0 = [](int i) consteval {
+  return f(i);
+};
+
+auto l1 = [](int i) constexpr {
+// expected-note@-1 {{declared here}}
+  int t = f(i);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{read of non-const variable}}
+  return f(0);  
+};
+
+}
+
+namespace cleanup {
+
+struct A {
+  int *p = new int(42);
+  consteval int get() { return *p; }
+  constexpr ~A() { delete p; }
+};
+int k1 = A().get();
+
+struct B {
+  int *p = new in

[PATCH] D68716: [clang] prevent crash for nonnull attribut in constant context (Bug 43601)

2019-10-09 Thread Tyker via Phabricator via cfe-commits
Tyker created this revision.
Tyker added a reviewer: rnk.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

bug : https://bugs.llvm.org/show_bug.cgi?id=43601


Repository:
  rC Clang

https://reviews.llvm.org/D68716

Files:
  clang/lib/AST/ExprConstant.cpp
  clang/test/SemaCXX/attr-nonnull.cpp


Index: clang/test/SemaCXX/attr-nonnull.cpp
===
--- clang/test/SemaCXX/attr-nonnull.cpp
+++ clang/test/SemaCXX/attr-nonnull.cpp
@@ -77,10 +77,11 @@
 constexpr int i32 = f3(0, &c);
 
 __attribute__((nonnull(4))) __attribute__((nonnull)) //expected-error {{out of 
bounds}}
-constexpr int f4(const int*, const int*) {
+constexpr int f4(const int*, const int*, int) {
   return 0;
 }
-constexpr int i4 = f4(&c, 0); //expected-error {{constant expression}} 
expected-note {{null passed}}
-constexpr int i42 = f4(0, &c); //expected-error {{constant expression}} 
expected-note {{null passed}}
+constexpr int i4 = f4(&c, 0, 0); //expected-error {{constant expression}} 
expected-note {{null passed}}
+constexpr int i42 = f4(0, &c, 1); //expected-error {{constant expression}} 
expected-note {{null passed}}
+constexpr int i43 = f4(&c, &c, 0);
 
 }
\ No newline at end of file
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -5451,6 +5451,7 @@
   Success = false;
 } else if (!ForbiddenNullArgs.empty() &&
ForbiddenNullArgs[I - Args.begin()] &&
+   ArgValues[I - Args.begin()].isLValue() &&
ArgValues[I - Args.begin()].isNullPointer()) {
   Info.CCEDiag(*I, diag::note_non_null_attribute_failed);
   if (!Info.noteFailure())


Index: clang/test/SemaCXX/attr-nonnull.cpp
===
--- clang/test/SemaCXX/attr-nonnull.cpp
+++ clang/test/SemaCXX/attr-nonnull.cpp
@@ -77,10 +77,11 @@
 constexpr int i32 = f3(0, &c);
 
 __attribute__((nonnull(4))) __attribute__((nonnull)) //expected-error {{out of bounds}}
-constexpr int f4(const int*, const int*) {
+constexpr int f4(const int*, const int*, int) {
   return 0;
 }
-constexpr int i4 = f4(&c, 0); //expected-error {{constant expression}} expected-note {{null passed}}
-constexpr int i42 = f4(0, &c); //expected-error {{constant expression}} expected-note {{null passed}}
+constexpr int i4 = f4(&c, 0, 0); //expected-error {{constant expression}} expected-note {{null passed}}
+constexpr int i42 = f4(0, &c, 1); //expected-error {{constant expression}} expected-note {{null passed}}
+constexpr int i43 = f4(&c, &c, 0);
 
 }
\ No newline at end of file
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -5451,6 +5451,7 @@
   Success = false;
 } else if (!ForbiddenNullArgs.empty() &&
ForbiddenNullArgs[I - Args.begin()] &&
+   ArgValues[I - Args.begin()].isLValue() &&
ArgValues[I - Args.begin()].isNullPointer()) {
   Info.CCEDiag(*I, diag::note_non_null_attribute_failed);
   if (!Info.noteFailure())
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68716: [clang] prevent crash for nonnull attribut in constant context (Bug 43601)

2019-10-09 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 224169.

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

https://reviews.llvm.org/D68716

Files:
  clang/lib/AST/ExprConstant.cpp
  clang/test/SemaCXX/attr-nonnull.cpp


Index: clang/test/SemaCXX/attr-nonnull.cpp
===
--- clang/test/SemaCXX/attr-nonnull.cpp
+++ clang/test/SemaCXX/attr-nonnull.cpp
@@ -77,10 +77,11 @@
 constexpr int i32 = f3(0, &c);
 
 __attribute__((nonnull(4))) __attribute__((nonnull)) //expected-error {{out of 
bounds}}
-constexpr int f4(const int*, const int*) {
+constexpr int f4(const int*, const int*, int) {
   return 0;
 }
-constexpr int i4 = f4(&c, 0); //expected-error {{constant expression}} 
expected-note {{null passed}}
-constexpr int i42 = f4(0, &c); //expected-error {{constant expression}} 
expected-note {{null passed}}
+constexpr int i4 = f4(&c, 0, 0); //expected-error {{constant expression}} 
expected-note {{null passed}}
+constexpr int i42 = f4(0, &c, 1); //expected-error {{constant expression}} 
expected-note {{null passed}}
+constexpr int i43 = f4(&c, &c, 0);
 
 }
\ No newline at end of file
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -5441,18 +5441,18 @@
 }
 }
   }
-  for (ArrayRef::iterator I = Args.begin(), E = Args.end();
-   I != E; ++I) {
-if (!Evaluate(ArgValues[I - Args.begin()], Info, *I)) {
+  for (unsigned Idx = 0; Idx < Args.size(); Idx++) {
+if (!Evaluate(ArgValues[Idx], Info, Args[Idx])) {
   // If we're checking for a potential constant expression, evaluate all
   // initializers even if some of them fail.
   if (!Info.noteFailure())
 return false;
   Success = false;
 } else if (!ForbiddenNullArgs.empty() &&
-   ForbiddenNullArgs[I - Args.begin()] &&
-   ArgValues[I - Args.begin()].isNullPointer()) {
-  Info.CCEDiag(*I, diag::note_non_null_attribute_failed);
+   ForbiddenNullArgs[Idx] &&
+   ArgValues[Idx].isLValue() &&
+   ArgValues[Idx].isNullPointer()) {
+  Info.CCEDiag(Args[Idx], diag::note_non_null_attribute_failed);
   if (!Info.noteFailure())
 return false;
   Success = false;


Index: clang/test/SemaCXX/attr-nonnull.cpp
===
--- clang/test/SemaCXX/attr-nonnull.cpp
+++ clang/test/SemaCXX/attr-nonnull.cpp
@@ -77,10 +77,11 @@
 constexpr int i32 = f3(0, &c);
 
 __attribute__((nonnull(4))) __attribute__((nonnull)) //expected-error {{out of bounds}}
-constexpr int f4(const int*, const int*) {
+constexpr int f4(const int*, const int*, int) {
   return 0;
 }
-constexpr int i4 = f4(&c, 0); //expected-error {{constant expression}} expected-note {{null passed}}
-constexpr int i42 = f4(0, &c); //expected-error {{constant expression}} expected-note {{null passed}}
+constexpr int i4 = f4(&c, 0, 0); //expected-error {{constant expression}} expected-note {{null passed}}
+constexpr int i42 = f4(0, &c, 1); //expected-error {{constant expression}} expected-note {{null passed}}
+constexpr int i43 = f4(&c, &c, 0);
 
 }
\ No newline at end of file
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -5441,18 +5441,18 @@
 }
 }
   }
-  for (ArrayRef::iterator I = Args.begin(), E = Args.end();
-   I != E; ++I) {
-if (!Evaluate(ArgValues[I - Args.begin()], Info, *I)) {
+  for (unsigned Idx = 0; Idx < Args.size(); Idx++) {
+if (!Evaluate(ArgValues[Idx], Info, Args[Idx])) {
   // If we're checking for a potential constant expression, evaluate all
   // initializers even if some of them fail.
   if (!Info.noteFailure())
 return false;
   Success = false;
 } else if (!ForbiddenNullArgs.empty() &&
-   ForbiddenNullArgs[I - Args.begin()] &&
-   ArgValues[I - Args.begin()].isNullPointer()) {
-  Info.CCEDiag(*I, diag::note_non_null_attribute_failed);
+   ForbiddenNullArgs[Idx] &&
+   ArgValues[Idx].isLValue() &&
+   ArgValues[Idx].isNullPointer()) {
+  Info.CCEDiag(Args[Idx], diag::note_non_null_attribute_failed);
   if (!Info.noteFailure())
 return false;
   Success = false;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68716: [clang] prevent crash for nonnull attribut in constant context (Bug 43601)

2019-10-10 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG59c6df9b2c52: [clang] prevent crash for nonnull attribut in 
constant context (Bug 43601) (authored by Tyker).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D68716

Files:
  clang/lib/AST/ExprConstant.cpp
  clang/test/SemaCXX/attr-nonnull.cpp


Index: clang/test/SemaCXX/attr-nonnull.cpp
===
--- clang/test/SemaCXX/attr-nonnull.cpp
+++ clang/test/SemaCXX/attr-nonnull.cpp
@@ -77,10 +77,11 @@
 constexpr int i32 = f3(0, &c);
 
 __attribute__((nonnull(4))) __attribute__((nonnull)) //expected-error {{out of 
bounds}}
-constexpr int f4(const int*, const int*) {
+constexpr int f4(const int*, const int*, int) {
   return 0;
 }
-constexpr int i4 = f4(&c, 0); //expected-error {{constant expression}} 
expected-note {{null passed}}
-constexpr int i42 = f4(0, &c); //expected-error {{constant expression}} 
expected-note {{null passed}}
+constexpr int i4 = f4(&c, 0, 0); //expected-error {{constant expression}} 
expected-note {{null passed}}
+constexpr int i42 = f4(0, &c, 1); //expected-error {{constant expression}} 
expected-note {{null passed}}
+constexpr int i43 = f4(&c, &c, 0);
 
 }
\ No newline at end of file
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -5441,18 +5441,18 @@
 }
 }
   }
-  for (ArrayRef::iterator I = Args.begin(), E = Args.end();
-   I != E; ++I) {
-if (!Evaluate(ArgValues[I - Args.begin()], Info, *I)) {
+  for (unsigned Idx = 0; Idx < Args.size(); Idx++) {
+if (!Evaluate(ArgValues[Idx], Info, Args[Idx])) {
   // If we're checking for a potential constant expression, evaluate all
   // initializers even if some of them fail.
   if (!Info.noteFailure())
 return false;
   Success = false;
 } else if (!ForbiddenNullArgs.empty() &&
-   ForbiddenNullArgs[I - Args.begin()] &&
-   ArgValues[I - Args.begin()].isNullPointer()) {
-  Info.CCEDiag(*I, diag::note_non_null_attribute_failed);
+   ForbiddenNullArgs[Idx] &&
+   ArgValues[Idx].isLValue() &&
+   ArgValues[Idx].isNullPointer()) {
+  Info.CCEDiag(Args[Idx], diag::note_non_null_attribute_failed);
   if (!Info.noteFailure())
 return false;
   Success = false;


Index: clang/test/SemaCXX/attr-nonnull.cpp
===
--- clang/test/SemaCXX/attr-nonnull.cpp
+++ clang/test/SemaCXX/attr-nonnull.cpp
@@ -77,10 +77,11 @@
 constexpr int i32 = f3(0, &c);
 
 __attribute__((nonnull(4))) __attribute__((nonnull)) //expected-error {{out of bounds}}
-constexpr int f4(const int*, const int*) {
+constexpr int f4(const int*, const int*, int) {
   return 0;
 }
-constexpr int i4 = f4(&c, 0); //expected-error {{constant expression}} expected-note {{null passed}}
-constexpr int i42 = f4(0, &c); //expected-error {{constant expression}} expected-note {{null passed}}
+constexpr int i4 = f4(&c, 0, 0); //expected-error {{constant expression}} expected-note {{null passed}}
+constexpr int i42 = f4(0, &c, 1); //expected-error {{constant expression}} expected-note {{null passed}}
+constexpr int i43 = f4(&c, &c, 0);
 
 }
\ No newline at end of file
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -5441,18 +5441,18 @@
 }
 }
   }
-  for (ArrayRef::iterator I = Args.begin(), E = Args.end();
-   I != E; ++I) {
-if (!Evaluate(ArgValues[I - Args.begin()], Info, *I)) {
+  for (unsigned Idx = 0; Idx < Args.size(); Idx++) {
+if (!Evaluate(ArgValues[Idx], Info, Args[Idx])) {
   // If we're checking for a potential constant expression, evaluate all
   // initializers even if some of them fail.
   if (!Info.noteFailure())
 return false;
   Success = false;
 } else if (!ForbiddenNullArgs.empty() &&
-   ForbiddenNullArgs[I - Args.begin()] &&
-   ArgValues[I - Args.begin()].isNullPointer()) {
-  Info.CCEDiag(*I, diag::note_non_null_attribute_failed);
+   ForbiddenNullArgs[Idx] &&
+   ArgValues[Idx].isLValue() &&
+   ArgValues[Idx].isNullPointer()) {
+  Info.CCEDiag(Args[Idx], diag::note_non_null_attribute_failed);
   if (!Info.noteFailure())
 return false;
   Success = false;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63960: [C++20] Add consteval-specific semantic for functions

2019-10-11 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 224588.
Tyker added a comment.

improve performance in a bad case


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

https://reviews.llvm.org/D63960

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/AST/Expr.h
  clang/include/clang/AST/Stmt.h
  clang/include/clang/Basic/DiagnosticASTKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp

Index: clang/test/SemaCXX/cxx2a-consteval.cpp
===
--- clang/test/SemaCXX/cxx2a-consteval.cpp
+++ clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -12,6 +12,7 @@
 }
 
 constexpr auto l_eval = [](int i) consteval {
+// expected-note@-1+ {{declared here}}
 
   return i;
 };
@@ -23,6 +24,7 @@
 
 struct A {
   consteval int f1(int i) const {
+// expected-note@-1 {{declared here}}
 return i;
   }
   consteval A(int i);
@@ -62,3 +64,203 @@
 consteval int main() { // expected-error {{'main' is not allowed to be declared consteval}}
   return 0;
 }
+
+consteval int f_eval(int i) {
+// expected-note@-1+ {{declared here}}
+  return i;
+}
+
+namespace taking_address {
+
+using func_type = int(int);
+
+func_type* p1 = (&f_eval);
+// expected-error@-1 {{take address}}
+func_type* p7 = __builtin_addressof(f_eval);
+// expected-error@-1 {{take address}}
+
+auto p = f_eval;
+// expected-error@-1 {{take address}}
+
+auto m1 = &basic_sema::A::f1;
+// expected-error@-1 {{take address}}
+auto l1 = &decltype(basic_sema::l_eval)::operator();
+// expected-error@-1 {{take address}}
+
+consteval int f(int i) {
+// expected-note@-1+ {{declared here}}
+  return i;
+}
+
+auto ptr = &f;
+// expected-error@-1 {{take address}}
+
+auto f1() {
+  return &f;
+// expected-error@-1 {{take address}}
+}
+
+}
+
+namespace invalid_function {
+using size_t = unsigned long;
+struct A {
+  consteval void *operator new(size_t count);
+  // expected-error@-1 {{'operator new' cannot be declared consteval}}
+  consteval void *operator new[](size_t count);
+  // expected-error@-1 {{'operator new[]' cannot be declared consteval}}
+  consteval void operator delete(void* ptr);
+  // expected-error@-1 {{'operator delete' cannot be declared consteval}}
+  consteval void operator delete[](void* ptr);
+  // expected-error@-1 {{'operator delete[]' cannot be declared consteval}}
+};
+
+}
+
+namespace nested {
+consteval int f() {
+  return 0;
+}
+
+consteval int f1(...) {
+  return 1;
+}
+
+enum E {};
+
+using T = int(&)();
+
+consteval auto operator+ (E, int(*a)()) {
+  return 0;
+}
+
+void d() {
+  auto i = f1(E() + &f);
+}
+
+auto l0 = [](auto) consteval {
+  return 0;
+};
+
+int i0 = l0(&f1);
+
+int i1 = f1(l0(4));
+
+int i2 = f1(&f1, &f1, &f1, &f1, &f1, &f1, &f1);
+
+int i3 = f1(f1(f1(&f1, &f1), f1(&f1, &f1), f1(f1(&f1, &f1), &f1)));
+
+}
+
+namespace user_defined_literal {
+
+consteval int operator"" _test(unsigned long long i) {
+// expected-note@-1+ {{declared here}}
+  return 0;
+}
+
+int i = 0_test;
+
+auto ptr = &operator"" _test;
+// expected-error@-1 {{take address}}
+
+}
+
+namespace return_address {
+
+consteval int f() {
+  return 0;
+}
+
+consteval int(*ret1(int i))() {
+  return &f;
+}
+
+auto ptr = ret1(0);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{pointer to a consteval}}
+
+struct A {
+  consteval int f(int) {
+return 0;
+  }
+};
+
+using mem_ptr_type = int (A::*)(int);
+
+template
+struct C {};
+
+C<&A::f> c;
+// expected-error@-1 {{is not a constant expression}}
+// expected-note@-2 {{pointer to a consteval}}
+
+consteval mem_ptr_type ret2() {
+  return &A::f;
+}
+
+C c1;
+// expected-error@-1 {{is not a constant expression}}
+// expected-note@-2 {{pointer to a consteval}}
+
+}
+
+namespace context {
+
+int g_i;
+// expected-note@-1 {{declared here}}
+
+consteval int f(int) {
+  return 0;
+}
+
+constexpr int c_i = 0;
+
+int t1 = f(g_i);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{read of non-const variable}}
+int t3 = f(c_i);
+
+constexpr int f_c(int i) {
+// expected-note@-1 {{declared here}}
+  int t = f(i);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{read of non-const variable}}
+  return f(0);  
+}
+
+consteval int f_eval(int i) {
+  return f(i);
+}
+
+auto l0 = [](int i) consteval {
+  return f(i);
+};
+
+auto l1 = [](int i) constexpr {
+// expected-note@-1 {{declared here}}
+  int t = f(i);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{read of non-const variable}}
+  return f(0);  
+};
+
+}
+
+namespace cleanup {
+
+struct A {
+ 

[PATCH] D63640: [clang] Improve Serialization/Imporing/Dumping of APValues

2019-10-14 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

ping @rsmith


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

https://reviews.llvm.org/D63640



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


[PATCH] D63960: [C++20] Add consteval-specific semantic for functions

2019-10-17 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

The now that constexpr destructors are legal. The code in this patch need to be 
adapted, I have question about the following code.

  struct A {
constexpr ~A() {}
  };
  
  consteval A f() {
  return A{};
  }
  
  void test() {
  A a;
  a = f(); // <-- here
  }

At the point i marked.
The invocation of f causes an immediate invocation 
(http://eel.is/c++draft/expr.const#12).
Immediate invocation are full expression 
(http://eel.is/c++draft/intro.execution#5).
Full expression resolve all there side-effects before evaluating the next full 
expression (http://eel.is/c++draft/intro.execution#9).
The return value of f() is created inside the immediate invocation.
So the destructor of the value returned by f() should be destroyed within the 
immediate evaluation.
But that value is needed for the assignment operator.
This seem contradictory. What have i misunderstood ? What should happen here ?


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

https://reviews.llvm.org/D63960



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


[PATCH] D63960: [C++20] Add consteval-specific semantic for functions

2019-10-18 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

ping @rsmith


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

https://reviews.llvm.org/D63960



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


[PATCH] D63640: [clang] Improve Serialization/Imporing/Dumping of APValues

2019-10-23 Thread Tyker via Phabricator via cfe-commits
Tyker marked an inline comment as done.
Tyker added inline comments.



Comment at: clang/lib/Serialization/ASTReader.cpp:9635
+if (IsExpr) {
+  Base = APValue::LValueBase(ReadExpr(F), CallIndex, Version);
+  ElemTy = Base.get()->getType();

Tyker wrote:
> rsmith wrote:
> > This is problematic.
> > 
> > `ReadExpr` will read a new copy of the expression, creating a distinct 
> > object. But in the case where we reach this when deserializing (for a 
> > `MaterializeTemporaryExpr`), we need to refer to the existing 
> > `MaterializeTemporaryExpr` in the initializer of its lifetime-extending 
> > declaration. We will also need to serialize the `ASTContext`'s 
> > `MaterializedTemporaryValues` collection so that the temporaries 
> > lifetime-extended in a constant initializer get properly handled.
> > 
> > That all sounds very messy, so I think we should reconsider the model that 
> > we use for lifetime-extended materialized temporaries. As a half-baked idea:
> > 
> >  * When we lifetime-extend a temporary, create a 
> > `MaterializedTemporaryDecl` to hold its value, and modify 
> > `MaterializeTemporaryExpr` to refer to the `MaterializedTemporaryDecl` 
> > rather than to just hold the subexpression for the temporary.
> >  * Change the `LValueBase` representation to denote the declaration rather 
> > than the expression.
> >  * Store the constant evaluated value for a materialized temporary on the 
> > `MaterializedTemporaryDecl` rather than on a side-table in the `ASTContext`.
> > 
> > With that done, we should verify that all remaining `Expr*`s used as 
> > `LValueBase`s are either only transiently used during evaluation or don't 
> > have these kinds of identity problems.
> Would it be possible to adapt serialization/deserialization so that they make 
> sure that `MaterializeTemporaryExpr` are unique.
> by:
> 
>   - When serializing `MaterializeTemporaryExpr` serialize a key obtained from 
> the pointer to the expression as it is unique.
>   - When deserializing `MaterializeTemporaryExpr` deserializing the key, and 
> than have a cache for previously deserialized expression that need to be 
> unique.
> 
> This would make easier adding new `Expr` that require uniqueness and seem 
> less complicated.
> What do you think ?
i added a review that does the refactoring https://reviews.llvm.org/D69360.


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

https://reviews.llvm.org/D63640



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


[PATCH] D69360: [NFC] Refactor representation of materialized temporaries

2019-10-23 Thread Tyker via Phabricator via cfe-commits
Tyker created this revision.
Tyker added a reviewer: rsmith.
Herald added a reviewer: martong.
Herald added subscribers: cfe-commits, arphaman.
Herald added a reviewer: shafik.
Herald added a project: clang.

this patch refactor representation of materialized temporaries to prevent an 
issue raised by rsmith in https://reviews.llvm.org/D63640#inline-612718


Repository:
  rC Clang

https://reviews.llvm.org/D69360

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/DeclNodes.td
  clang/include/clang/Sema/Template.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/DeclBase.cpp
  clang/lib/AST/DeclCXX.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Serialization/ASTCommon.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterDecl.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/tools/libclang/CIndex.cpp

Index: clang/tools/libclang/CIndex.cpp
===
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -6299,6 +6299,7 @@
   case Decl::PragmaDetectMismatch:
   case Decl::UsingPack:
   case Decl::Concept:
+  case Decl::MaterializeTemporary:
 return C;
 
   // Declaration kinds that don't make any sense here, but are
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1835,9 +1835,11 @@
 
 void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
   VisitExpr(E);
-  Record.AddStmt(E->getTemporary());
-  Record.AddDeclRef(E->getExtendingDecl());
-  Record.push_back(E->getManglingNumber());
+  Record.push_back(static_cast(E->getMaterializeTemporaryDecl()));
+  if (E->getMaterializeTemporaryDecl())
+Record.AddDeclRef(E->getMaterializeTemporaryDecl());
+  else
+Record.AddStmt(E->getTemporary());
   Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
 }
 
Index: clang/lib/Serialization/ASTWriterDecl.cpp
===
--- clang/lib/Serialization/ASTWriterDecl.cpp
+++ clang/lib/Serialization/ASTWriterDecl.cpp
@@ -124,6 +124,7 @@
 void VisitBlockDecl(BlockDecl *D);
 void VisitCapturedDecl(CapturedDecl *D);
 void VisitEmptyDecl(EmptyDecl *D);
+void VisitMaterializeTemporaryDecl(MaterializeTemporaryDecl* D);
 
 void VisitDeclContext(DeclContext *DC);
 template  void VisitRedeclarable(Redeclarable *D);
@@ -1131,6 +1132,17 @@
   Code = serialization::DECL_EMPTY;
 }
 
+void ASTDeclWriter::VisitMaterializeTemporaryDecl(MaterializeTemporaryDecl *D) {
+  VisitDecl(D);
+  Record.AddDeclRef(D->getExtendingDecl());
+  Record.AddStmt(D->getStmtWithTemporary());
+  Record.push_back(static_cast(D->getValue()));
+  if (D->getValue())
+Record.AddAPValue(*D->getValue());
+  Record.push_back(D->getManglingNumber());
+  Code = serialization::DECL_MATERIALIZE_TEMPORARY;
+}
+
 void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
   VisitDecl(D);
   Record.AddStmt(D->getBody());
Index: clang/lib/Serialization/ASTReaderStmt.cpp
===
--- clang/lib/Serialization/ASTReaderStmt.cpp
+++ clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1900,10 +1900,11 @@
 
 void ASTStmtReader::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
   VisitExpr(E);
-  E->State = Record.readSubExpr();
-  auto *VD = ReadDeclAs();
-  unsigned ManglingNumber = Record.readInt();
-  E->setExtendingDecl(VD, ManglingNumber);
+  bool HasMaterialzedDecl = Record.readInt();
+  if (HasMaterialzedDecl)
+E->State = ReadDeclAs();
+  else
+E->State = Record.readSubExpr();
 }
 
 void ASTStmtReader::VisitCXXFoldExpr(CXXFoldExpr *E) {
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -405,6 +405,7 @@
 void VisitBlockDecl(BlockDecl *BD);
 void VisitCapturedDecl(CapturedDecl *CD);
 void VisitEmptyDecl(EmptyDecl *D);
+void VisitMaterializeTemporaryDecl(MaterializeTemporaryDecl* D);
 
 std::pair VisitDeclContext(DeclContext *DC);
 
@@ -2346,6 +2347,15 @@
   VisitDecl(D);
 }
 
+void ASTDeclReader::VisitMaterializeTemporaryDecl(MaterializeTemporaryDecl* D) {
+  VisitDecl(D);
+  D->ExtendingDecl = ReadDeclAs();
+  D->StmtWithTemporary = Record.readStmt();
+  if (Record.readInt())
+D->Value = new (D->getASTContext()) APValue(Record.readAPValue());
+  D->ManglingNumber = Record.readInt();
+}
+
 

[PATCH] D63960: [C++20] Add consteval-specific semantic for functions

2019-10-25 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

ping @rsmith


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

https://reviews.llvm.org/D63960



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


[PATCH] D71739: [AssumeBundles] Use operand bundles to encode alignment assumptions

2020-05-22 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

In D71739#2048409 , @rjmccall wrote:

> Is there a good reason for this to use the same `llvm.assume` intrinsic as 
> before?


thee hasn't been any discussion i am aware of on this topic.
but personally i think keeping the same intrinsic makes sens because it 
logically expresses an assumption hence `assume` is a good name.
and most passes don't need to treat classic assumes differently from assume 
with operand bundles.

> Are there restrictions about what assumptions can be combined on a single 
> intrinsic call?  There can only be one bundle of a particular name on an 
> instruction, right?

there is any IR legality restriction about what combination or number of 
bundles can be present in an assume. however there is restrictions about 
argument of a given bundle.
having a single "align" bundle is just how the front-end used assume bundles 
for its alignment assumptions.

for example:
to salvage a store like 
`store i8 0, i8* %P, align 1`
we could generate
`call void @llvm.assume(i1 true) [ "dereferenceable"(i8* %P, i64 1), 
"nonnull"(i8* %P) ]`




Comment at: llvm/lib/Analysis/AssumeBundleQueries.cpp:104
+return 1;
+  };
   if (BOI.End - BOI.Begin > ABA_Argument)

jdoerfert wrote:
> I think this is a problem for things like `deref` which should default to 0?
currently only Alignment can have a non constant argument. but yes this will 
change if we support non-constant integer for deref.

the verifier has been updated this way, but i added an assert to make it clear.



Comment at: llvm/lib/Analysis/AssumeBundleQueries.cpp:110
+if (BOI.End - BOI.Begin > ABA_Argument + 1)
+  Result.ArgValue = MinAlign(Result.ArgValue, GetArgOr1(1));
   return Result;

jdoerfert wrote:
> Is this the min of the alignment and offset? If so, I'm not sure about min. 
> Either way, can you clang format this and add a comment why alignment is 
> special and how it looks?
> Is this the min of the alignment and offset?
Yes
> If so, I'm not sure about min
the objective of this is to make sure that getKnowledgeFromBundle doesn't 
misinterpret the contents of a bundles with a non-zero offset.
the description of MinAlign seems to match with what i needed
```
/// A and B are either alignments or offsets. Return the minimum alignment that
/// may be assumed after adding the two together.
```
the results seems to be correct aswell.



Comment at: llvm/lib/IR/Verifier.cpp:4418
+if (ArgCount == 3)
+  Assert(Call.getOperand(Elem.Begin + 2)->getType()->isIntegerTy(), 
"third argument should be an integer if present");
+return;

rjmccall wrote:
> Should the alignment and offset be restricted to constants and given value 
> restrictions?
the system operand bundles are replacing could deal with non-constant indexes 
and offsets
so i adapted alignment assume bundles to handle non-constant arguments.



Comment at: llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp:273
+  if (!isValidAssumeForContext(ACall, J, DT))
+continue;
   Align NewDestAlignment =

jdoerfert wrote:
> I'm curious, why was this needed? 
this code is part of the from the previous version of the patch, i left it 
untouched because it seemed to work as intended.

changes in this function seem to have no impact on the resulting behavior. and 
could be removed.



Comment at: llvm/test/Transforms/InstCombine/assume.ll:380
 ; CHECK-NEXT:[[CMP2:%.*]] = icmp ne i8 [[X:%.*]], 0
+; CHECK-NEXT:tail call void @llvm.assume(i1 false)
 ; CHECK-NEXT:tail call void @llvm.dbg.value(metadata i32 5, metadata !7, 
metadata !DIExpression()), !dbg !9

jdoerfert wrote:
> Can you add the "beginning" of the operand bundles here so it becomes clear 
> we do not have a no-op assume.
i don't think `call void @llvm.assume(i1 false)` is no-op since it exhibits UB. 
but it is redundant.
anyway this has been split of to an other patch.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71739



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


[PATCH] D71739: [WIP] Use operand bundles to encode alignment assumptions

2020-04-05 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

In D71739#1961508 , @jdoerfert wrote:

> @lebedev.ri  We'd need to identify other uses of the alignment encoding 
> in-tree so we can replace them as well. Also, this patch uses not only the 
> alignment but also the offset in the operand bundle. We can either allow that 
> or encode the offset via a gep in the IR. I guess the latter is easier to 
> implement until we have more reasons to allow more complex operand bundles 
> (which we will need to have eventually).


for now i think we will stay with the current "simple" alignment assumptions in 
operand bundles. but we can improve it later.

> @Tyker Do you want to take this?

i am fine with taking this. but there is a few thing to do before this.

i think that this patch depends on a few things:

- add an API to build assumes from provided knowledge.
- update users of alignment assumptions.

and a few things that i would like to do before:

- finish patches currently in review.
- improve generation of assume with operand bundles to minimize duplicates and 
extra instructions.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71739



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


[PATCH] D76420: Prevent IR-gen from emitting consteval declarations

2020-06-15 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG3bab88b7baa2: Prevent IR-gen from emitting consteval 
declarations (authored by Tyker).

Changed prior to commit:
  https://reviews.llvm.org/D76420?vs=264238&id=270685#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76420

Files:
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGExprAgg.cpp
  clang/lib/CodeGen/CGExprComplex.cpp
  clang/lib/CodeGen/CGExprConstant.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/ConstantEmitter.h
  clang/lib/Sema/SemaExpr.cpp
  clang/test/CodeGenCXX/cxx2a-consteval.cpp
  clang/test/SemaCXX/cxx2a-consteval.cpp

Index: clang/test/SemaCXX/cxx2a-consteval.cpp
===
--- clang/test/SemaCXX/cxx2a-consteval.cpp
+++ clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++2a -fsyntax-only -Wno-unused-value %s -verify
+// RUN: %clang_cc1 -std=c++2a -emit-llvm-only -Wno-unused-value %s -verify
 
 typedef __SIZE_TYPE__ size_t;
 
Index: clang/test/CodeGenCXX/cxx2a-consteval.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/cxx2a-consteval.cpp
@@ -0,0 +1,210 @@
+// NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+// RUN: %clang_cc1 -emit-llvm %s -std=c++2a -o %t.ll
+// RUN: FileCheck -check-prefix=EVAL -input-file=%t.ll %s
+// RUN: FileCheck -check-prefix=EVAL-FN -input-file=%t.ll %s
+// RUN: FileCheck -check-prefix=EVAL-STATIC -input-file=%t.ll %s
+// RUN: %clang_cc1 -emit-llvm %s -Dconsteval="" -std=c++2a -o %t.ll
+// RUN: FileCheck -check-prefix=EXPR -input-file=%t.ll %s
+
+// there is two version of symbol checks to ensure
+// that the symbol we are looking for are correct
+// EVAL-NOT: @__cxx_global_var_init()
+// EXPR: @__cxx_global_var_init()
+
+// EVAL-NOT: @_Z4ret7v()
+// EXPR: @_Z4ret7v()
+consteval int ret7() {
+  return 7;
+}
+
+int test_ret7() {
+  // EVAL-FN-LABEL: @_Z9test_ret7v(
+  // EVAL-FN-NEXT:  entry:
+  // EVAL-FN-NEXT:[[I:%.*]] = alloca i32, align 4
+  // EVAL-FN-NEXT:store i32 7, i32* [[I]], align 4
+  // EVAL-FN-NEXT:[[TMP0:%.*]] = load i32, i32* [[I]], align 4
+  // EVAL-FN-NEXT:ret i32 [[TMP0]]
+  //
+  int i = ret7();
+  return i;
+}
+
+// EVAL-STATIC: @global_i = global i32 7, align 4
+int global_i = ret7();
+
+// EVAL-STATIC: @_ZL7i_const = internal constant i32 5, align 4
+constexpr int i_const = 5;
+
+// EVAL-NOT: @_Z4retIv()
+// EXPR: @_Z4retIv()
+consteval const int &retI() {
+  return i_const;
+}
+
+const int &test_retRefI() {
+  // EVAL-FN-LABEL: @_Z12test_retRefIv(
+  // EVAL-FN-NEXT:  entry:
+  // EVAL-FN-NEXT:ret i32* @_ZL7i_const
+  //
+  return retI();
+}
+
+int test_retI() {
+  // EVAL-FN-LABEL: @_Z9test_retIv(
+  // EVAL-FN-NEXT:  entry:
+  // EVAL-FN-NEXT:[[TMP0:%.*]] = load i32, i32* @_ZL7i_const, align 4
+  // EVAL-FN-NEXT:ret i32 [[TMP0]]
+  //
+  return retI();
+}
+
+// EVAL-NOT: @_Z4retIv()
+// EXPR: @_Z4retIv()
+consteval const int *retIPtr() {
+  return &i_const;
+}
+
+int test_retIPtr() {
+  // EVAL-FN-LABEL: @_Z12test_retIPtrv(
+  // EVAL-FN-NEXT:  entry:
+  // EVAL-FN-NEXT:[[TMP0:%.*]] = load i32, i32* @_ZL7i_const, align 4
+  // EVAL-FN-NEXT:ret i32 [[TMP0]]
+  //
+  return *retIPtr();
+}
+
+const int *test_retPIPtr() {
+  // EVAL-FN-LABEL: @_Z13test_retPIPtrv(
+  // EVAL-FN-NEXT:  entry:
+  // EVAL-FN-NEXT:ret i32* @_ZL7i_const
+  //
+  return retIPtr();
+}
+
+// EVAL-NOT: @_Z4retIv()
+// EXPR: @_Z4retIv()
+consteval const int &&retIRRef() {
+  return static_cast(i_const);
+}
+
+const int &&test_retIRRef() {
+  return static_cast(retIRRef());
+}
+
+int test_retIRRefI() {
+  // EVAL-FN-LABEL: @_Z14test_retIRRefIv(
+  // EVAL-FN-NEXT:  entry:
+  // EVAL-FN-NEXT:[[TMP0:%.*]] = load i32, i32* @_ZL7i_const, align 4
+  // EVAL-FN-NEXT:ret i32 [[TMP0]]
+  //
+  return retIRRef();
+}
+
+struct Agg {
+  int a;
+  long b;
+};
+
+// EVAL-NOT: @_Z6retAggv()
+// EXPR: @_Z6retAggv()
+consteval Agg retAgg() {
+  return {13, 17};
+}
+
+long test_retAgg() {
+  // EVAL-FN-LABEL: @_Z11test_retAggv(
+  // EVAL-FN-NEXT:  entry:
+  // EVAL-FN-NEXT:[[B:%.*]] = alloca i64, align 8
+  // EVAL-FN-NEXT:[[REF_TMP:%.*]] = alloca [[STRUCT_AGG:%.*]], align 8
+  // EVAL-FN-NEXT:[[TMP0:%.*]] = getelementptr inbounds [[STRUCT_AGG]], %struct.Agg* [[REF_TMP]], i32 0, i32 0
+  // EVAL-FN-NEXT:store i32 13, i32* [[TMP0]], align 8
+  // EVAL-FN-NEXT:[[TMP1:%.*]] = getelementptr inbounds [[STRUCT_AGG]], %struct.Agg* [[REF_TMP]], i32 0, i32 1
+  // EVAL-FN-NEXT:store i64 17, i64* [[TMP1]], align 8
+  // EVAL-FN-NEXT: 

[PATCH] D71739: [AssumeBundles] Use operand bundles to encode alignment assumptions

2020-07-05 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 275550.
Tyker added a comment.

fixed the issue with multiple align in a single assume.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71739

Files:
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/test/CodeGen/align_value.cpp
  clang/test/CodeGen/alloc-align-attr.c
  clang/test/CodeGen/assume-aligned-and-alloc-align-attributes.c
  clang/test/CodeGen/builtin-align-array.c
  clang/test/CodeGen/builtin-align.c
  clang/test/CodeGen/builtin-assume-aligned.c
  
clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-lvalue.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-paramvar.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function.cpp
  
clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params-variable.cpp
  
clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params.cpp
  
clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-two-params.cpp
  clang/test/CodeGen/catch-alignment-assumption-openmp.cpp
  clang/test/CodeGen/non-power-of-2-alignment-assumptions.c
  clang/test/OpenMP/simd_codegen.cpp
  clang/test/OpenMP/simd_metadata.c
  clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp
  llvm/include/llvm/IR/IRBuilder.h
  llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h
  llvm/lib/Analysis/AssumeBundleQueries.cpp
  llvm/lib/IR/IRBuilder.cpp
  llvm/lib/IR/Verifier.cpp
  llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
  llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
  llvm/test/Transforms/AlignmentFromAssumptions/simple.ll
  llvm/test/Transforms/AlignmentFromAssumptions/simple32.ll
  llvm/test/Transforms/Inline/align.ll
  llvm/test/Transforms/InstCombine/assume.ll
  llvm/test/Transforms/PhaseOrdering/inlining-alignment-assumptions.ll
  llvm/test/Verifier/assume-bundles.ll
  llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp

Index: llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp
===
--- llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp
+++ llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp
@@ -546,3 +546,41 @@
   ASSERT_EQ(AR[0].Index, 1u);
   ASSERT_EQ(AR[0].Assume, &*First);
 }
+
+TEST(AssumeQueryAPI, Alignment) {
+  LLVMContext C;
+  SMDiagnostic Err;
+  std::unique_ptr Mod = parseAssemblyString(
+  "declare void @llvm.assume(i1)\n"
+  "define void @test(i32* %P, i32* %P1, i32* %P2, i32 %I3, i1 %B) {\n"
+  "call void @llvm.assume(i1 true) [\"align\"(i32* %P, i32 8, i32 %I3)]\n"
+  "call void @llvm.assume(i1 true) [\"align\"(i32* %P1, i32 %I3, i32 "
+  "%I3)]\n"
+  "call void @llvm.assume(i1 true) [\"align\"(i32* %P2, i32 16, i32 8)]\n"
+  "ret void\n}\n",
+  Err, C);
+  if (!Mod)
+Err.print("AssumeQueryAPI", errs());
+
+  Function *F = Mod->getFunction("test");
+  BasicBlock::iterator Start = F->begin()->begin();
+  IntrinsicInst *II;
+  RetainedKnowledge RK;
+  II = cast(&*Start);
+  RK = getKnowledgeFromBundle(*II, II->bundle_op_info_begin()[0]);
+  ASSERT_EQ(RK.AttrKind, Attribute::Alignment);
+  ASSERT_EQ(RK.WasOn, F->getArg(0));
+  ASSERT_EQ(RK.ArgValue, 1u);
+  Start++;
+  II = cast(&*Start);
+  RK = getKnowledgeFromBundle(*II, II->bundle_op_info_begin()[0]);
+  ASSERT_EQ(RK.AttrKind, Attribute::Alignment);
+  ASSERT_EQ(RK.WasOn, F->getArg(1));
+  ASSERT_EQ(RK.ArgValue, 1u);
+  Start++;
+  II = cast(&*Start);
+  RK = getKnowledgeFromBundle(*II, II->bundle_op_info_begin()[0]);
+  ASSERT_EQ(RK.AttrKind, Attribute::Alignment);
+  ASSERT_EQ(RK.WasOn, F->getArg(2));
+  ASSERT_EQ(RK.ArgValue, 8u);
+}
Index: llvm/test/Verifier/assume-bundles.ll
===
--- llvm/test/Verifier/assume-bundles.ll
+++ llvm/test/Verifier/assume-bundles.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: not opt -verify < %s 2>&1 | FileCheck %s
 
 declare void @llvm.assume(i1)
@@ -6,14 +7,21 @@
 ; CHECK: tags must be valid attribute names
   call void @llvm.assume(i1 true) ["adazdazd"()]
 ; CHECK: the second argument should be a constant integral value
-  call void @llvm.assume(i1 true) ["align"(i32* %P, i32 %P1)]
+  call void @llvm.assume(i1 true) ["dereferenceable"(i32* %P, i32 %P1)]
 ; CHECK: to many arguments
-  call void @llvm.assume(i1 true) ["align"(i32* %P, i32 8, i32 8)]
+  call void @llvm.assume(i1 true) ["dereferenceable"(i32* %P, i32 8, i32 8)]
 ; CHECK: this attribute should have 2 arguments
-  call void @llvm.assume(i1 true

[PATCH] D71739: [AssumeBundles] Use operand bundles to encode alignment assumptions

2020-07-08 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 276498.
Tyker added a comment.

addressed commemt.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71739

Files:
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/test/CodeGen/align_value.cpp
  clang/test/CodeGen/alloc-align-attr.c
  clang/test/CodeGen/assume-aligned-and-alloc-align-attributes.c
  clang/test/CodeGen/builtin-align-array.c
  clang/test/CodeGen/builtin-align.c
  clang/test/CodeGen/builtin-assume-aligned.c
  
clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-lvalue.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-paramvar.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function.cpp
  
clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params-variable.cpp
  
clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params.cpp
  
clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-two-params.cpp
  clang/test/CodeGen/catch-alignment-assumption-openmp.cpp
  clang/test/CodeGen/non-power-of-2-alignment-assumptions.c
  clang/test/OpenMP/simd_codegen.cpp
  clang/test/OpenMP/simd_metadata.c
  clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp
  llvm/include/llvm/IR/IRBuilder.h
  llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h
  llvm/lib/Analysis/AssumeBundleQueries.cpp
  llvm/lib/IR/IRBuilder.cpp
  llvm/lib/IR/Verifier.cpp
  llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
  llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
  llvm/test/Transforms/AlignmentFromAssumptions/simple.ll
  llvm/test/Transforms/AlignmentFromAssumptions/simple32.ll
  llvm/test/Transforms/Inline/align.ll
  llvm/test/Transforms/InstCombine/assume.ll
  llvm/test/Transforms/PhaseOrdering/inlining-alignment-assumptions.ll
  llvm/test/Verifier/assume-bundles.ll
  llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp

Index: llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp
===
--- llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp
+++ llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp
@@ -546,3 +546,41 @@
   ASSERT_EQ(AR[0].Index, 1u);
   ASSERT_EQ(AR[0].Assume, &*First);
 }
+
+TEST(AssumeQueryAPI, Alignment) {
+  LLVMContext C;
+  SMDiagnostic Err;
+  std::unique_ptr Mod = parseAssemblyString(
+  "declare void @llvm.assume(i1)\n"
+  "define void @test(i32* %P, i32* %P1, i32* %P2, i32 %I3, i1 %B) {\n"
+  "call void @llvm.assume(i1 true) [\"align\"(i32* %P, i32 8, i32 %I3)]\n"
+  "call void @llvm.assume(i1 true) [\"align\"(i32* %P1, i32 %I3, i32 "
+  "%I3)]\n"
+  "call void @llvm.assume(i1 true) [\"align\"(i32* %P2, i32 16, i32 8)]\n"
+  "ret void\n}\n",
+  Err, C);
+  if (!Mod)
+Err.print("AssumeQueryAPI", errs());
+
+  Function *F = Mod->getFunction("test");
+  BasicBlock::iterator Start = F->begin()->begin();
+  IntrinsicInst *II;
+  RetainedKnowledge RK;
+  II = cast(&*Start);
+  RK = getKnowledgeFromBundle(*II, II->bundle_op_info_begin()[0]);
+  ASSERT_EQ(RK.AttrKind, Attribute::Alignment);
+  ASSERT_EQ(RK.WasOn, F->getArg(0));
+  ASSERT_EQ(RK.ArgValue, 1u);
+  Start++;
+  II = cast(&*Start);
+  RK = getKnowledgeFromBundle(*II, II->bundle_op_info_begin()[0]);
+  ASSERT_EQ(RK.AttrKind, Attribute::Alignment);
+  ASSERT_EQ(RK.WasOn, F->getArg(1));
+  ASSERT_EQ(RK.ArgValue, 1u);
+  Start++;
+  II = cast(&*Start);
+  RK = getKnowledgeFromBundle(*II, II->bundle_op_info_begin()[0]);
+  ASSERT_EQ(RK.AttrKind, Attribute::Alignment);
+  ASSERT_EQ(RK.WasOn, F->getArg(2));
+  ASSERT_EQ(RK.ArgValue, 8u);
+}
Index: llvm/test/Verifier/assume-bundles.ll
===
--- llvm/test/Verifier/assume-bundles.ll
+++ llvm/test/Verifier/assume-bundles.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: not opt -verify < %s 2>&1 | FileCheck %s
 
 declare void @llvm.assume(i1)
@@ -6,14 +7,21 @@
 ; CHECK: tags must be valid attribute names
   call void @llvm.assume(i1 true) ["adazdazd"()]
 ; CHECK: the second argument should be a constant integral value
-  call void @llvm.assume(i1 true) ["align"(i32* %P, i32 %P1)]
+  call void @llvm.assume(i1 true) ["dereferenceable"(i32* %P, i32 %P1)]
 ; CHECK: to many arguments
-  call void @llvm.assume(i1 true) ["align"(i32* %P, i32 8, i32 8)]
+  call void @llvm.assume(i1 true) ["dereferenceable"(i32* %P, i32 8, i32 8)]
 ; CHECK: this attribute should have 2 arguments
-  call void @llvm.assume(i1 true) ["align"(i32* %P)]
+  call void @ll

[PATCH] D71739: [AssumeBundles] Use operand bundles to encode alignment assumptions

2020-07-08 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 276500.
Tyker added a comment.

fixed


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71739

Files:
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/test/CodeGen/align_value.cpp
  clang/test/CodeGen/alloc-align-attr.c
  clang/test/CodeGen/assume-aligned-and-alloc-align-attributes.c
  clang/test/CodeGen/builtin-align-array.c
  clang/test/CodeGen/builtin-align.c
  clang/test/CodeGen/builtin-assume-aligned.c
  
clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-lvalue.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-paramvar.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function.cpp
  
clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params-variable.cpp
  
clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params.cpp
  
clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-two-params.cpp
  clang/test/CodeGen/catch-alignment-assumption-openmp.cpp
  clang/test/CodeGen/non-power-of-2-alignment-assumptions.c
  clang/test/OpenMP/simd_codegen.cpp
  clang/test/OpenMP/simd_metadata.c
  clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp
  llvm/include/llvm/IR/IRBuilder.h
  llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h
  llvm/lib/Analysis/AssumeBundleQueries.cpp
  llvm/lib/IR/IRBuilder.cpp
  llvm/lib/IR/Verifier.cpp
  llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
  llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
  llvm/test/Transforms/AlignmentFromAssumptions/simple.ll
  llvm/test/Transforms/AlignmentFromAssumptions/simple32.ll
  llvm/test/Transforms/Inline/align.ll
  llvm/test/Transforms/InstCombine/assume.ll
  llvm/test/Transforms/PhaseOrdering/inlining-alignment-assumptions.ll
  llvm/test/Verifier/assume-bundles.ll
  llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp

Index: llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp
===
--- llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp
+++ llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp
@@ -546,3 +546,41 @@
   ASSERT_EQ(AR[0].Index, 1u);
   ASSERT_EQ(AR[0].Assume, &*First);
 }
+
+TEST(AssumeQueryAPI, Alignment) {
+  LLVMContext C;
+  SMDiagnostic Err;
+  std::unique_ptr Mod = parseAssemblyString(
+  "declare void @llvm.assume(i1)\n"
+  "define void @test(i32* %P, i32* %P1, i32* %P2, i32 %I3, i1 %B) {\n"
+  "call void @llvm.assume(i1 true) [\"align\"(i32* %P, i32 8, i32 %I3)]\n"
+  "call void @llvm.assume(i1 true) [\"align\"(i32* %P1, i32 %I3, i32 "
+  "%I3)]\n"
+  "call void @llvm.assume(i1 true) [\"align\"(i32* %P2, i32 16, i32 8)]\n"
+  "ret void\n}\n",
+  Err, C);
+  if (!Mod)
+Err.print("AssumeQueryAPI", errs());
+
+  Function *F = Mod->getFunction("test");
+  BasicBlock::iterator Start = F->begin()->begin();
+  IntrinsicInst *II;
+  RetainedKnowledge RK;
+  II = cast(&*Start);
+  RK = getKnowledgeFromBundle(*II, II->bundle_op_info_begin()[0]);
+  ASSERT_EQ(RK.AttrKind, Attribute::Alignment);
+  ASSERT_EQ(RK.WasOn, F->getArg(0));
+  ASSERT_EQ(RK.ArgValue, 1u);
+  Start++;
+  II = cast(&*Start);
+  RK = getKnowledgeFromBundle(*II, II->bundle_op_info_begin()[0]);
+  ASSERT_EQ(RK.AttrKind, Attribute::Alignment);
+  ASSERT_EQ(RK.WasOn, F->getArg(1));
+  ASSERT_EQ(RK.ArgValue, 1u);
+  Start++;
+  II = cast(&*Start);
+  RK = getKnowledgeFromBundle(*II, II->bundle_op_info_begin()[0]);
+  ASSERT_EQ(RK.AttrKind, Attribute::Alignment);
+  ASSERT_EQ(RK.WasOn, F->getArg(2));
+  ASSERT_EQ(RK.ArgValue, 8u);
+}
Index: llvm/test/Verifier/assume-bundles.ll
===
--- llvm/test/Verifier/assume-bundles.ll
+++ llvm/test/Verifier/assume-bundles.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: not opt -verify < %s 2>&1 | FileCheck %s
 
 declare void @llvm.assume(i1)
@@ -6,14 +7,21 @@
 ; CHECK: tags must be valid attribute names
   call void @llvm.assume(i1 true) ["adazdazd"()]
 ; CHECK: the second argument should be a constant integral value
-  call void @llvm.assume(i1 true) ["align"(i32* %P, i32 %P1)]
+  call void @llvm.assume(i1 true) ["dereferenceable"(i32* %P, i32 %P1)]
 ; CHECK: to many arguments
-  call void @llvm.assume(i1 true) ["align"(i32* %P, i32 8, i32 8)]
+  call void @llvm.assume(i1 true) ["dereferenceable"(i32* %P, i32 8, i32 8)]
 ; CHECK: this attribute should have 2 arguments
-  call void @llvm.assume(i1 true) ["align"(i32* %P)]
+  call void @llvm.assume(i1 

[PATCH] D71739: [AssumeBundles] Use operand bundles to encode alignment assumptions

2020-07-13 Thread Tyker via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rG8d09f20798ac: [AssumeBundles] Use operand bundles to encode 
alignment assumptions (authored by Tyker).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71739

Files:
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/test/CodeGen/align_value.cpp
  clang/test/CodeGen/alloc-align-attr.c
  clang/test/CodeGen/assume-aligned-and-alloc-align-attributes.c
  clang/test/CodeGen/builtin-align-array.c
  clang/test/CodeGen/builtin-align.c
  clang/test/CodeGen/builtin-assume-aligned.c
  
clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-lvalue.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-align_value-on-paramvar.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function-variable.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-alloc_align-on-function.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp
  
clang/test/CodeGen/catch-alignment-assumption-attribute-assume_aligned-on-function.cpp
  
clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params-variable.cpp
  
clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params.cpp
  
clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-two-params.cpp
  clang/test/CodeGen/catch-alignment-assumption-openmp.cpp
  clang/test/CodeGen/non-power-of-2-alignment-assumptions.c
  clang/test/OpenMP/simd_codegen.cpp
  clang/test/OpenMP/simd_metadata.c
  clang/test/OpenMP/target_teams_distribute_parallel_for_simd_codegen.cpp
  llvm/include/llvm/IR/IRBuilder.h
  llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h
  llvm/lib/Analysis/AssumeBundleQueries.cpp
  llvm/lib/IR/IRBuilder.cpp
  llvm/lib/IR/Verifier.cpp
  llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
  llvm/lib/Transforms/Scalar/AlignmentFromAssumptions.cpp
  llvm/test/Transforms/AlignmentFromAssumptions/simple.ll
  llvm/test/Transforms/AlignmentFromAssumptions/simple32.ll
  llvm/test/Transforms/Inline/align.ll
  llvm/test/Transforms/InstCombine/assume.ll
  llvm/test/Transforms/PhaseOrdering/inlining-alignment-assumptions.ll
  llvm/test/Verifier/assume-bundles.ll
  llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp

Index: llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp
===
--- llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp
+++ llvm/unittests/Analysis/AssumeBundleQueriesTest.cpp
@@ -546,3 +546,41 @@
   ASSERT_EQ(AR[0].Index, 1u);
   ASSERT_EQ(AR[0].Assume, &*First);
 }
+
+TEST(AssumeQueryAPI, Alignment) {
+  LLVMContext C;
+  SMDiagnostic Err;
+  std::unique_ptr Mod = parseAssemblyString(
+  "declare void @llvm.assume(i1)\n"
+  "define void @test(i32* %P, i32* %P1, i32* %P2, i32 %I3, i1 %B) {\n"
+  "call void @llvm.assume(i1 true) [\"align\"(i32* %P, i32 8, i32 %I3)]\n"
+  "call void @llvm.assume(i1 true) [\"align\"(i32* %P1, i32 %I3, i32 "
+  "%I3)]\n"
+  "call void @llvm.assume(i1 true) [\"align\"(i32* %P2, i32 16, i32 8)]\n"
+  "ret void\n}\n",
+  Err, C);
+  if (!Mod)
+Err.print("AssumeQueryAPI", errs());
+
+  Function *F = Mod->getFunction("test");
+  BasicBlock::iterator Start = F->begin()->begin();
+  IntrinsicInst *II;
+  RetainedKnowledge RK;
+  II = cast(&*Start);
+  RK = getKnowledgeFromBundle(*II, II->bundle_op_info_begin()[0]);
+  ASSERT_EQ(RK.AttrKind, Attribute::Alignment);
+  ASSERT_EQ(RK.WasOn, F->getArg(0));
+  ASSERT_EQ(RK.ArgValue, 1u);
+  Start++;
+  II = cast(&*Start);
+  RK = getKnowledgeFromBundle(*II, II->bundle_op_info_begin()[0]);
+  ASSERT_EQ(RK.AttrKind, Attribute::Alignment);
+  ASSERT_EQ(RK.WasOn, F->getArg(1));
+  ASSERT_EQ(RK.ArgValue, 1u);
+  Start++;
+  II = cast(&*Start);
+  RK = getKnowledgeFromBundle(*II, II->bundle_op_info_begin()[0]);
+  ASSERT_EQ(RK.AttrKind, Attribute::Alignment);
+  ASSERT_EQ(RK.WasOn, F->getArg(2));
+  ASSERT_EQ(RK.ArgValue, 8u);
+}
Index: llvm/test/Verifier/assume-bundles.ll
===
--- llvm/test/Verifier/assume-bundles.ll
+++ llvm/test/Verifier/assume-bundles.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: not opt -verify < %s 2>&1 | FileCheck %s
 
 declare void @llvm.assume(i1)
@@ -6,14 +7,21 @@
 ; CHECK: tags must be valid attribute names
   call void @llvm.assume(i1 true) ["adazdazd"()]
 ; CHECK: the second argument should be a constant integral value
-  call void @llvm.assume(i1 true) ["align"(i32* %P, i32 %P1)]
+  call void @llvm.assume(i1 true) ["dereferenceable"(i32* %P, i32 %P1)]
 ; CHECK: to many arguments
-  call void @llvm.assume(i1 true) ["align"(i32* %P, i32 8, i32 8)]
+  ca

  1   2   3   >