[PATCH] D114439: [Annotation] Allow parameter pack expansions in annotate attribute

2021-11-23 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

This seems like a good change to me. but i don't think my approval is enough


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D114439

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


[PATCH] D74130: [clang] fix consteval call in default arguments

2021-10-27 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/lib/Parse/ParseDecl.cpp:2393
 
   InitScope.pop();
 

aaron.ballman wrote:
> Is there a reason we're not moving this one to below 
> `AddInititializerToDecl()` as we did elsewhere?
yes, It was causing a few test failures, i didn't investigate much further.


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

https://reviews.llvm.org/D74130

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


[PATCH] D74130: [clang] fix consteval call in default arguments

2021-10-27 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 382702.
Tyker added a comment.

In D74130#3085313 , @aaron.ballman 
wrote:

> FWIW, I am not seeing double errors on that code. Here's the output I get 
> with this patch applied locally:
>
>   F:\source\llvm-project>cat "C:\Users\aballman\OneDrive - Intel 
> Corporation\Desktop\test.cpp"
>   consteval int f1() { return 0; }
>   consteval auto g() { return f1; }
>   
>   constexpr auto e = g();
>   constexpr auto e1 = f1;
>   
>   F:\source\llvm-project>llvm\out\build\x64-Debug\bin\clang.exe -fsyntax-only 
> -std=c++2b "C:\Users\aballman\OneDrive - Intel Corporation\Desktop\test.cpp"
>   C:\Users\aballman\OneDrive - Intel Corporation\Desktop\test.cpp:4:20: 
> error: call to consteval function 'g' is not a
> constant expression
>   constexpr auto e = g();
>  ^
>   C:\Users\aballman\OneDrive - Intel Corporation\Desktop\test.cpp:4:20: note: 
> pointer to a consteval declaration is not a
> constant expression
>   C:\Users\aballman\OneDrive - Intel Corporation\Desktop\test.cpp:1:15: note: 
> declared here
>   consteval int f1() { return 0; }
> ^
>   C:\Users\aballman\OneDrive - Intel Corporation\Desktop\test.cpp:4:16: 
> error: constexpr variable 'e' must be initialized
> by a constant expression
>   constexpr auto e = g();
>  ^   ~~~
>   C:\Users\aballman\OneDrive - Intel Corporation\Desktop\test.cpp:4:16: note: 
> pointer to a consteval declaration is not a
> constant expression
>   C:\Users\aballman\OneDrive - Intel Corporation\Desktop\test.cpp:1:15: note: 
> declared here
>   consteval int f1() { return 0; }
> ^
>   C:\Users\aballman\OneDrive - Intel Corporation\Desktop\test.cpp:5:21: 
> error: cannot take address of consteval function
> 'f1' outside of an immediate invocation
>   constexpr auto e1 = f1;
>   ^
>   C:\Users\aballman\OneDrive - Intel Corporation\Desktop\test.cpp:1:15: note: 
> declared here
>   consteval int f1() { return 0; }
> ^
>   C:\Users\aballman\OneDrive - Intel Corporation\Desktop\test.cpp:5:16: 
> error: constexpr variable 'e1' must be initialized
> by a constant expression
>   constexpr auto e1 = f1;
>  ^~~
>   C:\Users\aballman\OneDrive - Intel Corporation\Desktop\test.cpp:5:16: note: 
> pointer to a consteval declaration is not a
> constant expression
>   C:\Users\aballman\OneDrive - Intel Corporation\Desktop\test.cpp:1:15: note: 
> declared here
>   consteval int f1() { return 0; }
> ^
>   4 errors generated.
>
> These look like valid errors to me, so am I misunderstanding something? Is 
> the concern that we're emitting `error: constexpr variable '' must 
> be initialized by a constant expression` after we already issued a diagnostic 
> on the same line?

Yes, i think that
`error: constexpr variable '' must be initialized by a constant 
expression` + `call to consteval function '' is not a constant 
expression` or 
`error: constexpr variable '' must be initialized by a constant 
expression` + `cannot take address of consteval function ' outside of 
an immediate invocation`
 is emitting 2 errors for the same root cause. the correct solution in my mind 
would be to swap too constant context when processing the initializer of a 
constexpr (or constinit) variable. this would disable consteval checking.

> From my testing, there's more work to be done, but I think it can be done in 
> a follow-up. Consider:
>
>   template 
>   struct S {
> consteval S() = default;
> Ty Val;
>   };
>   
>   struct foo {
> foo();
>   };
>   
>   S s1; // Correctly rejected
>   S s2; // Incorrectly accepted
>
> With this patch applied, `s1` is correctly diagnosed, but `s2` is not. The 
> reason it's not is because `Sema::CheckForImmediateInvocation()` tests 
> `!Decl->isConsteval()` to early return, and for the instantiation of 
> `S`, the constructor is marked as "unspecified" rather than `consteval`. 
> The reason for that is because we set 
> `DefaultedDefaultConstructorIsConstexpr` to false at 
> https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/DeclCXX.cpp#L1309
>  when instantiating the class. I think we may have some confusion where we 
> mean "*IsConstexpr" to mean "is a constexpr function" or "is usable as a 
> constexpr function", because my reading of 
> https://eel.is/c++draft/dcl.constexpr#7 is that the instantiated template 
> constructor IS a constexpr function but it is not usable in a constant 
> expression. However, that might be orthogonal to the fixes here and should be 
> done separately.

having a function that is explicitly specified consteval not returning true for 
isConsteval seems wrong.

IsConstexpr means the function has a either a consteval or constexpr(maybe 
implicit) specifier.
so i guess that "is a constexpr function" would be isConstexprSpecified
and "is usable as a constexpr 

[PATCH] D74130: [clang] fix consteval call in default arguments

2021-10-21 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 381416.
Tyker added a comment.

In D74130#3073271 , @aaron.ballman 
wrote:

> @Tyker -- are you planning to pick this review back up again sometime in the 
> near future? If not, do you care if the review gets commandeered?

here is an update that i think is close to committable. if it is not i am fine 
if it gets commandeered.

Changes

- rebased
- fix the default parameter situation for functions and lambdas.
- fix the top level variables not being properly checked.

the double errors are not fixed on code like:

  consteval int f1() { return 0; }
  consteval auto g() { return f1; }
  
  constexpr auto e = g();
  constexpr auto e1 = f1;


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

https://reviews.llvm.org/D74130

Files:
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/ScopeInfo.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaExpr.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
@@ -258,6 +258,26 @@
   return f(0);  
 };
 
+consteval int f1() {
+// expected-note@-1+ {{declared here}}
+  return 0;
+}
+consteval auto g() { return f1; }
+consteval int h(int (*p)() = g()) { return p(); }
+int h1(int (*p)() = g()) { return p(); }
+// expected-error@-1 {{is not a constant expression}}
+// expected-note@-2 {{pointer to a consteval}}
+
+// FIXME: These 2 cases generate 2 errors instead of just 1.
+// constexpr auto e = g();
+// constexpr auto e1 = f1;
+
+auto l = [](int (*p)() = g()) { return p(); };
+// expected-error@-1 {{is not a constant expression}}
+// expected-note@-2 {{pointer to a consteval}}
+
+auto l2 = [](int (*p)() = g()) consteval { return p(); };
+
 }
 
 namespace std {
@@ -643,3 +663,22 @@
 // Show that we reject when not in an immediate context.
 int w2 = (a.*::f)(); // expected-error {{cannot take address of consteval function 'f' outside of an immediate invocation}}
 }
+
+namespace top_level {
+struct S {
+  consteval S() {}
+  int a;
+// expected-note@-1 {{subobject declared here}}
+};
+
+S s; // expected-error {{is not a constant expression}}
+// expected-note@-1 {{is not initialized}}
+
+struct S1 {
+  consteval S1() {}
+  int a = 0;
+};
+
+S1 s1;
+
+}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -16667,7 +16667,10 @@
   ConstantExpr::getStorageKind(Decl->getReturnType().getTypePtr(),
getASTContext()),
   /*IsImmediateInvocation*/ true);
-  ExprEvalContexts.back().ImmediateInvocationCandidates.emplace_back(Res, 0);
+  if (LambdaScopeInfo *LSI = getCurLambda())
+LSI->ImmediateInvocationCandidates.emplace_back(Res, 0);
+  else
+ExprEvalContexts.back().ImmediateInvocationCandidates.emplace_back(Res, 0);
   return Res;
 }
 
@@ -16700,16 +16703,19 @@
 }
 
 static void RemoveNestedImmediateInvocation(
-Sema , Sema::ExpressionEvaluationContextRecord ,
+Sema ,
+llvm::SmallVectorImpl
+,
+llvm::SmallPtrSetImpl ,
 SmallVector::reverse_iterator It) {
   struct ComplexRemove : TreeTransform {
 using Base = TreeTransform;
 llvm::SmallPtrSetImpl 
-SmallVector 
+SmallVectorImpl 
 SmallVector::reverse_iterator
 CurrentII;
 ComplexRemove(Sema , llvm::SmallPtrSetImpl ,
-  SmallVector ,
+  SmallVectorImpl ,
   SmallVector::reverse_iterator Current)
 : Base(SemaRef), DRSet(DR), IISet(II), CurrentII(Current) {}
@@ -16759,8 +16765,8 @@
   return Res;
 }
 bool AllowSkippingFirstCXXConstructExpr = true;
-  } Transformer(SemaRef, Rec.ReferenceToConsteval,
-Rec.ImmediateInvocationCandidates, It);
+  } Transformer(SemaRef, ReferenceToConsteval, ImmediateInvocationCandidates,
+It);
 
   /// CXXConstructExpr with a single argument are getting skipped by
   /// TreeTransform in some situtation because they could be implicit. This
@@ -16777,33 +16783,35 @@
   It->getPointer()->setSubExpr(Res.get());
 }
 
-static void
-HandleImmediateInvocations(Sema ,
-   Sema::ExpressionEvaluationContextRecord ) {
-  if ((Rec.ImmediateInvocationCandidates.size() == 0 &&
-   Rec.ReferenceToConsteval.size() == 0) ||
-  SemaRef.RebuildingImmediateInvocation)
+void Sema::HandleImmediateInvocations(
+llvm::SmallVectorImpl
+,
+llvm::SmallPtrSetImpl ) {
+  if ((ImmediateInvocationCandidates.size() == 0 &&
+   ReferenceToConsteval.size() == 0) ||
+  RebuildingImmediateInvocation || isUnevaluatedContext())
 return;
 
   /// When we have more then 1 ImmediateInvocationCandidates we 

[PATCH] D88645: [Annotation] Allows annotation to carry some additional constant arguments.

2021-02-13 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

I added the changes to the langref in https://reviews.llvm.org/D96646


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D88645

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


[PATCH] D91239: Update attribute example to fit the new Annotation API

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

I recently made it much easier to create AnnotationAttr in this context with 
https://reviews.llvm.org/rGd093401a2617d3c46aaed9eeaecf877e3ae1a9f1.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D91239

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


[PATCH] D88645: [Annotation] Allows annotation to carry some additional constant arguments.

2020-10-27 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

In D88645#2353152 , @thakis wrote:

> Looks like this broke tests: http://45.33.8.238/linux/31159/step_12.txt
>
> Please take a look, and revert for now if it takes a while to fix.

this is fixed by 4afa077899b 


In D88645#2354196 , @john.brawn wrote:

> This also causes the AnnotateFunctions example to no longer build:
>
>   
> /home/jb/work/llvm-project/clang/examples/AnnotateFunctions/AnnotateFunctions.cpp:
>  In member function ‘virtual bool 
> {anonymous}::AnnotateFunctionsConsumer::HandleTopLevelDecl(clang::DeclGroupRef)’:
>   
> /home/jb/work/llvm-project/clang/examples/AnnotateFunctions/AnnotateFunctions.cpp:36:70:
>  error: no matching function for call to 
> ‘clang::AnnotateAttr::CreateImplicit(clang::ASTContext&, const char [19])’
> "example_annotation"));
> ^
>
> it looks like it needs to be adjusted for the extra variadic arg that the 
> attribute now has.

this is fixed by 2618247c61c 



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D88645

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


[PATCH] D88645: [Annotation] Allows annotation to carry some additional constant arguments.

2020-10-26 Thread Tyker via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGd3205bbca3e0: [Annotation] Allows annotation to carry some 
additional constant arguments. (authored by Tyker).

Changed prior to commit:
  https://reviews.llvm.org/D88645?vs=300213=300608#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D88645

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ParsedAttr.h
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/ast-dump-attr.cpp
  clang/test/CodeGen/annotations-field.c
  clang/test/CodeGen/annotations-global.c
  clang/test/CodeGen/annotations-loc.c
  clang/test/CodeGen/annotations-var.c
  clang/test/CodeGenCXX/attr-annotate.cpp
  clang/test/CodeGenCXX/attr-annotate2.cpp
  clang/test/Misc/pragma-attribute-cxx.cpp
  clang/test/Misc/pragma-attribute-objc.m
  clang/test/Parser/access-spec-attrs.cpp
  clang/test/Parser/objc-implementation-attrs.m
  clang/test/Sema/annotate.c
  clang/test/Sema/pragma-attribute.c
  clang/test/SemaCXX/attr-annotate.cpp
  llvm/include/llvm/IR/Intrinsics.td
  llvm/test/Analysis/CostModel/X86/free-intrinsics.ll
  llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll
  llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
  llvm/test/CodeGen/Generic/ptr-annotate.ll
  llvm/test/Transforms/InstCombine/assume_inevitable.ll

Index: llvm/test/Transforms/InstCombine/assume_inevitable.ll
===
--- llvm/test/Transforms/InstCombine/assume_inevitable.ll
+++ llvm/test/Transforms/InstCombine/assume_inevitable.ll
@@ -15,7 +15,7 @@
 ; CHECK-NEXT:[[DUMMY_EQ:%.*]] = icmp ugt i32 [[LOADRES]], 42
 ; CHECK-NEXT:tail call void @llvm.assume(i1 [[DUMMY_EQ]])
 ; CHECK-NEXT:[[M_I8:%.*]] = bitcast i64* [[M]] to i8*
-; CHECK-NEXT:[[M_A:%.*]] = call i8* @llvm.ptr.annotation.p0i8(i8* nonnull [[M_I8]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i64 0, i64 0), i32 2)
+; CHECK-NEXT:[[M_A:%.*]] = call i8* @llvm.ptr.annotation.p0i8(i8* nonnull [[M_I8]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i64 0, i64 0), i32 2, i8* null)
 ; CHECK-NEXT:[[M_X:%.*]] = bitcast i8* [[M_A]] to i64*
 ; CHECK-NEXT:[[OBJSZ:%.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* [[C:%.*]], i1 false, i1 false, i1 false)
 ; CHECK-NEXT:store i64 [[OBJSZ]], i64* [[M_X]], align 4
@@ -44,7 +44,7 @@
   call void @llvm.lifetime.end.p0i8(i64 1, i8* %dummy)
 
   %m_i8 = bitcast i64* %m to i8*
-  %m_a = call i8* @llvm.ptr.annotation.p0i8(i8* %m_i8, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2)
+  %m_a = call i8* @llvm.ptr.annotation.p0i8(i8* %m_i8, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2, i8* null)
   %m_x = bitcast i8* %m_a to i64*
   %objsz = call i64 @llvm.objectsize.i64.p0i8(i8* %c, i1 false)
   store i64 %objsz, i64* %m_x
@@ -64,7 +64,7 @@
 
 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1)
 declare i32 @llvm.annotation.i32(i32, i8*, i8*, i32)
-declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32)
+declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32, i8*)
 
 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
Index: llvm/test/CodeGen/Generic/ptr-annotate.ll
===
--- llvm/test/CodeGen/Generic/ptr-annotate.ll
+++ llvm/test/CodeGen/Generic/ptr-annotate.ll
@@ -10,9 +10,9 @@
 define void @foo() {
 entry:
   %m = alloca i8, align 4
-  %0 = call i8* @llvm.ptr.annotation.p0i8(i8* %m, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2)
+  %0 = call i8* @llvm.ptr.annotation.p0i8(i8* %m, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2, i8* null)
   store i8 1, i8* %0, align 4
   ret void
 }
 
-declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32) #1
+declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32, i8*) #1
Index: llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
===
--- 

[PATCH] D88645: [Annotation] Allows annotation to carry some additional constant arguments.

2020-10-23 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 300213.
Tyker added a comment.

In D88645#2347731 , @aaron.ballman 
wrote:

> In D88645#2347725 , @Tyker wrote:
>
>> In D88645#2347050 , @aaron.ballman 
>> wrote:
>>
>>> LGTM aside from a request for a comment to be added. Thank you!
>>
>> do you mean an RFC on llvm-dev/cfe-dev ?
>
> Oh gosh no! I just meant I was asking for a comment to be added in 
> SemaDeclAttr.td before you commit. Sorry for the confusion! :-)

Thank for the review.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D88645

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ParsedAttr.h
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/ast-dump-attr.cpp
  clang/test/CodeGen/annotations-field.c
  clang/test/CodeGen/annotations-global.c
  clang/test/CodeGen/annotations-loc.c
  clang/test/CodeGen/annotations-var.c
  clang/test/CodeGenCXX/attr-annotate.cpp
  clang/test/CodeGenCXX/attr-annotate2.cpp
  clang/test/Misc/pragma-attribute-cxx.cpp
  clang/test/Misc/pragma-attribute-objc.m
  clang/test/Parser/access-spec-attrs.cpp
  clang/test/Parser/objc-implementation-attrs.m
  clang/test/Sema/annotate.c
  clang/test/Sema/pragma-attribute.c
  clang/test/SemaCXX/attr-annotate.cpp
  llvm/include/llvm/IR/Intrinsics.td
  llvm/test/Analysis/CostModel/X86/free-intrinsics.ll
  llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll
  llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
  llvm/test/CodeGen/Generic/ptr-annotate.ll
  llvm/test/Transforms/InstCombine/assume_inevitable.ll

Index: llvm/test/Transforms/InstCombine/assume_inevitable.ll
===
--- llvm/test/Transforms/InstCombine/assume_inevitable.ll
+++ llvm/test/Transforms/InstCombine/assume_inevitable.ll
@@ -15,7 +15,7 @@
 ; CHECK-NEXT:[[DUMMY_EQ:%.*]] = icmp ugt i32 [[LOADRES]], 42
 ; CHECK-NEXT:tail call void @llvm.assume(i1 [[DUMMY_EQ]])
 ; CHECK-NEXT:[[M_I8:%.*]] = bitcast i64* [[M]] to i8*
-; CHECK-NEXT:[[M_A:%.*]] = call i8* @llvm.ptr.annotation.p0i8(i8* nonnull [[M_I8]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i64 0, i64 0), i32 2)
+; CHECK-NEXT:[[M_A:%.*]] = call i8* @llvm.ptr.annotation.p0i8(i8* nonnull [[M_I8]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i64 0, i64 0), i32 2, i8* null)
 ; CHECK-NEXT:[[M_X:%.*]] = bitcast i8* [[M_A]] to i64*
 ; CHECK-NEXT:[[OBJSZ:%.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* [[C:%.*]], i1 false, i1 false, i1 false)
 ; CHECK-NEXT:store i64 [[OBJSZ]], i64* [[M_X]], align 4
@@ -44,7 +44,7 @@
   call void @llvm.lifetime.end.p0i8(i64 1, i8* %dummy)
 
   %m_i8 = bitcast i64* %m to i8*
-  %m_a = call i8* @llvm.ptr.annotation.p0i8(i8* %m_i8, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2)
+  %m_a = call i8* @llvm.ptr.annotation.p0i8(i8* %m_i8, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2, i8* null)
   %m_x = bitcast i8* %m_a to i64*
   %objsz = call i64 @llvm.objectsize.i64.p0i8(i8* %c, i1 false)
   store i64 %objsz, i64* %m_x
@@ -64,7 +64,7 @@
 
 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1)
 declare i32 @llvm.annotation.i32(i32, i8*, i8*, i32)
-declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32)
+declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32, i8*)
 
 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
Index: llvm/test/CodeGen/Generic/ptr-annotate.ll
===
--- llvm/test/CodeGen/Generic/ptr-annotate.ll
+++ llvm/test/CodeGen/Generic/ptr-annotate.ll
@@ -10,9 +10,9 @@
 define void @foo() {
 entry:
   %m = alloca i8, align 4
-  %0 = call i8* @llvm.ptr.annotation.p0i8(i8* %m, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2)
+  %0 = call i8* @llvm.ptr.annotation.p0i8(i8* %m, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2, i8* null)
   store i8 1, i8* %0, align 4
   ret void
 }
 
-declare i8* 

[PATCH] D88645: [Annotation] Allows annotation to carry some additional constant arguments.

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

In D88645#2347050 , @aaron.ballman 
wrote:

> LGTM aside from a request for a comment to be added. Thank you!

do you mean an RFC on llvm-dev/cfe-dev ?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D88645

___
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

2020-10-21 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

In D63640#2339917 , @rsmith wrote:

> In D63640#2331779 , @Tyker wrote:
>
>> but the "real" blocker is that the testing depends on D85144 
>>  for testing.
>> we could land it marking the tests XFAIL and correct it when dumping 
>> improvements arrive.
>
> I'd be OK with that. We'll have coverage for this in various forms landing 
> pretty soon.

i appiled martong's patch and landed it marking the test as XFAIL.


Repository:
  rG LLVM Github Monorepo

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

2020-10-21 Thread Tyker via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGcf34dd0c4e84: [clang] Improve Serialization/Imporing/Dumping 
of APValues (authored by Tyker).

Changed prior to commit:
  https://reviews.llvm.org/D63640?vs=298318=299732#toc

Repository:
  rG LLVM Github Monorepo

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/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.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,462 @@
+// 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
+
+// XFAIL: *
+
+#ifndef EMIT
+#define EMIT
+
+namespace Integer {
+
+consteval int fint() {
+  return 6789;
+}
+
+int Unique_Int = fint();
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int'
+//CHECK-NEXT: value: Int 6789
+
+consteval __uint128_t fint128() {
+  return ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+}
+
+constexpr __uint128_t Unique_Int128 = fint128();
+//CHECK:  VarDecl {{.*}} Unique_Int128
+//CHECK-NEXT: value: Int 156773562844924187900898496343692168785
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Int 156773562844924187900898496343692168785
+
+} // namespace Integer
+
+namespace FloatingPoint {
+
+consteval double fdouble() {
+  return double(567890.67890);
+}
+
+double Unique_Double = fdouble();
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}}
+//CHECK-NEXT: value: Float 5.678907e+05
+
+} // namespace FloatingPoint
+
+// FIXME: Add test for FixedPoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+consteval B fB() {
+  return B{1, 0.7};
+}
+
+constexpr B Basic_Struct = fB();
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: fields: Int 1, Float 7.00e-01
+//CHECK-NEXT: ImplicitCastExpr
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: fields: Int 1, Float 7.00e-01
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  constexpr A(B b, int I, double D, C _c) : B(b), i(I), d(D), c(_c) {}
+  int i;
+  double d;
+  C c;
+};
+
+consteval A fA() {
+  return A(Basic_Struct, 1, 79.789, {});
+}
+
+A Advanced_Struct = fA();
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}}
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: base: Struct
+//CHECK-NEXT: fields: Int 1, Float 7.00e-01
+//CHECK-NEXT: fields: Int 1, Float 7.978900e+01
+//CHECK-NEXT: field: Struct
+//CHECK-NEXT: field: Int 9
+
+} // namespace Struct
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+consteval v4si fv4si() {
+  return (v4si){8, 2, 3};
+}
+
+v4si Vector_Int = fv4si();
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Vector length=4
+//CHECK-NEXT: elements: Int 8, Int 2, Int 3, Int 0
+
+} // namespace Vector
+
+namespace Array {
+
+struct B {
+  int arr[6];
+};
+
+consteval B fint() {
+  return B{1, 2, 3, 4, 5, 6};
+}
+
+B Array_Int = fint();
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: field: Array size=6
+//CHECK-NEXT: elements: Int 1, Int 2, Int 3, Int 4
+//CHECK-NEXT: elements: Int 5, Int 6
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+struct C {
+  A arr[3];
+};
+
+consteval C fA() {
+  return {{A{}, A{-45678, 9.8}, A{9}}};
+}
+
+C Array2_Struct = fA();
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+struct D {
+  v4si arr[2];
+};
+
+consteval D fv4si() {
+  return {{{1, 2, 3, 4}, {4, 5, 6, 7}}};
+}
+
+D Array_Vector = fv4si();
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}}
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: field: Array size=2
+//CHECK-NEXT: element: Vector length=4
+//CHECK-NEXT: elements: Int 1, Int 2, Int 3, Int 4
+//CHECK-NEXT: element: Vector length=4
+//CHECK-NEXT: elements: Int 4, Int 5, Int 6, Int 7
+
+} // namespace Array
+
+namespace Union {
+
+struct A {
+  int i = 6789;
+  float f = 987.9876;
+};
+
+union U {
+  int i;
+  A a{567890, 9876.5678f};
+};
+
+consteval U fU1() {
+  return U{0};
+}
+
+U Unique_Union1 = fU1();
+//CHECK:  VarDecl {{.*}} Unique_Union

[PATCH] D88645: [Annotation] Allows annotation to carry some additional constant arguments.

2020-10-20 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:3706
+
+if (!Result || !Notes.empty()) {
+  Diag(E->getBeginLoc(), diag::err_attribute_argument_n_type)

aaron.ballman wrote:
> I'm surprised that the presence of notes alone would mean the attribute 
> argument has an error and should be skipped. Are there circumstances under 
> which `Result` is true but `Notes` is non-empty?
AFAIK
Result means the expression can be folded to a constant.
Note.empty() means the expression is a valid constant expression in the current 
language mode.

the difference is observable in code like:
```
constexpr int foldable_but_invalid() {
  int *A = new int(0);
  return *A;
}

[[clang::annotate("", foldable_but_invalid())]] void f1() {}
```
foldable_but_invalid retruns a constant but any constant evaluation of this 
function is invalid because it doesn't desallocate A.
with !Notes.empty() this fails, without it no errors occurs.

i think it is desirable that attributes don't diverge from the language mode.
I added a test for this.



Comment at: clang/test/SemaCXX/attr-annotate.cpp:96
+}
+
+void test() {}

aaron.ballman wrote:
> Some more tests for various constant expression situations that may be weird:
> ```
> int n = 10;
> int vla[n];
> 
> [[clang::annotate("vlas are awful", sizeof(vla[++n]))] int i = 0; // reject, 
> the sizeof is not unevaluated
> 
> [[clang::annotate("_Generic selection expression should be fine", _Generic(n, 
> int : 0, default : 1))]] int j = 0; // second arg should resolve to 0 fine
> 
> void designator();
> [[clang::annotate("function designators?", designator)]] int k = 0; // Should 
> work?
> ```
added CK_FunctionToPointerDecay cast when needed
the rest was working as is.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D88645

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


[PATCH] D88645: [Annotation] Allows annotation to carry some additional constant arguments.

2020-10-20 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 299333.
Tyker marked 4 inline comments as done.
Tyker added a comment.
Herald added a subscriber: dexonsmith.

addressed comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D88645

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ParsedAttr.h
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/ast-dump-attr.cpp
  clang/test/CodeGen/annotations-field.c
  clang/test/CodeGen/annotations-global.c
  clang/test/CodeGen/annotations-loc.c
  clang/test/CodeGen/annotations-var.c
  clang/test/CodeGenCXX/attr-annotate.cpp
  clang/test/CodeGenCXX/attr-annotate2.cpp
  clang/test/Misc/pragma-attribute-cxx.cpp
  clang/test/Misc/pragma-attribute-objc.m
  clang/test/Parser/access-spec-attrs.cpp
  clang/test/Parser/objc-implementation-attrs.m
  clang/test/Sema/annotate.c
  clang/test/Sema/pragma-attribute.c
  clang/test/SemaCXX/attr-annotate.cpp
  llvm/include/llvm/IR/Intrinsics.td
  llvm/test/Analysis/CostModel/X86/free-intrinsics.ll
  llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll
  llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
  llvm/test/CodeGen/Generic/ptr-annotate.ll
  llvm/test/Transforms/InstCombine/assume_inevitable.ll

Index: llvm/test/Transforms/InstCombine/assume_inevitable.ll
===
--- llvm/test/Transforms/InstCombine/assume_inevitable.ll
+++ llvm/test/Transforms/InstCombine/assume_inevitable.ll
@@ -15,7 +15,7 @@
 ; CHECK-NEXT:[[DUMMY_EQ:%.*]] = icmp ugt i32 [[LOADRES]], 42
 ; CHECK-NEXT:tail call void @llvm.assume(i1 [[DUMMY_EQ]])
 ; CHECK-NEXT:[[M_I8:%.*]] = bitcast i64* [[M]] to i8*
-; CHECK-NEXT:[[M_A:%.*]] = call i8* @llvm.ptr.annotation.p0i8(i8* nonnull [[M_I8]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i64 0, i64 0), i32 2)
+; CHECK-NEXT:[[M_A:%.*]] = call i8* @llvm.ptr.annotation.p0i8(i8* nonnull [[M_I8]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i64 0, i64 0), i32 2, i8* null)
 ; CHECK-NEXT:[[M_X:%.*]] = bitcast i8* [[M_A]] to i64*
 ; CHECK-NEXT:[[OBJSZ:%.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* [[C:%.*]], i1 false, i1 false, i1 false)
 ; CHECK-NEXT:store i64 [[OBJSZ]], i64* [[M_X]], align 4
@@ -44,7 +44,7 @@
   call void @llvm.lifetime.end.p0i8(i64 1, i8* %dummy)
 
   %m_i8 = bitcast i64* %m to i8*
-  %m_a = call i8* @llvm.ptr.annotation.p0i8(i8* %m_i8, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2)
+  %m_a = call i8* @llvm.ptr.annotation.p0i8(i8* %m_i8, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2, i8* null)
   %m_x = bitcast i8* %m_a to i64*
   %objsz = call i64 @llvm.objectsize.i64.p0i8(i8* %c, i1 false)
   store i64 %objsz, i64* %m_x
@@ -64,7 +64,7 @@
 
 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1)
 declare i32 @llvm.annotation.i32(i32, i8*, i8*, i32)
-declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32)
+declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32, i8*)
 
 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
Index: llvm/test/CodeGen/Generic/ptr-annotate.ll
===
--- llvm/test/CodeGen/Generic/ptr-annotate.ll
+++ llvm/test/CodeGen/Generic/ptr-annotate.ll
@@ -10,9 +10,9 @@
 define void @foo() {
 entry:
   %m = alloca i8, align 4
-  %0 = call i8* @llvm.ptr.annotation.p0i8(i8* %m, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2)
+  %0 = call i8* @llvm.ptr.annotation.p0i8(i8* %m, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2, i8* null)
   store i8 1, i8* %0, align 4
   ret void
 }
 
-declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32) #1
+declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32, i8*) #1
Index: llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
===
--- llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
+++ llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
@@ -15,8 +15,8 @@
 ; CHECK-SIZE-NEXT:  Cost Model: Found an 

[PATCH] D74130: [clang] fix consteval call in default arguments

2020-10-17 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 298818.
Tyker marked 9 inline comments as done.
Tyker added a comment.

addressed comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D74130

Files:
  clang/include/clang/AST/Expr.h
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/ScopeInfo.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaLambda.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
@@ -258,6 +258,26 @@
   return f(0);  
 };
 
+consteval int f1() {
+// expected-note@-1+ {{declared here}}
+  return 0;
+}
+consteval auto g() { return f1; }
+consteval int h(int (*p)() = g()) { return p(); }
+int h1(int (*p)() = g()) { return p(); }
+// expected-error@-1 {{is not a constant expression}}
+// expected-note@-2 {{pointer to a consteval}}
+
+constexpr auto e = g();
+// expected-error@-1 {{call to consteval function}}
+// expected-note@-2 {{is not a constant expression}}
+
+auto l = [](int (*p)() = g()) { return p(); };
+// expected-error@-1 {{is not a constant expression}}
+// expected-note@-2 {{pointer to a consteval}}
+
+auto l2 = [](int (*p)() = g()) consteval { return p(); };
+
 }
 
 namespace std {
@@ -594,3 +614,42 @@
 }
 
 } // namespace special_ctor
+
+namespace top_level {
+struct S {
+  consteval S() {}
+  int a;
+// expected-note@-1 {{subobject declared here}}
+};
+
+S s; // expected-error {{is not a constant expression}}
+// expected-note@-1 {{is not initialized}}
+
+struct S1 {
+  consteval S1() {}
+  int a = 0;
+};
+
+S1 s1;
+
+}
+
+namespace unevaluated {
+struct N {
+  constexpr N() {}
+  N(N const&) = delete;
+};
+template  constexpr void bad_assert_copyable() { T t; T t2 = t; }
+using ineffective = decltype(bad_assert_copyable());
+
+template  consteval void assert_copyable() { T t; T t2 = t; }
+using check = decltype(assert_copyable());
+}
+
+// namespace error {
+
+// consteval void check(bool b) { if (!b) throw; }
+// constinit int x = true ? 1 : (check(false), 2);
+// constinit int x1 = (check(false), 2);
+
+// }
Index: clang/lib/Sema/SemaLambda.cpp
===
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -891,6 +891,16 @@
   LambdaScopeInfo *const LSI = getCurLambda();
   assert(LSI && "LambdaScopeInfo should be on stack!");
 
+  /// If the lambda is consteval the paramters will be evaluated in constant
+  /// context immediate invocations don't need to be kept.
+  if (ParamInfo.getDeclSpec().getConstexprSpecifier() != CSK_consteval) {
+ExprEvalContexts.back().ReferenceToConsteval.insert(
+LSI->ReferenceToConsteval.begin(), LSI->ReferenceToConsteval.end());
+ExprEvalContexts.back().ImmediateInvocationCandidates.append(
+LSI->ImmediateInvocationCandidates.begin(),
+LSI->ImmediateInvocationCandidates.end());
+  }
+
   // Determine if we're within a context where we know that the lambda will
   // be dependent, because there are template parameters in scope.
   bool KnownDependent;
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -16183,7 +16183,7 @@
 
 ExprResult Sema::CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl) {
   if (!E.isUsable() || !Decl || !Decl->isConsteval() || isConstantEvaluated() ||
-  RebuildingImmediateInvocation)
+  RebuildingImmediateInvocation || isUnevaluatedContext())
 return E;
 
   /// Opportunistically remove the callee from ReferencesToConsteval if we can.
@@ -16229,6 +16229,7 @@
 SemaRef.Diag(CE->getBeginLoc(), diag::err_invalid_consteval_call) << FD;
 for (auto  : Notes)
   SemaRef.Diag(Note.first, Note.second);
+CE->markFailed();
 return;
   }
   CE->MoveIntoResult(Eval.Val, SemaRef.getASTContext());
@@ -16312,13 +16313,25 @@
   It->getPointer()->setSubExpr(Res.get());
 }
 
-static void
-HandleImmediateInvocations(Sema ,
-   Sema::ExpressionEvaluationContextRecord ) {
+void Sema::HandleImmediateInvocations(
+Sema::ExpressionEvaluationContextRecord ) {
   if ((Rec.ImmediateInvocationCandidates.size() == 0 &&
Rec.ReferenceToConsteval.size() == 0) ||
-  SemaRef.RebuildingImmediateInvocation)
+  RebuildingImmediateInvocation || isUnevaluatedContext())
+return;
+
+  /// If the scope is lambda params we don't know wether the lambda is consteval
+  /// yet. So we store all the needed information in the lambda and resolve it
+  /// later.
+  if (Rec.ExprContext ==
+  Sema::ExpressionEvaluationContextRecord::EK_LambdaParam) {
+

[PATCH] D74130: [clang] fix consteval call in default arguments

2020-10-17 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/lib/Sema/Sema.cpp:1026
 
+  HandleImmediateInvocations(ExprEvalContexts.back());
+

rsmith wrote:
> What do we need this for? If I'm understanding the patch correctly, I think 
> the only way we should propagate immediate invocations upwards should be from 
> the `ExpressionEvaluationContext` of a lambda default argument into the 
> `ExpressionEvaluationContext` of the lambda itself, so it should never reach 
> the top level.
This is fixing a separate bug that consteval call in to top-level 
ExprEvalContext are not handled.
like this:
```
struct S {
  consteval S(bool b) {if (b) throw;}
};
S s2(true);
```
this emits no error.
because the immediate invocation are added to global scope and the global scope 
is never poped via PopExpressionEvaluationContext.



Comment at: clang/lib/Sema/SemaDeclCXX.cpp:17045-17048
+  bool HasConstantInitializer = false;
+  if (auto *VD = dyn_cast(D))
+HasConstantInitializer = VD->isConstexpr() || VD->hasAttr();
+  isConstantEvaluatedOverride = HasConstantInitializer;

rsmith wrote:
> This needs a comment explaining what's going on: why are `constexpr` / 
> `constinit` variables special here, but (for example) a variable of type 
> `const int` is not?
> 
> Actually, I think this change might not be correct. Consider the following:
> 
> ```
> consteval void check(bool b) { if (!b) throw; }
> constinit int x = true ? 1 : (check(false), 2);
> ```
> 
> This code is ill-formed: the immediate invocation of `check(false)` is not a 
> constant expression. But I think with this code change, we won't require 
> `check(false)` to be a constant expression, instead deferring to checking 
> whether the initializer of `x` as a whole is a constant expression (which it 
> is!). So we'll accept invalid code.
this fixes an issue where we would generate 2 error when we couldn't evaluate a 
consteval call inside the initialization of a constexpr/constinit 
variable.
```
consteval void check(bool b) { if (!b) throw; }
constinit int x = (check(false), 2);
```
one of those error is "call to consteval function 'check' is not a constant 
expression"
the second is "variable does not have a constant initializer"

i fixed it by marking the expression as failed when the consteval call fails.



Comment at: clang/lib/Sema/SemaDeclCXX.cpp:17062
 ExitDeclaratorContext(S);
+  isConstantEvaluatedOverride = false;
 }

rsmith wrote:
> Do we need to restore the old value here, rather than resetting to `false`? 
> In a case like:
> 
> ```
> consteval int g() { return 0; }
> constexpr int a = ({ constexpr int b = 0; g(); });
> ```
> 
> it looks like we'd lose the 'override' flag at the end of the definition of 
> `b`.
> 
> Generally I find the idea of using a global override flag like this to be 
> dubious: there are a lot of ways in which we switch context during `Sema`, 
> and we'd need to make sure we switch out this context at those times too. If 
> we can avoid using a global state flag for this (for example by carrying this 
> on the `ExpressionEvaluationContextRecord`, that'd be a lot less worrying.
i changed approach and this isn't needed anymore.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D74130

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


[PATCH] D74130: [clang] fix consteval call in default arguements

2020-10-15 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 298344.
Tyker retitled this revision from "[clang] fix consteval call in default 
arguements " to "[clang] fix consteval call in default arguements".
Tyker added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

rebased and add more fixes


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D74130

Files:
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaLambda.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
@@ -258,6 +258,26 @@
   return f(0);  
 };
 
+consteval int f1() {
+// expected-note@-1+ {{declared here}}
+  return 0;
+}
+consteval auto g() { return f1; }
+consteval int h(int (*p)() = g()) { return p(); }
+int h1(int (*p)() = g()) { return p(); }
+// expected-error@-1 {{is not a constant expression}}
+// expected-note@-2 {{pointer to a consteval}}
+
+constexpr auto e = g();
+// expected-error@-1 {{must be initialized by a constant expression}}
+// expected-note@-2 {{is not a constant expression}}
+
+auto l = [](int (*p)() = g()) { return p(); };
+// expected-error@-1 {{is not a constant expression}}
+// expected-note@-2 {{pointer to a consteval}}
+
+auto l2 = [](int (*p)() = g()) consteval { return p(); };
+
 }
 
 namespace std {
@@ -594,3 +614,22 @@
 }
 
 } // namespace special_ctor
+
+namespace top_level {
+struct S {
+  consteval S() {}
+  int a;
+// expected-note@-1 {{subobject declared here}}
+};
+
+S s; // expected-error {{is not a constant expression}}
+// expected-note@-1 {{is not initialized}}
+
+struct S1 {
+  consteval S1() {}
+  int a = 0;
+};
+
+S1 s1;
+
+}
Index: clang/lib/Sema/SemaLambda.cpp
===
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -891,6 +891,10 @@
   LambdaScopeInfo *const LSI = getCurLambda();
   assert(LSI && "LambdaScopeInfo should be on stack!");
 
+  if (ParamInfo.getDeclSpec().getConstexprSpecifier() == CSK_consteval)
+ExprEvalContexts.back().IIEndScopeAction =
+ExpressionEvaluationContextRecord::IIESA_Drop;
+
   // Determine if we're within a context where we know that the lambda will
   // be dependent, because there are template parameters in scope.
   bool KnownDependent;
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -16097,13 +16097,16 @@
   return TransformToPE(*this).TransformExpr(E);
 }
 
-void
-Sema::PushExpressionEvaluationContext(
+void Sema::PushExpressionEvaluationContext(
 ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl,
-ExpressionEvaluationContextRecord::ExpressionKind ExprContext) {
+ExpressionEvaluationContextRecord::ExpressionKind ExprContext,
+bool IsLambdaParamScope) {
   ExprEvalContexts.emplace_back(NewContext, ExprCleanupObjects.size(), Cleanup,
 LambdaContextDecl, ExprContext);
   Cleanup.reset();
+  if (IsLambdaParamScope)
+ExprEvalContexts.back().IIEndScopeAction =
+Sema::ExpressionEvaluationContextRecord::IIESA_Propagate;
   if (!MaybeODRUseExprs.empty())
 std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs);
 }
@@ -16183,7 +16186,9 @@
 
 ExprResult Sema::CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl) {
   if (!E.isUsable() || !Decl || !Decl->isConsteval() || isConstantEvaluated() ||
-  RebuildingImmediateInvocation)
+  RebuildingImmediateInvocation ||
+  ExprEvalContexts.back().IIEndScopeAction ==
+  ExpressionEvaluationContextRecord::IIESA_Drop)
 return E;
 
   /// Opportunistically remove the callee from ReferencesToConsteval if we can.
@@ -16312,14 +16317,31 @@
   It->getPointer()->setSubExpr(Res.get());
 }
 
-static void
-HandleImmediateInvocations(Sema ,
-   Sema::ExpressionEvaluationContextRecord ) {
+void Sema::HandleImmediateInvocations(
+Sema::ExpressionEvaluationContextRecord ) {
   if ((Rec.ImmediateInvocationCandidates.size() == 0 &&
Rec.ReferenceToConsteval.size() == 0) ||
-  SemaRef.RebuildingImmediateInvocation)
+  RebuildingImmediateInvocation ||
+  Rec.IIEndScopeAction ==
+  Sema::ExpressionEvaluationContextRecord::IIESA_Drop)
 return;
 
+  /// If we can't handle immediate invocations yet. add them to the outer scope.
+  /// This occurs for default argument of lambdas as we can't know if the lambda
+  /// is consteval until after the parameter context has been poped.
+  if (Rec.IIEndScopeAction ==
+  

[PATCH] D88643: [NFC] Correct name of profile function to Profile in APValue

2020-10-15 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG53122ce2b39f: [NFC] Correct name of profile function to 
Profile in APValue (authored by Tyker).

Changed prior to commit:
  https://reviews.llvm.org/D88643?vs=295502=298330#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D88643

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

Index: clang/lib/AST/APValue.cpp
===
--- clang/lib/AST/APValue.cpp
+++ clang/lib/AST/APValue.cpp
@@ -77,7 +77,7 @@
   return QualType::getFromOpaquePtr(DynamicAllocType);
 }
 
-void APValue::LValueBase::profile(llvm::FoldingSetNodeID ) const {
+void APValue::LValueBase::Profile(llvm::FoldingSetNodeID ) const {
   ID.AddPointer(Ptr.getOpaqueValue());
   if (is() || is())
 return;
@@ -103,7 +103,7 @@
   Value = reinterpret_cast(BaseOrMember.getOpaqueValue());
 }
 
-void APValue::LValuePathEntry::profile(llvm::FoldingSetNodeID ) const {
+void APValue::LValuePathEntry::Profile(llvm::FoldingSetNodeID ) const {
   ID.AddInteger(Value);
 }
 
@@ -414,7 +414,7 @@
   std::swap(Data, RHS.Data);
 }
 
-void APValue::profile(llvm::FoldingSetNodeID ) const {
+void APValue::Profile(llvm::FoldingSetNodeID ) const {
   ID.AddInteger(Kind);
 
   switch (Kind) {
@@ -430,10 +430,10 @@
   case Struct:
 ID.AddInteger(getStructNumBases());
 for (unsigned I = 0, N = getStructNumBases(); I != N; ++I)
-  getStructBase(I).profile(ID);
+  getStructBase(I).Profile(ID);
 ID.AddInteger(getStructNumFields());
 for (unsigned I = 0, N = getStructNumFields(); I != N; ++I)
-  getStructField(I).profile(ID);
+  getStructField(I).Profile(ID);
 return;
 
   case Union:
@@ -442,7 +442,7 @@
   return;
 }
 ID.AddPointer(getUnionField()->getCanonicalDecl());
-getUnionValue().profile(ID);
+getUnionValue().Profile(ID);
 return;
 
   case Array: {
@@ -459,9 +459,9 @@
 //   ['a', 'c', 'x', 'x', 'x'] is profiled as
 //   [5, 'x', 3, 'c', 'a']
 llvm::FoldingSetNodeID FillerID;
-(hasArrayFiller() ? getArrayFiller() :
- getArrayInitializedElt(getArrayInitializedElts() -
-   1)).profile(FillerID);
+(hasArrayFiller() ? getArrayFiller()
+  : getArrayInitializedElt(getArrayInitializedElts() - 1))
+.Profile(FillerID);
 ID.AddNodeID(FillerID);
 unsigned NumFillers = getArraySize() - getArrayInitializedElts();
 unsigned N = getArrayInitializedElts();
@@ -481,7 +481,7 @@
   // element.
   if (N != getArraySize()) {
 llvm::FoldingSetNodeID ElemID;
-getArrayInitializedElt(N - 1).profile(ElemID);
+getArrayInitializedElt(N - 1).Profile(ElemID);
 if (ElemID != FillerID) {
   ID.AddInteger(NumFillers);
   ID.AddNodeID(ElemID);
@@ -497,14 +497,14 @@
 
 // Emit the remaining elements.
 for (; N != 0; --N)
-  getArrayInitializedElt(N - 1).profile(ID);
+  getArrayInitializedElt(N - 1).Profile(ID);
 return;
   }
 
   case Vector:
 ID.AddInteger(getVectorLength());
 for (unsigned I = 0, N = getVectorLength(); I != N; ++I)
-  getVectorElt(I).profile(ID);
+  getVectorElt(I).Profile(ID);
 return;
 
   case Int:
@@ -533,7 +533,7 @@
 return;
 
   case LValue:
-getLValueBase().profile(ID);
+getLValueBase().Profile(ID);
 ID.AddInteger(getLValueOffset().getQuantity());
 ID.AddInteger(isNullPointer());
 ID.AddInteger(isLValueOnePastTheEnd());
@@ -541,7 +541,7 @@
 // to union members, but we don't have the type here so we don't know
 // how to interpret the entries.
 for (LValuePathEntry E : getLValuePath())
-  E.profile(ID);
+  E.Profile(ID);
 return;
 
   case MemberPointer:
Index: clang/include/clang/AST/APValue.h
===
--- clang/include/clang/AST/APValue.h
+++ clang/include/clang/AST/APValue.h
@@ -151,7 +151,7 @@
 static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type);
 static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
 
-void profile(llvm::FoldingSetNodeID ) const;
+void Profile(llvm::FoldingSetNodeID ) const;
 
 template 
 bool is() const { return Ptr.is(); }
@@ -219,7 +219,7 @@
 }
 uint64_t getAsArrayIndex() const { return Value; }
 
-void profile(llvm::FoldingSetNodeID ) const;
+void Profile(llvm::FoldingSetNodeID ) const;
 
 friend bool operator==(LValuePathEntry A, LValuePathEntry B) {
   return A.Value == B.Value;
@@ -363,10 +363,10 @@
   /// Swaps the contents of this and the given APValue.
   void swap(APValue );
 
-  /// Profile this value. There is no guarantee that values of different
+  /// profile this value. There is no guarantee that values of different
   /// types will not produce the same profiled value, so the 

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

2020-10-15 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 298318.
Tyker added a comment.

try to apply martongs's suggestions.


Repository:
  rG LLVM Github Monorepo

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/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.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,460 @@
+// 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 {
+
+consteval int fint() {
+  return 6789;
+}
+
+int Unique_Int = fint();
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int'
+//CHECK-NEXT: value: Int 6789
+
+consteval __uint128_t fint128() {
+  return ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+}
+
+constexpr __uint128_t Unique_Int128 = fint128();
+//CHECK:  VarDecl {{.*}} Unique_Int128
+//CHECK-NEXT: value: Int 156773562844924187900898496343692168785
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Int 156773562844924187900898496343692168785
+
+} // namespace Integer
+
+namespace FloatingPoint {
+
+consteval double fdouble() {
+  return double(567890.67890);
+}
+
+double Unique_Double = fdouble();
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}}
+//CHECK-NEXT: value: Float 5.678907e+05
+
+} // namespace FloatingPoint
+
+// FIXME: Add test for FixedPoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+consteval B fB() {
+  return B{1, 0.7};
+}
+
+constexpr B Basic_Struct = fB();
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: fields: Int 1, Float 7.00e-01
+//CHECK-NEXT: ImplicitCastExpr
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: fields: Int 1, Float 7.00e-01
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  constexpr A(B b, int I, double D, C _c) : B(b), i(I), d(D), c(_c) {}
+  int i;
+  double d;
+  C c;
+};
+
+consteval A fA() {
+  return A(Basic_Struct, 1, 79.789, {});
+}
+
+A Advanced_Struct = fA();
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}}
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: base: Struct
+//CHECK-NEXT: fields: Int 1, Float 7.00e-01
+//CHECK-NEXT: fields: Int 1, Float 7.978900e+01
+//CHECK-NEXT: field: Struct
+//CHECK-NEXT: field: Int 9
+
+} // namespace Struct
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+consteval v4si fv4si() {
+  return (v4si){8, 2, 3};
+}
+
+v4si Vector_Int = fv4si();
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Vector length=4
+//CHECK-NEXT: elements: Int 8, Int 2, Int 3, Int 0
+
+} // namespace Vector
+
+namespace Array {
+
+struct B {
+  int arr[6];
+};
+
+consteval B fint() {
+  return B{1, 2, 3, 4, 5, 6};
+}
+
+B Array_Int = fint();
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: field: Array size=6
+//CHECK-NEXT: elements: Int 1, Int 2, Int 3, Int 4
+//CHECK-NEXT: elements: Int 5, Int 6
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+struct C {
+  A arr[3];
+};
+
+consteval C fA() {
+  return {{A{}, A{-45678, 9.8}, A{9}}};
+}
+
+C Array2_Struct = fA();
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+struct D {
+  v4si arr[2];
+};
+
+consteval D fv4si() {
+  return {{{1, 2, 3, 4}, {4, 5, 6, 7}}};
+}
+
+D Array_Vector = fv4si();
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}}
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: field: Array size=2
+//CHECK-NEXT: element: Vector length=4
+//CHECK-NEXT: elements: Int 1, Int 2, Int 3, Int 4
+//CHECK-NEXT: element: Vector length=4
+//CHECK-NEXT: elements: Int 4, Int 5, Int 6, Int 7
+
+} // namespace Array
+
+namespace Union {
+
+struct A {
+  int i = 6789;
+  float f = 987.9876;
+};
+
+union U {
+  int i;
+  A a{567890, 9876.5678f};
+};
+
+consteval U fU1() {
+  return U{0};
+}
+
+U Unique_Union1 = fU1();
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Union .i Int 0
+
+consteval U fU() {
+  return U{};
+}
+
+U Unique_Union2 = fU();
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Union .a
+//CHECK-NEXT: Struct
+//CHECK-NEXT: fields: Int 567890, Float 9.876567e+03
+
+} // 

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

2020-10-15 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

In D63640#2331734 , @martong wrote:

> In D63640#2331410 , @rsmith wrote:
>
>> Reverse ping: I have a patch implementing class type non-type template 
>> parameters that's blocked on this landing. If you won't have time to address 
>> @martong's comments soon, do you mind if I take this over and land it?
>
> It is okay for me to commit this patch in its current state. The changes I 
> suggested could result in a cleaner code, but I can do those changes after we 
> land this.

i couldn't apply martong's suggestion because importChecked is part of 
ASTNodeImporter not ASTImporter, but cleaned up some code.
but the "real" blocker is that the testing depends on D85144 
 for testing.


Repository:
  rG LLVM Github Monorepo

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] D88645: [Annotation] Allows annotation to carry some additional constant arguments.

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



Comment at: clang/lib/CodeGen/CodeGenFunction.cpp:2229-2233
+  SmallVector Args = {
+  AnnotatedVal,
+  Builder.CreateBitCast(CGM.EmitAnnotationString(AnnotationStr), 
Int8PtrTy),
+  Builder.CreateBitCast(CGM.EmitAnnotationUnit(Location), Int8PtrTy),
+  CGM.EmitAnnotationLineNo(Location),

keryell wrote:
> Curious reindenting with mix-and-match of spaces & tabulations?
these are not tabs i believe this is just how phabricator shows indentation 
changes.



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:3693
+if (E->isValueDependent() || E->isTypeDependent() ||
+(CE && CE->hasAPValueResult()))
+  continue;

aaron.ballman wrote:
> What is the rationale for bailing out when the constant expression has an 
> `APValue` result?
the intent was that during nested template instantiation arguement will be 
evaluated as soon as they are neither value nor type dependent and the result 
will be stored in the ConstantExpr. if an arguement has already been evaluated 
in a previous instantiation we don't want to evaluate it again.
but because of SubstExpr ConstantExpr are getting removed so it removed it.



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:3704-3705
+  Result = E->EvaluateAsRValue(Eval, Context, true);
+else
+  Result = E->EvaluateAsLValue(Eval, Context, true);
+

keryell wrote:
> aaron.ballman wrote:
> > Tyker wrote:
> > > aaron.ballman wrote:
> > > > Under what circumstances would we want the constant expressions to be 
> > > > lvalues? I would have guessed you would want to call 
> > > > `Expr::EvaluateAsConstantExpr()` instead of either of these.
> > > Expr::EvaluateAsConstantExpr will evaluate expression in there value 
> > > category.
> > > this can be quite surprising in some situations like:
> > > ```
> > > const int g_i = 0;
> > > [[clang::annotate("test", g_i)]] void t() {} // annotation carries a 
> > > pointer/reference on g_i
> > > [[clang::annotate("test", (int)g_i)]] void t1() {} // annotation carries 
> > > the value 0
> > > [[clang::annotate("test", g_i + 0)]] void t1() {} // annotation carries 
> > > the value 0
> > > 
> > > ```
> > > with EvaluateAsRValue in all of the cases above the annotation will carry 
> > > the value 0.
> > > 
> > > optionally we could wrap expression with an LValue to RValue cast and 
> > > call EvaluateAsConstantExpr this should also work.
> > Thank you for the explanation. I think wrapping with an lvalue to rvalue 
> > conversion may make more sense -- `EvaluateAsRValue()` tries really hard to 
> > get an rvalue out of something even if the standard says that's not okay. 
> > It'll automatically apply the lvalue to rvalue conversion if appropriate, 
> > but it'll also do more than that (such as evaluating side effects).
> This needs some motivating comments and explanations in the code.
> Also the variations on `g_i` annotation above are quite interesting and 
> should appear in the unit tests. I am unsure they are now.
> Perhaps more interesting with other values than `0` in the example. :-)
> I guess we can still use `[[clang::annotate("test", _i)]] void t() {}` to 
> have a pointer on `g_i` and `(int&)g_i` for reference? To add to the unit 
> tests if not already checked.
> 
i changed to use EvaluateAsConstantExpr + LValueToRvalue cast.

> This needs some motivating comments and explanations in the code.
> Also the variations on `g_i` annotation above are quite interesting and 
> should appear in the unit tests. I am unsure they are now.
they are tested not as expressively as above but they are tested.

> Perhaps more interesting with other values than `0` in the example. :-)
> I guess we can still use `[[clang::annotate("test", _i)]] void t() {}` to 
> have a pointer on `g_i`
yes this is how it is working.
> `(int&)g_i` for reference? To add to the unit tests if not already checked.
(int&)g_i has the salve value category and same type as g_i it just has a noop 
cast around it.
pointer an reference are indistinguishable in an APValue the only difference is 
the c++ type of what they represent.
and they are of course lowered to the same thing. so we only need the pointer 
case.



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D88645

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


[PATCH] D88645: [Annotation] Allows annotation to carry some additional constant arguments.

2020-10-10 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 297409.
Tyker marked 11 inline comments as done.
Tyker added a comment.

addressed comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D88645

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ParsedAttr.h
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/ast-dump-attr.cpp
  clang/test/CodeGen/annotations-field.c
  clang/test/CodeGen/annotations-global.c
  clang/test/CodeGen/annotations-loc.c
  clang/test/CodeGen/annotations-var.c
  clang/test/CodeGenCXX/attr-annotate.cpp
  clang/test/Misc/pragma-attribute-cxx.cpp
  clang/test/Misc/pragma-attribute-objc.m
  clang/test/Parser/access-spec-attrs.cpp
  clang/test/Parser/objc-implementation-attrs.m
  clang/test/Sema/annotate.c
  clang/test/Sema/pragma-attribute.c
  clang/test/SemaCXX/attr-annotate.cpp
  llvm/include/llvm/IR/Intrinsics.td
  llvm/test/Analysis/CostModel/X86/free-intrinsics.ll
  llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll
  llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
  llvm/test/CodeGen/Generic/ptr-annotate.ll
  llvm/test/Transforms/InstCombine/assume_inevitable.ll

Index: llvm/test/Transforms/InstCombine/assume_inevitable.ll
===
--- llvm/test/Transforms/InstCombine/assume_inevitable.ll
+++ llvm/test/Transforms/InstCombine/assume_inevitable.ll
@@ -15,7 +15,7 @@
 ; CHECK-NEXT:[[DUMMY_EQ:%.*]] = icmp ugt i32 [[LOADRES]], 42
 ; CHECK-NEXT:tail call void @llvm.assume(i1 [[DUMMY_EQ]])
 ; CHECK-NEXT:[[M_I8:%.*]] = bitcast i64* [[M]] to i8*
-; CHECK-NEXT:[[M_A:%.*]] = call i8* @llvm.ptr.annotation.p0i8(i8* nonnull [[M_I8]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i64 0, i64 0), i32 2)
+; CHECK-NEXT:[[M_A:%.*]] = call i8* @llvm.ptr.annotation.p0i8(i8* nonnull [[M_I8]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i64 0, i64 0), i32 2, i8* null)
 ; CHECK-NEXT:[[M_X:%.*]] = bitcast i8* [[M_A]] to i64*
 ; CHECK-NEXT:[[OBJSZ:%.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* [[C:%.*]], i1 false, i1 false, i1 false)
 ; CHECK-NEXT:store i64 [[OBJSZ]], i64* [[M_X]], align 4
@@ -44,7 +44,7 @@
   call void @llvm.lifetime.end.p0i8(i64 1, i8* %dummy)
 
   %m_i8 = bitcast i64* %m to i8*
-  %m_a = call i8* @llvm.ptr.annotation.p0i8(i8* %m_i8, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2)
+  %m_a = call i8* @llvm.ptr.annotation.p0i8(i8* %m_i8, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2, i8* null)
   %m_x = bitcast i8* %m_a to i64*
   %objsz = call i64 @llvm.objectsize.i64.p0i8(i8* %c, i1 false)
   store i64 %objsz, i64* %m_x
@@ -64,7 +64,7 @@
 
 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1)
 declare i32 @llvm.annotation.i32(i32, i8*, i8*, i32)
-declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32)
+declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32, i8*)
 
 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
Index: llvm/test/CodeGen/Generic/ptr-annotate.ll
===
--- llvm/test/CodeGen/Generic/ptr-annotate.ll
+++ llvm/test/CodeGen/Generic/ptr-annotate.ll
@@ -10,9 +10,9 @@
 define void @foo() {
 entry:
   %m = alloca i8, align 4
-  %0 = call i8* @llvm.ptr.annotation.p0i8(i8* %m, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2)
+  %0 = call i8* @llvm.ptr.annotation.p0i8(i8* %m, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2, i8* null)
   store i8 1, i8* %0, align 4
   ret void
 }
 
-declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32) #1
+declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32, i8*) #1
Index: llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
===
--- llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
+++ llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
@@ -15,8 +15,8 @@
 ; CHECK-SIZE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.start.p0i8(i64 1, i8* 

[PATCH] D88645: [Annotation] Allows annotation to carry some additional constant arguments.

2020-10-09 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:3683
+  auto *Attr =
+  AnnotateAttr::Create(Context, Str, Args.empty() ? nullptr : Args.data(),
+   Args.size(), CI.getRange(), CI.getSyntax());

aaron.ballman wrote:
> Just curious, but is the `?:` actually necessary? I would have assumed that 
> an empty `ArrayRef` would return `nullptr` from `data()`.
maybe it was(in a previous version of the code) but not anymore since there is 
always at least one argument.



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:3688
+Expr * = Attr->args_begin()[Idx];
+ConstantExpr *CE = dyn_cast(E);
+if (!E) {

aaron.ballman wrote:
> `auto *` since the type is spelled out in the initialization.
> 
> Also, I think this is unsafe -- it looks like during template instantiation, 
> any arguments that have a substitution failure will come through as 
> `nullptr`, and this will crash.
> 
> What should happen on template instantiation failure for these arguments? I 
> think the whole attribute should probably be dropped with appropriate 
> diagnostics rather than emitting a partial attribute, but perhaps you have 
> different ideas.
When template instantation fails nullptr is put in the Expr arguments and  
AddAnnotationAttr will emit a diagnostic and not associate the attribut to the 
declaration.



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:3704-3705
+  Result = E->EvaluateAsRValue(Eval, Context, true);
+else
+  Result = E->EvaluateAsLValue(Eval, Context, true);
+

aaron.ballman wrote:
> Under what circumstances would we want the constant expressions to be 
> lvalues? I would have guessed you would want to call 
> `Expr::EvaluateAsConstantExpr()` instead of either of these.
Expr::EvaluateAsConstantExpr will evaluate expression in there value category.
this can be quite surprising in some situations like:
```
const int g_i = 0;
[[clang::annotate("test", g_i)]] void t() {} // annotation carries a 
pointer/reference on g_i
[[clang::annotate("test", (int)g_i)]] void t1() {} // annotation carries the 
value 0
[[clang::annotate("test", g_i + 0)]] void t1() {} // annotation carries the 
value 0

```
with EvaluateAsRValue in all of the cases above the annotation will carry the 
value 0.

optionally we could wrap expression with an LValue to RValue cast and call 
EvaluateAsConstantExpr this should also work.



Comment at: clang/test/SemaCXX/attr-annotate.cpp:1
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -verify %s
+

aaron.ballman wrote:
> Do you mean to emit llvm here? I think that should probably be `-fsyntax-only`
The reason i put an -emit-llvm is to also test the asserts in IRgen on more 
complex code.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D88645

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


[PATCH] D88645: [Annotation] Allows annotation to carry some additional constant arguments.

2020-10-09 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 297159.
Tyker marked 7 inline comments as done.
Tyker added a comment.

addressed comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D88645

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ParsedAttr.h
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/ast-dump-attr.cpp
  clang/test/CodeGen/annotations-field.c
  clang/test/CodeGen/annotations-global.c
  clang/test/CodeGen/annotations-loc.c
  clang/test/CodeGen/annotations-var.c
  clang/test/CodeGenCXX/attr-annotate.cpp
  clang/test/Misc/pragma-attribute-cxx.cpp
  clang/test/Misc/pragma-attribute-objc.m
  clang/test/Parser/access-spec-attrs.cpp
  clang/test/Parser/objc-implementation-attrs.m
  clang/test/Sema/annotate.c
  clang/test/Sema/pragma-attribute.c
  clang/test/SemaCXX/attr-annotate.cpp
  llvm/include/llvm/IR/Intrinsics.td
  llvm/test/Analysis/CostModel/X86/free-intrinsics.ll
  llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll
  llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
  llvm/test/CodeGen/Generic/ptr-annotate.ll
  llvm/test/Transforms/InstCombine/assume_inevitable.ll

Index: llvm/test/Transforms/InstCombine/assume_inevitable.ll
===
--- llvm/test/Transforms/InstCombine/assume_inevitable.ll
+++ llvm/test/Transforms/InstCombine/assume_inevitable.ll
@@ -15,7 +15,7 @@
 ; CHECK-NEXT:[[DUMMY_EQ:%.*]] = icmp ugt i32 [[LOADRES]], 42
 ; CHECK-NEXT:tail call void @llvm.assume(i1 [[DUMMY_EQ]])
 ; CHECK-NEXT:[[M_I8:%.*]] = bitcast i64* [[M]] to i8*
-; CHECK-NEXT:[[M_A:%.*]] = call i8* @llvm.ptr.annotation.p0i8(i8* nonnull [[M_I8]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i64 0, i64 0), i32 2)
+; CHECK-NEXT:[[M_A:%.*]] = call i8* @llvm.ptr.annotation.p0i8(i8* nonnull [[M_I8]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i64 0, i64 0), i32 2, i8* null)
 ; CHECK-NEXT:[[M_X:%.*]] = bitcast i8* [[M_A]] to i64*
 ; CHECK-NEXT:[[OBJSZ:%.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* [[C:%.*]], i1 false, i1 false, i1 false)
 ; CHECK-NEXT:store i64 [[OBJSZ]], i64* [[M_X]], align 4
@@ -44,7 +44,7 @@
   call void @llvm.lifetime.end.p0i8(i64 1, i8* %dummy)
 
   %m_i8 = bitcast i64* %m to i8*
-  %m_a = call i8* @llvm.ptr.annotation.p0i8(i8* %m_i8, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2)
+  %m_a = call i8* @llvm.ptr.annotation.p0i8(i8* %m_i8, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2, i8* null)
   %m_x = bitcast i8* %m_a to i64*
   %objsz = call i64 @llvm.objectsize.i64.p0i8(i8* %c, i1 false)
   store i64 %objsz, i64* %m_x
@@ -64,7 +64,7 @@
 
 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1)
 declare i32 @llvm.annotation.i32(i32, i8*, i8*, i32)
-declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32)
+declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32, i8*)
 
 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
Index: llvm/test/CodeGen/Generic/ptr-annotate.ll
===
--- llvm/test/CodeGen/Generic/ptr-annotate.ll
+++ llvm/test/CodeGen/Generic/ptr-annotate.ll
@@ -10,9 +10,9 @@
 define void @foo() {
 entry:
   %m = alloca i8, align 4
-  %0 = call i8* @llvm.ptr.annotation.p0i8(i8* %m, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2)
+  %0 = call i8* @llvm.ptr.annotation.p0i8(i8* %m, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2, i8* null)
   store i8 1, i8* %0, align 4
   ret void
 }
 
-declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32) #1
+declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32, i8*) #1
Index: llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
===
--- llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
+++ llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
@@ -15,8 +15,8 @@
 ; CHECK-SIZE-NEXT:  Cost Model: Found an estimated cost of 0 for instruction: call void @llvm.lifetime.start.p0i8(i64 1, i8* undef)

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

2020-10-01 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/lib/AST/ASTImporter.cpp:9010
+  ToPath[Idx] =
+  cast(const_cast(ImpDecl.get()));
+}

rsmith wrote:
> We want the path in an `APValue` to be canonical, but importing a canonical 
> decl might result in a non-canonical decl.
> but importing a canonical decl might result in a non-canonical decl.
this is a quite surprising behavior.



Comment at: clang/lib/AST/ASTImporter.cpp:9030-9031
+} else {
+  FromElemTy =
+  FromValue.getLValueBase().get()->getType();
+  llvm::Expected ImpDecl =

rsmith wrote:
> If you're intentionally not handling `DynamicAllocLValue` here (because those 
> should always be transient), a comment to that effect would be useful.
i added an asserts with a message.


Repository:
  rG LLVM Github Monorepo

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

2020-10-01 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 295626.
Tyker marked 15 inline comments as done.
Tyker added a comment.

addressed comments


Repository:
  rG LLVM Github Monorepo

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/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.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,460 @@
+// 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 {
+
+consteval int fint() {
+  return 6789;
+}
+
+int Unique_Int = fint();
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int'
+//CHECK-NEXT: value: Int 6789
+
+consteval __uint128_t fint128() {
+  return ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+}
+
+constexpr __uint128_t Unique_Int128 = fint128();
+//CHECK:  VarDecl {{.*}} Unique_Int128
+//CHECK-NEXT: value: Int 156773562844924187900898496343692168785
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Int 156773562844924187900898496343692168785
+
+} // namespace Integer
+
+namespace FloatingPoint {
+
+consteval double fdouble() {
+  return double(567890.67890);
+}
+
+double Unique_Double = fdouble();
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}}
+//CHECK-NEXT: value: Float 5.678907e+05
+
+} // namespace FloatingPoint
+
+// FIXME: Add test for FixedPoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+consteval B fB() {
+  return B{1, 0.7};
+}
+
+constexpr B Basic_Struct = fB();
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: fields: Int 1, Float 7.00e-01
+//CHECK-NEXT: ImplicitCastExpr
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: fields: Int 1, Float 7.00e-01
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  constexpr A(B b, int I, double D, C _c) : B(b), i(I), d(D), c(_c) {}
+  int i;
+  double d;
+  C c;
+};
+
+consteval A fA() {
+  return A(Basic_Struct, 1, 79.789, {});
+}
+
+A Advanced_Struct = fA();
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}}
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: base: Struct
+//CHECK-NEXT: fields: Int 1, Float 7.00e-01
+//CHECK-NEXT: fields: Int 1, Float 7.978900e+01
+//CHECK-NEXT: field: Struct
+//CHECK-NEXT: field: Int 9
+
+} // namespace Struct
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+consteval v4si fv4si() {
+  return (v4si){8, 2, 3};
+}
+
+v4si Vector_Int = fv4si();
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Vector length=4
+//CHECK-NEXT: elements: Int 8, Int 2, Int 3, Int 0
+
+} // namespace Vector
+
+namespace Array {
+
+struct B {
+  int arr[6];
+};
+
+consteval B fint() {
+  return B{1, 2, 3, 4, 5, 6};
+}
+
+B Array_Int = fint();
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: field: Array size=6
+//CHECK-NEXT: elements: Int 1, Int 2, Int 3, Int 4
+//CHECK-NEXT: elements: Int 5, Int 6
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+struct C {
+  A arr[3];
+};
+
+consteval C fA() {
+  return {{A{}, A{-45678, 9.8}, A{9}}};
+}
+
+C Array2_Struct = fA();
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+struct D {
+  v4si arr[2];
+};
+
+consteval D fv4si() {
+  return {{{1, 2, 3, 4}, {4, 5, 6, 7}}};
+}
+
+D Array_Vector = fv4si();
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}}
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: field: Array size=2
+//CHECK-NEXT: element: Vector length=4
+//CHECK-NEXT: elements: Int 1, Int 2, Int 3, Int 4
+//CHECK-NEXT: element: Vector length=4
+//CHECK-NEXT: elements: Int 4, Int 5, Int 6, Int 7
+
+} // namespace Array
+
+namespace Union {
+
+struct A {
+  int i = 6789;
+  float f = 987.9876;
+};
+
+union U {
+  int i;
+  A a{567890, 9876.5678f};
+};
+
+consteval U fU1() {
+  return U{0};
+}
+
+U Unique_Union1 = fU1();
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Union .i Int 0
+
+consteval U fU() {
+  return U{};
+}
+
+U Unique_Union2 = fU();
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Union .a
+//CHECK-NEXT: Struct
+//CHECK-NEXT: fields: Int 567890, Float 

[PATCH] D88645: [Annotation] Allows annotation to carry some additional constant arguments.

2020-10-01 Thread Tyker via Phabricator via cfe-commits
Tyker created this revision.
Tyker added a reviewer: aaron.ballman.
Herald added projects: clang, LLVM.
Herald added subscribers: llvm-commits, cfe-commits.
Tyker requested review of this revision.
Herald added a subscriber: jdoerfert.

This allows using annotation in a much more contexts than it currently has.
especially when annotation with template or constexpr.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D88645

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/ParsedAttr.h
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/AST/ast-dump-attr.cpp
  clang/test/CodeGen/annotations-field.c
  clang/test/CodeGen/annotations-global.c
  clang/test/CodeGen/annotations-loc.c
  clang/test/CodeGen/annotations-var.c
  clang/test/CodeGenCXX/attr-annotate.cpp
  clang/test/Misc/pragma-attribute-cxx.cpp
  clang/test/Misc/pragma-attribute-objc.m
  clang/test/Parser/access-spec-attrs.cpp
  clang/test/Parser/objc-implementation-attrs.m
  clang/test/Sema/annotate.c
  clang/test/Sema/pragma-attribute.c
  clang/test/SemaCXX/attr-annotate.cpp
  llvm/include/llvm/IR/Intrinsics.td
  llvm/test/Analysis/CostModel/X86/free-intrinsics.ll
  llvm/test/Analysis/CostModel/free-intrinsics-datalayout.ll
  llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
  llvm/test/CodeGen/Generic/ptr-annotate.ll
  llvm/test/Transforms/InstCombine/assume_inevitable.ll

Index: llvm/test/Transforms/InstCombine/assume_inevitable.ll
===
--- llvm/test/Transforms/InstCombine/assume_inevitable.ll
+++ llvm/test/Transforms/InstCombine/assume_inevitable.ll
@@ -15,7 +15,7 @@
 ; CHECK-NEXT:[[DUMMY_EQ:%.*]] = icmp ugt i32 [[LOADRES]], 42
 ; CHECK-NEXT:tail call void @llvm.assume(i1 [[DUMMY_EQ]])
 ; CHECK-NEXT:[[M_I8:%.*]] = bitcast i64* [[M]] to i8*
-; CHECK-NEXT:[[M_A:%.*]] = call i8* @llvm.ptr.annotation.p0i8(i8* nonnull [[M_I8]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i64 0, i64 0), i32 2)
+; CHECK-NEXT:[[M_A:%.*]] = call i8* @llvm.ptr.annotation.p0i8(i8* nonnull [[M_I8]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i64 0, i64 0), i32 2, i8* null)
 ; CHECK-NEXT:[[M_X:%.*]] = bitcast i8* [[M_A]] to i64*
 ; CHECK-NEXT:[[OBJSZ:%.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* [[C:%.*]], i1 false, i1 false, i1 false)
 ; CHECK-NEXT:store i64 [[OBJSZ]], i64* [[M_X]], align 4
@@ -44,7 +44,7 @@
   call void @llvm.lifetime.end.p0i8(i64 1, i8* %dummy)
 
   %m_i8 = bitcast i64* %m to i8*
-  %m_a = call i8* @llvm.ptr.annotation.p0i8(i8* %m_i8, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2)
+  %m_a = call i8* @llvm.ptr.annotation.p0i8(i8* %m_i8, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2, i8* null)
   %m_x = bitcast i8* %m_a to i64*
   %objsz = call i64 @llvm.objectsize.i64.p0i8(i8* %c, i1 false)
   store i64 %objsz, i64* %m_x
@@ -64,7 +64,7 @@
 
 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1)
 declare i32 @llvm.annotation.i32(i32, i8*, i8*, i32)
-declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32)
+declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32, i8*)
 
 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture)
 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture)
Index: llvm/test/CodeGen/Generic/ptr-annotate.ll
===
--- llvm/test/CodeGen/Generic/ptr-annotate.ll
+++ llvm/test/CodeGen/Generic/ptr-annotate.ll
@@ -10,9 +10,9 @@
 define void @foo() {
 entry:
   %m = alloca i8, align 4
-  %0 = call i8* @llvm.ptr.annotation.p0i8(i8* %m, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2)
+  %0 = call i8* @llvm.ptr.annotation.p0i8(i8* %m, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str1, i32 0, i32 0), i32 2, i8* null)
   store i8 1, i8* %0, align 4
   ret void
 }
 
-declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32) #1
+declare i8* @llvm.ptr.annotation.p0i8(i8*, i8*, i8*, i32, i8*) #1
Index: llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
===
--- llvm/test/Analysis/CostModel/free-intrinsics-no_info.ll
+++ 

[PATCH] D88643: [NFC] Correct name of profile function to Profile in APValue

2020-10-01 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.
Tyker requested review of this revision.

Capitalize the profile function of APValue such that it can be used by 
FoldingSetNodeID


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D88643

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

Index: clang/lib/AST/APValue.cpp
===
--- clang/lib/AST/APValue.cpp
+++ clang/lib/AST/APValue.cpp
@@ -77,7 +77,7 @@
   return QualType::getFromOpaquePtr(DynamicAllocType);
 }
 
-void APValue::LValueBase::profile(llvm::FoldingSetNodeID ) const {
+void APValue::LValueBase::Profile(llvm::FoldingSetNodeID ) const {
   ID.AddPointer(Ptr.getOpaqueValue());
   if (is() || is())
 return;
@@ -103,7 +103,7 @@
   Value = reinterpret_cast(BaseOrMember.getOpaqueValue());
 }
 
-void APValue::LValuePathEntry::profile(llvm::FoldingSetNodeID ) const {
+void APValue::LValuePathEntry::Profile(llvm::FoldingSetNodeID ) const {
   ID.AddInteger(Value);
 }
 
@@ -414,7 +414,7 @@
   std::swap(Data, RHS.Data);
 }
 
-void APValue::profile(llvm::FoldingSetNodeID ) const {
+void APValue::Profile(llvm::FoldingSetNodeID ) const {
   ID.AddInteger(Kind);
 
   switch (Kind) {
@@ -430,10 +430,10 @@
   case Struct:
 ID.AddInteger(getStructNumBases());
 for (unsigned I = 0, N = getStructNumBases(); I != N; ++I)
-  getStructBase(I).profile(ID);
+  getStructBase(I).Profile(ID);
 ID.AddInteger(getStructNumFields());
 for (unsigned I = 0, N = getStructNumFields(); I != N; ++I)
-  getStructField(I).profile(ID);
+  getStructField(I).Profile(ID);
 return;
 
   case Union:
@@ -442,7 +442,7 @@
   return;
 }
 ID.AddPointer(getUnionField()->getCanonicalDecl());
-getUnionValue().profile(ID);
+getUnionValue().Profile(ID);
 return;
 
   case Array: {
@@ -459,9 +459,9 @@
 //   ['a', 'c', 'x', 'x', 'x'] is profiled as
 //   [5, 'x', 3, 'c', 'a']
 llvm::FoldingSetNodeID FillerID;
-(hasArrayFiller() ? getArrayFiller() :
- getArrayInitializedElt(getArrayInitializedElts() -
-   1)).profile(FillerID);
+(hasArrayFiller() ? getArrayFiller()
+  : getArrayInitializedElt(getArrayInitializedElts() - 1))
+.Profile(FillerID);
 ID.AddNodeID(FillerID);
 unsigned NumFillers = getArraySize() - getArrayInitializedElts();
 unsigned N = getArrayInitializedElts();
@@ -481,7 +481,7 @@
   // element.
   if (N != getArraySize()) {
 llvm::FoldingSetNodeID ElemID;
-getArrayInitializedElt(N - 1).profile(ElemID);
+getArrayInitializedElt(N - 1).Profile(ElemID);
 if (ElemID != FillerID) {
   ID.AddInteger(NumFillers);
   ID.AddNodeID(ElemID);
@@ -497,14 +497,14 @@
 
 // Emit the remaining elements.
 for (; N != 0; --N)
-  getArrayInitializedElt(N - 1).profile(ID);
+  getArrayInitializedElt(N - 1).Profile(ID);
 return;
   }
 
   case Vector:
 ID.AddInteger(getVectorLength());
 for (unsigned I = 0, N = getVectorLength(); I != N; ++I)
-  getVectorElt(I).profile(ID);
+  getVectorElt(I).Profile(ID);
 return;
 
   case Int:
@@ -533,7 +533,7 @@
 return;
 
   case LValue:
-getLValueBase().profile(ID);
+getLValueBase().Profile(ID);
 ID.AddInteger(getLValueOffset().getQuantity());
 ID.AddInteger(isNullPointer());
 ID.AddInteger(isLValueOnePastTheEnd());
@@ -541,7 +541,7 @@
 // to union members, but we don't have the type here so we don't know
 // how to interpret the entries.
 for (LValuePathEntry E : getLValuePath())
-  E.profile(ID);
+  E.Profile(ID);
 return;
 
   case MemberPointer:
Index: clang/include/clang/AST/APValue.h
===
--- clang/include/clang/AST/APValue.h
+++ clang/include/clang/AST/APValue.h
@@ -150,7 +150,7 @@
 static LValueBase getDynamicAlloc(DynamicAllocLValue LV, QualType Type);
 static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo);
 
-void profile(llvm::FoldingSetNodeID ) const;
+void Profile(llvm::FoldingSetNodeID ) const;
 
 template 
 bool is() const { return Ptr.is(); }
@@ -218,7 +218,7 @@
 }
 uint64_t getAsArrayIndex() const { return Value; }
 
-void profile(llvm::FoldingSetNodeID ) const;
+void Profile(llvm::FoldingSetNodeID ) const;
 
 friend bool operator==(LValuePathEntry A, LValuePathEntry B) {
   return A.Value == B.Value;
@@ -363,9 +363,9 @@
   void swap(APValue );
 
   /// Profile this value. There is no guarantee that values of different
-  /// types will not produce the same profiled value, so the type should
-  /// typically also be profiled if it's not implied by the context.
-  void profile(llvm::FoldingSetNodeID ) const;
+  /// types will not produce the same Profiled value, so the type should
+  

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

2020-09-12 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

i believe all known issues with this patch have been fixed is it fine to reland 
?


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] D85144: [clang] Improve Dumping of APValues

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

In D85144#2205461 , @riccibruno wrote:

> I agree with you that it's fine to use `printPretty`  for leaves (and 
> additionally it would be annoying to duplicate the `LValue` case); that's 
> what I was planning to do anyway.
>
> What I am not sure I agree with is the additional complexity to handle the 
> (debugger-only and easy to avoid) case where no context is given.

i don't have a strong opinion on this.
it adds complexity, isn't testable and in many situation where the ASTContext 
is missing the QualType is missing too anyway.
soo i removed that code path.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85144

Files:
  clang/include/clang/AST/APValue.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/test/AST/ast-dump-APValue-LValue.cpp
  clang/test/AST/ast-dump-APValue-MemPtr.cpp
  clang/test/AST/ast-dump-APValue-todo.cpp

Index: clang/test/AST/ast-dump-APValue-todo.cpp
===
--- clang/test/AST/ast-dump-APValue-todo.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-// Test without serialization:
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
-// RUN:-ast-dump %s -ast-dump-filter Test \
-// RUN: | FileCheck --strict-whitespace --match-full-lines %s
-//
-// Test with serialization:
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 -emit-pch -o %t %s
-// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
-// RUN:   -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \
-// RUN: | sed -e "s/ //" -e "s/ imported//" \
-// RUN: | FileCheck --strict-whitespace --match-full-lines %s
-
-int i;
-struct S {
-  int i;
-};
-
-void Test() {
-  constexpr int *pi = 
-  // CHECK:  | `-VarDecl {{.*}}  col:{{.*}} pi 'int *const' constexpr cinit
-  // CHECK-NEXT:  |   |-value: LValue 
-
-  constexpr int(S::*pmi) = ::i;
-  // CHECK:`-VarDecl {{.*}}  col:{{.*}} pmi 'int (S::*const)' constexpr cinit
-  // CHECK-NEXT:  |-value: MemberPointer 
-}
Index: clang/test/AST/ast-dump-APValue-MemPtr.cpp
===
--- /dev/null
+++ clang/test/AST/ast-dump-APValue-MemPtr.cpp
@@ -0,0 +1,15 @@
+// Test without serialization:
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
+// RUN:-ast-dump %s -ast-dump-filter Test \
+// RUN: | FileCheck --strict-whitespace %s
+
+int i;
+struct S {
+  int i;
+};
+
+void Test() {
+  constexpr int(S::*pmi) = ::i;
+  // CHECK:VarDecl {{.*}}  col:{{.*}} pmi 'int (S::*const)' constexpr cinit
+  // CHECK-NEXT:  value: MemberPointer ::i
+}
Index: clang/test/AST/ast-dump-APValue-LValue.cpp
===
--- /dev/null
+++ clang/test/AST/ast-dump-APValue-LValue.cpp
@@ -0,0 +1,12 @@
+// Test without serialization:
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
+// RUN:-ast-dump %s -ast-dump-filter Test \
+// RUN: | FileCheck --strict-whitespace %s
+
+int i;
+
+void Test() {
+  constexpr int *pi = 
+  // CHECK:  VarDecl {{.*}}  col:{{.*}} pi 'int *const' constexpr cinit
+  // CHECK-NEXT:  |-value: LValue 
+}
Index: clang/lib/AST/TextNodeDumper.cpp
===
--- clang/lib/AST/TextNodeDumper.cpp
+++ clang/lib/AST/TextNodeDumper.cpp
@@ -493,7 +493,11 @@
 return;
   case APValue::LValue:
 (void)Context;
-OS << "LValue ";
+OS << "LValue ";
+if (Context)
+  Value.printPretty(OS, Context, Ty);
+else
+  OS << "";
 return;
   case APValue::Array: {
 unsigned ArraySize = Value.getArraySize();
@@ -558,10 +562,12 @@
 return;
   }
   case APValue::MemberPointer:
-OS << "MemberPointer ";
+OS << "MemberPointer ";
+Value.printPretty(OS, Context, Ty);
 return;
   case APValue::AddrLabelDiff:
-OS << "AddrLabelDiff ";
+OS << "AddrLabelDiff ";
+Value.printPretty(OS, Context, Ty);
 return;
   }
   llvm_unreachable("Unknown APValue kind!");
Index: clang/lib/AST/APValue.cpp
===
--- clang/lib/AST/APValue.cpp
+++ clang/lib/AST/APValue.cpp
@@ -388,6 +388,11 @@
 
 void APValue::printPretty(raw_ostream , const ASTContext ,
   QualType Ty) const {
+  printPretty(Out, , Ty);
+}
+
+void APValue::printPretty(raw_ostream , const ASTContext *Ctx,
+  QualType Ty) const {
   switch (getKind()) {
   case APValue::None:
 Out << "";
@@ -426,6 +431,7 @@
 << GetApproxValue(getComplexFloatImag()) << "i";
 return;
   case APValue::LValue: {
+assert(Ctx);
 bool IsReference = 

[PATCH] D85933: Don't track consteval references for dependent members

2020-08-14 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

thanks for this,

here is a few comments aside from that this seems fine.




Comment at: clang/lib/Sema/SemaOverload.cpp:1761
+  llvm::SaveAndRestore DisableIITracking(
+  S.RebuildingImmediateInvocation, true);
+

I don't think RebuildingImmediateInvocation should be used here since we are 
not rebuilding immediate invocations

setSuppressAllDiagnostics or TentativeAnalysisScope seems more adapted.



Comment at: clang/test/SemaCXX/cxx2a-consteval.cpp:131
+  consteval A() = default;
+  consteval ~A() = default; // expected-error {{destructor cannot be declared 
consteval}}
+};

could you check that this diagnostic and those like it doesn't appear when the 
struct A isn't instantiated.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85933

___
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

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

rebased


Repository:
  rG LLVM Github Monorepo

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/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.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,460 @@
+// 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 {
+
+consteval int fint() {
+  return 6789;
+}
+
+int Unique_Int = fint();
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int'
+//CHECK-NEXT: value: Int 6789
+
+consteval __uint128_t fint128() {
+  return ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+}
+
+constexpr __uint128_t Unique_Int128 = fint128();
+//CHECK:  VarDecl {{.*}} Unique_Int128
+//CHECK-NEXT: value: Int 156773562844924187900898496343692168785
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Int 156773562844924187900898496343692168785
+
+} // namespace Integer
+
+namespace FloatingPoint {
+
+consteval double fdouble() {
+  return double(567890.67890);
+}
+
+double Unique_Double = fdouble();
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}}
+//CHECK-NEXT: value: Float 5.678907e+05
+
+} // namespace FloatingPoint
+
+// FIXME: Add test for FixedPoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+consteval B fB() {
+  return B{1, 0.7};
+}
+
+constexpr B Basic_Struct = fB();
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: fields: Int 1, Float 7.00e-01
+//CHECK-NEXT: ImplicitCastExpr
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: fields: Int 1, Float 7.00e-01
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  constexpr A(B b, int I, double D, C _c) : B(b), i(I), d(D), c(_c) {}
+  int i;
+  double d;
+  C c;
+};
+
+consteval A fA() {
+  return A(Basic_Struct, 1, 79.789, {});
+}
+
+A Advanced_Struct = fA();
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}}
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: base: Struct
+//CHECK-NEXT: fields: Int 1, Float 7.00e-01
+//CHECK-NEXT: fields: Int 1, Float 7.978900e+01
+//CHECK-NEXT: field: Struct
+//CHECK-NEXT: field: Int 9
+
+} // namespace Struct
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+consteval v4si fv4si() {
+  return (v4si){8, 2, 3};
+}
+
+v4si Vector_Int = fv4si();
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Vector length=4
+//CHECK-NEXT: elements: Int 8, Int 2, Int 3, Int 0
+
+} // namespace Vector
+
+namespace Array {
+
+struct B {
+  int arr[6];
+};
+
+consteval B fint() {
+  return B{1, 2, 3, 4, 5, 6};
+}
+
+B Array_Int = fint();
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: field: Array size=6
+//CHECK-NEXT: elements: Int 1, Int 2, Int 3, Int 4
+//CHECK-NEXT: elements: Int 5, Int 6
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+struct C {
+  A arr[3];
+};
+
+consteval C fA() {
+  return {{A{}, A{-45678, 9.8}, A{9}}};
+}
+
+C Array2_Struct = fA();
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+struct D {
+  v4si arr[2];
+};
+
+consteval D fv4si() {
+  return {{{1, 2, 3, 4}, {4, 5, 6, 7}}};
+}
+
+D Array_Vector = fv4si();
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}}
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: field: Array size=2
+//CHECK-NEXT: element: Vector length=4
+//CHECK-NEXT: elements: Int 1, Int 2, Int 3, Int 4
+//CHECK-NEXT: element: Vector length=4
+//CHECK-NEXT: elements: Int 4, Int 5, Int 6, Int 7
+
+} // namespace Array
+
+namespace Union {
+
+struct A {
+  int i = 6789;
+  float f = 987.9876;
+};
+
+union U {
+  int i;
+  A a{567890, 9876.5678f};
+};
+
+consteval U fU1() {
+  return U{0};
+}
+
+U Unique_Union1 = fU1();
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Union .i Int 0
+
+consteval U fU() {
+  return U{};
+}
+
+U Unique_Union2 = fU();
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Union .a
+//CHECK-NEXT: Struct
+//CHECK-NEXT: fields: Int 567890, Float 9.876567e+03
+
+} // namespace Union
+
+namespace 

[PATCH] D85144: [clang] Improve Dumping of APValues

2020-08-07 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 283984.
Tyker marked an inline comment as done.
Tyker added a comment.

this a patch i had to improve dumping before your improvement to dumping.

I think there is benefits to being able to dump APValues like LValues without 
an ASTContext even if the output will not be as good. but i agree that now that 
the dumper has an ASTContext during ast-dump it is hard to test.

In D85144#2191440 , @riccibruno wrote:

> Thanks for finishing this.
>
> I don't see why you are adding `dumpPretty`; the point of the `dump` function 
> I added is to dump the `APValue` as the tree-like structure it is. But your 
> `dumpPretty` doesn't do that at all.

the intent was to reuse the same printing code that is already used for 
diagnostics (printPretty) since it can print Member pointers and LValues. it 
isn't being used for printing anything that isn't a leaf(as in no child 
APValues) when used in AST dump. maybe the name is the issue here.

> So `dump` does one thing and `dumpPretty` does another completely different 
> thing.

i removed dumpPretty and instead added a new overload to printPretty.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85144

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/test/AST/ast-dump-APValue-LValue.cpp
  clang/test/AST/ast-dump-APValue-MemPtr.cpp
  clang/test/AST/ast-dump-APValue-todo.cpp

Index: clang/test/AST/ast-dump-APValue-todo.cpp
===
--- clang/test/AST/ast-dump-APValue-todo.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-// Test without serialization:
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
-// RUN:-ast-dump %s -ast-dump-filter Test \
-// RUN: | FileCheck --strict-whitespace --match-full-lines %s
-//
-// Test with serialization:
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 -emit-pch -o %t %s
-// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
-// RUN:   -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \
-// RUN: | sed -e "s/ //" -e "s/ imported//" \
-// RUN: | FileCheck --strict-whitespace --match-full-lines %s
-
-int i;
-struct S {
-  int i;
-};
-
-void Test() {
-  constexpr int *pi = 
-  // CHECK:  | `-VarDecl {{.*}}  col:{{.*}} pi 'int *const' constexpr cinit
-  // CHECK-NEXT:  |   |-value: LValue 
-
-  constexpr int(S::*pmi) = ::i;
-  // CHECK:`-VarDecl {{.*}}  col:{{.*}} pmi 'int (S::*const)' constexpr cinit
-  // CHECK-NEXT:  |-value: MemberPointer 
-}
Index: clang/test/AST/ast-dump-APValue-MemPtr.cpp
===
--- /dev/null
+++ clang/test/AST/ast-dump-APValue-MemPtr.cpp
@@ -0,0 +1,23 @@
+// Test without serialization:
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
+// RUN:-ast-dump %s -ast-dump-filter Test \
+// RUN: | FileCheck --strict-whitespace --match-full-lines %s
+//
+// TODO: Add serialization when it is finished
+
+int i;
+struct S {
+  int i;
+};
+
+void Test() {
+  constexpr int(S::*pmi) = ::i;
+}
+// CHECK:Dumping Test:
+// CHECK-NEXT:FunctionDecl {{.*}} <{{.*}}ast-dump-APValue-MemPtr.cpp{{.*}}, line:{{.*}}> line:{{.*}} Test 'void ()'
+// CHECK-NEXT:`-CompoundStmt {{.*}} 
+// CHECK-NEXT:  `-DeclStmt {{.*}} 
+// CHECK-NEXT:`-VarDecl {{.*}}  col:{{.*}} pmi 'int (S::*const)' constexpr cinit
+// CHECK-NEXT:  |-value: MemberPointer ::i
+// CHECK-NEXT:  `-UnaryOperator {{.*}}  'int S::*' prefix '&' cannot overflow
+// CHECK-NEXT:`-DeclRefExpr {{.*}}  'int' lvalue Field {{.*}} 'i' 'int'
Index: clang/test/AST/ast-dump-APValue-LValue.cpp
===
--- /dev/null
+++ clang/test/AST/ast-dump-APValue-LValue.cpp
@@ -0,0 +1,21 @@
+// Test without serialization:
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
+// RUN:-ast-dump %s -ast-dump-filter Test \
+// RUN: | FileCheck --strict-whitespace --match-full-lines %s
+//
+// TODO: Add serialization when it is finished
+
+int i;
+
+void Test() {
+  constexpr int *pi = 
+
+}
+// CHECK:Dumping Test:
+// CHECK-NEXT:FunctionDecl {{.*}} <{{.*}}ast-dump-APValue-LValue.cpp{{.*}}, line:{{.*}}> line:{{.*}} Test 'void ()'
+// CHECK-NEXT:`-CompoundStmt {{.*}} 
+// CHECK-NEXT:  `-DeclStmt {{.*}} 
+// CHECK-NEXT:`-VarDecl {{.*}}  col:{{.*}} pi 'int *const' constexpr cinit
+// CHECK-NEXT:  |-value: LValue 
+// CHECK-NEXT:  `-UnaryOperator {{.*}}  'int *' prefix '&' cannot overflow
+// CHECK-NEXT:`-DeclRefExpr {{.*}}  'int' lvalue Var {{.*}} 'i' 'int'
Index: clang/lib/AST/TextNodeDumper.cpp

[PATCH] D85144: [clang] Improve Dumping of APValues

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

remove unintended code.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D85144

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/test/AST/ast-dump-APValue-LValue.cpp
  clang/test/AST/ast-dump-APValue-MemPtr.cpp
  clang/test/AST/ast-dump-APValue-todo.cpp

Index: clang/test/AST/ast-dump-APValue-todo.cpp
===
--- clang/test/AST/ast-dump-APValue-todo.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-// Test without serialization:
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
-// RUN:-ast-dump %s -ast-dump-filter Test \
-// RUN: | FileCheck --strict-whitespace --match-full-lines %s
-//
-// Test with serialization:
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 -emit-pch -o %t %s
-// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
-// RUN:   -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \
-// RUN: | sed -e "s/ //" -e "s/ imported//" \
-// RUN: | FileCheck --strict-whitespace --match-full-lines %s
-
-int i;
-struct S {
-  int i;
-};
-
-void Test() {
-  constexpr int *pi = 
-  // CHECK:  | `-VarDecl {{.*}}  col:{{.*}} pi 'int *const' constexpr cinit
-  // CHECK-NEXT:  |   |-value: LValue 
-
-  constexpr int(S::*pmi) = ::i;
-  // CHECK:`-VarDecl {{.*}}  col:{{.*}} pmi 'int (S::*const)' constexpr cinit
-  // CHECK-NEXT:  |-value: MemberPointer 
-}
Index: clang/test/AST/ast-dump-APValue-MemPtr.cpp
===
--- /dev/null
+++ clang/test/AST/ast-dump-APValue-MemPtr.cpp
@@ -0,0 +1,15 @@
+// Test without serialization:
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
+// RUN:-ast-dump %s -ast-dump-filter Test \
+// RUN: | FileCheck --strict-whitespace %s
+
+int i;
+struct S {
+  int i;
+};
+
+void Test() {
+  constexpr int(S::*pmi) = ::i;
+  // CHECK:VarDecl {{.*}}  col:{{.*}} pmi 'int (S::*const)' constexpr cinit
+  // CHECK-NEXT:  value: MemberPointer ::i
+}
Index: clang/test/AST/ast-dump-APValue-LValue.cpp
===
--- /dev/null
+++ clang/test/AST/ast-dump-APValue-LValue.cpp
@@ -0,0 +1,12 @@
+// Test without serialization:
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
+// RUN:-ast-dump %s -ast-dump-filter Test \
+// RUN: | FileCheck --strict-whitespace %s
+
+int i;
+
+void Test() {
+  constexpr int *pi = 
+  // CHECK:  VarDecl {{.*}}  col:{{.*}} pi 'int *const' constexpr cinit
+  // CHECK-NEXT:  |-value: LValue 
+}
Index: clang/lib/AST/TextNodeDumper.cpp
===
--- clang/lib/AST/TextNodeDumper.cpp
+++ clang/lib/AST/TextNodeDumper.cpp
@@ -493,7 +493,8 @@
 return;
   case APValue::LValue:
 (void)Context;
-OS << "LValue ";
+OS << "LValue ";
+Value.dumpPretty(OS, Ty, PrintPolicy);
 return;
   case APValue::Array: {
 unsigned ArraySize = Value.getArraySize();
@@ -558,10 +559,12 @@
 return;
   }
   case APValue::MemberPointer:
-OS << "MemberPointer ";
+OS << "MemberPointer ";
+Value.dumpPretty(OS, Ty, PrintPolicy);
 return;
   case APValue::AddrLabelDiff:
-OS << "AddrLabelDiff ";
+OS << "AddrLabelDiff ";
+Value.dumpPretty(OS, Ty, PrintPolicy);
 return;
   }
   llvm_unreachable("Unknown APValue kind!");
Index: clang/lib/AST/APValue.cpp
===
--- clang/lib/AST/APValue.cpp
+++ clang/lib/AST/APValue.cpp
@@ -386,9 +386,10 @@
   return V.convertToDouble();
 }
 
-void APValue::printPretty(raw_ostream , const ASTContext ,
-  QualType Ty) const {
-  switch (getKind()) {
+static void InternalPrinter(raw_ostream , const APValue , QualType Ty,
+const ASTContext *Ctx,
+const clang::PrintingPolicy ) {
+  switch (Value.getKind()) {
   case APValue::None:
 Out << "";
 return;
@@ -397,33 +398,33 @@
 return;
   case APValue::Int:
 if (Ty->isBooleanType())
-  Out << (getInt().getBoolValue() ? "true" : "false");
+  Out << (Value.getInt().getBoolValue() ? "true" : "false");
 else
-  Out << getInt();
+  Out << Value.getInt();
 return;
   case APValue::Float:
-Out << GetApproxValue(getFloat());
+Out << GetApproxValue(Value.getFloat());
 return;
   case APValue::FixedPoint:
-Out << getFixedPoint();
+Out << Value.getFixedPoint();
 return;
   case APValue::Vector: {
 Out << '{';
 QualType ElemTy = Ty->castAs()->getElementType();
-

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

2020-08-03 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:11883-11885
   ExprResult Result =
   ActOnFinishFullExpr(Init, VDecl->getLocation(),
   /*DiscardedValue*/ false, VDecl->isConstexpr());

rsmith wrote:
> This may create additional AST nodes outside the `ConstantExpr`, which 
> `VarDecl::evaluateValue` is not expecting to see (in particular, if we have 
> cleanups for the initializer). Should the `ConstantExpr` go outside those 
> nodes rather than inside?
i removed the changes to the storage of constexpr values since it was only used 
for testing purposes and we can now use consteval for that purpose.



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

rsmith wrote:
> Tyker wrote:
> > 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.
> What are the cases for which we still encounter expressions as lvalue bases 
> during serialization? I think all the other ones should be OK, but maybe 
> there's another interesting one we've overlooked.
the 2 example that come to mind are string literals and type_info there are 
probably more.


Repository:
  rG LLVM Github Monorepo

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] D85144: [clang] Improve Dumping of APValues

2020-08-03 Thread Tyker via Phabricator via cfe-commits
Tyker created this revision.
Tyker added reviewers: rsmith, riccibruno.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Tyker requested review of this revision.

this is required for proper testing of D63640 


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85144

Files:
  clang/include/clang/AST/APValue.h
  clang/include/clang/AST/PrettyPrinter.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/test/AST/ast-dump-APValue-LValue.cpp
  clang/test/AST/ast-dump-APValue-MemPtr.cpp
  clang/test/AST/ast-dump-APValue-todo.cpp

Index: clang/test/AST/ast-dump-APValue-todo.cpp
===
--- clang/test/AST/ast-dump-APValue-todo.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-// Test without serialization:
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
-// RUN:-ast-dump %s -ast-dump-filter Test \
-// RUN: | FileCheck --strict-whitespace --match-full-lines %s
-//
-// Test with serialization:
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 -emit-pch -o %t %s
-// RUN: %clang_cc1 -x c++ -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
-// RUN:   -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \
-// RUN: | sed -e "s/ //" -e "s/ imported//" \
-// RUN: | FileCheck --strict-whitespace --match-full-lines %s
-
-int i;
-struct S {
-  int i;
-};
-
-void Test() {
-  constexpr int *pi = 
-  // CHECK:  | `-VarDecl {{.*}}  col:{{.*}} pi 'int *const' constexpr cinit
-  // CHECK-NEXT:  |   |-value: LValue 
-
-  constexpr int(S::*pmi) = ::i;
-  // CHECK:`-VarDecl {{.*}}  col:{{.*}} pmi 'int (S::*const)' constexpr cinit
-  // CHECK-NEXT:  |-value: MemberPointer 
-}
Index: clang/test/AST/ast-dump-APValue-MemPtr.cpp
===
--- /dev/null
+++ clang/test/AST/ast-dump-APValue-MemPtr.cpp
@@ -0,0 +1,15 @@
+// Test without serialization:
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
+// RUN:-ast-dump %s -ast-dump-filter Test \
+// RUN: | FileCheck --strict-whitespace %s
+
+int i;
+struct S {
+  int i;
+};
+
+void Test() {
+  constexpr int(S::*pmi) = ::i;
+  // CHECK:VarDecl {{.*}}  col:{{.*}} pmi 'int (S::*const)' constexpr cinit
+  // CHECK-NEXT:  value: MemberPointer ::i
+}
Index: clang/test/AST/ast-dump-APValue-LValue.cpp
===
--- /dev/null
+++ clang/test/AST/ast-dump-APValue-LValue.cpp
@@ -0,0 +1,12 @@
+// Test without serialization:
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -Wno-unused-value -std=gnu++17 \
+// RUN:-ast-dump %s -ast-dump-filter Test \
+// RUN: | FileCheck --strict-whitespace %s
+
+int i;
+
+void Test() {
+  constexpr int *pi = 
+  // CHECK:  VarDecl {{.*}}  col:{{.*}} pi 'int *const' constexpr cinit
+  // CHECK-NEXT:  |-value: LValue 
+}
Index: clang/lib/AST/TextNodeDumper.cpp
===
--- clang/lib/AST/TextNodeDumper.cpp
+++ clang/lib/AST/TextNodeDumper.cpp
@@ -493,7 +493,8 @@
 return;
   case APValue::LValue:
 (void)Context;
-OS << "LValue ";
+OS << "LValue ";
+Value.dumpPretty(OS, Ty, PrintPolicy);
 return;
   case APValue::Array: {
 unsigned ArraySize = Value.getArraySize();
@@ -558,10 +559,12 @@
 return;
   }
   case APValue::MemberPointer:
-OS << "MemberPointer ";
+OS << "MemberPointer ";
+Value.dumpPretty(OS, Ty, PrintPolicy);
 return;
   case APValue::AddrLabelDiff:
-OS << "AddrLabelDiff ";
+OS << "AddrLabelDiff ";
+Value.dumpPretty(OS, Ty, PrintPolicy);
 return;
   }
   llvm_unreachable("Unknown APValue kind!");
Index: clang/lib/AST/APValue.cpp
===
--- clang/lib/AST/APValue.cpp
+++ clang/lib/AST/APValue.cpp
@@ -386,9 +386,10 @@
   return V.convertToDouble();
 }
 
-void APValue::printPretty(raw_ostream , const ASTContext ,
-  QualType Ty) const {
-  switch (getKind()) {
+static void InternalPrinter(raw_ostream , const APValue , QualType Ty,
+const ASTContext *Ctx,
+const clang::PrintingPolicy ) {
+  switch (Value.getKind()) {
   case APValue::None:
 Out << "";
 return;
@@ -397,33 +398,33 @@
 return;
   case APValue::Int:
 if (Ty->isBooleanType())
-  Out << (getInt().getBoolValue() ? "true" : "false");
+  Out << (Value.getInt().getBoolValue() ? "true" : "false");
 else
-  Out << getInt();
+  Out << Value.getInt();
 return;
   case APValue::Float:
-Out << GetApproxValue(getFloat());
+Out << GetApproxValue(Value.getFloat());
 return;
   case APValue::FixedPoint:
-Out << getFixedPoint();
+Out << Value.getFixedPoint();
 return;
   case 

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

2020-08-03 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 282682.
Tyker edited the summary of this revision.
Tyker added a comment.

Sorry for the delay

In D63640#2151016 , @rsmith wrote:

> Are we at a point where we can test this now?

Yes we can use consteval to test it. so i removed changes to constexpr AST 
modling.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D63640

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/ASTImporter.h
  clang/lib/AST/APValue.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/Expr.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.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,460 @@
+// 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 {
+
+consteval int fint() {
+  return 6789;
+}
+
+int Unique_Int = fint();
+//CHECK:  VarDecl {{.*}} Unique_Int
+//CHECK-NEXT: ConstantExpr {{.*}} 'int'
+//CHECK-NEXT: value: Int 6789
+
+consteval __uint128_t fint128() {
+  return ((__uint128_t)0x75f17d6b3588f843 << 64) | 0xb13dea7c9c324e51;
+}
+
+constexpr __uint128_t Unique_Int128 = fint128();
+//CHECK:  VarDecl {{.*}} Unique_Int128
+//CHECK-NEXT: value: Int 156773562844924187900898496343692168785
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Int 156773562844924187900898496343692168785
+
+} // namespace Integer
+
+namespace FloatingPoint {
+
+consteval double fdouble() {
+  return double(567890.67890);
+}
+
+double Unique_Double = fdouble();
+//CHECK:  VarDecl {{.*}} Unique_Double
+//CHECK-NEXT: ConstantExpr {{.*}}
+//CHECK-NEXT: value: Float 5.678907e+05
+
+} // namespace FloatingPoint
+
+// FIXME: Add test for FixedPoint, ComplexInt, ComplexFloat, AddrLabelDiff.
+
+namespace Struct {
+
+struct B {
+  int i;
+  double d;
+};
+
+consteval B fB() {
+  return B{1, 0.7};
+}
+
+constexpr B Basic_Struct = fB();
+//CHECK:  VarDecl {{.*}} Basic_Struct
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: fields: Int 1, Float 7.00e-01
+//CHECK-NEXT: ImplicitCastExpr
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: fields: Int 1, Float 7.00e-01
+
+struct C {
+  int i = 9;
+};
+
+struct A : B {
+  constexpr A(B b, int I, double D, C _c) : B(b), i(I), d(D), c(_c) {}
+  int i;
+  double d;
+  C c;
+};
+
+consteval A fA() {
+  return A(Basic_Struct, 1, 79.789, {});
+}
+
+A Advanced_Struct = fA();
+//CHECK:  VarDecl {{.*}} Advanced_Struct
+//CHECK-NEXT: ConstantExpr {{.*}}
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: base: Struct
+//CHECK-NEXT: fields: Int 1, Float 7.00e-01
+//CHECK-NEXT: fields: Int 1, Float 7.978900e+01
+//CHECK-NEXT: field: Struct
+//CHECK-NEXT: field: Int 9
+
+} // namespace Struct
+
+namespace Vector {
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+consteval v4si fv4si() {
+  return (v4si){8, 2, 3};
+}
+
+v4si Vector_Int = fv4si();
+//CHECK:  VarDecl {{.*}} Vector_Int
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Vector length=4
+//CHECK-NEXT: elements: Int 8, Int 2, Int 3, Int 0
+
+} // namespace Vector
+
+namespace Array {
+
+struct B {
+  int arr[6];
+};
+
+consteval B fint() {
+  return B{1, 2, 3, 4, 5, 6};
+}
+
+B Array_Int = fint();
+//CHECK:  VarDecl {{.*}} Array_Int
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: field: Array size=6
+//CHECK-NEXT: elements: Int 1, Int 2, Int 3, Int 4
+//CHECK-NEXT: elements: Int 5, Int 6
+
+struct A {
+  int i = 789;
+  double d = 67890.09876;
+};
+
+struct C {
+  A arr[3];
+};
+
+consteval C fA() {
+  return {{A{}, A{-45678, 9.8}, A{9}}};
+}
+
+C Array2_Struct = fA();
+//CHECK:  VarDecl {{.*}} Array2_Struct
+//CHECK-NEXT: ConstantExpr {{.*}}
+
+using v4si = int __attribute__((__vector_size__(16)));
+
+struct D {
+  v4si arr[2];
+};
+
+consteval D fv4si() {
+  return {{{1, 2, 3, 4}, {4, 5, 6, 7}}};
+}
+
+D Array_Vector = fv4si();
+//CHECK:  VarDecl {{.*}} Array_Vector
+//CHECK-NEXT: ConstantExpr {{.*}}
+//CHECK-NEXT: value: Struct
+//CHECK-NEXT: field: Array size=2
+//CHECK-NEXT: element: Vector length=4
+//CHECK-NEXT: elements: Int 1, Int 2, Int 3, Int 4
+//CHECK-NEXT: element: Vector length=4
+//CHECK-NEXT: elements: Int 4, Int 5, Int 6, Int 7
+
+} // namespace Array
+
+namespace Union {
+
+struct A {
+  int i = 6789;
+  float f = 987.9876;
+};
+
+union U {
+  int i;
+  A a{567890, 9876.5678f};
+};
+
+consteval U fU1() {
+  return U{0};
+}
+
+U Unique_Union1 = fU1();
+//CHECK:  VarDecl {{.*}} Unique_Union
+//CHECK-NEXT: ConstantExpr
+//CHECK-NEXT: value: Union .i Int 0
+
+consteval U fU() {
+  return U{};
+}
+
+U 

[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)]
+  

[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-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 

[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 

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

2020-06-25 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGc95ffadb2474: [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/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 

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

2020-06-24 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 272968.
Tyker marked 2 inline comments as done.
Tyker added a comment.

addressed comments


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/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 true) 

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

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

sorry for not doing much recently.

i split with an NFC patch with only test updates.
and addressed comments


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/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] 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=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 () {
+  return i_const;
+}
+
+const int _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 _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 &() {
+  return static_cast(i_const);
+}
+
+const int &_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:store i64 17, i64* [[B]], 

[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] D76420: Prevent IR-gen from emitting consteval declarations

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

NFC


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/CGBlocks.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/CGObjC.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CGStmtOpenMP.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,212 @@
+// 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 () {
+  return i_const;
+}
+
+const int _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 _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 &() {
+  return static_cast(i_const);
+}
+
+// EVAL-NOT: @_Z4retIv()
+// EXPR: @_Z4retIv()
+const int &_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:store i64 17, i64* [[B]], align 8
+  // EVAL-FN-NEXT:

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

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




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/CGBlocks.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/CGObjC.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CGStmtOpenMP.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/constant-expression-cxx11.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/SemaCXX/constant-expression-cxx11.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1578,7 +1578,7 @@
 namespace CompoundLiteral {
   // Matching GCC, file-scope array compound literals initialized by constants
   // are lifetime-extended.
-  constexpr int *p = (int*)(int[1]){3}; // expected-warning {{C99}}
+  constexpr int *p = (int*)(int[1]){2 + __builtin_is_constant_evaluated()}; // expected-warning {{C99}}
   static_assert(*p == 3, "");
   static_assert((int[2]){1, 2}[1] == 2, ""); // expected-warning {{C99}}
 
Index: clang/test/CodeGenCXX/cxx2a-consteval.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/cxx2a-consteval.cpp
@@ -0,0 +1,212 @@
+// 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 () {
+  return i_const;
+}
+
+const int _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 _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 &() {
+  return static_cast(i_const);
+}
+
+// EVAL-NOT: @_Z4retIv()
+// EXPR: @_Z4retIv()
+const int &_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: 

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

2020-05-15 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/lib/AST/ExprConstant.cpp:6807-6808
 
+llvm::SaveAndRestore InConstantContext(Info.InConstantContext, true);
 return StmtVisitorTy::Visit(E->getSubExpr());
   }

rsmith wrote:
> I don't think this is really right, but perhaps the difference isn't 
> observable right now. What I'm thinking of is a case like this:
> 
> ```
> consteval int do_stuff() {
>   __builtin_produce_diagnostic("hello world\n");
>   return 42;
> }
> constexpr int f() {
>   int n = do_stuff();
>   return n;
> }
> int k = f();
> ```
> 
> Here, I would expect that when we process the immediate invocation of 
> `do_stuff()` in `f`, we would immediately evaluate it, including issuing its 
> diagnostic. And then for all subsequent calls to `f()`, we would never 
> re-evaluate it.
> 
> I can see a couple of ways this could work:
> 
>  * Whenever we create a `ConstantExpr`, we always evaluate it and fill in the 
> `APValue` result; it's never absent except perhaps in a window of time 
> between forming that AST node and deciding for sure that we want to keep it 
> (for nested immediate invocation handling).
>  * Whenever constant evaluation meets a `ConstantExpr` that doesn't have an 
> associated result yet, it triggers that result to be computed and cached, as 
> a separate evaluation.
> 
> I think the first of those two approaches is much better: lazily evaluating 
> the `ConstantExpr` will require us to save update records if we're writing an 
> AST file, and will mean we don't always have an obvious point where the 
> side-effects from builtin consteval functions (eg, reflection-driven actions) 
> happen.
> 
> So I think the right thing to do is probably to say that a `ConstantExpr` 
> that hasn't yet had its `APValue` result filled in is non-constant for now, 
> and to ensure that everywhere that creates a `ConstantExpr` always eventually 
> either removes it again or fills in the result.
ok seems reasonable.




Comment at: clang/lib/CodeGen/CGExprConstant.cpp:1364-1365
+llvm::Constant *ConstantEmitter::tryEmitConstantExpr(const ConstantExpr *CE) {
+  if (!CE->isImmediateInvocation())
+return nullptr;
+  const Expr *Inner = CE->getSubExpr()->IgnoreImplicit();

rsmith wrote:
> I'm fine with having this check for now, but eventually I think we should do 
> this for all `ConstantExpr`s, regardless of whether they're immediate 
> invocations.
this can be relaxed to hasAPValueResult without any change in behavior.



Comment at: clang/lib/CodeGen/CGExprConstant.cpp:1374
+  emitAbstract(CE->getBeginLoc(), CE->getAPValueResult(), RetType);
+  return Res;
+}

rsmith wrote:
> Can we assert that we succeeded here? This emission should never fail.
from the comment on emitAbstract's declaration it seems to already be the case.
```
  /// Emit the result of the given expression as an abstract constant,
  /// asserting that it succeeded.  This is only safe to do when the
  /// expression is known to be a constant expression with either a fairly
  /// simple type or a known simple form.
  llvm::Constant *emitAbstract(const Expr *E, QualType T);
  llvm::Constant *emitAbstract(SourceLocation loc, const APValue ,
   QualType T);
``` 



Comment at: clang/lib/CodeGen/CGExprScalar.cpp:464-470
+  QualType RetType = cast(E->getSubExpr()->IgnoreImplicit())
+ ->getCallReturnType(CGF.getContext());
+  if (RetType->isReferenceType()) {
+return CGF.Builder.CreateLoad(Address(
+Result, CGF.getContext().getTypeAlignInChars(
+cast(RetType)->getPointeeType(;
+  }

rsmith wrote:
> OK, so this is presumably handling the case where `ScalarExprEmitter` is used 
> to emit an lvalue expression, under the understanding that when it reaches 
> the eventual lvalue a load will be implicitly generated.
> 
> Looking for a `CallExpr` that returns a reference type is not the best way to 
> handle this. It's brittle (it would break if `tryEmitConstantExpr` starts 
> emitting more kinds of `ConstantExpr` or if we start supporting more kinds of 
> immediate invocations) and we don't need to perform such a subtle check: 
> instead, please just check whether `E` is an lvalue, and perform a load if so.
we need to generate a load for rvalue-reference as well so i think we need to 
check wether E is a glvalue instead of just lvalue.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76420



___
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-05-15 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 264236.
Tyker marked 12 inline comments as done.
Tyker added a comment.

addressed comments


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/CGBlocks.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/CGObjC.cpp
  clang/lib/CodeGen/CGStmt.cpp
  clang/lib/CodeGen/CGStmtOpenMP.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/constant-expression-cxx11.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/SemaCXX/constant-expression-cxx11.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1578,7 +1578,7 @@
 namespace CompoundLiteral {
   // Matching GCC, file-scope array compound literals initialized by constants
   // are lifetime-extended.
-  constexpr int *p = (int*)(int[1]){3}; // expected-warning {{C99}}
+  constexpr int *p = (int*)(int[1]){2 + __builtin_is_constant_evaluated()}; // expected-warning {{C99}}
   static_assert(*p == 3, "");
   static_assert((int[2]){1, 2}[1] == 2, ""); // expected-warning {{C99}}
 
Index: clang/test/CodeGenCXX/cxx2a-consteval.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/cxx2a-consteval.cpp
@@ -0,0 +1,212 @@
+// 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
+// RUNA: 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 _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);
+}
+
+// EVAL-NOT: @_Z4retIv()
+// EXPR: @_Z4retIv()
+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: 

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

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

rebased


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76420

Files:
  clang/include/clang/AST/Expr.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/CodeGen/CGCall.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 -Wno-unused-value %s -verify > /dev/null
 
 typedef __SIZE_TYPE__ size_t;
 
Index: clang/test/CodeGenCXX/cxx2a-consteval.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/cxx2a-consteval.cpp
@@ -0,0 +1,212 @@
+// 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
+// RUNA: 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 _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);
+}
+
+// EVAL-NOT: @_Z4retIv()
+// EXPR: @_Z4retIv()
+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:store i64 17, i64* [[B]], align 8
+// EVAL-FN-NEXT:[[TMP2:%.*]] = load i64, i64* [[B]], align 8
+// EVAL-FN-NEXT:ret i64 [[TMP2]]
+//
+  long b = retAgg().b;
+  return b;
+}
+
+// EVAL-STATIC: @A = 

[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] D76724: Prevent immediate evaluations inside of decltype

2020-03-25 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/lib/Sema/SemaExpr.cpp:15389
   if (!E.isUsable() || !Decl || !Decl->isConsteval() || isConstantEvaluated() 
||
-  RebuildingImmediateInvocation)
+  isInDeclType(*this) || RebuildingImmediateInvocation)
 return E;

the issue is seems more general than delctype. it applies to all unvealuated 
context (sizeof, alignof ...)

i think we should use Sema::isUnevaluatedContext() here.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76724



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


[PATCH] D76443: Use ConstantExpr cached APValues if present for code generation

2020-03-21 Thread Tyker via Phabricator via cfe-commits
Tyker added inline comments.



Comment at: clang/lib/CodeGen/CGExprConstant.cpp:1871
+llvm::Constant *CodeGenModule::EmitConstantValue(const APValue ,
+ QualType DestType,
+ CodeGenFunction *CGF) {

this looks like it is doing the same thing as `llvm::Constant 
*ConstantEmitter::tryEmitAbstract(const APValue , QualType T)` how is it 
different ?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76443



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


[PATCH] D74007: [clang] Add support for consteval constructors

2020-03-20 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG180581cfcf51: [clang] Add support for consteval constructors 
(authored by Tyker).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D74007?vs=242881=251596#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D74007

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaInit.cpp
  clang/lib/Sema/TreeTransform.h
  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
@@ -260,6 +260,19 @@
 
 }
 
+namespace std {
+
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+
+template 
+constexpr typename std::remove_reference::type&& move(T &) noexcept {
+  return static_cast::type &&>(t);
+}
+
+}
+
 namespace temporaries {
 
 struct A {
@@ -295,12 +308,12 @@
   { int k = const_a_ref(A()); }
   { int k = const_a_ref(a); }
   { int k = rvalue_ref(A()); }
-  { int k = rvalue_ref(static_cast(a)); }
+  { int k = rvalue_ref(std::move(a)); }
   { int k = const_a_ref(A().ret_a()); }
   { int k = const_a_ref(to_lvalue_ref(A().ret_a())); }
-  { int k = const_a_ref(to_lvalue_ref(static_cast(a))); }
+  { int k = const_a_ref(to_lvalue_ref(std::move(a))); }
   { int k = by_value_a(A().ret_a()); }
-  { int k = by_value_a(to_lvalue_ref(static_cast(a))); }
+  { int k = by_value_a(to_lvalue_ref(std::move(a))); }
   { int k = (A().ret_a(), A().ret_i()); }
   { int k = (const_a_ref(A().ret_a()), A().ret_i()); }//
 }
@@ -353,10 +366,10 @@
   { int k = const_a_ref(A()); }
   { int k = const_a_ref(a); }
   { int k = rvalue_ref(A()); }
-  { int k = rvalue_ref(static_cast(a)); }
+  { int k = rvalue_ref(std::move(a)); }
   { int k = const_a_ref(A().ret_a()); }
   { int k = const_a_ref(to_lvalue_ref(A().ret_a())); }
-  { int k = const_a_ref(to_lvalue_ref(static_cast(a))); }
+  { int k = const_a_ref(to_lvalue_ref(std::move(a))); }
   { int k = by_value_a(A().ret_a()); }
   { int k = by_value_a(to_lvalue_ref(static_cast(a))); }
   { int k = (A().ret_a(), A().ret_i()); }// expected-error {{is not a constant expression}}
@@ -388,6 +401,27 @@
   // expected-note@-1 {{is not a constant expression}} expected-note@-1 {{temporary created here}}
 }
 
+struct S1 {
+  S1* ptr = nullptr;
+  consteval S1(int i) : ptr(this) {
+if (this == ptr && i)
+  ptr = nullptr;
+  }
+  constexpr ~S1() {}
+};
+
+void test1() {
+  S1 s(1);
+  s = S1(1);
+  s = S1(0); // expected-error {{is not a constant expression}}
+  // expected-note@-1 {{is not a constant expression}} expected-note@-1 {{temporary created here}}
+}
+
+}
+namespace ctor {
+
+consteval int f_eval() { // expected-note+ {{declared here}}
+  return 0;
 }
 
 namespace std {
@@ -441,3 +475,103 @@
 };
   }
 }
+
+struct A {
+  int(*ptr)();
+  consteval A(int(*p)() = nullptr) : ptr(p) {}
+};
+
+struct B {
+  int(*ptr)();
+  B() : ptr(nullptr) {}
+  consteval B(int(*p)(), int) : ptr(p) {}
+};
+
+void test() {
+  { A a; }
+  { A a(_eval); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
+  { B b(nullptr, 0); }
+  { B b(_eval, 0); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
+  { A a{}; }
+  { A a{_eval}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
+  { B b{nullptr, 0}; }
+  { B b{_eval, 0}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
+  { A a = A(); }
+  { A a = A(_eval); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
+  { B b = B(nullptr, 0); }
+  { B b = B(_eval, 0); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
+  { A a = A{}; }
+  { A a = A{_eval}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
+  { B b = B{nullptr, 0}; }
+  { B b = B{_eval, 0}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
+  { A a; a = A(); }
+  { A a; a = A(_eval); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
+  { B b; b = B(nullptr, 0); }
+  { B b; b = B(_eval, 0); } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
+  { A a; a = A{}; }
+  { A a; a = A{_eval}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
+  { B b; b = B{nullptr, 0}; }
+  { B b; b = B{_eval, 0}; } // expected-error {{is not a constant expression}} expected-note {{to a consteval}}
+  { A* a; a = new A(); 

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

2020-03-19 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.
Tyker added a parent revision: D74130: [clang] fix consteval call in default 
arguements .

with this patch instead of emitting calls to consteval function. the IR-gen 
will emit a store of the already computed result.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D76420

Files:
  clang/include/clang/AST/Expr.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/CodeGen/CGCall.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 -Wno-unused-value %s -verify > /dev/null
 
 typedef __SIZE_TYPE__ size_t;
 
Index: clang/test/CodeGenCXX/cxx2a-consteval.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/cxx2a-consteval.cpp
@@ -0,0 +1,212 @@
+// 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
+// RUNA: 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 _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);
+}
+
+// EVAL-NOT: @_Z4retIv()
+// EXPR: @_Z4retIv()
+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] D76396: Allow immediate invocation of constructors

2020-03-19 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

thanks for the the patch, but I have already a patch aiming to do the same 
thing. D74007 

> Provide improvements which allow the cached values of ConstantExpr to be used 
> by both the constant evaluator and code gen

this is definitely something we should do.

> Update the application of evaluation contexts, using the stronger guarantees 
> of manifest constant evaluation to apply the ConstantEvaluated evaluation 
> context in more places

the tracking of evaluation context isn't as good as it could/should.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76396



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


[PATCH] D74418: [clang] fix error detection in consteval calls

2020-02-26 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGca50f09db9f8: [clang] fix error detection in consteval calls 
(authored by Tyker).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D74418?vs=243892=246810#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D74418

Files:
  clang/lib/Sema/SemaExpr.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
@@ -309,6 +309,14 @@
 
 namespace alloc {
 
+consteval int f() {
+  int *A = new int(0);
+// expected-note@-1+ {{allocation performed here was not deallocated}}
+  return *A;
+}
+
+int i1 = f(); // expected-error {{is not a constant expression}}
+
 struct A {
   int* p = new int(42);
   // expected-note@-1+ {{heap allocation performed here}}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -15368,8 +15368,9 @@
   Expr::EvalResult Eval;
   Eval.Diag = 
   ConstantExpr *CE = Candidate.getPointer();
-  if (!CE->EvaluateAsConstantExpr(Eval, Expr::EvaluateForCodeGen,
-  SemaRef.getASTContext(), true)) {
+  bool Result = CE->EvaluateAsConstantExpr(Eval, Expr::EvaluateForCodeGen,
+   SemaRef.getASTContext(), true);
+  if (!Result || !Notes.empty()) {
 Expr *InnerExpr = CE->getSubExpr()->IgnoreImplicit();
 FunctionDecl *FD = nullptr;
 if (auto *Call = dyn_cast(InnerExpr))


Index: clang/test/SemaCXX/cxx2a-consteval.cpp
===
--- clang/test/SemaCXX/cxx2a-consteval.cpp
+++ clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -309,6 +309,14 @@
 
 namespace alloc {
 
+consteval int f() {
+  int *A = new int(0);
+// expected-note@-1+ {{allocation performed here was not deallocated}}
+  return *A;
+}
+
+int i1 = f(); // expected-error {{is not a constant expression}}
+
 struct A {
   int* p = new int(42);
   // expected-note@-1+ {{heap allocation performed here}}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -15368,8 +15368,9 @@
   Expr::EvalResult Eval;
   Eval.Diag = 
   ConstantExpr *CE = Candidate.getPointer();
-  if (!CE->EvaluateAsConstantExpr(Eval, Expr::EvaluateForCodeGen,
-  SemaRef.getASTContext(), true)) {
+  bool Result = CE->EvaluateAsConstantExpr(Eval, Expr::EvaluateForCodeGen,
+   SemaRef.getASTContext(), true);
+  if (!Result || !Notes.empty()) {
 Expr *InnerExpr = CE->getSubExpr()->IgnoreImplicit();
 FunctionDecl *FD = nullptr;
 if (auto *Call = dyn_cast(InnerExpr))
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D71037: [Diagnostic] Add ftabstop to -Wmisleading-indentation

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

In D71037#1871089 , @efriedma wrote:

> I just ran into this warning, and I think there's a bit of a discoverability 
> problem related to the width of tabs and -ftabstop.  If you have mixed tabs 
> and spaces, and you've correctly specified the tab stop width with -ftabstop, 
> everything works fine.  If you haven't specified -ftabstop, you get a 
> warning, and the issue isn't obvious.  Depending on your editor settings, the 
> code might look fine at first glance, and the warning text doesn't mention 
> -ftabstop at all.  Maybe there's something that could be improved here, if 
> we're printing a warning for two lines with mismatched indentation styles?


i agree that this is not obvious. i added a patch to improve this 
https://reviews.llvm.org/D75009.


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

https://reviews.llvm.org/D71037



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


[PATCH] D75009: [Diagnostic] Improve discoverability of ftabstop for misleading indentation

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

i tried to find a good message but i don't think i succeeded. any suggestions.


Repository:
  rC Clang

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

https://reviews.llvm.org/D75009



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


[PATCH] D75009: [Diagnostic] Improve discoverability of ftabstop for misleading indentation

2020-02-22 Thread Tyker via Phabricator via cfe-commits
Tyker created this revision.
Tyker added a reviewer: eli.friedman.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Tyker added a comment.

i tried to find a good message but i don't think i succeeded. any suggestions.


This adds an additional note after the misleading warning when the code has a 
mix of tab and space informing about -ftabstop when -ftabstop is used in the 
generation of the warning.


Repository:
  rC Clang

https://reviews.llvm.org/D75009

Files:
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/lib/Parse/ParseStmt.cpp
  clang/test/Parser/warn-misleading-indentation.cpp

Index: clang/test/Parser/warn-misleading-indentation.cpp
===
--- clang/test/Parser/warn-misleading-indentation.cpp
+++ clang/test/Parser/warn-misleading-indentation.cpp
@@ -234,7 +234,8 @@
  	return 0;
 #if (TAB_SIZE == 1)
 // expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
-// expected-note@-5 {{here}}
+// expected-note@-3 {{there is a mix of tabs spaces; the tab size (-ftabstop=X) is set to 1}}
+// expected-note@-6 {{here}}
 #endif 
 }
 
@@ -256,7 +257,20 @@
   		return 0;
 #if (TAB_SIZE == 8)
 // expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
-// expected-note@-5 {{here}}
+// expected-note@-3 {{there is a mix of tabs spaces; the tab size (-ftabstop=X) is set to 8}}
+// expected-note@-6 {{here}}
+#endif
+}
+
+int a7()
+{
+	if (0)
+		return 1;
+return 0;
+#if (TAB_SIZE == 4)
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+// expected-note@-3 {{there is a mix of tabs spaces; the tab size (-ftabstop=X) is set to 4}}
+// expected-note@-6 {{here}}
 #endif
 }
 
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -1217,11 +1217,12 @@
 
   /// Compute the column number will aligning tabs on TabStop (-ftabstop), this
   /// gives the visual indentation of the SourceLocation.
-  static unsigned getVisualIndentation(SourceManager , SourceLocation Loc) {
+  static unsigned getVisualIndentation(SourceManager , SourceLocation Loc,
+   bool& HasTab, bool& HasSpace) {
 unsigned TabStop = SM.getDiagnostics().getDiagnosticOptions().TabStop;
 
 unsigned ColNo = SM.getSpellingColumnNumber(Loc);
-if (ColNo == 0 || TabStop == 1)
+if (ColNo == 0)
   return ColNo;
 
 std::pair FIDAndOffset = SM.getDecomposedLoc(Loc);
@@ -1241,6 +1242,8 @@
 // expanding tabs.
 for (const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
  ++CurPos) {
+  HasTab |= *CurPos == '\t';
+  HasSpace |= *CurPos == ' ';
   if (*CurPos == '\t')
 // Advance visual column to next tabstop.
 VisualColumn += (TabStop - VisualColumn % TabStop);
@@ -1266,9 +1269,12 @@
   P.MisleadingIndentationElseLoc = SourceLocation();
 
 SourceManager  = P.getPreprocessor().getSourceManager();
-unsigned PrevColNum = getVisualIndentation(SM, PrevLoc);
-unsigned CurColNum = getVisualIndentation(SM, Tok.getLocation());
-unsigned StmtColNum = getVisualIndentation(SM, StmtLoc);
+bool HasTab = false;
+bool HasSpace = false;
+unsigned PrevColNum = getVisualIndentation(SM, PrevLoc, HasTab, HasSpace);
+unsigned CurColNum =
+getVisualIndentation(SM, Tok.getLocation(), HasTab, HasSpace);
+unsigned StmtColNum = getVisualIndentation(SM, StmtLoc, HasTab, HasSpace);
 
 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
@@ -1278,6 +1284,10 @@
 (Tok.isNot(tok::identifier) ||
  P.getPreprocessor().LookAhead(0).isNot(tok::colon))) {
   P.Diag(Tok.getLocation(), diag::warn_misleading_indentation) << Kind;
+  if (HasTab && HasSpace)
+P.Diag(Tok.getLocation(),
+   diag::note_misleading_indentation_tab_space_mix)
+<< SM.getDiagnostics().getDiagnosticOptions().TabStop;
   P.Diag(StmtLoc, diag::note_previous_statement);
 }
   }
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -63,6 +63,8 @@
   InGroup, DefaultIgnore;
 def note_previous_statement : Note<
   "previous statement is here">;
+def note_misleading_indentation_tab_space_mix : Note<
+  "there is a mix of tabs spaces; the tab size (-ftabstop=X) is set to %0">;
 
 def ext_thread_before : Extension<"'__thread' before '%0'">;
 def ext_keyword_as_ident : ExtWarn<
___
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

2020-02-04 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG008e7bf92343: [C++20] Add consteval-specific semantic for 
functions (authored by Tyker).

Changed prior to commit:
  https://reviews.llvm.org/D63960?vs=232450=242391#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D63960

Files:
  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/Expr.cpp
  clang/lib/AST/ExprConstant.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/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 %s -verify
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only -Wno-unused-value %s -verify
 
 namespace basic_sema {
 
@@ -12,6 +12,7 @@
 }
 
 constexpr auto l_eval = [](int i) consteval {
+// expected-note@-1+ {{declared here}}
 
   return i;
 };
@@ -23,11 +24,12 @@
 
 struct A {
   consteval int f1(int i) const {
+// expected-note@-1 {{declared here}}
 return i;
   }
   consteval A(int i);
   consteval A() = default;
-  consteval ~A() = default;
+  consteval ~A() = default; // expected-error {{destructor cannot be declared consteval}}
 };
 
 consteval struct B {}; // expected-error {{struct cannot be marked consteval}}
@@ -51,14 +53,329 @@
 struct D {
   C c;
   consteval D() = default; // expected-error {{cannot be consteval}}
-  consteval ~D() = default; // expected-error {{cannot be consteval}}
+  consteval ~D() = default; // expected-error {{destructor cannot be declared consteval}}
 };
 
-struct E : C { // expected-note {{here}}
-  consteval ~E() {} // expected-error {{cannot be declared consteval because base class 'basic_sema::C' does not have a constexpr destructor}}
+struct E : C {
+  consteval ~E() {} // expected-error {{cannot be declared consteval}}
 };
 }
 
 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 = (_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 = _sema::A::f1;
+// expected-error@-1 {{take address}}
+auto l1 = (basic_sema::l_eval)::operator();
+// expected-error@-1 {{take address}}
+
+consteval int f(int i) {
+// expected-note@-1+ {{declared here}}
+  return i;
+}
+
+auto ptr = 
+// expected-error@-1 {{take address}}
+
+auto f1() {
+  return 
+// 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}}
+  consteval ~A() {}
+  // expected-error@-1 {{destructor 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() + );
+}
+
+auto l0 = [](auto) consteval {
+  return 0;
+};
+
+int i0 = l0();
+
+int i1 = f1(l0(4));
+
+int i2 = f1(, , , , , , );
+
+int i3 = 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 = "" _test;
+// expected-error@-1 {{take address}}
+
+consteval auto operator"" _test1(unsigned long long i) {
+  return _eval;
+}
+
+auto i1 = 0_test1; // expected-error {{is not a constant expression}}
+// expected-note@-1 {{is not a constant expression}}
+
+}
+
+namespace return_address {
+
+consteval int f() {
+// expected-note@-1 {{declared here}}
+  return 0;
+}
+
+consteval int(*ret1(int i))() {
+  return 
+}
+
+auto ptr = ret1(0);
+// expected-error@-1 {{is not a constant expression}}
+// expected-note@-2 {{pointer to a consteval}}
+
+struct A {
+  consteval int f(int) {
+ 

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

2020-02-04 Thread Tyker via Phabricator via cfe-commits
Tyker marked 8 inline comments as done.
Tyker added a comment.

thank you for the review.
i am sorry there were so many back and forth.


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

2020-02-03 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

@aaron.ballman do you think you can review this ?


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

2020-01-13 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

@rsmith friendly reminder


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

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

rebased


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/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

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]][[CYAN]] Int: 1[[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{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:7[[RESET]], [[Yellow]]col:14[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | |   `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:3[[RESET]], [[Yellow]]line:14:5[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] Int: 2[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[MAGENTA]]ConstantExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[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]] 2[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:14:5[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:8:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}}
Index: clang/lib/Serialization/ASTWriterStmt.cpp
===
--- clang/lib/Serialization/ASTWriterStmt.cpp
+++ clang/lib/Serialization/ASTWriterStmt.cpp
@@ -473,7 +473,8 @@
   case ConstantExpr::RSK_Int64:
 Record.push_back(E->Int64Result());
 Record.push_back(E->ConstantExprBits.IsUnsigned |
- E->ConstantExprBits.BitWidth << 1);
+ E->ConstantExprBits.BitWidth << 1 |
+ E->ConstantExprBits.APValueKind << 8);
 break;
   case ConstantExpr::RSK_APValue:
 Record.AddAPValue(E->APValueResult());
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -5065,14 +5065,90 @@
 AddAPFloat(Value.getComplexFloatImag());
 return;
   }
-  case APValue::LValue:
   case APValue::Vector:
+push_back(Value.getVectorLength());
+for (unsigned Idx = 0; Idx < 

[PATCH] D72202: [Diagnostic] make Wmisleading-indendation not warn about labels

2020-01-06 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGf5329bfc76bb: [Diagnostic] make Wmisleading-indendation not 
warn about labels (authored by Tyker).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D72202

Files:
  clang/lib/Parse/ParseStmt.cpp
  clang/test/Parser/warn-misleading-indentation.cpp


Index: clang/test/Parser/warn-misleading-indentation.cpp
===
--- clang/test/Parser/warn-misleading-indentation.cpp
+++ clang/test/Parser/warn-misleading-indentation.cpp
@@ -305,3 +305,10 @@
 fail:;
 }
 
+void f_label(int b) {
+  if (b)
+return;
+a:
+  return;
+  goto a;
+}
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -1272,10 +1272,12 @@
 
 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
- !Tok.isAtStartOfLine()) && SM.getPresumedLineNumber(StmtLoc) !=
-  SM.getPresumedLineNumber(Tok.getLocation())) {
-  P.Diag(Tok.getLocation(), diag::warn_misleading_indentation)
-  << Kind;
+ !Tok.isAtStartOfLine()) &&
+SM.getPresumedLineNumber(StmtLoc) !=
+SM.getPresumedLineNumber(Tok.getLocation()) &&
+(Tok.isNot(tok::identifier) ||
+ P.getPreprocessor().LookAhead(0).isNot(tok::colon))) {
+  P.Diag(Tok.getLocation(), diag::warn_misleading_indentation) << Kind;
   P.Diag(StmtLoc, diag::note_previous_statement);
 }
   }


Index: clang/test/Parser/warn-misleading-indentation.cpp
===
--- clang/test/Parser/warn-misleading-indentation.cpp
+++ clang/test/Parser/warn-misleading-indentation.cpp
@@ -305,3 +305,10 @@
 fail:;
 }
 
+void f_label(int b) {
+  if (b)
+return;
+a:
+  return;
+  goto a;
+}
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -1272,10 +1272,12 @@
 
 if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
 ((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
- !Tok.isAtStartOfLine()) && SM.getPresumedLineNumber(StmtLoc) !=
-  SM.getPresumedLineNumber(Tok.getLocation())) {
-  P.Diag(Tok.getLocation(), diag::warn_misleading_indentation)
-  << Kind;
+ !Tok.isAtStartOfLine()) &&
+SM.getPresumedLineNumber(StmtLoc) !=
+SM.getPresumedLineNumber(Tok.getLocation()) &&
+(Tok.isNot(tok::identifier) ||
+ P.getPreprocessor().LookAhead(0).isNot(tok::colon))) {
+  P.Diag(Tok.getLocation(), diag::warn_misleading_indentation) << Kind;
   P.Diag(StmtLoc, diag::note_previous_statement);
 }
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

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

In D70638#1804138 , @aaron.ballman 
wrote:

> In D70638#1803364 , @xbolva00 wrote:
>
> > (re-ping; I think this false positive for goto label case is important to 
> > be fixed before 10 release)
>
>
> I agree -- @Tyker, are you planning to work on that fix?


i made a patch. https://reviews.llvm.org/D72202


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70638



___
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

2020-01-04 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] D71037: [Diagnostic] Add ftabstop to -Wmisleading-indentation

2020-01-03 Thread Tyker via Phabricator via cfe-commits
Tyker closed this revision.
Tyker added a comment.

In D71037#1803704 , @mstorsjo wrote:

> In D71037#1803574 , @Tyker wrote:
>
> > In D71037#1803361 , @xbolva00 
> > wrote:
> >
> > > Can you add a test case for that crash? Otherwise OK.
> >
> >
> > as i said. the bug can only occur for one line files. so we can't have a 
> > run line and a the crashing line. so i wasn't able to make a test for it.
>
>
> Is it possible to have the `RUN` bit at the end of the line in a comment, 
> after the test code itself?


it is possible.

i committed the fix and the tests.


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

https://reviews.llvm.org/D71037



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


[PATCH] D71037: [Diagnostic] Add ftabstop to -Wmisleading-indentation

2020-01-03 Thread Tyker via Phabricator via cfe-commits
Tyker added a comment.

In D71037#1803361 , @xbolva00 wrote:

> Can you add a test case for that crash? Otherwise OK.


as i said. the bug can only occur for one line files. so we can't have a run 
line and a the crashing line. so i wasn't able to make a test for it.


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

https://reviews.llvm.org/D71037



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


[PATCH] D71037: [Diagnostic] Add ftabstop to -Wmisleading-indentation

2020-01-03 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 236058.
Tyker added a comment.

This update should fixes the issue.
the assert was incorrect. because file offsets are 0-based where as column 
numbers are 1-based.


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

https://reviews.llvm.org/D71037

Files:
  clang/lib/Parse/ParseStmt.cpp
  clang/test/Parser/warn-misleading-indentation.cpp

Index: clang/test/Parser/warn-misleading-indentation.cpp
===
--- clang/test/Parser/warn-misleading-indentation.cpp
+++ clang/test/Parser/warn-misleading-indentation.cpp
@@ -1,7 +1,9 @@
 // RUN: %clang_cc1 -x c -fsyntax-only -verify %s
-// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wmisleading-indentation -DWITH_WARN %s
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -DWITH_WARN -DCXX17 %s
 // RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -Wno-misleading-indentation -DCXX17 %s
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wmisleading-indentation -DWITH_WARN -ftabstop 8 -DTAB_SIZE=8 %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -DWITH_WARN  -ftabstop 4 -DTAB_SIZE=4 -DCXX17 %s
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wall -Wno-unused -DWITH_WARN -ftabstop 1 -DTAB_SIZE=1 %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -Wmisleading-indentation -DCXX17 -DWITH_WARN -ftabstop 2 -DTAB_SIZE=2 %s
 
 #ifndef WITH_WARN
 // expected-no-diagnostics
@@ -225,3 +227,81 @@
 // expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
 #endif
 }
+int a4()
+{
+	if (0)
+		return 1;
+ 	return 0;
+#if (TAB_SIZE == 1)
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+// expected-note@-5 {{here}}
+#endif 
+}
+
+int a5()
+{
+	if (0)
+		return 1;
+		return 0;
+#if WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+// expected-note@-5 {{here}}
+#endif
+}
+
+int a6()
+{
+	if (0)
+		return 1;
+  		return 0;
+#if (TAB_SIZE == 8)
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+// expected-note@-5 {{here}}
+#endif
+}
+
+#define FOO \
+ goto fail
+
+int main(int argc, char* argv[]) {
+  if (5 != 0)
+goto fail;
+  else
+goto fail;
+
+  if (1) {
+if (1)
+  goto fail;
+else if (1)
+  goto fail;
+else if (1)
+  goto fail;
+else
+  goto fail;
+  } else if (1) {
+if (1)
+  goto fail;
+  }
+
+  if (1) {
+if (1)
+  goto fail;
+  } else if (1)
+goto fail;
+
+
+  if (1) goto fail; goto fail;
+
+if (0)
+goto fail;
+
+goto fail;
+
+if (0)
+FOO;
+
+goto fail;
+
+fail:;
+}
+
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -1214,6 +1214,42 @@
 if (Kind == MSK_else && !ShouldSkip)
   P.MisleadingIndentationElseLoc = SL;
   }
+
+  /// Compute the column number will aligning tabs on TabStop (-ftabstop), this
+  /// gives the visual indentation of the SourceLocation.
+  static unsigned getVisualIndentation(SourceManager , SourceLocation Loc) {
+unsigned TabStop = SM.getDiagnostics().getDiagnosticOptions().TabStop;
+
+unsigned ColNo = SM.getSpellingColumnNumber(Loc);
+if (ColNo == 0 || TabStop == 1)
+  return ColNo;
+
+std::pair FIDAndOffset = SM.getDecomposedLoc(Loc);
+
+bool Invalid;
+StringRef BufData = SM.getBufferData(FIDAndOffset.first, );
+if (Invalid)
+  return 0;
+
+const char *EndPos = BufData.data() + FIDAndOffset.second;
+// FileOffset are 0-based and Column numbers are 1-based
+assert(FIDAndOffset.second + 1 >= ColNo &&
+   "Column number smaller than file offset?");
+
+unsigned VisualColumn = 0; // Stored as 0-based column, here.
+// Loop from beginning of line up to Loc's file position, counting columns,
+// expanding tabs.
+for (const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
+ ++CurPos) {
+  if (*CurPos == '\t')
+// Advance visual column to next tabstop.
+VisualColumn += (TabStop - VisualColumn % TabStop);
+  else
+VisualColumn++;
+}
+return VisualColumn + 1;
+  }
+
   void Check() {
 Token Tok = P.getCurToken();
 if (P.getActions().getDiagnostics().isIgnored(
@@ -1230,9 +1266,9 @@
   P.MisleadingIndentationElseLoc = SourceLocation();
 
 SourceManager  = P.getPreprocessor().getSourceManager();
-unsigned PrevColNum = SM.getSpellingColumnNumber(PrevLoc);
-unsigned CurColNum = SM.getSpellingColumnNumber(Tok.getLocation());
-unsigned StmtColNum = SM.getSpellingColumnNumber(StmtLoc);
+unsigned PrevColNum = getVisualIndentation(SM, PrevLoc);
+unsigned CurColNum = getVisualIndentation(SM, Tok.getLocation());
+unsigned 

[PATCH] D71037: [Diagnostic] Add ftabstop to -Wmisleading-indentation

2019-12-30 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb47b35ff51b3: [Diagnostic] Add ftabstop to 
-Wmisleading-indentation (authored by Tyker).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71037

Files:
  clang/lib/Parse/ParseStmt.cpp
  clang/test/Parser/warn-misleading-indentation.cpp

Index: clang/test/Parser/warn-misleading-indentation.cpp
===
--- clang/test/Parser/warn-misleading-indentation.cpp
+++ clang/test/Parser/warn-misleading-indentation.cpp
@@ -1,7 +1,9 @@
 // RUN: %clang_cc1 -x c -fsyntax-only -verify %s
-// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wmisleading-indentation -DWITH_WARN %s
-// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -DWITH_WARN -DCXX17 %s
 // RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -Wno-misleading-indentation -DCXX17 %s
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wmisleading-indentation -DWITH_WARN -ftabstop 8 -DTAB_SIZE=8 %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -DWITH_WARN  -ftabstop 4 -DTAB_SIZE=4 -DCXX17 %s
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wall -Wno-unused -DWITH_WARN -ftabstop 1 -DTAB_SIZE=1 %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -Wmisleading-indentation -DCXX17 -DWITH_WARN -ftabstop 2 -DTAB_SIZE=2 %s
 
 #ifndef WITH_WARN
 // expected-no-diagnostics
@@ -225,3 +227,80 @@
 // expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
 #endif
 }
+int a4()
+{
+	if (0)
+		return 1;
+ 	return 0;
+#if (TAB_SIZE == 1)
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+// expected-note@-5 {{here}}
+#endif 
+}
+
+int a5()
+{
+	if (0)
+		return 1;
+		return 0;
+#if WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+// expected-note@-5 {{here}}
+#endif
+}
+
+int a6()
+{
+	if (0)
+		return 1;
+  		return 0;
+#if (TAB_SIZE == 8)
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+// expected-note@-5 {{here}}
+#endif
+}
+
+#define FOO \
+ goto fail
+
+int main(int argc, char* argv[]) {
+  if (5 != 0)
+goto fail;
+  else
+goto fail;
+
+  if (1) {
+if (1)
+  goto fail;
+else if (1)
+  goto fail;
+else if (1)
+  goto fail;
+else
+  goto fail;
+  } else if (1) {
+if (1)
+  goto fail;
+  }
+
+  if (1) {
+if (1)
+  goto fail;
+  } else if (1)
+goto fail;
+
+
+  if (1) goto fail; goto fail;
+
+if (0)
+goto fail;
+
+goto fail;
+
+if (0)
+FOO;
+
+goto fail;
+
+fail:;
+}
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -1214,6 +1214,41 @@
 if (Kind == MSK_else && !ShouldSkip)
   P.MisleadingIndentationElseLoc = SL;
   }
+
+  /// Compute the column number will aligning tabs on TabStop (-ftabstop), this
+  /// gives the visual indentation of the SourceLocation.
+  static unsigned getVisualIndentation(SourceManager , SourceLocation Loc) {
+unsigned TabStop = SM.getDiagnostics().getDiagnosticOptions().TabStop;
+
+unsigned ColNo = SM.getSpellingColumnNumber(Loc);
+if (ColNo == 0 || TabStop == 1)
+  return ColNo;
+
+std::pair FIDAndOffset = SM.getDecomposedLoc(Loc);
+
+bool Invalid;
+StringRef BufData = SM.getBufferData(FIDAndOffset.first, );
+if (Invalid)
+  return 0;
+
+const char *EndPos = BufData.data() + FIDAndOffset.second;
+assert(FIDAndOffset.second > ColNo &&
+   "Column number smaller than file offset?");
+
+unsigned VisualColumn = 0; // Stored as 0-based column, here.
+// Loop from beginning of line up to Loc's file position, counting columns,
+// expanding tabs.
+for (const char *CurPos = EndPos - (ColNo - 1); CurPos != EndPos;
+ ++CurPos) {
+  if (*CurPos == '\t')
+// Advance visual column to next tabstop.
+VisualColumn += (TabStop - VisualColumn % TabStop);
+  else
+VisualColumn++;
+}
+return VisualColumn + 1;
+  }
+
   void Check() {
 Token Tok = P.getCurToken();
 if (P.getActions().getDiagnostics().isIgnored(
@@ -1230,9 +1265,9 @@
   P.MisleadingIndentationElseLoc = SourceLocation();
 
 SourceManager  = P.getPreprocessor().getSourceManager();
-unsigned PrevColNum = SM.getSpellingColumnNumber(PrevLoc);
-unsigned CurColNum = SM.getSpellingColumnNumber(Tok.getLocation());
-unsigned StmtColNum = SM.getSpellingColumnNumber(StmtLoc);
+unsigned PrevColNum = getVisualIndentation(SM, PrevLoc);
+unsigned CurColNum = getVisualIndentation(SM, 

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

2019-12-14 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] D71083: [Diagnsotics] Small Improvement on -Wmisleading-indentation

2019-12-12 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Tyker marked an inline comment as done.
Closed by commit rG9c8cfa09d762: [Diagnsotics] Small Improvement on 
-Wmisleading-indentation (authored by Tyker).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71083

Files:
  clang/lib/Parse/ParseStmt.cpp
  clang/test/Parser/warn-misleading-indentation.cpp


Index: clang/test/Parser/warn-misleading-indentation.cpp
===
--- clang/test/Parser/warn-misleading-indentation.cpp
+++ clang/test/Parser/warn-misleading-indentation.cpp
@@ -205,4 +205,23 @@
 i = 4;
 }
 return;
-}
\ No newline at end of file
+}
+
+void s(int num) {
+{
+if (1)
+return;
+else
+return;
+return;
+}
+if (0)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+return;
+return;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the 
previous 'if'}}
+#endif
+}
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -1201,13 +1201,12 @@
   SourceLocation PrevLoc;
   unsigned NumDirectives;
   MisleadingStatementKind Kind;
-  bool NeedsChecking;
   bool ShouldSkip;
   MisleadingIndentationChecker(Parser , MisleadingStatementKind K,
SourceLocation SL)
   : P(P), StmtLoc(SL), PrevLoc(P.getCurToken().getLocation()),
 NumDirectives(P.getPreprocessor().getNumDirectives()), Kind(K),
-NeedsChecking(true), ShouldSkip(P.getCurToken().is(tok::l_brace)) {
+ShouldSkip(P.getCurToken().is(tok::l_brace)) {
 if (!P.MisleadingIndentationElseLoc.isInvalid()) {
   StmtLoc = P.MisleadingIndentationElseLoc;
   P.MisleadingIndentationElseLoc = SourceLocation();
@@ -1216,9 +1215,10 @@
   P.MisleadingIndentationElseLoc = SL;
   }
   void Check() {
-NeedsChecking = false;
 Token Tok = P.getCurToken();
-if (ShouldSkip || NumDirectives != P.getPreprocessor().getNumDirectives() 
||
+if (P.getActions().getDiagnostics().isIgnored(
+diag::warn_misleading_indentation, Tok.getLocation()) ||
+ShouldSkip || NumDirectives != P.getPreprocessor().getNumDirectives() 
||
 Tok.isOneOf(tok::semi, tok::r_brace) || Tok.isAnnotation() ||
 Tok.getLocation().isMacroID() || PrevLoc.isMacroID() ||
 StmtLoc.isMacroID() ||
@@ -1226,6 +1226,8 @@
   P.MisleadingIndentationElseLoc = SourceLocation();
   return;
 }
+if (Kind == MSK_else)
+  P.MisleadingIndentationElseLoc = SourceLocation();
 
 SourceManager  = P.getPreprocessor().getSourceManager();
 unsigned PrevColNum = SM.getSpellingColumnNumber(PrevLoc);


Index: clang/test/Parser/warn-misleading-indentation.cpp
===
--- clang/test/Parser/warn-misleading-indentation.cpp
+++ clang/test/Parser/warn-misleading-indentation.cpp
@@ -205,4 +205,23 @@
 i = 4;
 }
 return;
-}
\ No newline at end of file
+}
+
+void s(int num) {
+{
+if (1)
+return;
+else
+return;
+return;
+}
+if (0)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+return;
+return;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+}
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -1201,13 +1201,12 @@
   SourceLocation PrevLoc;
   unsigned NumDirectives;
   MisleadingStatementKind Kind;
-  bool NeedsChecking;
   bool ShouldSkip;
   MisleadingIndentationChecker(Parser , MisleadingStatementKind K,
SourceLocation SL)
   : P(P), StmtLoc(SL), PrevLoc(P.getCurToken().getLocation()),
 NumDirectives(P.getPreprocessor().getNumDirectives()), Kind(K),
-NeedsChecking(true), ShouldSkip(P.getCurToken().is(tok::l_brace)) {
+ShouldSkip(P.getCurToken().is(tok::l_brace)) {
 if (!P.MisleadingIndentationElseLoc.isInvalid()) {
   StmtLoc = P.MisleadingIndentationElseLoc;
   P.MisleadingIndentationElseLoc = SourceLocation();
@@ -1216,9 +1215,10 @@
   P.MisleadingIndentationElseLoc = SL;
   }
   void Check() {
-NeedsChecking = false;
 Token Tok = P.getCurToken();
-if (ShouldSkip || NumDirectives != P.getPreprocessor().getNumDirectives() ||
+if (P.getActions().getDiagnostics().isIgnored(
+diag::warn_misleading_indentation, Tok.getLocation()) ||
+ShouldSkip || NumDirectives != P.getPreprocessor().getNumDirectives() 

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

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

now that the issue with uniqueness of expressions is solved. we should be able 
to keep going on that review @rsmith.
https://reviews.llvm.org/D63960 should be i think close to completion. so maybe 
for testing i could use immediate invocation as a source for ConstantExpr 
instead of the code i added to make constexpr variables emit ConstantExpr ?


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-12-05 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 232450.
Tyker marked 14 inline comments as done.
Tyker added a comment.

comments were fixed.


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

https://reviews.llvm.org/D63960

Files:
  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/Expr.cpp
  clang/lib/AST/ExprConstant.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/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 %s -verify
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only -Wno-unused-value %s -verify
 
 namespace basic_sema {
 
@@ -12,6 +12,7 @@
 }
 
 constexpr auto l_eval = [](int i) consteval {
+// expected-note@-1+ {{declared here}}
 
   return i;
 };
@@ -23,11 +24,12 @@
 
 struct A {
   consteval int f1(int i) const {
+// expected-note@-1 {{declared here}}
 return i;
   }
   consteval A(int i);
   consteval A() = default;
-  consteval ~A() = default;
+  consteval ~A() = default; // expected-error {{destructor cannot be declared consteval}}
 };
 
 consteval struct B {}; // expected-error {{struct cannot be marked consteval}}
@@ -51,14 +53,329 @@
 struct D {
   C c;
   consteval D() = default; // expected-error {{cannot be consteval}}
-  consteval ~D() = default; // expected-error {{cannot be consteval}}
+  consteval ~D() = default; // expected-error {{destructor cannot be declared consteval}}
 };
 
-struct E : C { // expected-note {{here}}
-  consteval ~E() {} // expected-error {{cannot be declared consteval because base class 'basic_sema::C' does not have a constexpr destructor}}
+struct E : C {
+  consteval ~E() {} // expected-error {{cannot be declared consteval}}
 };
 }
 
 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 = (_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 = _sema::A::f1;
+// expected-error@-1 {{take address}}
+auto l1 = (basic_sema::l_eval)::operator();
+// expected-error@-1 {{take address}}
+
+consteval int f(int i) {
+// expected-note@-1+ {{declared here}}
+  return i;
+}
+
+auto ptr = 
+// expected-error@-1 {{take address}}
+
+auto f1() {
+  return 
+// 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}}
+  consteval ~A() {}
+  // expected-error@-1 {{destructor 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() + );
+}
+
+auto l0 = [](auto) consteval {
+  return 0;
+};
+
+int i0 = l0();
+
+int i1 = f1(l0(4));
+
+int i2 = f1(, , , , , , );
+
+int i3 = 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 = "" _test;
+// expected-error@-1 {{take address}}
+
+consteval auto operator"" _test1(unsigned long long i) {
+  return _eval;
+}
+
+auto i1 = 0_test1; // expected-error {{could not be evaluated}}
+// expected-note@-1 {{is not a constant expression}}
+
+}
+
+namespace return_address {
+
+consteval int f() {
+// expected-note@-1 {{declared here}}
+  return 0;
+}
+
+consteval int(*ret1(int i))() {
+  return 
+}
+
+auto ptr = ret1(0);
+// expected-error@-1 {{could not be evaluated}}
+// expected-note@-2 {{pointer to a consteval}}
+
+struct A {
+  consteval int f(int) {
+// expected-note@-1+ {{declared here}}
+return 0;
+  }
+};
+
+using mem_ptr_type = int (A::*)(int);
+
+template
+struct C {};
+
+C<::f> c;
+// expected-error@-1 {{is not a 

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

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



Comment at: clang/lib/AST/ExprConstant.cpp:13618
+  if (InPlace) {
+LValue LVal;
+if (!::EvaluateInPlace(Result.Val, Info, LVal, this) ||

rsmith wrote:
> This isn't sufficient: the evaluation process can refer back to the object 
> under construction (eg, via `this`), and we need an lvalue that actually 
> names the result in order for this to work.
> 
> I think you'll need to do something like creating a suitable object (perhaps 
> a `LifetimeExtendedTemporaryDecl`) in the caller to represent the result of 
> the immediate invocation, and passing that into here.
i believe this solution should work. without LifetimeExtendedTemporaryDecl 
because reference/pointer on temporaries are not valid results of constant 
evaluation. so the AST should never store an APValue whose LValue is a 
ConstantExpr.


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] D70638: [Diagnostic] add a warning which warns about misleading indentation

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

i have not tested the performance impact. but i tried to do the heavier checks 
last to minimize the impact.
i added your tests file to the improvement commit.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70638



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


[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

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

the warning was not affected by -ftabstop. i made a patch that fix this.

https://reviews.llvm.org/D71037

and I agree that mixing tabs and space is a horrible idea for many reasons.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70638



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


[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

2019-12-04 Thread Tyker via Phabricator via cfe-commits
Tyker marked 6 inline comments as done.
Tyker added a comment.

i did a few test on the linux kernel on prior version of this patchs and the 
mix of spaces and tabs caused some false positives. but i do believe there is 
still a bug here.
for the mix of space and tabs. gcc has a -ftabstop=//X// to specify how large 
tabs should be counted as.
clang has it as well i am going to check that it is taken in account.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70638



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


[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

2019-12-03 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGbc840b21e161: [Diagnostic] add a warning which warns about 
misleading indentation (authored by Tyker).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70638

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseStmt.cpp
  clang/test/Index/pragma-diag-reparse.c
  clang/test/Misc/warning-wall.c
  clang/test/Parser/warn-misleading-indentation.cpp
  clang/test/Preprocessor/pragma_diagnostic_sections.cpp

Index: clang/test/Preprocessor/pragma_diagnostic_sections.cpp
===
--- clang/test/Preprocessor/pragma_diagnostic_sections.cpp
+++ clang/test/Preprocessor/pragma_diagnostic_sections.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -Wno-misleading-indentation -verify %s
 
 // rdar://8365684
 struct S {
Index: clang/test/Parser/warn-misleading-indentation.cpp
===
--- /dev/null
+++ clang/test/Parser/warn-misleading-indentation.cpp
@@ -0,0 +1,208 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wmisleading-indentation -DWITH_WARN %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -DWITH_WARN -DCXX17 %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -Wno-misleading-indentation -DCXX17 %s
+
+#ifndef WITH_WARN
+// expected-no-diagnostics
+#endif
+
+void f0(int i) {
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+  return;
+#ifdef CXX17
+  if constexpr (false)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 0;
+i += 1;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+#endif
+}
+
+void f1(int i) {
+  for (;i;)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'for'}}
+#endif
+  return;
+}
+
+void f2(int i) {
+  while (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1; i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'while'}}
+#endif
+  return;
+}
+
+void f3(int i) {
+  if (i)
+i = i + 1;
+  else
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+const int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'else'}}
+#endif
+}
+
+#ifdef CXX17
+struct Range {
+  int *begin() {return nullptr;}
+  int *end() {return nullptr;}
+};
+#endif
+
+void f4(int i) {
+  if (i)
+  i *= 2;
+  return;
+  if (i)
+i *= 2;
+;
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+typedef int Int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+#ifdef CXX17
+  Range R;
+  for (auto e : R)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+using Int2 = int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'for'}}
+#endif
+#endif
+}
+
+int bar(void);
+
+int foo(int* dst)
+{   
+if (dst)
+   return
+bar();
+  if (dst)
+dst = dst + \
+bar();
+  return 0;
+}
+
+void g(int i) {
+  if (1)
+i = 2;
+  else
+ if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-3 {{here}}
+#endif
+i = 4;
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+}
+
+// Or this
+#define TEST i = 5
+void g0(int i) {
+  if (1)
+i = 2;
+  else
+i = 5;
+TEST;
+}
+
+void g1(int i) {
+  if (1)
+i = 2;
+  else if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+  i = 4;
+  i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+}
+
+void g2(int i) {
+  if (1)
+i = 2;
+  else
+if (i == 3)
+{i = 4;}
+i = 5;
+}
+
+void g6(int i) {
+if (1)
+if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 4;
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; 

[PATCH] D70861: [NFCI] update formating for misleading indentation warning

2019-12-03 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG2f9604727526: [NFCI] update formating for misleading 
indentation warning (authored by Tyker).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70861

Files:
  clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp


Index: clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -2525,19 +2525,18 @@
 
 // Find the most recent expression bound to the symbol in the current
 // context.
-  if (!ReferenceRegion) {
-if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) {
-  SVal Val = State->getSVal(MR);
-  if (Val.getAsLocSymbol() == Sym) {
-const VarRegion* VR = MR->getBaseRegion()->getAs();
-// Do not show local variables belonging to a function other than
-// where the error is reported.
-if (!VR ||
-(VR->getStackFrame() == LeakContext->getStackFrame()))
-  ReferenceRegion = MR;
-  }
+if (!ReferenceRegion) {
+  if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) {
+SVal Val = State->getSVal(MR);
+if (Val.getAsLocSymbol() == Sym) {
+  const VarRegion *VR = MR->getBaseRegion()->getAs();
+  // Do not show local variables belonging to a function other than
+  // where the error is reported.
+  if (!VR || (VR->getStackFrame() == LeakContext->getStackFrame()))
+ReferenceRegion = MR;
 }
   }
+}
 
 // Allocation node, is the last node in the current or parent context in
 // which the symbol was tracked.


Index: clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -2525,19 +2525,18 @@
 
 // Find the most recent expression bound to the symbol in the current
 // context.
-  if (!ReferenceRegion) {
-if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) {
-  SVal Val = State->getSVal(MR);
-  if (Val.getAsLocSymbol() == Sym) {
-const VarRegion* VR = MR->getBaseRegion()->getAs();
-// Do not show local variables belonging to a function other than
-// where the error is reported.
-if (!VR ||
-(VR->getStackFrame() == LeakContext->getStackFrame()))
-  ReferenceRegion = MR;
-  }
+if (!ReferenceRegion) {
+  if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) {
+SVal Val = State->getSVal(MR);
+if (Val.getAsLocSymbol() == Sym) {
+  const VarRegion *VR = MR->getBaseRegion()->getAs();
+  // Do not show local variables belonging to a function other than
+  // where the error is reported.
+  if (!VR || (VR->getStackFrame() == LeakContext->getStackFrame()))
+ReferenceRegion = MR;
 }
   }
+}
 
 // Allocation node, is the last node in the current or parent context in
 // which the symbol was tracked.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

2019-12-03 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 231949.

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

https://reviews.llvm.org/D70638

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseStmt.cpp
  clang/test/Index/pragma-diag-reparse.c
  clang/test/Misc/warning-wall.c
  clang/test/Parser/warn-misleading-indentation.cpp
  clang/test/Preprocessor/pragma_diagnostic_sections.cpp

Index: clang/test/Preprocessor/pragma_diagnostic_sections.cpp
===
--- clang/test/Preprocessor/pragma_diagnostic_sections.cpp
+++ clang/test/Preprocessor/pragma_diagnostic_sections.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -Wno-misleading-indentation -verify %s
 
 // rdar://8365684
 struct S {
Index: clang/test/Parser/warn-misleading-indentation.cpp
===
--- /dev/null
+++ clang/test/Parser/warn-misleading-indentation.cpp
@@ -0,0 +1,208 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wmisleading-indentation -DWITH_WARN %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -DWITH_WARN -DCXX17 %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -Wno-misleading-indentation -DCXX17 %s
+
+#ifndef WITH_WARN
+// expected-no-diagnostics
+#endif
+
+void f0(int i) {
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+  return;
+#ifdef CXX17
+  if constexpr (false)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 0;
+i += 1;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+#endif
+}
+
+void f1(int i) {
+  for (;i;)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'for'}}
+#endif
+  return;
+}
+
+void f2(int i) {
+  while (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1; i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'while'}}
+#endif
+  return;
+}
+
+void f3(int i) {
+  if (i)
+i = i + 1;
+  else
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+const int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'else'}}
+#endif
+}
+
+#ifdef CXX17
+struct Range {
+  int *begin() {return nullptr;}
+  int *end() {return nullptr;}
+};
+#endif
+
+void f4(int i) {
+  if (i)
+  i *= 2;
+  return;
+  if (i)
+i *= 2;
+;
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+typedef int Int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+#ifdef CXX17
+  Range R;
+  for (auto e : R)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+using Int2 = int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'for'}}
+#endif
+#endif
+}
+
+int bar(void);
+
+int foo(int* dst)
+{   
+if (dst)
+   return
+bar();
+  if (dst)
+dst = dst + \
+bar();
+  return 0;
+}
+
+void g(int i) {
+  if (1)
+i = 2;
+  else
+ if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-3 {{here}}
+#endif
+i = 4;
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+}
+
+// Or this
+#define TEST i = 5
+void g0(int i) {
+  if (1)
+i = 2;
+  else
+i = 5;
+TEST;
+}
+
+void g1(int i) {
+  if (1)
+i = 2;
+  else if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+  i = 4;
+  i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+}
+
+void g2(int i) {
+  if (1)
+i = 2;
+  else
+if (i == 3)
+{i = 4;}
+i = 5;
+}
+
+void g6(int i) {
+if (1)
+if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 4;
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+}
+
+void g7(int i) {
+  if (1)
+i = 4;
+#ifdef TEST1
+#endif
+i = 5;
+}
+
+void a1(int i) { if (1) i = 4; return; }
+
+void a2(int i) {
+ 

[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

2019-12-02 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 231792.
Tyker added a comment.

improved based on aaron's comment.


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

https://reviews.llvm.org/D70638

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
  clang/test/Index/pragma-diag-reparse.c
  clang/test/Misc/warning-wall.c
  clang/test/Parser/warn-misleading-indentation.cpp
  clang/test/Preprocessor/pragma_diagnostic_sections.cpp

Index: clang/test/Preprocessor/pragma_diagnostic_sections.cpp
===
--- clang/test/Preprocessor/pragma_diagnostic_sections.cpp
+++ clang/test/Preprocessor/pragma_diagnostic_sections.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -Wno-misleading-indentation -verify %s
 
 // rdar://8365684
 struct S {
Index: clang/test/Parser/warn-misleading-indentation.cpp
===
--- /dev/null
+++ clang/test/Parser/warn-misleading-indentation.cpp
@@ -0,0 +1,208 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wmisleading-indentation -DWITH_WARN %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -DWITH_WARN -DCXX17 %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -Wno-misleading-indentation -DCXX17 %s
+
+#ifndef WITH_WARN
+// expected-no-diagnostics
+#endif
+
+void f0(int i) {
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+  return;
+#ifdef CXX17
+  if constexpr (false)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 0;
+i += 1;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+#endif
+}
+
+void f1(int i) {
+  for (;i;)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'for'}}
+#endif
+  return;
+}
+
+void f2(int i) {
+  while (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1; i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'while'}}
+#endif
+  return;
+}
+
+void f3(int i) {
+  if (i)
+i = i + 1;
+  else
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+const int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'else'}}
+#endif
+}
+
+#ifdef CXX17
+struct Range {
+  int *begin() {return nullptr;}
+  int *end() {return nullptr;}
+};
+#endif
+
+void f4(int i) {
+  if (i)
+  i *= 2;
+  return;
+  if (i)
+i *= 2;
+;
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+typedef int Int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+#ifdef CXX17
+  Range R;
+  for (auto e : R)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+using Int2 = int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'for'}}
+#endif
+#endif
+}
+
+int bar(void);
+
+int foo(int* dst)
+{   
+if (dst)
+   return
+bar();
+  if (dst)
+dst = dst + \
+bar();
+  return 0;
+}
+
+void g(int i) {
+  if (1)
+i = 2;
+  else
+ if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-3 {{here}}
+#endif
+i = 4;
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+}
+
+// Or this
+#define TEST i = 5
+void g0(int i) {
+  if (1)
+i = 2;
+  else
+i = 5;
+TEST;
+}
+
+void g1(int i) {
+  if (1)
+i = 2;
+  else if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+  i = 4;
+  i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+}
+
+void g2(int i) {
+  if (1)
+i = 2;
+  else
+if (i == 3)
+{i = 4;}
+i = 5;
+}
+
+void g6(int i) {
+if (1)
+if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 4;
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+}
+
+void g7(int i) {
+  if (1)

[PATCH] D70190: [clang][modules] Add support for merging lifetime-extended temporaries

2019-11-30 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG3c7f6b439699: [clang][modules] Add support for merging 
lifetime-extended temporaries (authored by Tyker).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70190

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/AST/TextNodeDumper.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/test/Modules/Inputs/merge-lifetime-extended-temporary/a.h
  clang/test/Modules/Inputs/merge-lifetime-extended-temporary/b.h
  clang/test/Modules/Inputs/merge-lifetime-extended-temporary/c.h
  clang/test/Modules/Inputs/merge-lifetime-extended-temporary/module.modulemap
  clang/test/Modules/merge-lifetime-extended-temporary.cpp

Index: clang/test/Modules/merge-lifetime-extended-temporary.cpp
===
--- /dev/null
+++ clang/test/Modules/merge-lifetime-extended-temporary.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-lifetime-extended-temporary -verify -std=c++11 %s -DORDER=1
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-lifetime-extended-temporary -verify -std=c++11 %s -DORDER=2
+
+// expected-no-diagnostics
+#if ORDER == 1
+#include "c.h"
+#include "b.h"
+#else
+#include "b.h"
+#include "c.h"
+#endif
+
+static_assert(PtrTemp1 == , "");
+static_assert(PtrTemp1 == PtrTemp2, "");
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/module.modulemap
===
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/module.modulemap
@@ -0,0 +1,14 @@
+module "a" {
+  export *
+  header "a.h"
+}
+
+module "b" {
+  export *
+  header "b.h"
+}
+
+module "c" {
+  export *
+  header "c.h"
+}
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/c.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/c.h
@@ -0,0 +1,4 @@
+
+#include "a.h"
+
+constexpr const int* PtrTemp2 = 
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/b.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/b.h
@@ -0,0 +1,4 @@
+
+#include "a.h"
+
+constexpr const int* PtrTemp1 = 
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/a.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/a.h
@@ -0,0 +1,2 @@
+
+constexpr const int& LETemp = 0;
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -424,6 +424,9 @@
 template
 void mergeMergeable(Mergeable *D);
 
+template <>
+void mergeMergeable(Mergeable *D);
+
 void mergeTemplatePattern(RedeclarableTemplateDecl *D,
   RedeclarableTemplateDecl *Existing,
   DeclID DsID, bool IsKeyDecl);
@@ -2358,6 +2361,7 @@
   if (Record.readInt())
 D->Value = new (D->getASTContext()) APValue(Record.readAPValue());
   D->ManglingNumber = Record.readInt();
+  mergeMergeable(D);
 }
 
 std::pair
@@ -2555,6 +2559,28 @@
   return false;
 }
 
+/// Attempts to merge LifetimeExtendedTemporaryDecl with
+/// identical class definitions from two different modules.
+template<>
+void ASTDeclReader::mergeMergeable(
+Mergeable *D) {
+  // If modules are not available, there is no reason to perform this merge.
+  if (!Reader.getContext().getLangOpts().Modules)
+return;
+
+  LifetimeExtendedTemporaryDecl *LETDecl =
+  static_cast(D);
+
+  LifetimeExtendedTemporaryDecl * =
+  Reader.LETemporaryForMerging[std::make_pair(
+  LETDecl->getExtendingDecl(), LETDecl->getManglingNumber())];
+  if (LookupResult)
+Reader.getContext().setPrimaryMergedDecl(LETDecl,
+ LookupResult->getCanonicalDecl());
+  else
+LookupResult = LETDecl;
+}
+
 /// Attempts to merge the given declaration (D) with another declaration
 /// of the same entity, for the case where the entity is not actually
 /// redeclarable. This happens, for instance, when merging the fields of
Index: clang/lib/AST/TextNodeDumper.cpp
===
--- clang/lib/AST/TextNodeDumper.cpp
+++ clang/lib/AST/TextNodeDumper.cpp
@@ -1338,6 +1338,17 @@
 OS << " <>>";
 }
 
+void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
+const 

[PATCH] D70190: [clang][modules] Add support for merging lifetime-extended temporaries

2019-11-30 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 231589.

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

https://reviews.llvm.org/D70190

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/AST/TextNodeDumper.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/test/Modules/Inputs/merge-lifetime-extended-temporary/a.h
  clang/test/Modules/Inputs/merge-lifetime-extended-temporary/b.h
  clang/test/Modules/Inputs/merge-lifetime-extended-temporary/c.h
  clang/test/Modules/Inputs/merge-lifetime-extended-temporary/module.modulemap
  clang/test/Modules/merge-lifetime-extended-temporary.cpp

Index: clang/test/Modules/merge-lifetime-extended-temporary.cpp
===
--- /dev/null
+++ clang/test/Modules/merge-lifetime-extended-temporary.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-lifetime-extended-temporary -verify -std=c++11 %s -DORDER=1
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-lifetime-extended-temporary -verify -std=c++11 %s -DORDER=2
+
+// expected-no-diagnostics
+#if ORDER == 1
+#include "c.h"
+#include "b.h"
+#else
+#include "b.h"
+#include "c.h"
+#endif
+
+static_assert(PtrTemp1 == , "");
+static_assert(PtrTemp1 == PtrTemp2, "");
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/module.modulemap
===
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/module.modulemap
@@ -0,0 +1,14 @@
+module "a" {
+  export *
+  header "a.h"
+}
+
+module "b" {
+  export *
+  header "b.h"
+}
+
+module "c" {
+  export *
+  header "c.h"
+}
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/c.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/c.h
@@ -0,0 +1,4 @@
+
+#include "a.h"
+
+constexpr const int* PtrTemp2 = 
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/b.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/b.h
@@ -0,0 +1,4 @@
+
+#include "a.h"
+
+constexpr const int* PtrTemp1 = 
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/a.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/a.h
@@ -0,0 +1,2 @@
+
+constexpr const int& LETemp = 0;
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -424,6 +424,9 @@
 template
 void mergeMergeable(Mergeable *D);
 
+template <>
+void mergeMergeable(Mergeable *D);
+
 void mergeTemplatePattern(RedeclarableTemplateDecl *D,
   RedeclarableTemplateDecl *Existing,
   DeclID DsID, bool IsKeyDecl);
@@ -2358,6 +2361,7 @@
   if (Record.readInt())
 D->Value = new (D->getASTContext()) APValue(Record.readAPValue());
   D->ManglingNumber = Record.readInt();
+  mergeMergeable(D);
 }
 
 std::pair
@@ -2555,6 +2559,28 @@
   return false;
 }
 
+/// Attempts to merge LifetimeExtendedTemporaryDecl with
+/// identical class definitions from two different modules.
+template<>
+void ASTDeclReader::mergeMergeable(
+Mergeable *D) {
+  // If modules are not available, there is no reason to perform this merge.
+  if (!Reader.getContext().getLangOpts().Modules)
+return;
+
+  LifetimeExtendedTemporaryDecl *LETDecl =
+  static_cast(D);
+
+  LifetimeExtendedTemporaryDecl * =
+  Reader.LETemporaryForMerging[std::make_pair(
+  LETDecl->getExtendingDecl(), LETDecl->getManglingNumber())];
+  if (LookupResult)
+Reader.getContext().setPrimaryMergedDecl(LETDecl,
+ LookupResult->getCanonicalDecl());
+  else
+LookupResult = LETDecl;
+}
+
 /// Attempts to merge the given declaration (D) with another declaration
 /// of the same entity, for the case where the entity is not actually
 /// redeclarable. This happens, for instance, when merging the fields of
Index: clang/lib/AST/TextNodeDumper.cpp
===
--- clang/lib/AST/TextNodeDumper.cpp
+++ clang/lib/AST/TextNodeDumper.cpp
@@ -1338,6 +1338,17 @@
 OS << " <>>";
 }
 
+void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
+const LifetimeExtendedTemporaryDecl *D) {
+  OS << " extended by ";
+  dumpBareDeclRef(D->getExtendingDecl());
+  OS << " mangling ";
+  {
+ColorScope Color(OS, ShowColors, ValueColor);
+OS << D->getManglingNumber();
+ 

[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

2019-11-30 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 231585.

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

https://reviews.llvm.org/D70638

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseStmt.cpp
  clang/test/Index/pragma-diag-reparse.c
  clang/test/Misc/warning-wall.c
  clang/test/Parser/warn-misleading-indentation.cpp
  clang/test/Preprocessor/pragma_diagnostic_sections.cpp

Index: clang/test/Preprocessor/pragma_diagnostic_sections.cpp
===
--- clang/test/Preprocessor/pragma_diagnostic_sections.cpp
+++ clang/test/Preprocessor/pragma_diagnostic_sections.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -Wno-misleading-indentation -verify %s
 
 // rdar://8365684
 struct S {
Index: clang/test/Parser/warn-misleading-indentation.cpp
===
--- /dev/null
+++ clang/test/Parser/warn-misleading-indentation.cpp
@@ -0,0 +1,208 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wmisleading-indentation -DWITH_WARN %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -DWITH_WARN -DCXX17 %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -Wno-misleading-indentation -DCXX17 %s
+
+#ifndef WITH_WARN
+// expected-no-diagnostics
+#endif
+
+void f0(int i) {
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+  return;
+#ifdef CXX17
+  if constexpr (false)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 0;
+i += 1;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+#endif
+}
+
+void f1(int i) {
+  for (;i;)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'for'}}
+#endif
+  return;
+}
+
+void f2(int i) {
+  while (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1; i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'while'}}
+#endif
+  return;
+}
+
+void f3(int i) {
+  if (i)
+i = i + 1;
+  else
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+const int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'else'}}
+#endif
+}
+
+#ifdef CXX17
+struct Range {
+  int *begin() {return nullptr;}
+  int *end() {return nullptr;}
+};
+#endif
+
+void f4(int i) {
+  if (i)
+  i *= 2;
+  return;
+  if (i)
+i *= 2;
+;
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+typedef int Int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+#ifdef CXX17
+  Range R;
+  for (auto e : R)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+using Int2 = int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'for'}}
+#endif
+#endif
+}
+
+int bar(void);
+
+int foo(int* dst)
+{   
+if (dst)
+   return
+bar();
+  if (dst)
+dst = dst + \
+bar();
+  return 0;
+}
+
+void g(int i) {
+  if (1)
+i = 2;
+  else
+ if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 4;
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'else if'}}
+#endif
+}
+
+// Or this
+#define TEST i = 5
+void g0(int i) {
+  if (1)
+i = 2;
+  else
+i = 5;
+TEST;
+}
+
+void g1(int i) {
+  if (1)
+i = 2;
+  else if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+  i = 4;
+  i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'else if'}}
+#endif
+}
+
+void g2(int i) {
+  if (1)
+i = 2;
+  else
+if (i == 3)
+{i = 4;}
+i = 5;
+}
+
+void g6(int i) {
+if (1)
+if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 4;
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+}
+
+void g7(int i) {
+  if (1)
+i = 4;
+#ifdef TEST1
+#endif
+i = 5;
+}
+
+void a1(int i) { if (1) i = 4; return; }
+
+void 

[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

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



Comment at: clang/lib/Parse/ParseStmt.cpp:1376
+
+MIChecker.Check(ElseStmt.isUsable());
 

Tyker wrote:
> xbolva00 wrote:
> > What is wrong with code you used some rev ago?
> > 
> > if (usable) check();
> > 
> > Now you uselessly instantiate MIChecker since if Usable = false, check is 
> > not called.
> > 
> > I like the older code more...
> > 
> > If (usable) checkForMisleadingIndention(...) 
> > 
> > Was good and accepted.
> previous patch gave up on else if because we can't know wether there are 
> braces.
> 
> this revision can produce correct diagnostics on else if
the MisleadingIndentationChecker gathers information during its construction 
this allows having more context and removes many false positives. 

but I can bring back
If (usable) MIChecker.Check(...)


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

https://reviews.llvm.org/D70638



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


[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

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



Comment at: clang/lib/Parse/ParseStmt.cpp:1376
+
+MIChecker.Check(ElseStmt.isUsable());
 

xbolva00 wrote:
> What is wrong with code you used some rev ago?
> 
> if (usable) check();
> 
> Now you uselessly instantiate MIChecker since if Usable = false, check is not 
> called.
> 
> I like the older code more...
> 
> If (usable) checkForMisleadingIndention(...) 
> 
> Was good and accepted.
previous patch gave up on else if because we can't know wether there are braces.

this revision can produce correct diagnostics on else if


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

https://reviews.llvm.org/D70638



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


[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

2019-11-30 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 231584.

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

https://reviews.llvm.org/D70638

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseStmt.cpp
  clang/test/Index/pragma-diag-reparse.c
  clang/test/Misc/warning-wall.c
  clang/test/Parser/warn-misleading-indentation.cpp
  clang/test/Preprocessor/pragma_diagnostic_sections.cpp

Index: clang/test/Preprocessor/pragma_diagnostic_sections.cpp
===
--- clang/test/Preprocessor/pragma_diagnostic_sections.cpp
+++ clang/test/Preprocessor/pragma_diagnostic_sections.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -Wno-misleading-indentation -verify %s
 
 // rdar://8365684
 struct S {
Index: clang/test/Parser/warn-misleading-indentation.cpp
===
--- /dev/null
+++ clang/test/Parser/warn-misleading-indentation.cpp
@@ -0,0 +1,208 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wmisleading-indentation -DWITH_WARN %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -DWITH_WARN -DCXX17 %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -Wno-misleading-indentation -DCXX17 %s
+
+#ifndef WITH_WARN
+// expected-no-diagnostics
+#endif
+
+void f0(int i) {
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+  return;
+#ifdef CXX17
+  if constexpr (false)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 0;
+i += 1;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+#endif
+}
+
+void f1(int i) {
+  for (;i;)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'for'}}
+#endif
+  return;
+}
+
+void f2(int i) {
+  while (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1; i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'while'}}
+#endif
+  return;
+}
+
+void f3(int i) {
+  if (i)
+i = i + 1;
+  else
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+const int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'else'}}
+#endif
+}
+
+#ifdef CXX17
+struct Range {
+  int *begin() {return nullptr;}
+  int *end() {return nullptr;}
+};
+#endif
+
+void f4(int i) {
+  if (i)
+  i *= 2;
+  return;
+  if (i)
+i *= 2;
+;
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+typedef int Int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+#ifdef CXX17
+  Range R;
+  for (auto e : R)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+using Int2 = int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'for'}}
+#endif
+#endif
+}
+
+int bar(void);
+
+int foo(int* dst)
+{   
+if (dst)
+   return
+bar();
+  if (dst)
+dst = dst + \
+bar();
+  return 0;
+}
+
+void g(int i) {
+  if (1)
+i = 2;
+  else
+ if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 4;
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'else if'}}
+#endif
+}
+
+// Or this
+#define TEST i = 5
+void g0(int i) {
+  if (1)
+i = 2;
+  else
+i = 5;
+TEST;
+}
+
+void g1(int i) {
+  if (1)
+i = 2;
+  else if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+  i = 4;
+  i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'else if'}}
+#endif
+}
+
+void g2(int i) {
+  if (1)
+i = 2;
+  else
+if (i == 3)
+{i = 4;}
+i = 5;
+}
+
+void g6(int i) {
+if (1)
+if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 4;
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+}
+
+void g7(int i) {
+  if (1)
+i = 4;
+#ifdef TEST1
+#endif
+i = 5;
+}
+
+void a1(int i) { if (1) i = 4; return; }
+
+void 

[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

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

Improve the warning for else if


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

https://reviews.llvm.org/D70638

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseStmt.cpp
  clang/test/Index/pragma-diag-reparse.c
  clang/test/Misc/warning-wall.c
  clang/test/Preprocessor/pragma_diagnostic_sections.cpp

Index: clang/test/Preprocessor/pragma_diagnostic_sections.cpp
===
--- clang/test/Preprocessor/pragma_diagnostic_sections.cpp
+++ clang/test/Preprocessor/pragma_diagnostic_sections.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -Wno-misleading-indentation -verify %s
 
 // rdar://8365684
 struct S {
Index: clang/test/Misc/warning-wall.c
===
--- clang/test/Misc/warning-wall.c
+++ clang/test/Misc/warning-wall.c
@@ -90,6 +90,7 @@
 CHECK-NEXT:-Wdangling-else
 CHECK-NEXT:  -Wswitch
 CHECK-NEXT:  -Wswitch-bool
+CHECK-NEXT:  -Wmisleading-indentation
 
 
 CHECK-NOT:-W
Index: clang/test/Index/pragma-diag-reparse.c
===
--- clang/test/Index/pragma-diag-reparse.c
+++ clang/test/Index/pragma-diag-reparse.c
@@ -11,6 +11,7 @@
   return x;
 }
 
+#pragma clang diagnostic ignored "-Wmisleading-indentation"
 void foo() { int b=0; while (b==b); }
 
 // RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_FAILONERROR=1 c-index-test -test-load-source-reparse 5 local \
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -1191,6 +1191,56 @@
   return false;
 }
 
+namespace {
+
+enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while, MSK_else_if };
+
+struct MisleadingIndentationChecker {
+  Parser 
+  SourceLocation StmtLoc;
+  SourceLocation PrevLoc;
+  unsigned NumDirectives;
+  MisleadingStatementKind Kind;
+  bool NeedsChecking;
+  bool ShouldSkip;
+  MisleadingIndentationChecker(Parser , MisleadingStatementKind K,
+   SourceLocation SL)
+  : P(P), StmtLoc(SL), PrevLoc(P.getCurToken().getLocation()),
+NumDirectives(P.getPreprocessor().getNumDirectives()), Kind(K),
+NeedsChecking(true),
+ShouldSkip(P.getCurToken().is(tok::l_brace) ||
+   (K == MSK_else && P.getCurToken().is(tok::kw_if))) {}
+  void Check(bool ShouldCheck) {
+NeedsChecking = false;
+Token Tok = P.getCurToken();
+if (!ShouldCheck || ShouldSkip ||
+NumDirectives != P.getPreprocessor().getNumDirectives() ||
+Tok.isOneOf(tok::semi, tok::r_brace) || Tok.isAnnotation() ||
+Tok.getLocation().isMacroID() || PrevLoc.isMacroID() ||
+StmtLoc.isMacroID())
+  return;
+SourceManager  = P.getPreprocessor().getSourceManager();
+unsigned PrevColNum = SM.getSpellingColumnNumber(PrevLoc);
+unsigned CurColNum = SM.getSpellingColumnNumber(Tok.getLocation());
+unsigned StmtColNum = SM.getSpellingColumnNumber(StmtLoc);
+
+if (PrevColNum != 0 && CurColNum != 0 && StmtColNum != 0 &&
+((PrevColNum > StmtColNum && PrevColNum == CurColNum) ||
+ !Tok.isAtStartOfLine())) {
+  if (SM.getPresumedLineNumber(StmtLoc) ==
+  SM.getPresumedLineNumber(Tok.getLocation()))
+return;
+  P.Diag(Tok.getLocation(), diag::warn_misleading_indentation)
+  << Kind;
+  P.Diag(StmtLoc, diag::note_previous_statement);
+}
+  }
+  ~MisleadingIndentationChecker() {
+assert(!NeedsChecking && "Check Has not been called");
+  }
+};
+
+}
 
 /// ParseIfStatement
 ///   if-statement: [C99 6.8.4.1]
@@ -1199,7 +1249,8 @@
 /// [C++]   'if' '(' condition ')' statement
 /// [C++]   'if' '(' condition ')' statement 'else' statement
 ///
-StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
+StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc,
+SourceLocation ElseLocOnElseIf) {
   assert(Tok.is(tok::kw_if) && "Not an if stmt!");
   SourceLocation IfLoc = ConsumeToken();  // eat the 'if'.
 
@@ -1265,6 +1316,10 @@
   //
   ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
 
+  MisleadingIndentationChecker MIChecker(
+  *this, ElseLocOnElseIf.isInvalid() ? MSK_if : MSK_else_if,
+  ElseLocOnElseIf.isInvalid() ? IfLoc : ElseLocOnElseIf);
+
   // Read the 'then' stmt.
   SourceLocation ThenStmtLoc = Tok.getLocation();
 
@@ -1278,6 +1333,8 @@
 ThenStmt = ParseStatement();
   }
 
+  

[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

2019-11-29 Thread Tyker via Phabricator via cfe-commits
Tyker updated this revision to Diff 231561.

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

https://reviews.llvm.org/D70638

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Lex/Preprocessor.h
  clang/lib/Parse/ParseStmt.cpp
  clang/test/Index/pragma-diag-reparse.c
  clang/test/Misc/warning-wall.c
  clang/test/Parser/warn-misleading-indentation.cpp
  clang/test/Preprocessor/pragma_diagnostic_sections.cpp

Index: clang/test/Preprocessor/pragma_diagnostic_sections.cpp
===
--- clang/test/Preprocessor/pragma_diagnostic_sections.cpp
+++ clang/test/Preprocessor/pragma_diagnostic_sections.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -Wno-misleading-indentation -verify %s
 
 // rdar://8365684
 struct S {
Index: clang/test/Parser/warn-misleading-indentation.cpp
===
--- /dev/null
+++ clang/test/Parser/warn-misleading-indentation.cpp
@@ -0,0 +1,210 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wmisleading-indentation -DWITH_WARN %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -DWITH_WARN -DCXX17 %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -Wno-misleading-indentation -DCXX17 %s
+
+#ifndef WITH_WARN
+// expected-no-diagnostics
+#endif
+
+void f0(int i) {
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+  return;
+#ifdef CXX17
+  if constexpr (false)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 0;
+i += 1;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+#endif
+}
+
+void f1(int i) {
+  for (;i;)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'for'}}
+#endif
+  return;
+}
+
+void f2(int i) {
+  while (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1; i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'while'}}
+#endif
+  return;
+}
+
+void f3(int i) {
+  if (i)
+i = i + 1;
+  else
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+const int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'else'}}
+#endif
+}
+
+#ifdef CXX17
+struct Range {
+  int *begin() {return nullptr;}
+  int *end() {return nullptr;}
+};
+#endif
+
+void f4(int i) {
+  if (i)
+  i *= 2;
+  return;
+  if (i)
+i *= 2;
+;
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+typedef int Int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+#ifdef CXX17
+  Range R;
+  for (auto e : R)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+using Int2 = int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'for'}}
+#endif
+#endif
+}
+
+int bar(void);
+
+int foo(int* dst)
+{   
+if (dst)
+   return
+bar();
+  if (dst)
+dst = dst + \
+bar();
+  return 0;
+}
+
+// No diagnostics from GCC on this
+void g(int i) {
+  if (1)
+i = 2;
+  else
+ if (i == 3)
+i = 4;
+i = 5;
+}
+
+// Or this
+#define TEST i = 5
+void g0(int i) {
+  if (1)
+i = 2;
+  else
+i = 5;
+TEST;
+}
+
+void g1(int i) {
+  if (1)
+i = 2;
+  else
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+if (i == 3)
+i = 4;
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'else'}}
+#endif
+}
+
+void g2(int i) {
+  if (1)
+i = 2;
+  else
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+if (i == 3)
+{i = 4;}
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'else'}}
+#endif
+}
+
+void g6(int i) {
+if (1)
+if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 4;
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+}
+
+void g7(int i) {
+  if (1)
+i = 4;
+#ifdef TEST1
+#endif
+i = 5;
+}
+
+void a1(int i) { if (1) i = 4; return; }
+
+void a2(int i) 

[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

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

I just found out that `Parser::isCXXDeclarationStatement` is does more then 
just disambiguation it can emit diagnostics. which can cause error on correct 
code. so we can't use it in this context to disambiguate.

so it is not possible to easily disambiguate between statements and 
declaration. i changed the warning message to reflect that but the message 
isn't so good now.


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

https://reviews.llvm.org/D70638

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
  clang/test/Index/pragma-diag-reparse.c
  clang/test/Misc/warning-wall.c
  clang/test/Preprocessor/pragma_diagnostic_sections.cpp

Index: clang/test/Preprocessor/pragma_diagnostic_sections.cpp
===
--- clang/test/Preprocessor/pragma_diagnostic_sections.cpp
+++ clang/test/Preprocessor/pragma_diagnostic_sections.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -Wno-misleading-indentation -verify %s
 
 // rdar://8365684
 struct S {
Index: clang/test/Misc/warning-wall.c
===
--- clang/test/Misc/warning-wall.c
+++ clang/test/Misc/warning-wall.c
@@ -90,6 +90,7 @@
 CHECK-NEXT:-Wdangling-else
 CHECK-NEXT:  -Wswitch
 CHECK-NEXT:  -Wswitch-bool
+CHECK-NEXT:  -Wmisleading-indentation
 
 
 CHECK-NOT:-W
Index: clang/test/Index/pragma-diag-reparse.c
===
--- clang/test/Index/pragma-diag-reparse.c
+++ clang/test/Index/pragma-diag-reparse.c
@@ -11,6 +11,7 @@
   return x;
 }
 
+#pragma clang diagnostic ignored "-Wmisleading-indentation"
 void foo() { int b=0; while (b==b); }
 
 // RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_FAILONERROR=1 c-index-test -test-load-source-reparse 5 local \
Index: clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -2525,19 +2525,18 @@
 
 // Find the most recent expression bound to the symbol in the current
 // context.
-  if (!ReferenceRegion) {
-if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) {
-  SVal Val = State->getSVal(MR);
-  if (Val.getAsLocSymbol() == Sym) {
-const VarRegion* VR = MR->getBaseRegion()->getAs();
-// Do not show local variables belonging to a function other than
-// where the error is reported.
-if (!VR ||
-(VR->getStackFrame() == LeakContext->getStackFrame()))
-  ReferenceRegion = MR;
-  }
+if (!ReferenceRegion) {
+  if (const MemRegion *MR = C.getLocationRegionIfPostStore(N)) {
+SVal Val = State->getSVal(MR);
+if (Val.getAsLocSymbol() == Sym) {
+  const VarRegion *VR = MR->getBaseRegion()->getAs();
+  // Do not show local variables belonging to a function other than
+  // where the error is reported.
+  if (!VR || (VR->getStackFrame() == LeakContext->getStackFrame()))
+ReferenceRegion = MR;
 }
   }
+}
 
 // Allocation node, is the last node in the current or parent context in
 // which the symbol was tracked.
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -1191,6 +1191,55 @@
   return false;
 }
 
+namespace {
+
+enum MisleadingStatementKind { MSK_if, MSK_else, MSK_for, MSK_while };
+
+struct MisleadingIndentationChecker {
+  Parser 
+  SourceLocation StmtLoc;
+  SourceLocation PrevLoc;
+  unsigned NumDirectives;
+  MisleadingStatementKind Kind;
+  bool NeedsChecking;
+  bool HasBraces;
+  MisleadingIndentationChecker(Parser , MisleadingStatementKind K,
+   SourceLocation SL)
+  : P(P), StmtLoc(SL), PrevLoc(P.getCurToken().getLocation()),
+NumDirectives(P.getPreprocessor().getNumDirectives()), Kind(K),
+NeedsChecking(true), HasBraces(P.getCurToken().is(tok::l_brace)) {
+}
+  void Check(bool ShouldCheck) {
+NeedsChecking = false;
+Token Tok = P.getCurToken();
+if (!ShouldCheck || HasBraces ||
+NumDirectives != P.getPreprocessor().getNumDirectives() ||
+Tok.isOneOf(tok::semi, tok::r_brace) || Tok.isAnnotation() ||
+Tok.getLocation().isMacroID() || PrevLoc.isMacroID() ||
+

[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

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

yeah i saw. this version of the patch builds all llvm subproject(not tested on 
llgo) without warnings. there is only one case in llvm's code in which this 
warning is more agressive thant GCC's.

  if (1)
i = 0;
  
  // comment
i = 1; //  clang + this patch warns through the comment wereas gcc doesn't.

i don't believe a warning in this case is too bad.


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

https://reviews.llvm.org/D70638

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
  clang/test/Index/pragma-diag-reparse.c
  clang/test/Misc/warning-wall.c
  clang/test/Parser/warn-misleading-indentation.cpp
  clang/test/Preprocessor/pragma_diagnostic_sections.cpp

Index: clang/test/Preprocessor/pragma_diagnostic_sections.cpp
===
--- clang/test/Preprocessor/pragma_diagnostic_sections.cpp
+++ clang/test/Preprocessor/pragma_diagnostic_sections.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -Wno-misleading-indentation -verify %s
 
 // rdar://8365684
 struct S {
Index: clang/test/Parser/warn-misleading-indentation.cpp
===
--- /dev/null
+++ clang/test/Parser/warn-misleading-indentation.cpp
@@ -0,0 +1,210 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wmisleading-indentation -DWITH_WARN %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -DWITH_WARN -DCXX17 %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -Wno-misleading-indentation -DCXX17 %s
+
+#ifndef WITH_WARN
+// expected-no-diagnostics
+#endif
+
+void f0(int i) {
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; declaration is not part of the previous 'if'}}
+#endif
+  return;
+#ifdef CXX17
+  if constexpr (false)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 0;
+i += 1;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+#endif
+}
+
+void f1(int i) {
+  for (;i;)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'for'}}
+#endif
+  return;
+}
+
+void f2(int i) {
+  while (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1; i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'while'}}
+#endif
+  return;
+}
+
+void f3(int i) {
+  if (i)
+i = i + 1;
+  else
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+const int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; declaration is not part of the previous 'else'}}
+#endif
+}
+
+#ifdef CXX17
+struct Range {
+  int *begin() {return nullptr;}
+  int *end() {return nullptr;}
+};
+#endif
+
+void f4(int i) {
+  if (i)
+  i *= 2;
+  return;
+  if (i)
+i *= 2;
+;
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+typedef int Int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; declaration is not part of the previous 'if'}}
+#endif
+#ifdef CXX17
+  Range R;
+  for (auto e : R)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+using Int2 = int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; declaration is not part of the previous 'for'}}
+#endif
+#endif
+}
+
+int bar(void);
+
+int foo(int* dst)
+{   
+if (dst)
+   return
+bar();
+  if (dst)
+dst = dst + \
+bar();
+  return 0;
+}
+
+// No diagnostics from GCC on this
+void g(int i) {
+  if (1)
+i = 2;
+  else
+ if (i == 3)
+i = 4;
+i = 5;
+}
+
+// Or this
+#define TEST i = 5
+void g0(int i) {
+  if (1)
+i = 2;
+  else
+i = 5;
+TEST;
+}
+
+void g1(int i) {
+  if (1)
+i = 2;
+  else
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+if (i == 3)
+i = 4;
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'else'}}
+#endif
+}
+
+void g2(int i) {
+  if (1)
+i = 2;
+  else
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+if (i == 3)
+{i = 4;}
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not 

[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

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

Thanks for the review


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70638



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


[PATCH] D70638: [Diagnostic] add a warning which warns about misleading indentation

2019-11-25 Thread Tyker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG7b86188b50bf: [Diagnostic] add a warning which warns about 
misleading indentation (authored by Tyker).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70638

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseStmt.cpp
  clang/test/Index/pragma-diag-reparse.c
  clang/test/Misc/warning-wall.c
  clang/test/Preprocessor/pragma_diagnostic_sections.cpp
  clang/test/SemaCXX/warn-misleading-indentation.cpp

Index: clang/test/SemaCXX/warn-misleading-indentation.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/warn-misleading-indentation.cpp
@@ -0,0 +1,184 @@
+// RUN: %clang_cc1 -x c -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c -fsyntax-only -verify -Wmisleading-indentation -DWITH_WARN %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -DWITH_WARN -DCXX17 %s
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify -Wall -Wno-unused -Wno-misleading-indentation -DCXX17 %s
+
+#ifndef WITH_WARN
+// expected-no-diagnostics
+#endif
+
+void f0(int i) {
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; declaration is not part of the previous 'if'}}
+#endif
+  return;
+#ifdef CXX17
+  if constexpr (false)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 0;
+i += 1;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+#endif
+}
+
+void f1(int i) {
+  for (;i;)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1;
+i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'for'}}
+#endif
+  return;
+}
+
+void f2(int i) {
+  while (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = i + 1; i *= 2;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'while'}}
+#endif
+  return;
+}
+
+void f3(int i) {
+  if (i)
+i = i + 1;
+  else
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+const int x = 0;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; declaration is not part of the previous 'else'}}
+#endif
+}
+
+#ifdef CXX17
+struct Range {
+  int *begin() {return nullptr;}
+  int *end() {return nullptr;}
+};
+#endif
+
+void f4(int i) {
+  if (i)
+  i *= 2;
+  return;
+  if (i)
+i *= 2;
+;
+  if (i)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+typedef int Int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; declaration is not part of the previous 'if'}}
+#endif
+#ifdef CXX17
+  Range R;
+  for (auto e : R)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i *= 2;
+using Int2 = int;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; declaration is not part of the previous 'for'}}
+#endif
+#endif
+}
+
+int bar(void);
+
+int foo(int* dst)
+{   
+if (dst)
+   return
+bar();
+  if (dst)
+dst = dst + \
+bar();
+  return 0;
+}
+
+// No diagnostics from GCC on this
+void g(int i) {
+  if (1)
+i = 2;
+  else
+ if (i == 3)
+i = 4;
+i = 5;
+}
+
+// Or this
+#define TEST i = 5
+void g0(int i) {
+  if (1)
+i = 2;
+  else
+i = 5;
+TEST;
+}
+
+void g1(int i) {
+  if (1)
+i = 2;
+  else
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+if (i == 3)
+i = 4;
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'else'}}
+#endif
+}
+
+void g2(int i) {
+  if (1)
+i = 2;
+  else
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+if (i == 3)
+{i = 4;}
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'else'}}
+#endif
+}
+
+void g6(int i) {
+if (1)
+  if (i == 3)
+#ifdef WITH_WARN
+// expected-note@-2 {{here}}
+#endif
+i = 4;
+i = 5;
+#ifdef WITH_WARN
+// expected-warning@-2 {{misleading indentation; statement is not part of the previous 'if'}}
+#endif
+}
Index: clang/test/Preprocessor/pragma_diagnostic_sections.cpp
===
--- clang/test/Preprocessor/pragma_diagnostic_sections.cpp
+++ clang/test/Preprocessor/pragma_diagnostic_sections.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wall -Wunused-macros -Wunused-parameter -Wno-uninitialized -verify %s
+// RUN: %clang_cc1 -fsyntax-only 

[PATCH] D70190: [clang][modules] Add support for merging lifetime-extended temporaries

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

rebased
added new lines.


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

https://reviews.llvm.org/D70190

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/include/clang/AST/TextNodeDumper.h
  clang/include/clang/Serialization/ASTReader.h
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/test/Modules/Inputs/merge-lifetime-extended-temporary/a.h
  clang/test/Modules/Inputs/merge-lifetime-extended-temporary/b.h
  clang/test/Modules/Inputs/merge-lifetime-extended-temporary/c.h
  clang/test/Modules/Inputs/merge-lifetime-extended-temporary/module.modulemap
  clang/test/Modules/merge-lifetime-extended-temporary.cpp

Index: clang/test/Modules/merge-lifetime-extended-temporary.cpp
===
--- /dev/null
+++ clang/test/Modules/merge-lifetime-extended-temporary.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-lifetime-extended-temporary -verify -std=c++11 %s -DORDER=1
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-lifetime-extended-temporary -verify -std=c++11 %s -DORDER=2
+
+// expected-no-diagnostics
+#if ORDER == 1
+#include "c.h"
+#include "b.h"
+#else
+#include "b.h"
+#include "c.h"
+#endif
+
+static_assert(PtrTemp1 == , "");
+static_assert(PtrTemp1 == PtrTemp2, "");
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/module.modulemap
===
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/module.modulemap
@@ -0,0 +1,14 @@
+module "a" {
+  export *
+  header "a.h"
+}
+
+module "b" {
+  export *
+  header "b.h"
+}
+
+module "c" {
+  export *
+  header "c.h"
+}
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/c.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/c.h
@@ -0,0 +1,4 @@
+
+#include "a.h"
+
+constexpr const int* PtrTemp2 = 
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/b.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/b.h
@@ -0,0 +1,4 @@
+
+#include "a.h"
+
+constexpr const int* PtrTemp1 = 
Index: clang/test/Modules/Inputs/merge-lifetime-extended-temporary/a.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/merge-lifetime-extended-temporary/a.h
@@ -0,0 +1,2 @@
+
+constexpr const int& LETemp = 0;
Index: clang/lib/Serialization/ASTReaderDecl.cpp
===
--- clang/lib/Serialization/ASTReaderDecl.cpp
+++ clang/lib/Serialization/ASTReaderDecl.cpp
@@ -424,6 +424,9 @@
 template
 void mergeMergeable(Mergeable *D);
 
+template <>
+void mergeMergeable(Mergeable *D);
+
 void mergeTemplatePattern(RedeclarableTemplateDecl *D,
   RedeclarableTemplateDecl *Existing,
   DeclID DsID, bool IsKeyDecl);
@@ -2358,6 +2361,7 @@
   if (Record.readInt())
 D->Value = new (D->getASTContext()) APValue(Record.readAPValue());
   D->ManglingNumber = Record.readInt();
+  mergeMergeable(D);
 }
 
 std::pair
@@ -2555,6 +2559,28 @@
   return false;
 }
 
+/// Attempts to merge LifetimeExtendedTemporaryDecl with
+/// identical class definitions from two different modules.
+template<>
+void ASTDeclReader::mergeMergeable(
+Mergeable *D) {
+  // If modules are not available, there is no reason to perform this merge.
+  if (!Reader.getContext().getLangOpts().Modules)
+return;
+
+  LifetimeExtendedTemporaryDecl *LETDecl =
+  static_cast(D);
+
+  LifetimeExtendedTemporaryDecl * =
+  Reader.LETemporaryForMerging[std::make_pair(
+  LETDecl->getExtendingDecl(), LETDecl->getManglingNumber())];
+  if (LookupResult)
+Reader.getContext().setPrimaryMergedDecl(LETDecl,
+ LookupResult->getCanonicalDecl());
+  else
+LookupResult = LETDecl;
+}
+
 /// Attempts to merge the given declaration (D) with another declaration
 /// of the same entity, for the case where the entity is not actually
 /// redeclarable. This happens, for instance, when merging the fields of
Index: clang/lib/AST/TextNodeDumper.cpp
===
--- clang/lib/AST/TextNodeDumper.cpp
+++ clang/lib/AST/TextNodeDumper.cpp
@@ -1338,6 +1338,17 @@
 OS << " <>>";
 }
 
+void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
+const LifetimeExtendedTemporaryDecl *D) {
+  OS << " extended by ";
+  dumpBareDeclRef(D->getExtendingDecl());
+  OS << " mangling ";
+  {
+ColorScope Color(OS, ShowColors, 

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

2019-11-21 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] D70190: [clang][modules] Add support for merging lifetime-extended temporaries

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

@rsmith ping


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

https://reviews.llvm.org/D70190



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


  1   2   3   >