[PATCH] D82845: [Analyzer][StreamChecker] Report every leak, clean up state.

2020-07-20 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 279133.
balazske added a comment.

Rebase to master.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D82845

Files:
  clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -46,3 +46,34 @@
 }
 // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
 // expected-note@-2 {{Opened stream never closed. Potential resource leak}}
+
+void check_note_leak_2(int c) {
+  FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
+  if (!F1)
+// expected-note@-1 {{'F1' is non-null}}
+// expected-note@-2 {{Taking false branch}}
+// expected-note@-3 {{'F1' is non-null}}
+// expected-note@-4 {{Taking false branch}}
+return;
+  FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
+  if (!F2) {
+// expected-note@-1 {{'F2' is non-null}}
+// expected-note@-2 {{Taking false branch}}
+// expected-note@-3 {{'F2' is non-null}}
+// expected-note@-4 {{Taking false branch}}
+fclose(F1);
+return;
+  }
+  if (c)
+// expected-note@-1 {{Assuming 'c' is not equal to 0}}
+// expected-note@-2 {{Taking true branch}}
+// expected-note@-3 {{Assuming 'c' is not equal to 0}}
+// expected-note@-4 {{Taking true branch}}
+return;
+  // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
+  // expected-note@-2 {{Opened stream never closed. Potential resource leak}}
+  // expected-warning@-3 {{Opened stream never closed. Potential resource leak}}
+  // expected-note@-4 {{Opened stream never closed. Potential resource leak}}
+  fclose(F1);
+  fclose(F2);
+}
Index: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -337,6 +337,12 @@
   /// to ensure uniform handling.
   void reportFEofWarning(CheckerContext &C, ProgramStateRef State) const;
 
+  /// Emit resource leak warnings for the given symbols.
+  /// Createn a non-fatal error node for these, and returns it (if any warnings
+  /// were generated). Return value is non-null.
+  ExplodedNode *reportLeaks(const SmallVector &LeakedSyms,
+CheckerContext &C, ExplodedNode *Pred) const;
+
   /// Find the description data of the function called by a call event.
   /// Returns nullptr if no function is recognized.
   const FnDescription *lookupFn(const CallEvent &Call) const {
@@ -956,28 +962,19 @@
   C.addTransition(State);
 }
 
-void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper,
- CheckerContext &C) const {
-  ProgramStateRef State = C.getState();
-
-  // TODO: Clean up the state.
-  const StreamMapTy &Map = State->get();
-  for (const auto &I : Map) {
-SymbolRef Sym = I.first;
-const StreamState &SS = I.second;
-if (!SymReaper.isDead(Sym) || !SS.isOpened())
-  continue;
-
-ExplodedNode *N = C.generateErrorNode();
-if (!N)
-  continue;
+ExplodedNode *
+StreamChecker::reportLeaks(const SmallVector &LeakedSyms,
+   CheckerContext &C, ExplodedNode *Pred) const {
+  // Do not warn for non-closed stream at program exit.
+  // FIXME: Use BugType::SuppressOnSink instead.
+  if (Pred && Pred->getCFGBlock() && Pred->getCFGBlock()->hasNoReturnElement())
+return Pred;
 
-// Do not warn for non-closed stream at program exit.
-ExplodedNode *Pred = C.getPredecessor();
-if (Pred && Pred->getCFGBlock() &&
-Pred->getCFGBlock()->hasNoReturnElement())
-  continue;
+  ExplodedNode *Err = C.generateNonFatalErrorNode(C.getState(), Pred);
+  if (!Err)
+return Pred;
 
+  for (SymbolRef LeakSym : LeakedSyms) {
 // Resource leaks can result in multiple warning that describe the same kind
 // of programming error:
 //  void f() {
@@ -989,8 +986,7 @@
 // from a different kinds of errors), the reduction in redundant reports
 // makes this a worthwhile heuristic.
 // FIXME: Add a checker option to turn this uniqueing feature off.
-
-const ExplodedNode *StreamOpenNode = getAcquisitionSite(N, Sym, C);
+const ExplodedNode *StreamOpenNode = getAcquisitionSite(Err, LeakSym, C);
 assert(StreamOpenNode && "Could not find place of stream opening.");
 PathDiagnosticLocation LocUsedForUniqueing =
 PathDiagnosticLocation::createBegin(
@@ -1000,12 +996,38 @@
 std::unique_ptr R =
 std::make_unique(
 BT_ResourceLeak,
-"Opened stream never closed. Potential resource leak.", N,
+"Opened stream never closed. Potential resource leak.", Err

[PATCH] D84136: [clangd] Fix visitation of ConceptSpecializationExpr in constrained-parameter

2020-07-20 Thread Nathan Ridge via Phabricator via cfe-commits
nridge created this revision.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous, 
MaskRay, ilya-biryukov.
Herald added a project: clang.

There were two problems here:

- RecursiveASTVisitor did not traverse 
TypeConstraint::ImmediatelyDeclaredConstraint
- ConceptSpecializationExpr::getEndLoc() returned an invalid location in case 
of a constrained-parameter with no explicit arguments


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84136

Files:
  clang-tools-extra/clangd/unittests/FindTargetTests.cpp
  clang/include/clang/AST/ExprConcepts.h
  clang/include/clang/AST/RecursiveASTVisitor.h


Index: clang/include/clang/AST/RecursiveASTVisitor.h
===
--- clang/include/clang/AST/RecursiveASTVisitor.h
+++ clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1839,8 +1839,10 @@
   // D is the "T" in something like "template class vector;"
   if (D->getTypeForDecl())
 TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
-  if (const auto *TC = D->getTypeConstraint())
+  if (const auto *TC = D->getTypeConstraint()) {
+TRY_TO(TraverseStmt(TC->getImmediatelyDeclaredConstraint()));
 TRY_TO(TraverseConceptReference(*TC));
+  }
   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
 TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
 })
Index: clang/include/clang/AST/ExprConcepts.h
===
--- clang/include/clang/AST/ExprConcepts.h
+++ clang/include/clang/AST/ExprConcepts.h
@@ -126,7 +126,11 @@
   }
 
   SourceLocation getEndLoc() const LLVM_READONLY {
-return ArgsAsWritten->RAngleLoc;
+// If the ConceptSpecializationExpr is the ImmediatelyDeclaredConstraint
+// of a TypeConstraint written syntactically as a constrained-parameter,
+// there may not be a template argument list.
+return ArgsAsWritten->RAngleLoc.isValid() ? ArgsAsWritten->RAngleLoc
+  : ConceptName.getEndLoc();
   }
 
   // Iterators
Index: clang-tools-extra/clangd/unittests/FindTargetTests.cpp
===
--- clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -407,6 +407,34 @@
   // FIXME: Should we truncate the pretty-printed form of a concept decl
   // somewhere?
   {"template  concept Fooable = requires (T t) { t.foo(); 
};"});
+
+  // constrained-parameter
+  Code = R"cpp(
+template 
+concept Fooable = true;
+
+template <[[Fooable]] T>
+void bar(T t);
+  )cpp";
+  Flags.push_back("-std=c++20");
+  EXPECT_DECLS("ConceptSpecializationExpr",
+   // FIXME: Should we truncate the pretty-printed form of a 
concept
+   // decl somewhere?
+   {"template  concept Fooable = true;"});
+
+  // partial-concept-id
+  Code = R"cpp(
+template 
+concept Fooable = true;
+
+template <[[Fooable]] T>
+void bar(T t);
+  )cpp";
+  Flags.push_back("-std=c++20");
+  EXPECT_DECLS("ConceptSpecializationExpr",
+   // FIXME: Should we truncate the pretty-printed form of a 
concept
+   // decl somewhere?
+   {"template  concept Fooable = true;"});
 }
 
 TEST_F(TargetDeclTest, FunctionTemplate) {


Index: clang/include/clang/AST/RecursiveASTVisitor.h
===
--- clang/include/clang/AST/RecursiveASTVisitor.h
+++ clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1839,8 +1839,10 @@
   // D is the "T" in something like "template class vector;"
   if (D->getTypeForDecl())
 TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
-  if (const auto *TC = D->getTypeConstraint())
+  if (const auto *TC = D->getTypeConstraint()) {
+TRY_TO(TraverseStmt(TC->getImmediatelyDeclaredConstraint()));
 TRY_TO(TraverseConceptReference(*TC));
+  }
   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
 TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
 })
Index: clang/include/clang/AST/ExprConcepts.h
===
--- clang/include/clang/AST/ExprConcepts.h
+++ clang/include/clang/AST/ExprConcepts.h
@@ -126,7 +126,11 @@
   }
 
   SourceLocation getEndLoc() const LLVM_READONLY {
-return ArgsAsWritten->RAngleLoc;
+// If the ConceptSpecializationExpr is the ImmediatelyDeclaredConstraint
+// of a TypeConstraint written syntactically as a constrained-parameter,
+// there may not be a template argument list.
+return ArgsAsWritten->RAngleLoc.isValid() ? ArgsAsWritten->RAngleLoc
+  : ConceptName.getEndLoc();
   }
 
   // Iterators
Index: clang-tools-extra/clangd/unittests/FindTargetTests.cpp
===
--- clang-tools-extra/c

[PATCH] D83914: [clangd] Plan features for FoldingRanges

2020-07-20 Thread Kirill Bobyrev via Phabricator via cfe-commits
kbobyrev added inline comments.



Comment at: clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp:246
+
+  if ([[B && I > 42 || ~([[++I]])]]) {[[
+++I;

sammccall wrote:
> confused about [[++I]] - why is this foldable but not I > 42 etc - is this 
> because of the containing parens?
> 
> FWIW, Personally, I'd want the whole if condition to be  foldable (maybe only 
> if it spans lines), and only paren subexpressions, arg lists etc that span 
> lines to be foldable. It's hard to imagine a UX that could expose folding 
> small parens in a way that's not annoying. (e.g. shows lots of extra UI 
> elements, or prevents folding the outer expression)
Sounds good! Added a separate expressions test to Misc, too.



Comment at: clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp:329
+  )cpp",
+  // Argument lists.
+  R"cpp(

sammccall wrote:
> missing lambdas, blocks, objc methods.
> cover bodies in the same tests?
> capture lists of lambdas?
What kind of blocks? Do you mean statement groups? What do you mean by "cover 
bodies in the same tests"? What kind of bodies?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83914



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


[PATCH] D83914: [clangd] Plan features for FoldingRanges

2020-07-20 Thread Sam McCall via Phabricator via cfe-commits
sammccall added inline comments.



Comment at: clang-tools-extra/clangd/unittests/SemanticSelectionTests.cpp:329
+  )cpp",
+  // Argument lists.
+  R"cpp(

kbobyrev wrote:
> sammccall wrote:
> > missing lambdas, blocks, objc methods.
> > cover bodies in the same tests?
> > capture lists of lambdas?
> What kind of blocks? Do you mean statement groups? What do you mean by "cover 
> bodies in the same tests"? What kind of bodies?
> What kind of blocks? 

Parallel-universe lambdas

https://clang.llvm.org/doxygen/classclang_1_1BlockDecl.html#details

(Commonly used in the apple world I think, though it's not actually an 
extension to objc but rather c)

> What do you mean by "cover bodies in the same tests"?
You have to go through the different ways to write functions here, I was just 
suggesting making sure they are definitions so you can test their body ranges 
too...


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83914



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


[PATCH] D84140: [clang] Set the error-bit for ill-formed semantic InitListExpr.

2020-07-20 Thread Haojian Wu via Phabricator via cfe-commits
hokein created this revision.
hokein added a reviewer: sammccall.
Herald added subscribers: kbobyrev, usaxena95, kadircet, arphaman, jkorous.
Herald added a project: clang.

When a semantic checking fails on a syntactic InitListExpr, we will
get an ill-formed semantic InitListExpr (e.g. some inits are nullptr),
using this semantic InitListExpr in clang (without setting the err-bits) is 
crashy.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84140

Files:
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/Expr.h
  clang/lib/Sema/SemaInit.cpp


Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -962,6 +962,8 @@
   FillInEmptyInitializations(Entity, FullyStructuredList,
  RequiresSecondPass, nullptr, 0);
   }
+  if (hadError && FullyStructuredList)
+FullyStructuredList->markError();
 }
 
 int InitListChecker::numArrayElements(QualType DeclType) {
Index: clang/include/clang/AST/Expr.h
===
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -4690,6 +4690,14 @@
   setDependence(getDependence() | expr->getDependence());
   }
 
+  /// Mark the semantic form of the InitListExpr as error when the semantic
+  /// analysis fails.
+  void markError() {
+assert(isSemanticForm());
+setDependence(getDependence() | ExprDependence::Error |
+  ExprDependence::ValueInstantiation);
+  }
+
   /// Reserve space for some number of initializers.
   void reserveInits(const ASTContext &C, unsigned NumInits);
 
Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -957,6 +957,16 @@
   template  void foo() {
 (void)[[size^of]](T);
   })cpp",
+  R"cpp(// should not crash on invalid semantic form of init-list-expr.
+/*error-ok*/
+struct Foo {
+  int xyz = 0;
+};
+class Bar {};
+constexpr Foo s = ^{
+  .xyz = Bar(),
+};
+  )cpp",
   // literals
   "auto x = t^rue;",
   "auto x = '^A';",


Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -962,6 +962,8 @@
   FillInEmptyInitializations(Entity, FullyStructuredList,
  RequiresSecondPass, nullptr, 0);
   }
+  if (hadError && FullyStructuredList)
+FullyStructuredList->markError();
 }
 
 int InitListChecker::numArrayElements(QualType DeclType) {
Index: clang/include/clang/AST/Expr.h
===
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -4690,6 +4690,14 @@
   setDependence(getDependence() | expr->getDependence());
   }
 
+  /// Mark the semantic form of the InitListExpr as error when the semantic
+  /// analysis fails.
+  void markError() {
+assert(isSemanticForm());
+setDependence(getDependence() | ExprDependence::Error |
+  ExprDependence::ValueInstantiation);
+  }
+
   /// Reserve space for some number of initializers.
   void reserveInits(const ASTContext &C, unsigned NumInits);
 
Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -957,6 +957,16 @@
   template  void foo() {
 (void)[[size^of]](T);
   })cpp",
+  R"cpp(// should not crash on invalid semantic form of init-list-expr.
+/*error-ok*/
+struct Foo {
+  int xyz = 0;
+};
+class Bar {};
+constexpr Foo s = ^{
+  .xyz = Bar(),
+};
+  )cpp",
   // literals
   "auto x = t^rue;",
   "auto x = '^A';",
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D75044: [AArch64] __builtin_return_address for PAuth.

2020-07-20 Thread Daniel Kiss via Phabricator via cfe-commits
danielkiss added a comment.

Patch for gcc is merged. 
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=a70d5d81c41048556fd86eaa1036018a6bfba115


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

https://reviews.llvm.org/D75044



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


[PATCH] D84140: [clang] Set the error-bit for ill-formed semantic InitListExpr.

2020-07-20 Thread Sam McCall via Phabricator via cfe-commits
sammccall accepted this revision.
sammccall added inline comments.
This revision is now accepted and ready to land.



Comment at: clang/lib/Sema/SemaInit.cpp:965
   }
+  if (hadError && FullyStructuredList)
+FullyStructuredList->markError();

Can we have a clang test for this? If nothing else, an AST-dump test should be 
able to capture this, right?

If we can turn it into a real clang crash, we may be able to get this on the 
release branch.



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84140



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


[PATCH] D84140: [clang] Set the error-bit for ill-formed semantic InitListExpr.

2020-07-20 Thread Sam McCall via Phabricator via cfe-commits
sammccall added inline comments.



Comment at: clang/include/clang/AST/Expr.h:4697
+assert(isSemanticForm());
+setDependence(getDependence() | ExprDependence::Error |
+  ExprDependence::ValueInstantiation);

Hmm, actually hardcoding the error->VI relationship seems like a smell here...
I'm not sure what the best fix is though, any ideas?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84140



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


[PATCH] D84140: [clang] Set the error-bit for ill-formed semantic InitListExpr.

2020-07-20 Thread Haojian Wu via Phabricator via cfe-commits
hokein marked 2 inline comments as done.
hokein added inline comments.



Comment at: clang/include/clang/AST/Expr.h:4697
+assert(isSemanticForm());
+setDependence(getDependence() | ExprDependence::Error |
+  ExprDependence::ValueInstantiation);

sammccall wrote:
> Hmm, actually hardcoding the error->VI relationship seems like a smell here...
> I'm not sure what the best fix is though, any ideas?
yeah, this is duplicated with the one in `computeDependence(RecoveryExpr)`.

ideas:
1. making this `markError` public method in `Expr` and use it 
`computeDependence`, so that we have a single place.
2. add an alias `ErrorDependent = Error | ValueInstantiation` in the enum 
`ExprDependence` 

any preference? personally, I'd prefer 2.



Comment at: clang/lib/Sema/SemaInit.cpp:965
   }
+  if (hadError && FullyStructuredList)
+FullyStructuredList->markError();

sammccall wrote:
> Can we have a clang test for this? If nothing else, an AST-dump test should 
> be able to capture this, right?
> 
> If we can turn it into a real clang crash, we may be able to get this on the 
> release branch.
> 
I tried it, but no luck to get such testcase :( 

ast-dump doesn't really help, it just dumps the syntactic form, not the 
semantic form.

another option will be to write an unittest in AST, implementing a RAV to 
retrieve the semantic form of the ini-list-expr, and check the error-bit.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84140



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


[PATCH] D83966: Enable the test for hasArraySize() AST matcher in all language modes

2020-07-20 Thread Dmitri Gribenko via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb6073ee9ae84: Enable the test for hasArraySize() AST matcher 
in all language modes (authored by gribozavr).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83966

Files:
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp


Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -3219,13 +3219,13 @@
 }
 
 TEST_P(ASTMatchersTest, HasArraySize) {
-  if (GetParam().Language != Lang_CXX03) {
-// FIXME: Fix this test to work in all C++ language modes.
+  if (!GetParam().isCXX()) {
 return;
   }
 
   EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
-  cxxNewExpr(hasArraySize(integerLiteral(equals(10));
+  cxxNewExpr(hasArraySize(
+  
ignoringParenImpCasts(integerLiteral(equals(10)));
 }
 
 TEST_P(ASTMatchersTest, HasDefinition_MatchesStructDefinition) {


Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -3219,13 +3219,13 @@
 }
 
 TEST_P(ASTMatchersTest, HasArraySize) {
-  if (GetParam().Language != Lang_CXX03) {
-// FIXME: Fix this test to work in all C++ language modes.
+  if (!GetParam().isCXX()) {
 return;
   }
 
   EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
-  cxxNewExpr(hasArraySize(integerLiteral(equals(10));
+  cxxNewExpr(hasArraySize(
+  ignoringParenImpCasts(integerLiteral(equals(10)));
 }
 
 TEST_P(ASTMatchersTest, HasDefinition_MatchesStructDefinition) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] b6073ee - Enable the test for hasArraySize() AST matcher in all language modes

2020-07-20 Thread Dmitri Gribenko via cfe-commits

Author: Dmitri Gribenko
Date: 2020-07-20T10:23:00+02:00
New Revision: b6073ee9ae842d1999fd7798a0aac0f8427d6aea

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

LOG: Enable the test for hasArraySize() AST matcher in all language modes

Summary:
In C++11 and later Clang generates an implicit conversion from int to
size_t in the AST.

Reviewers: ymandel, hokein

Reviewed By: hokein

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D83966

Added: 


Modified: 
clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp

Removed: 




diff  --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp 
b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index 36e92c632c03..4bd50191e163 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -3219,13 +3219,13 @@ TEST_P(ASTMatchersTest, IsArray) {
 }
 
 TEST_P(ASTMatchersTest, HasArraySize) {
-  if (GetParam().Language != Lang_CXX03) {
-// FIXME: Fix this test to work in all C++ language modes.
+  if (!GetParam().isCXX()) {
 return;
   }
 
   EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
-  cxxNewExpr(hasArraySize(integerLiteral(equals(10));
+  cxxNewExpr(hasArraySize(
+  
ignoringParenImpCasts(integerLiteral(equals(10)));
 }
 
 TEST_P(ASTMatchersTest, HasDefinition_MatchesStructDefinition) {



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


[Differential] D83966: Enable the test for hasArraySize() AST matcher in all language modes

2020-07-20 Thread Dmitri Gribenko 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 rGb6073ee9ae84: Enable the test for hasArraySize() AST matcher 
in all language modes (authored by gribozavr).

Repository:
  rG LLVM Github Monorepo

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


  https://reviews.llvm.org/D83966

Files:
  clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp



Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -3219,13 +3219,13 @@
 }
 
 TEST_P(ASTMatchersTest, HasArraySize) {
-  if (GetParam().Language != Lang_CXX03) {
-// FIXME: Fix this test to work in all C++ language modes.
+  if (!GetParam().isCXX()) {
 return;
   }
 
   EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
-  cxxNewExpr(hasArraySize(integerLiteral(equals(10));
+  cxxNewExpr(hasArraySize(
+  
ignoringParenImpCasts(integerLiteral(equals(10)));
 }
 
 TEST_P(ASTMatchersTest, HasDefinition_MatchesStructDefinition) {


Index: clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -3219,13 +3219,13 @@
 }
 
 TEST_P(ASTMatchersTest, HasArraySize) {
-  if (GetParam().Language != Lang_CXX03) {
-// FIXME: Fix this test to work in all C++ language modes.
+  if (!GetParam().isCXX()) {
 return;
   }
 
   EXPECT_TRUE(matches("struct MyClass {}; MyClass *p1 = new MyClass[10];",
-  cxxNewExpr(hasArraySize(integerLiteral(equals(10));
+  cxxNewExpr(hasArraySize(
+  ignoringParenImpCasts(integerLiteral(equals(10)));
 }
 
 TEST_P(ASTMatchersTest, HasDefinition_MatchesStructDefinition) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84122: [clangd] Handle deduction guides in TargetFinder and ExplicitReferenceCollector

2020-07-20 Thread Haojian Wu via Phabricator via cfe-commits
hokein accepted this revision.
hokein added inline comments.
This revision is now accepted and ready to land.
Herald added a subscriber: kbobyrev.



Comment at: clang-tools-extra/clangd/unittests/FindTargetTests.cpp:403
+  )cpp";
+  Flags.push_back("-std=c++17");
+  EXPECT_DECLS("CXXDeductionGuideDecl", {"template  struct Test"});

looks like we insert "-std=c++17" twice, see line 389.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84122



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


[PATCH] D84103: [clang-format] Make sure rst documentation matches comments

2020-07-20 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay added a comment.

Thanks for doing this..


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84103



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


[PATCH] D84144: [clangd] Remove TokenBuffer usage in TypeHierarchy

2020-07-20 Thread Aleksandr Platonov via Phabricator via cfe-commits
ArcsinX created this revision.
Herald added subscribers: cfe-commits, kbobyrev, usaxena95, kadircet, arphaman, 
jkorous, MaskRay, ilya-biryukov.
Herald added a project: clang.

This patch mostly reverts D74850 .
We could not use `AST.getTokens()` here, because it does not have tokens from 
the preamble.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84144

Files:
  clang-tools-extra/clangd/XRefs.cpp
  clang-tools-extra/clangd/unittests/SyncAPI.cpp
  clang-tools-extra/clangd/unittests/SyncAPI.h
  clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp

Index: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
===
--- clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
+++ clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
@@ -523,6 +523,39 @@
WithKind(SymbolKind::Struct), Children();
 }
 
+TEST(TypeHierarchy, Preamble) {
+  Annotations SourceAnnotations(R"cpp(
+#include "header_in_preamble.h"
+struct Ch^ild : Parent {
+  int b;
+};)cpp");
+
+  Annotations HeaderInPreambleAnnotations(R"cpp(
+struct Parent {
+  int a;
+};)cpp");
+
+  MockCompilationDatabase CDB;
+  MockFS FS;
+  ClangdServer Server(CDB, FS, ClangdServer::optsForTest());
+
+  // Fill the filesystem.
+  auto FooCpp = testPath("foo.cpp");
+  FS.Files[FooCpp] = "";
+  auto HeaderInPreambleH = testPath("header_in_preamble.h");
+  FS.Files[HeaderInPreambleH] = HeaderInPreambleAnnotations.code().str();
+  runAddDocument(Server, FooCpp, SourceAnnotations.code());
+
+  // Type hierarchy for `Child`
+  auto Result = runTypeHierarchy(Server, FooCpp, SourceAnnotations.point(), 1,
+ TypeHierarchyDirection::Parents);
+  ASSERT_TRUE(bool(Result));
+  ASSERT_TRUE(*Result);
+
+  EXPECT_THAT(**Result, AllOf(WithName("Child"),
+  Parents(AllOf(WithName("Parent"), Parents();
+}
+
 SymbolID findSymbolIDByName(SymbolIndex *Index, llvm::StringRef Name,
 llvm::StringRef TemplateArgs = "") {
   SymbolID Result;
Index: clang-tools-extra/clangd/unittests/SyncAPI.h
===
--- clang-tools-extra/clangd/unittests/SyncAPI.h
+++ clang-tools-extra/clangd/unittests/SyncAPI.h
@@ -60,6 +60,10 @@
 llvm::Expected>
 runSwitchHeaderSource(ClangdServer &Server, PathRef File);
 
+llvm::Expected>
+runTypeHierarchy(ClangdServer &Server, PathRef File, Position Pos, int Resolve,
+ TypeHierarchyDirection Direction);
+
 } // namespace clangd
 } // namespace clang
 
Index: clang-tools-extra/clangd/unittests/SyncAPI.cpp
===
--- clang-tools-extra/clangd/unittests/SyncAPI.cpp
+++ clang-tools-extra/clangd/unittests/SyncAPI.cpp
@@ -154,5 +154,13 @@
   return std::move(*Result);
 }
 
+llvm::Expected>
+runTypeHierarchy(ClangdServer &Server, PathRef File, Position Pos, int Resolve,
+ TypeHierarchyDirection Direction) {
+  llvm::Optional>> Result;
+  Server.typeHierarchy(File, Pos, Resolve, Direction, capture(Result));
+  return std::move(*Result);
+}
+
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/XRefs.cpp
===
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -1183,23 +1183,24 @@
 
 // FIXME(nridge): Reduce duplication between this function and declToSym().
 static llvm::Optional
-declToTypeHierarchyItem(ASTContext &Ctx, const NamedDecl &ND,
-const syntax::TokenBuffer &TB) {
+declToTypeHierarchyItem(ASTContext &Ctx, const NamedDecl &ND) {
   auto &SM = Ctx.getSourceManager();
   SourceLocation NameLoc = nameLocation(ND, Ctx.getSourceManager());
+  SourceLocation BeginLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getBeginLoc()));
+  SourceLocation EndLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getEndLoc()));
+  const auto NameRange =
+  toHalfOpenFileRange(SM, Ctx.getLangOpts(), {BeginLoc, EndLoc});
+  if (!NameRange)
+return llvm::None;
   auto FilePath =
   getCanonicalPath(SM.getFileEntryForID(SM.getFileID(NameLoc)), SM);
   auto TUPath = getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM);
   if (!FilePath || !TUPath)
 return llvm::None; // Not useful without a uri.
 
-  auto DeclToks = TB.spelledForExpanded(TB.expandedTokens(ND.getSourceRange()));
-  if (!DeclToks || DeclToks->empty())
-return llvm::None;
-
-  auto NameToks = TB.spelledForExpanded(TB.expandedTokens(NameLoc));
-  if (!NameToks || NameToks->empty())
-return llvm::None;
+  Position NameBegin = sourceLocToPosition(SM, NameLoc);
+  Position NameEnd = sourceLocToPosition(
+  SM, Lexer::getLocForEndOfToken(NameLoc, 0, SM, Ctx.getLangOpts()));
 
   index::SymbolInfo SymInfo = index::getSymbolInfo(&ND);
   // FIXME: this is not classifying

[PATCH] D83407: [analyzer][StdLibraryFunctionsChecker] Add POSIX networking functions

2020-07-20 Thread Gabor Marton via Phabricator via cfe-commits
martong added a comment.

Ping :)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83407



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


[PATCH] D84145: [AST][RecoveryExpr] Fix a crash on opencl C++.

2020-07-20 Thread Haojian Wu via Phabricator via cfe-commits
hokein created this revision.
hokein added a reviewer: sammccall.
Herald added subscribers: Anastasia, yaxunl.
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84145

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/SemaOpenCL/recovery-expr.cl


Index: clang/test/SemaOpenCL/recovery-expr.cl
===
--- /dev/null
+++ clang/test/SemaOpenCL/recovery-expr.cl
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=clc++ 
-frecovery-ast
+
+void kernel nocrash() {
+  constant int L1 = 0;
+
+  private int *constant L2 = L1++; // expected-error {{read-only variable is 
not assignable}}
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11067,8 +11067,14 @@
   // except that the aforementioned are allowed in unevaluated
   // expressions.  Everything else falls under the
   // "may accept other forms of constant expressions" exception.
-  // (We never end up here for C++, so the constant expression
-  // rules there don't matter.)
+  //
+  // Regular C++ code will not end up here (exceptions: language extensions,
+  // OpenCL C++ etc), so the constant expression rules there don't matter.
+  if (Init->isValueDependent()) {
+assert(Init->containsErrors() &&
+   "Dependent code should only occur in error-recovery path.");
+return true;
+  }
   const Expr *Culprit;
   if (Init->isConstantInitializer(Context, false, &Culprit))
 return false;


Index: clang/test/SemaOpenCL/recovery-expr.cl
===
--- /dev/null
+++ clang/test/SemaOpenCL/recovery-expr.cl
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=clc++ -frecovery-ast
+
+void kernel nocrash() {
+  constant int L1 = 0;
+
+  private int *constant L2 = L1++; // expected-error {{read-only variable is not assignable}}
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11067,8 +11067,14 @@
   // except that the aforementioned are allowed in unevaluated
   // expressions.  Everything else falls under the
   // "may accept other forms of constant expressions" exception.
-  // (We never end up here for C++, so the constant expression
-  // rules there don't matter.)
+  //
+  // Regular C++ code will not end up here (exceptions: language extensions,
+  // OpenCL C++ etc), so the constant expression rules there don't matter.
+  if (Init->isValueDependent()) {
+assert(Init->containsErrors() &&
+   "Dependent code should only occur in error-recovery path.");
+return true;
+  }
   const Expr *Culprit;
   if (Init->isConstantInitializer(Context, false, &Culprit))
 return false;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84032: [clang] Make clear Sema::CheckForConstantInitializer is for C-only codepath.

2020-07-20 Thread Haojian Wu via Phabricator via cfe-commits
hokein abandoned this revision.
hokein marked an inline comment as done.
hokein added inline comments.



Comment at: clang/lib/Sema/SemaDecl.cpp:11072
   // rules there don't matter.)
+  assert(!getLangOpts().CPlusPlus || getLangOpts().OpenCLCPlusPlus);
   const Expr *Culprit;

hokein wrote:
> openCL for C++ is tricky, see 
> https://github.com/llvm/llvm-project/blob/master/clang/lib/Sema/SemaDecl.cpp#L12134-L12135.
actually, I think the code is correct, the above comment is not up-to-date, so 
we just need to update the comment, see D84145.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84032



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


[PATCH] D84144: [clangd] Remove TokenBuffer usage in TypeHierarchy

2020-07-20 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

ah embarrassing :/ thanks for catching this! It should've been obvious from the 
fact that there's a "FilePath" and a "TUPath" going on ..




Comment at: clang-tools-extra/clangd/XRefs.cpp:1191
+  SourceLocation EndLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getEndLoc()));
+  const auto NameRange =
+  toHalfOpenFileRange(SM, Ctx.getLangOpts(), {BeginLoc, EndLoc});

let's rename it to `DeclRange` rather than `NameRange`.



Comment at: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp:550
+  // Type hierarchy for `Child`
+  auto Result = runTypeHierarchy(Server, FooCpp, SourceAnnotations.point(), 1,
+ TypeHierarchyDirection::Parents);

you can keep using the `TestTU`. just provide the header via `AdditionalFiles` 
and `TU.build` should first build a preamble and use it. That way you can get 
rid of additions to the SyncAPI and usage of ClangdServer in here.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84144



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


[Differential] D82845: [Analyzer][StreamChecker] Report every leak, clean up state.

2020-07-20 Thread Balázs Kéri 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 rG9b7c43d341da: [Analyzer][StreamChecker] Report every leak, 
clean up state. (authored by balazske).

Changed prior to commit:
  https://reviews.llvm.org/D82845?vs=278755&id=278998#toc

Repository:
  rG LLVM Github Monorepo

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


  https://reviews.llvm.org/D82845

Files:
  clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -46,3 +46,34 @@
 }
 // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
 // expected-note@-2 {{Opened stream never closed. Potential resource leak}}
+
+void check_note_leak_2(int c) {
+  FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
+  if (!F1)
+// expected-note@-1 {{'F1' is non-null}}
+// expected-note@-2 {{Taking false branch}}
+// expected-note@-3 {{'F1' is non-null}}
+// expected-note@-4 {{Taking false branch}}
+return;
+  FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
+  if (!F2) {
+// expected-note@-1 {{'F2' is non-null}}
+// expected-note@-2 {{Taking false branch}}
+// expected-note@-3 {{'F2' is non-null}}
+// expected-note@-4 {{Taking false branch}}
+fclose(F1);
+return;
+  }
+  if (c)
+// expected-note@-1 {{Assuming 'c' is not equal to 0}}
+// expected-note@-2 {{Taking true branch}}
+// expected-note@-3 {{Assuming 'c' is not equal to 0}}
+// expected-note@-4 {{Taking true branch}}
+return;
+  // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
+  // expected-note@-2 {{Opened stream never closed. Potential resource leak}}
+  // expected-warning@-3 {{Opened stream never closed. Potential resource leak}}
+  // expected-note@-4 {{Opened stream never closed. Potential resource leak}}
+  fclose(F1);
+  fclose(F2);
+}
Index: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -337,6 +337,12 @@
   /// to ensure uniform handling.
   void reportFEofWarning(CheckerContext &C, ProgramStateRef State) const;
 
+  /// Emit resource leak warnings for the given symbols.
+  /// Createn a non-fatal error node for these, and returns it (if any warnings
+  /// were generated). Return value is non-null.
+  ExplodedNode *reportLeaks(const SmallVector &LeakedSyms,
+CheckerContext &C, ExplodedNode *Pred) const;
+
   /// Find the description data of the function called by a call event.
   /// Returns nullptr if no function is recognized.
   const FnDescription *lookupFn(const CallEvent &Call) const {
@@ -956,28 +962,19 @@
   C.addTransition(State);
 }
 
-void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper,
- CheckerContext &C) const {
-  ProgramStateRef State = C.getState();
-
-  // TODO: Clean up the state.
-  const StreamMapTy &Map = State->get();
-  for (const auto &I : Map) {
-SymbolRef Sym = I.first;
-const StreamState &SS = I.second;
-if (!SymReaper.isDead(Sym) || !SS.isOpened())
-  continue;
-
-ExplodedNode *N = C.generateErrorNode();
-if (!N)
-  continue;
+ExplodedNode *
+StreamChecker::reportLeaks(const SmallVector &LeakedSyms,
+   CheckerContext &C, ExplodedNode *Pred) const {
+  // Do not warn for non-closed stream at program exit.
+  // FIXME: Use BugType::SuppressOnSink instead.
+  if (Pred && Pred->getCFGBlock() && Pred->getCFGBlock()->hasNoReturnElement())
+return Pred;
 
-// Do not warn for non-closed stream at program exit.
-ExplodedNode *Pred = C.getPredecessor();
-if (Pred && Pred->getCFGBlock() &&
-Pred->getCFGBlock()->hasNoReturnElement())
-  continue;
+  ExplodedNode *Err = C.generateNonFatalErrorNode(C.getState(), Pred);
+  if (!Err)
+return Pred;
 
+  for (SymbolRef LeakSym : LeakedSyms) {
 // Resource leaks can result in multiple warning that describe the same kind
 // of programming error:
 //  void f() {
@@ -989,8 +986,7 @@
 // from a different kinds of errors), the reduction in redundant reports
 // makes this a worthwhile heuristic.
 // FIXME: Add a checker option to turn this uniqueing feature off.
-
-const ExplodedNode *StreamOpenNode = getAcquisitionSite(N, Sym, C);
+const ExplodedNode *StreamOpenNode = getAcquisitionSite(Err, LeakSym, C);
 assert(StreamOpenNode && "Could not find place of stream opening.");
 PathDiagnosticLocation LocUsedForUniqueing =
 PathDiagnosticLocation::createBegin(
@@ -10

[clang] 9b7c43d - [Analyzer][StreamChecker] Report every leak, clean up state.

2020-07-20 Thread Balázs Kéri via cfe-commits

Author: Balázs Kéri
Date: 2020-07-20T11:49:00+02:00
New Revision: 9b7c43d341da319c69b11205ee1deb642f286e59

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

LOG: [Analyzer][StreamChecker] Report every leak, clean up state.

Summary:
Report resource leaks with non-fatal error.
Report every resource leak.
Stream state is cleaned up at `checkDeadSymbols`.

Reviewers: Szelethus, baloghadamsoftware, NoQ

Reviewed By: Szelethus

Subscribers: rnkovacs, xazax.hun, baloghadamsoftware, szepet, a.sidorin, 
mikhail.ramalho, Szelethus, donat.nagy, dkrupp, gamesh411, Charusso, martong, 
ASDenysPetrov, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D82845

Added: 


Modified: 
clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
clang/test/Analysis/stream-note.c

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index f6abbe4f8f03..1e963249156f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -337,6 +337,12 @@ class StreamChecker : public Checker &LeakedSyms,
+CheckerContext &C, ExplodedNode *Pred) const;
+
   /// Find the description data of the function called by a call event.
   /// Returns nullptr if no function is recognized.
   const FnDescription *lookupFn(const CallEvent &Call) const {
@@ -956,28 +962,19 @@ void StreamChecker::reportFEofWarning(CheckerContext &C,
   C.addTransition(State);
 }
 
-void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper,
- CheckerContext &C) const {
-  ProgramStateRef State = C.getState();
-
-  // TODO: Clean up the state.
-  const StreamMapTy &Map = State->get();
-  for (const auto &I : Map) {
-SymbolRef Sym = I.first;
-const StreamState &SS = I.second;
-if (!SymReaper.isDead(Sym) || !SS.isOpened())
-  continue;
-
-ExplodedNode *N = C.generateErrorNode();
-if (!N)
-  continue;
+ExplodedNode *
+StreamChecker::reportLeaks(const SmallVector &LeakedSyms,
+   CheckerContext &C, ExplodedNode *Pred) const {
+  // Do not warn for non-closed stream at program exit.
+  // FIXME: Use BugType::SuppressOnSink instead.
+  if (Pred && Pred->getCFGBlock() && Pred->getCFGBlock()->hasNoReturnElement())
+return Pred;
 
-// Do not warn for non-closed stream at program exit.
-ExplodedNode *Pred = C.getPredecessor();
-if (Pred && Pred->getCFGBlock() &&
-Pred->getCFGBlock()->hasNoReturnElement())
-  continue;
+  ExplodedNode *Err = C.generateNonFatalErrorNode(C.getState(), Pred);
+  if (!Err)
+return Pred;
 
+  for (SymbolRef LeakSym : LeakedSyms) {
 // Resource leaks can result in multiple warning that describe the same 
kind
 // of programming error:
 //  void f() {
@@ -989,8 +986,7 @@ void StreamChecker::checkDeadSymbols(SymbolReaper 
&SymReaper,
 // from a 
diff erent kinds of errors), the reduction in redundant reports
 // makes this a worthwhile heuristic.
 // FIXME: Add a checker option to turn this uniqueing feature off.
-
-const ExplodedNode *StreamOpenNode = getAcquisitionSite(N, Sym, C);
+const ExplodedNode *StreamOpenNode = getAcquisitionSite(Err, LeakSym, C);
 assert(StreamOpenNode && "Could not find place of stream opening.");
 PathDiagnosticLocation LocUsedForUniqueing =
 PathDiagnosticLocation::createBegin(
@@ -1000,12 +996,38 @@ void StreamChecker::checkDeadSymbols(SymbolReaper 
&SymReaper,
 std::unique_ptr R =
 std::make_unique(
 BT_ResourceLeak,
-"Opened stream never closed. Potential resource leak.", N,
+"Opened stream never closed. Potential resource leak.", Err,
 LocUsedForUniqueing,
 StreamOpenNode->getLocationContext()->getDecl());
-R->markInteresting(Sym);
+R->markInteresting(LeakSym);
 C.emitReport(std::move(R));
   }
+
+  return Err;
+}
+
+void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper,
+ CheckerContext &C) const {
+  ProgramStateRef State = C.getState();
+
+  llvm::SmallVector LeakedSyms;
+
+  const StreamMapTy &Map = State->get();
+  for (const auto &I : Map) {
+SymbolRef Sym = I.first;
+const StreamState &SS = I.second;
+if (!SymReaper.isDead(Sym))
+  continue;
+if (SS.isOpened())
+  LeakedSyms.push_back(Sym);
+State = State->remove(Sym);
+  }
+
+  ExplodedNode *N = C.getPredecessor();
+  if (!LeakedSyms.empty())
+N = reportLeaks(LeakedSyms, C, N);
+
+  C.addTransition(State, N);
 }
 
 ProgramStateRef StreamChecker::checkPointerEscape(

diff  --git a/clang/test/Analysis/stream-note.c 
b/clang/test

[PATCH] D82845: [Analyzer][StreamChecker] Report every leak, clean up state.

2020-07-20 Thread Balázs Kéri via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG9b7c43d341da: [Analyzer][StreamChecker] Report every leak, 
clean up state. (authored by balazske).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D82845

Files:
  clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -46,3 +46,34 @@
 }
 // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
 // expected-note@-2 {{Opened stream never closed. Potential resource leak}}
+
+void check_note_leak_2(int c) {
+  FILE *F1 = fopen("foo1.c", "r"); // expected-note {{Stream opened here}}
+  if (!F1)
+// expected-note@-1 {{'F1' is non-null}}
+// expected-note@-2 {{Taking false branch}}
+// expected-note@-3 {{'F1' is non-null}}
+// expected-note@-4 {{Taking false branch}}
+return;
+  FILE *F2 = fopen("foo2.c", "r"); // expected-note {{Stream opened here}}
+  if (!F2) {
+// expected-note@-1 {{'F2' is non-null}}
+// expected-note@-2 {{Taking false branch}}
+// expected-note@-3 {{'F2' is non-null}}
+// expected-note@-4 {{Taking false branch}}
+fclose(F1);
+return;
+  }
+  if (c)
+// expected-note@-1 {{Assuming 'c' is not equal to 0}}
+// expected-note@-2 {{Taking true branch}}
+// expected-note@-3 {{Assuming 'c' is not equal to 0}}
+// expected-note@-4 {{Taking true branch}}
+return;
+  // expected-warning@-1 {{Opened stream never closed. Potential resource leak}}
+  // expected-note@-2 {{Opened stream never closed. Potential resource leak}}
+  // expected-warning@-3 {{Opened stream never closed. Potential resource leak}}
+  // expected-note@-4 {{Opened stream never closed. Potential resource leak}}
+  fclose(F1);
+  fclose(F2);
+}
Index: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -337,6 +337,12 @@
   /// to ensure uniform handling.
   void reportFEofWarning(CheckerContext &C, ProgramStateRef State) const;
 
+  /// Emit resource leak warnings for the given symbols.
+  /// Createn a non-fatal error node for these, and returns it (if any warnings
+  /// were generated). Return value is non-null.
+  ExplodedNode *reportLeaks(const SmallVector &LeakedSyms,
+CheckerContext &C, ExplodedNode *Pred) const;
+
   /// Find the description data of the function called by a call event.
   /// Returns nullptr if no function is recognized.
   const FnDescription *lookupFn(const CallEvent &Call) const {
@@ -956,28 +962,19 @@
   C.addTransition(State);
 }
 
-void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper,
- CheckerContext &C) const {
-  ProgramStateRef State = C.getState();
-
-  // TODO: Clean up the state.
-  const StreamMapTy &Map = State->get();
-  for (const auto &I : Map) {
-SymbolRef Sym = I.first;
-const StreamState &SS = I.second;
-if (!SymReaper.isDead(Sym) || !SS.isOpened())
-  continue;
-
-ExplodedNode *N = C.generateErrorNode();
-if (!N)
-  continue;
+ExplodedNode *
+StreamChecker::reportLeaks(const SmallVector &LeakedSyms,
+   CheckerContext &C, ExplodedNode *Pred) const {
+  // Do not warn for non-closed stream at program exit.
+  // FIXME: Use BugType::SuppressOnSink instead.
+  if (Pred && Pred->getCFGBlock() && Pred->getCFGBlock()->hasNoReturnElement())
+return Pred;
 
-// Do not warn for non-closed stream at program exit.
-ExplodedNode *Pred = C.getPredecessor();
-if (Pred && Pred->getCFGBlock() &&
-Pred->getCFGBlock()->hasNoReturnElement())
-  continue;
+  ExplodedNode *Err = C.generateNonFatalErrorNode(C.getState(), Pred);
+  if (!Err)
+return Pred;
 
+  for (SymbolRef LeakSym : LeakedSyms) {
 // Resource leaks can result in multiple warning that describe the same kind
 // of programming error:
 //  void f() {
@@ -989,8 +986,7 @@
 // from a different kinds of errors), the reduction in redundant reports
 // makes this a worthwhile heuristic.
 // FIXME: Add a checker option to turn this uniqueing feature off.
-
-const ExplodedNode *StreamOpenNode = getAcquisitionSite(N, Sym, C);
+const ExplodedNode *StreamOpenNode = getAcquisitionSite(Err, LeakSym, C);
 assert(StreamOpenNode && "Could not find place of stream opening.");
 PathDiagnosticLocation LocUsedForUniqueing =
 PathDiagnosticLocation::createBegin(
@@ -1000,12 +996,38 @@
 std::unique_ptr R =
 std::make_unique(
 BT_ResourceLeak,
-"Opened stream never closed. Po

[PATCH] D84146: [AST][RecoveryExpr] Add recovery-ast tests for C language, NFC.

2020-07-20 Thread Haojian Wu via Phabricator via cfe-commits
hokein created this revision.
hokein added a reviewer: sammccall.
Herald added a project: clang.

some examples are working already.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84146

Files:
  clang/test/AST/ast-dump-recovery.c


Index: clang/test/AST/ast-dump-recovery.c
===
--- /dev/null
+++ clang/test/AST/ast-dump-recovery.c
@@ -0,0 +1,56 @@
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast 
-fno-recovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
+
+int some_func(int);
+
+// CHECK: VarDecl {{.*}} unmatch_arg_call 'int' cinit
+// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
+int unmatch_arg_call = some_func();
+
+const int a = 1;
+
+// CHECK: VarDecl {{.*}} postfix_inc
+// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'a'
+int postfix_inc = a++;
+
+// CHECK: VarDecl {{.*}} prefix_inc
+// CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a'
+int prefix_inc = ++a;
+
+// CHECK: VarDecl {{.*}} unary_address
+// CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:  `-ParenExpr {{.*}}
+// CHECK-NEXT:`-BinaryOperator {{.*}} '+'
+// CHECK-NEXT:  |-ImplicitCastExpr
+// CHECK-NEXT:  | `-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int'
+int unary_address = &(a + 1);
+
+// CHECK: VarDecl {{.*}} unary_bitinverse
+// CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:  `-ParenExpr {{.*}}
+// CHECK-NEXT:`-BinaryOperator {{.*}} '+'
+// CHECK-NEXT:  |-ImplicitCastExpr
+// CHECK-NEXT:  | `-ImplicitCastExpr
+// CHECK-NEXT:  |   `-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:  `-FloatingLiteral {{.*}} 'double'
+int unary_bitinverse = ~(a + 0.0);
+
+// CHECK:   VarDecl {{.*}} ternary 'int' cinit
+// CHECK-NEXT:  `-RecoveryExpr {{.*}}
+// CHECK-NEXT:|-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:|-TypoExpr {{.*}}
+// CHECK-NEXT:`-DeclRefExpr {{.*}} 'a'
+// FIXME: The TypoExpr should never be print, and should be downgraded to
+// RecoveryExpr -- typo correction is performed too early in C-only codepath,
+// which makes no correction when clang finishes the full expr 
(Sema::Sema::ActOnFinishFullExpr).
+// this will be fixed when we support dependent mechanism and delayed typo 
correction for C.
+int ternary = a ? undef : a;
+
+void test1() {
+  // CHECK: `-RecoveryExpr {{.*}} contains-errors
+  // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a' 'const int'
+  static int foo = a++; // verify no crash on local static var decl.
+}


Index: clang/test/AST/ast-dump-recovery.c
===
--- /dev/null
+++ clang/test/AST/ast-dump-recovery.c
@@ -0,0 +1,56 @@
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -fno-recovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
+
+int some_func(int);
+
+// CHECK: VarDecl {{.*}} unmatch_arg_call 'int' cinit
+// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
+int unmatch_arg_call = some_func();
+
+const int a = 1;
+
+// CHECK: VarDecl {{.*}} postfix_inc
+// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'a'
+int postfix_inc = a++;
+
+// CHECK: VarDecl {{.*}} prefix_inc
+// CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a'
+int prefix_inc = ++a;
+
+// CHECK: VarDecl {{.*}} unary_address
+// CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:  `-ParenExpr {{.*}}
+// CHECK-NEXT:`-BinaryOperator {{.*}} '+'
+// CHECK-NEXT:  |-ImplicitCastExpr
+// CHECK-NEXT:  | `-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int'
+int unary_address = &(a + 1);
+
+// CHECK: VarDecl {{.*}} unary_bitinverse
+// CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:  `-ParenExpr {{.*}}
+// CHECK-NEXT:`-BinaryOperator {{.*}} '+'
+// CHECK-NEXT:  |-ImplicitCastExpr
+// CHECK-NEXT:  | `-ImplicitCastExpr
+// CHECK-NEXT:  |   `-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:  `-FloatingLiteral {{.*}} 'double'
+int unary_bitinverse = ~(a + 0.0);
+
+// CHECK:   VarDecl {{.*}} ternary 'int' cinit
+// CHECK-NEXT:  `-RecoveryExpr {{.*}}
+// CHECK-NEXT:|-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:|-TypoExpr {{.*}}
+// CHECK-NEXT:`-DeclRefExpr {{.*}} 'a'
+// FIXME: The TypoExpr should never be print, and should be downgraded to
+// RecoveryExpr -- typo correction is performed too early in C-only codepath,
+// which makes no correction when clang finishes the full expr (Sema::Sema::ActOnFinishFullExpr).
+// this will be fixed when we support dependent mechanism and delayed typo correction for C.
+int ternary = a ? undef : a;
+
+void test1() {
+  // CHECK: `-Recovery

[clang] 8513a68 - [clang-cl] Allow a colon after the /Fe option (PR46720)

2020-07-20 Thread Hans Wennborg via cfe-commits

Author: Hans Wennborg
Date: 2020-07-20T12:06:41+02:00
New Revision: 8513a681f7d8d1188706762e712168aebc3119dd

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

LOG: [clang-cl] Allow a colon after the /Fe option (PR46720)

Added: 


Modified: 
clang/include/clang/Driver/Options.td
clang/test/Driver/cl-outputs.c

Removed: 




diff  --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 65049074dc8e..aaceaf92f9f5 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4669,6 +4669,7 @@ def _SLASH_FI : CLJoinedOrSeparate<"FI">,
 def _SLASH_Fe : CLJoined<"Fe">,
   HelpText<"Set output executable file name">,
   MetaVarName<"">;
+def _SLASH_Fe_COLON : CLJoined<"Fe:">, Alias<_SLASH_Fe>;
 def _SLASH_Fi : CLCompileJoined<"Fi">,
   HelpText<"Set preprocess output file name (with /P)">,
   MetaVarName<"">;

diff  --git a/clang/test/Driver/cl-outputs.c b/clang/test/Driver/cl-outputs.c
index 6e105e46850d..75ff77e15910 100644
--- a/clang/test/Driver/cl-outputs.c
+++ b/clang/test/Driver/cl-outputs.c
@@ -99,6 +99,7 @@
 // DEFAULTDLL: "-implib:cl-outputs.lib"
 
 // RUN: %clang_cl /Fefoo -### -- %s 2>&1 | FileCheck -check-prefix=FeNOEXT %s
+// RUN: %clang_cl /Fe:foo -### -- %s 2>&1 | FileCheck -check-prefix=FeNOEXT %s
 // FeNOEXT: "-out:foo.exe"
 
 // RUN: %clang_cl /Fe -### -- %s 2>&1 | FileCheck -check-prefix=FeEMPTY %s
@@ -111,6 +112,7 @@
 // FeNOEXTDLL: "-implib:foo.lib"
 
 // RUN: %clang_cl /Fefoo.ext -### -- %s 2>&1 | FileCheck -check-prefix=FeEXT %s
+// RUN: %clang_cl /Fe:foo.ext -### -- %s 2>&1 | FileCheck -check-prefix=FeEXT 
%s
 // FeEXT: "-out:foo.ext"
 
 // RUN: %clang_cl /LD /Fefoo.ext -### -- %s 2>&1 | FileCheck 
-check-prefix=FeEXTDLL %s



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


[PATCH] D84147: Use typedef to represent storage type in FPOption and FPOptionsOverride

2020-07-20 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff created this revision.
sepavloff added reviewers: rjmccall, mibintc.
Herald added a project: clang.

Size of FPOption is now 14 bit, which is closed to the current limit
of 16 bits. Adding new properties to FPOption would require change of
the types, which represent storage of FPOption and FPOptionsOverride.
To facilitate this change, the storage types were changed from standard
integer types to typedefs defined inside the proper classes. Checks for
size of these storage types were added.

No functional changes intended.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84147

Files:
  clang/include/clang/Basic/FPOptions.def
  clang/include/clang/Basic/LangOptions.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTReader.h

Index: clang/include/clang/Serialization/ASTReader.h
===
--- clang/include/clang/Serialization/ASTReader.h
+++ clang/include/clang/Serialization/ASTReader.h
@@ -858,10 +858,10 @@
   SourceLocation PointersToMembersPragmaLocation;
 
   /// The pragma float_control state.
-  Optional FpPragmaCurrentValue;
+  Optional FpPragmaCurrentValue;
   SourceLocation FpPragmaCurrentLocation;
   struct FpPragmaStackEntry {
-unsigned Value;
+FPOptionsOverride::storage_type Value;
 SourceLocation Location;
 SourceLocation PushLocation;
 StringRef SlotLabel;
Index: clang/include/clang/Sema/Sema.h
===
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -587,7 +587,7 @@
   PragmaStack CodeSegStack;
 
   // This stack tracks the current state of Sema.CurFPFeatures.
-  PragmaStack FpPragmaStack;
+  PragmaStack FpPragmaStack;
   FPOptionsOverride CurFPFeatureOverrides() {
 FPOptionsOverride result;
 if (!FpPragmaStack.hasValue()) {
@@ -1405,12 +1405,12 @@
   S.CurFPFeatures = OldFPFeaturesState;
   S.FpPragmaStack.CurrentValue = OldOverrides;
 }
-unsigned getOverrides() { return OldOverrides; }
+FPOptionsOverride::storage_type getOverrides() { return OldOverrides; }
 
   private:
 Sema& S;
 FPOptions OldFPFeaturesState;
-unsigned OldOverrides;
+FPOptionsOverride::storage_type OldOverrides;
   };
 
   void addImplicitTypedef(StringRef Name, QualType T);
Index: clang/include/clang/Basic/LangOptions.h
===
--- clang/include/clang/Basic/LangOptions.h
+++ clang/include/clang/Basic/LangOptions.h
@@ -374,6 +374,8 @@
 
   using RoundingMode = llvm::RoundingMode;
 
+  static constexpr unsigned StorageBitSize = 8 * sizeof(storage_type);
+
   // Define a fake option named "First" so that we have a PREVIOUS even for the
   // real first option.
   static constexpr storage_type FirstShift = 0, FirstWidth = 0;
@@ -385,6 +387,12 @@
  << NAME##Shift;
 #include "clang/Basic/FPOptions.def"
 
+  static constexpr storage_type TotalWidth = 0
+#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) +WIDTH
+#include "clang/Basic/FPOptions.def"
+  ;
+  static_assert(TotalWidth <= StorageBitSize, "Too short type for FPOptions");
+
 private:
   storage_type Value;
 
@@ -402,8 +410,8 @@
 setFPContractMode(LO.getDefaultFPContractMode());
 setRoundingMode(LO.getFPRoundingMode());
 setFPExceptionMode(LO.getFPExceptionMode());
-setAllowFEnvAccess(LangOptions::FPM_Off),
-setAllowFPReassociate(LO.AllowFPReassoc);
+setAllowFEnvAccess(LangOptions::FPM_Off);
+setAllowFPReassociate(LO.AllowFPReassoc);
 setNoHonorNaNs(LO.NoHonorNaNs);
 setNoHonorInfs(LO.NoHonorInfs);
 setNoSignedZero(LO.NoSignedZero);
@@ -453,18 +461,45 @@
   LLVM_DUMP_METHOD void dump();
 };
 
-/// The FPOptions override type is value of the new FPOptions
-///  plus a mask showing which fields are actually set in it:
+/// Represents difference between two FPOptions values.
+///
+/// The effect of language constructs changing the set of floating point options
+/// is usually a change of some FP properties while leaving others intact. This
+/// class describes such changes by keeping information about what FP options
+/// are overridden.
+///
+/// The integral set of FP options, described by the class FPOptions, may be
+/// represented as a default FP option set, defined by language standard and
+/// command line options, with the overrides introduced by pragmas.
+///
+/// The is implemented as a value of the new FPOptions plus a mask showing which
+/// fields are actually set in it.
 class FPOptionsOverride {
   FPOptions Options;
   FPOptions::storage_type OverrideMask = 0;
 
 public:
   using RoundingMode = llvm::RoundingMode;
+
+  /// The type suitable for storing values of FPOptionsOverride. Must be twice
+  /// as wide as bit size of FPOption.
+  using storage_type = uint32_t;
+  static_assert(sizeof(storage_type) >= 2 * sizeof(FPOptions::storage_type),
+"T

[PATCH] D84144: [clangd] Remove TokenBuffer usage in TypeHierarchy

2020-07-20 Thread Aleksandr Platonov via Phabricator via cfe-commits
ArcsinX updated this revision to Diff 279168.
ArcsinX added a comment.

NameRange => DeclRange
Simplify TypeHierarchy.Preamble test.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84144

Files:
  clang-tools-extra/clangd/XRefs.cpp
  clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp

Index: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
===
--- clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
+++ clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
@@ -523,6 +523,31 @@
WithKind(SymbolKind::Struct), Children();
 }
 
+TEST(TypeHierarchy, Preamble) {
+  Annotations SourceAnnotations(R"cpp(
+#include "header_in_preamble.h"
+struct Ch^ild : Parent {
+  int b;
+};)cpp");
+
+  Annotations HeaderInPreambleAnnotations(R"cpp(
+struct Parent {
+  int a;
+};)cpp");
+
+  TestTU TU = TestTU::withCode(SourceAnnotations.code());
+  TU.AdditionalFiles["header_in_preamble.h"] =
+  HeaderInPreambleAnnotations.code().str();
+  auto AST = TU.build();
+
+  llvm::Optional Result = getTypeHierarchy(
+  AST, SourceAnnotations.point(), 1, TypeHierarchyDirection::Parents);
+
+  ASSERT_TRUE(Result);
+  EXPECT_THAT(*Result, AllOf(WithName("Child"),
+ Parents(AllOf(WithName("Parent"), Parents();
+}
+
 SymbolID findSymbolIDByName(SymbolIndex *Index, llvm::StringRef Name,
 llvm::StringRef TemplateArgs = "") {
   SymbolID Result;
Index: clang-tools-extra/clangd/XRefs.cpp
===
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -1183,23 +1183,24 @@
 
 // FIXME(nridge): Reduce duplication between this function and declToSym().
 static llvm::Optional
-declToTypeHierarchyItem(ASTContext &Ctx, const NamedDecl &ND,
-const syntax::TokenBuffer &TB) {
+declToTypeHierarchyItem(ASTContext &Ctx, const NamedDecl &ND) {
   auto &SM = Ctx.getSourceManager();
   SourceLocation NameLoc = nameLocation(ND, Ctx.getSourceManager());
+  SourceLocation BeginLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getBeginLoc()));
+  SourceLocation EndLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getEndLoc()));
+  const auto DeclRange =
+  toHalfOpenFileRange(SM, Ctx.getLangOpts(), {BeginLoc, EndLoc});
+  if (!DeclRange)
+return llvm::None;
   auto FilePath =
   getCanonicalPath(SM.getFileEntryForID(SM.getFileID(NameLoc)), SM);
   auto TUPath = getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM);
   if (!FilePath || !TUPath)
 return llvm::None; // Not useful without a uri.
 
-  auto DeclToks = TB.spelledForExpanded(TB.expandedTokens(ND.getSourceRange()));
-  if (!DeclToks || DeclToks->empty())
-return llvm::None;
-
-  auto NameToks = TB.spelledForExpanded(TB.expandedTokens(NameLoc));
-  if (!NameToks || NameToks->empty())
-return llvm::None;
+  Position NameBegin = sourceLocToPosition(SM, NameLoc);
+  Position NameEnd = sourceLocToPosition(
+  SM, Lexer::getLocForEndOfToken(NameLoc, 0, SM, Ctx.getLangOpts()));
 
   index::SymbolInfo SymInfo = index::getSymbolInfo(&ND);
   // FIXME: this is not classifying constructors, destructors and operators
@@ -1210,12 +1211,9 @@
   THI.name = printName(Ctx, ND);
   THI.kind = SK;
   THI.deprecated = ND.isDeprecated();
-  THI.range = halfOpenToRange(
-  SM, syntax::Token::range(SM, DeclToks->front(), DeclToks->back())
-  .toCharRange(SM));
-  THI.selectionRange = halfOpenToRange(
-  SM, syntax::Token::range(SM, NameToks->front(), NameToks->back())
-  .toCharRange(SM));
+  THI.range = Range{sourceLocToPosition(SM, DeclRange->getBegin()),
+sourceLocToPosition(SM, DeclRange->getEnd())};
+  THI.selectionRange = Range{NameBegin, NameEnd};
   if (!THI.range.contains(THI.selectionRange)) {
 // 'selectionRange' must be contained in 'range', so in cases where clang
 // reports unrelated ranges we need to reconcile somehow.
@@ -1282,8 +1280,7 @@
 
 static void fillSuperTypes(const CXXRecordDecl &CXXRD, ASTContext &ASTCtx,
std::vector &SuperTypes,
-   RecursionProtectionSet &RPSet,
-   const syntax::TokenBuffer &TB) {
+   RecursionProtectionSet &RPSet) {
   // typeParents() will replace dependent template specializations
   // with their class template, so to avoid infinite recursion for
   // certain types of hierarchies, keep the templates encountered
@@ -1298,9 +1295,9 @@
 
   for (const CXXRecordDecl *ParentDecl : typeParents(&CXXRD)) {
 if (Optional ParentSym =
-declToTypeHierarchyItem(ASTCtx, *ParentDecl, TB)) {
+declToTypeHierarchyItem(ASTCtx, *ParentDecl)) {
   ParentSym->parents.emplace();
-  fillSuperTypes(*ParentDecl

[PATCH] D84144: [clangd] Remove TokenBuffer usage in TypeHierarchy

2020-07-20 Thread Aleksandr Platonov via Phabricator via cfe-commits
ArcsinX marked 2 inline comments as done.
ArcsinX added inline comments.



Comment at: clang-tools-extra/clangd/XRefs.cpp:1191
+  SourceLocation EndLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getEndLoc()));
+  const auto NameRange =
+  toHalfOpenFileRange(SM, Ctx.getLangOpts(), {BeginLoc, EndLoc});

kadircet wrote:
> let's rename it to `DeclRange` rather than `NameRange`.
Renamed.



Comment at: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp:550
+  // Type hierarchy for `Child`
+  auto Result = runTypeHierarchy(Server, FooCpp, SourceAnnotations.point(), 1,
+ TypeHierarchyDirection::Parents);

kadircet wrote:
> you can keep using the `TestTU`. just provide the header via 
> `AdditionalFiles` and `TU.build` should first build a preamble and use it. 
> That way you can get rid of additions to the SyncAPI and usage of 
> ClangdServer in here.
Thanks, done.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84144



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


[PATCH] D72705: [analyzer] Added new checker 'alpha.unix.ErrorReturn'.

2020-07-20 Thread Balázs Kéri via Phabricator via cfe-commits
balazske added a comment.

This checker can have two purposes, one is to verify that all paths have the 
error check, other is to find at least one path without error check. The first 
is the one that can be done with dataflow based analysis but looks like a 
difficult problem. For example is it possible to handle this case (`X` does not 
change)?

  int Ret;
  if (X)
Ret = fgetc(fd);
  else
Ret = strtol(SomeString);
  ...
  bool IsError;
  if (X)
IsError = (Ret == EOF);
  else
IsError = (Ret < -100 || Ret > 100);

The other "purpose" is to find one path with missing error check, the current 
code should do something like that. The path sensitivity is used here to store 
for a symbol from which function call it comes from, and probably to determine 
value of other symbols in the program if they appear in a comparison.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D72705



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


[PATCH] D84144: [clangd] Remove TokenBuffer usage in TypeHierarchy

2020-07-20 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added a comment.
This revision is now accepted and ready to land.

LGTM, just some improvements to the testing. also please let me know if I 
should land this for you.




Comment at: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp:533
+
+  Annotations HeaderInPreambleAnnotations(R"cpp(
+struct Parent {

this doesn't need to be an `Annotation` and sorry for missing it in the first 
pass but since this only has a single header, you can actually do something 
like:

```
TestTU TU = TestTU::withCode(SourceAnnotations.code());
TU.HeaderCode = "struct Parent { int a; }";
```

and also drop the include directive in `SourceAnnotations` as `TU.HeaderCode` 
is implicitly included.



Comment at: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp:548
+  EXPECT_THAT(*Result, AllOf(WithName("Child"),
+ Parents(AllOf(WithName("Parent"), Parents();
+}

could you also make sure selection range is correct at least for `Parent` (as 
main file ranges are tested elsewhere already), so that we don't regress it in 
the future.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84144



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


[PATCH] D84090: [clang-format] Add SpaceAroundBitFieldColon option

2020-07-20 Thread Krasimir Georgiev via Phabricator via cfe-commits
krasimir added a comment.

@wanders, thank you for digging through code to get a feeling of the usage!

I agree with others to have an enum option. +1 to `None` over `Neither`.
I'd prefer `Before` / `After` instead of `Left` / `Right`; those seem more 
prevalent in names and values of existing options.
I'd slightly prefer leaving `After` / `Right` out; it seems it's not widely 
used and that would be one less case to maintain. However I'm OK with keeping 
it in for consistency.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84090



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


[PATCH] D83407: [analyzer][StdLibraryFunctionsChecker] Add POSIX networking functions

2020-07-20 Thread Kristóf Umann via Phabricator via cfe-commits
Szelethus accepted this revision.
Szelethus added a comment.
This revision is now accepted and ready to land.

LGTM!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83407



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


[PATCH] D82739: [clangd] Improve heuristic resolution of dependent types in TargetFinder

2020-07-20 Thread Haojian Wu via Phabricator via cfe-commits
hokein accepted this revision.
hokein added a comment.
This revision is now accepted and ready to land.
Herald added a subscriber: kbobyrev.

thanks, looks good.




Comment at: clang-tools-extra/clangd/FindTarget.cpp:71
+
+  if (const auto *RT = T->getAs()) {
+return dyn_cast(RT->getDecl());

nit: remove the `{}`, and elsewhere.



Comment at: clang-tools-extra/clangd/FindTarget.cpp:91
+// Try to heuristically resolve the type of a dependent expression `E`.
+const Type *resolveDependentExprToType(const Expr *E) {
+  std::vector Decls = resolveDependentExprToDecls(E);

I'd move `resolveDependentExprToType` close to `resolveDependentExprToDecls` 
(they are quite related).

consider putting `resolveDependentExprToType` after 
`resolveDependentExprToDecls` definition, and add a forward declaration of 
`resolveDependentExprToType` before the `resolveDependentExprToDecls`.



Comment at: clang-tools-extra/clangd/FindTarget.cpp:190
 }
+Expr *Base = ME->isImplicitAccess() ? nullptr : ME->getBase();
+if (const auto *BT = BaseType->getAs()) {

nit: move the Base to the if below.



Comment at: clang-tools-extra/clangd/FindTarget.cpp:194
+  // represented as BultinType::Dependent which gives us no information. We
+  // can get further b analyzing the depedent expression.
+  if (Base && BT->getKind() == BuiltinType::Dependent) {

nit: b -> by



Comment at: clang-tools-extra/clangd/FindTarget.cpp:197
+BaseType = resolveDependentExprToType(Base);
+if (!BaseType)
+  return {};

this branch is redundant, we can remove it, since 
`getMembersReferencedViaDependentName` can handle a nullptr.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D82739



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


[Differential] D84021: [Driver] Add support for -msve-vector-bits=scalable.

2020-07-20 Thread Paul Walker 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 rGab7abd8bf41b: [Driver] Add support for 
-msve-vector-bits=scalable. (authored by paulwalker-arm).

Repository:
  rG LLVM Github Monorepo

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


  https://reviews.llvm.org/D84021

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/Arch/AArch64.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/aarch64-sve-vector-bits.c

Index: clang/test/Driver/aarch64-sve-vector-bits.c
===
--- clang/test/Driver/aarch64-sve-vector-bits.c
+++ clang/test/Driver/aarch64-sve-vector-bits.c
@@ -12,12 +12,15 @@
 // RUN:  -msve-vector-bits=1024 2>&1 | FileCheck --check-prefix=CHECK-1024 %s
 // RUN: %clang -c %s -### -target aarch64-none-linux-gnu -march=armv8-a+sve \
 // RUN:  -msve-vector-bits=2048 2>&1 | FileCheck --check-prefix=CHECK-2048 %s
+// RUN: %clang -c %s -### -target aarch64-none-linux-gnu -march=armv8-a+sve \
+// RUN:  -msve-vector-bits=scalable 2>&1 | FileCheck --check-prefix=CHECK-SCALABLE %s
 
 // CHECK-128: "-msve-vector-bits=128"
 // CHECK-256: "-msve-vector-bits=256"
 // CHECK-512: "-msve-vector-bits=512"
 // CHECK-1024: "-msve-vector-bits=1024"
 // CHECK-2048: "-msve-vector-bits=2048"
+// CHECK-SCALABLE-NOT: "-msve-vector-bits=
 
 // Bail out if -msve-vector-bits is specified without SVE enabled
 // -
@@ -47,11 +50,13 @@
 // -
 // RUN: not %clang -c %s -o /dev/null -target aarch64-none-linux-gnu \
 // RUN:  -march=armv8-a+sve 2>&1 | FileCheck --check-prefix=CHECK-NO-FLAG-ERROR %s
+// RUN: not %clang -c %s -o /dev/null -target aarch64-none-linux-gnu \
+// RUN:  -march=armv8-a+sve -msve-vector-bits=scalable 2>&1 | FileCheck --check-prefix=CHECK-NO-FLAG-ERROR %s
 
 typedef __SVInt32_t svint32_t;
 typedef svint32_t noflag __attribute__((arm_sve_vector_bits(256)));
 
-// CHECK-NO-FLAG-ERROR: error: 'arm_sve_vector_bits' is not supported when '-msve-vector-bits=' is not specified
+// CHECK-NO-FLAG-ERROR: error: 'arm_sve_vector_bits' is only supported when '-msve-vector-bits=' is specified with a value of 128, 256, 512, 1024 or 2048
 
 // Error if attribute vector size != -msve-vector-bits
 // -
Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -1720,15 +1720,15 @@
   if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) {
 StringRef Val = A->getValue();
 const Driver &D = getToolChain().getDriver();
-if (!Val.equals("128") && !Val.equals("256") && !Val.equals("512") &&
-!Val.equals("1024") && !Val.equals("2048")) {
+if (Val.equals("128") || Val.equals("256") || Val.equals("512") ||
+Val.equals("1024") || Val.equals("2048"))
+  CmdArgs.push_back(
+  Args.MakeArgString(llvm::Twine("-msve-vector-bits=") + Val));
+// Silently drop requests for vector-length agnostic code as it's implied.
+else if (!Val.equals("scalable"))
   // Handle the unsupported values passed to msve-vector-bits.
   D.Diag(diag::err_drv_unsupported_option_argument)
   << A->getOption().getName() << Val;
-} else if (A->getOption().matches(options::OPT_msve_vector_bits_EQ)) {
-  CmdArgs.push_back(
-  Args.MakeArgString(llvm::Twine("-msve-vector-bits=") + Val));
-}
   }
 }
 
Index: clang/lib/Driver/ToolChains/Arch/AArch64.cpp
===
--- clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -370,8 +370,8 @@
 V8_6Pos = Features.insert(std::next(V8_6Pos), {"+i8mm", "+bf16"});
 
   bool HasSve = llvm::is_contained(Features, "+sve");
-  // -msve_vector_bits= flag is valid only if SVE is enabled.
-  if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ))
+  // -msve-vector-bits= flag is valid only if SVE is enabled.
+  if (Args.hasArg(options::OPT_msve_vector_bits_EQ))
 if (!HasSve)
   D.Diag(diag::err_drv_invalid_sve_vector_bits);
 
Index: clang/include/clang/Driver/Options.td
===
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -2346,8 +2346,9 @@
 
 def msve_vector_bits_EQ : Joined<["-"], "msve-vector-bits=">,
   Group, Flags<[DriverOption,CC1Option]>,
-  HelpText<"Set the size of fixed-length SVE vectors in bits.">,
-  Values<"128,256,512,1024,2048">;
+  HelpText<"Specify the size in bits of an SVE vector regis

[clang] ab7abd8 - [Driver] Add support for -msve-vector-bits=scalable.

2020-07-20 Thread Paul Walker via cfe-commits

Author: Paul Walker
Date: 2020-07-20T10:46:22Z
New Revision: ab7abd8bf41b558aef402a21c637211760bc2739

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

LOG: [Driver] Add support for -msve-vector-bits=scalable.

No real action is taken for a value of scalable but it provides a
route to disable an earlier specification and is effectively its
default value when omitted.

Patch also removes an "unused variable" warning.

Differential Revision: https://reviews.llvm.org/D84021

Added: 


Modified: 
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Arch/AArch64.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/test/Driver/aarch64-sve-vector-bits.c

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d1de4e0488d3..2e0791526aec 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2816,7 +2816,8 @@ def err_attribute_bad_sve_vector_size : Error<
   "invalid SVE vector size '%0', must match value set by "
   "'-msve-vector-bits' ('%1')">;
 def err_attribute_arm_feature_sve_bits_unsupported : Error<
-  "%0 is not supported when '-msve-vector-bits=' is not specified">;
+  "%0 is only supported when '-msve-vector-bits=' is specified with a "
+  "value of 128, 256, 512, 1024 or 2048.">;
 def err_attribute_requires_positive_integer : Error<
   "%0 attribute requires a %select{positive|non-negative}1 "
   "integral compile time constant expression">;

diff  --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index aaceaf92f9f5..d549e4b58507 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2346,8 +2346,9 @@ foreach i = {8-15,18} in
 
 def msve_vector_bits_EQ : Joined<["-"], "msve-vector-bits=">,
   Group, Flags<[DriverOption,CC1Option]>,
-  HelpText<"Set the size of fixed-length SVE vectors in bits.">,
-  Values<"128,256,512,1024,2048">;
+  HelpText<"Specify the size in bits of an SVE vector register. Defaults to 
the"
+   " vector length agnostic value of \"scalable\". (AArch64 only)">,
+  Values<"128,256,512,1024,2048,scalable">;
 
 def msign_return_address_EQ : Joined<["-"], "msign-return-address=">,
   Flags<[CC1Option]>, Group, Values<"none,all,non-leaf">,

diff  --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp 
b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
index 428b72a48904..43959f5abe43 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -370,8 +370,8 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
 V8_6Pos = Features.insert(std::next(V8_6Pos), {"+i8mm", "+bf16"});
 
   bool HasSve = llvm::is_contained(Features, "+sve");
-  // -msve_vector_bits= flag is valid only if SVE is enabled.
-  if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ))
+  // -msve-vector-bits= flag is valid only if SVE is enabled.
+  if (Args.hasArg(options::OPT_msve_vector_bits_EQ))
 if (!HasSve)
   D.Diag(diag::err_drv_invalid_sve_vector_bits);
 

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 91f133897271..8ce7e20408ab 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1720,15 +1720,15 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
   if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) {
 StringRef Val = A->getValue();
 const Driver &D = getToolChain().getDriver();
-if (!Val.equals("128") && !Val.equals("256") && !Val.equals("512") &&
-!Val.equals("1024") && !Val.equals("2048")) {
+if (Val.equals("128") || Val.equals("256") || Val.equals("512") ||
+Val.equals("1024") || Val.equals("2048"))
+  CmdArgs.push_back(
+  Args.MakeArgString(llvm::Twine("-msve-vector-bits=") + Val));
+// Silently drop requests for vector-length agnostic code as it's implied.
+else if (!Val.equals("scalable"))
   // Handle the unsupported values passed to msve-vector-bits.
   D.Diag(diag::err_drv_unsupported_option_argument)
   << A->getOption().getName() << Val;
-} else if (A->getOption().matches(options::OPT_msve_vector_bits_EQ)) {
-  CmdArgs.push_back(
-  Args.MakeArgString(llvm::Twine("-msve-vector-bits=") + Val));
-}
   }
 }
 

diff  --git a/clang/test/Driver/aarch64-sve-vector-bits.c 
b/clang/test/Driver/aarch64-sve-vector-bits.c
index c3d0d05bb9b6..ffe82f113fd1 100644
--- a/clang/test/Driver/aarch64-sve-vector-bits.c
+++ b/clang/test/Driver/aarch64-sve-vector-bits.c
@@ -12,12 +12,15 @@
 // RUN:  -msve-vector-bits=102

[PATCH] D84021: [Driver] Add support for -msve-vector-bits=scalable.

2020-07-20 Thread Paul Walker via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGab7abd8bf41b: [Driver] Add support for 
-msve-vector-bits=scalable. (authored by paulwalker-arm).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84021

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/Arch/AArch64.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/aarch64-sve-vector-bits.c

Index: clang/test/Driver/aarch64-sve-vector-bits.c
===
--- clang/test/Driver/aarch64-sve-vector-bits.c
+++ clang/test/Driver/aarch64-sve-vector-bits.c
@@ -12,12 +12,15 @@
 // RUN:  -msve-vector-bits=1024 2>&1 | FileCheck --check-prefix=CHECK-1024 %s
 // RUN: %clang -c %s -### -target aarch64-none-linux-gnu -march=armv8-a+sve \
 // RUN:  -msve-vector-bits=2048 2>&1 | FileCheck --check-prefix=CHECK-2048 %s
+// RUN: %clang -c %s -### -target aarch64-none-linux-gnu -march=armv8-a+sve \
+// RUN:  -msve-vector-bits=scalable 2>&1 | FileCheck --check-prefix=CHECK-SCALABLE %s
 
 // CHECK-128: "-msve-vector-bits=128"
 // CHECK-256: "-msve-vector-bits=256"
 // CHECK-512: "-msve-vector-bits=512"
 // CHECK-1024: "-msve-vector-bits=1024"
 // CHECK-2048: "-msve-vector-bits=2048"
+// CHECK-SCALABLE-NOT: "-msve-vector-bits=
 
 // Bail out if -msve-vector-bits is specified without SVE enabled
 // -
@@ -47,11 +50,13 @@
 // -
 // RUN: not %clang -c %s -o /dev/null -target aarch64-none-linux-gnu \
 // RUN:  -march=armv8-a+sve 2>&1 | FileCheck --check-prefix=CHECK-NO-FLAG-ERROR %s
+// RUN: not %clang -c %s -o /dev/null -target aarch64-none-linux-gnu \
+// RUN:  -march=armv8-a+sve -msve-vector-bits=scalable 2>&1 | FileCheck --check-prefix=CHECK-NO-FLAG-ERROR %s
 
 typedef __SVInt32_t svint32_t;
 typedef svint32_t noflag __attribute__((arm_sve_vector_bits(256)));
 
-// CHECK-NO-FLAG-ERROR: error: 'arm_sve_vector_bits' is not supported when '-msve-vector-bits=' is not specified
+// CHECK-NO-FLAG-ERROR: error: 'arm_sve_vector_bits' is only supported when '-msve-vector-bits=' is specified with a value of 128, 256, 512, 1024 or 2048
 
 // Error if attribute vector size != -msve-vector-bits
 // -
Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -1720,15 +1720,15 @@
   if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) {
 StringRef Val = A->getValue();
 const Driver &D = getToolChain().getDriver();
-if (!Val.equals("128") && !Val.equals("256") && !Val.equals("512") &&
-!Val.equals("1024") && !Val.equals("2048")) {
+if (Val.equals("128") || Val.equals("256") || Val.equals("512") ||
+Val.equals("1024") || Val.equals("2048"))
+  CmdArgs.push_back(
+  Args.MakeArgString(llvm::Twine("-msve-vector-bits=") + Val));
+// Silently drop requests for vector-length agnostic code as it's implied.
+else if (!Val.equals("scalable"))
   // Handle the unsupported values passed to msve-vector-bits.
   D.Diag(diag::err_drv_unsupported_option_argument)
   << A->getOption().getName() << Val;
-} else if (A->getOption().matches(options::OPT_msve_vector_bits_EQ)) {
-  CmdArgs.push_back(
-  Args.MakeArgString(llvm::Twine("-msve-vector-bits=") + Val));
-}
   }
 }
 
Index: clang/lib/Driver/ToolChains/Arch/AArch64.cpp
===
--- clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -370,8 +370,8 @@
 V8_6Pos = Features.insert(std::next(V8_6Pos), {"+i8mm", "+bf16"});
 
   bool HasSve = llvm::is_contained(Features, "+sve");
-  // -msve_vector_bits= flag is valid only if SVE is enabled.
-  if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ))
+  // -msve-vector-bits= flag is valid only if SVE is enabled.
+  if (Args.hasArg(options::OPT_msve_vector_bits_EQ))
 if (!HasSve)
   D.Diag(diag::err_drv_invalid_sve_vector_bits);
 
Index: clang/include/clang/Driver/Options.td
===
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -2346,8 +2346,9 @@
 
 def msve_vector_bits_EQ : Joined<["-"], "msve-vector-bits=">,
   Group, Flags<[DriverOption,CC1Option]>,
-  HelpText<"Set the size of fixed-length SVE vectors in bits.">,
-  Values<"128,256,512,1024,2048">;
+  HelpText<"Specify the size in bits of an SVE vector register. Defaults to the"
+   " vector length agnostic 

[PATCH] D84144: [clangd] Remove TokenBuffer usage in TypeHierarchy

2020-07-20 Thread Aleksandr Platonov via Phabricator via cfe-commits
ArcsinX updated this revision to Diff 279174.
ArcsinX added a comment.

Check source range for Parent


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84144

Files:
  clang-tools-extra/clangd/XRefs.cpp
  clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp

Index: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
===
--- clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
+++ clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
@@ -523,6 +523,35 @@
WithKind(SymbolKind::Struct), Children();
 }
 
+TEST(TypeHierarchy, Preamble) {
+  Annotations SourceAnnotations(R"cpp(
+#include "header_in_preamble.h"
+struct Ch^ild : Parent {
+  int b;
+};)cpp");
+
+  Annotations HeaderInPreambleAnnotations(R"cpp(
+struct [[Parent]] {
+  int a;
+};)cpp");
+
+  TestTU TU = TestTU::withCode(SourceAnnotations.code());
+  TU.AdditionalFiles["header_in_preamble.h"] =
+  HeaderInPreambleAnnotations.code().str();
+  auto AST = TU.build();
+
+  llvm::Optional Result = getTypeHierarchy(
+  AST, SourceAnnotations.point(), 1, TypeHierarchyDirection::Parents);
+
+  ASSERT_TRUE(Result);
+  EXPECT_THAT(
+  *Result,
+  AllOf(WithName("Child"),
+Parents(AllOf(WithName("Parent"),
+  SelectionRangeIs(HeaderInPreambleAnnotations.range()),
+  Parents();
+}
+
 SymbolID findSymbolIDByName(SymbolIndex *Index, llvm::StringRef Name,
 llvm::StringRef TemplateArgs = "") {
   SymbolID Result;
Index: clang-tools-extra/clangd/XRefs.cpp
===
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -1183,23 +1183,24 @@
 
 // FIXME(nridge): Reduce duplication between this function and declToSym().
 static llvm::Optional
-declToTypeHierarchyItem(ASTContext &Ctx, const NamedDecl &ND,
-const syntax::TokenBuffer &TB) {
+declToTypeHierarchyItem(ASTContext &Ctx, const NamedDecl &ND) {
   auto &SM = Ctx.getSourceManager();
   SourceLocation NameLoc = nameLocation(ND, Ctx.getSourceManager());
+  SourceLocation BeginLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getBeginLoc()));
+  SourceLocation EndLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getEndLoc()));
+  const auto DeclRange =
+  toHalfOpenFileRange(SM, Ctx.getLangOpts(), {BeginLoc, EndLoc});
+  if (!DeclRange)
+return llvm::None;
   auto FilePath =
   getCanonicalPath(SM.getFileEntryForID(SM.getFileID(NameLoc)), SM);
   auto TUPath = getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM);
   if (!FilePath || !TUPath)
 return llvm::None; // Not useful without a uri.
 
-  auto DeclToks = TB.spelledForExpanded(TB.expandedTokens(ND.getSourceRange()));
-  if (!DeclToks || DeclToks->empty())
-return llvm::None;
-
-  auto NameToks = TB.spelledForExpanded(TB.expandedTokens(NameLoc));
-  if (!NameToks || NameToks->empty())
-return llvm::None;
+  Position NameBegin = sourceLocToPosition(SM, NameLoc);
+  Position NameEnd = sourceLocToPosition(
+  SM, Lexer::getLocForEndOfToken(NameLoc, 0, SM, Ctx.getLangOpts()));
 
   index::SymbolInfo SymInfo = index::getSymbolInfo(&ND);
   // FIXME: this is not classifying constructors, destructors and operators
@@ -1210,12 +1211,9 @@
   THI.name = printName(Ctx, ND);
   THI.kind = SK;
   THI.deprecated = ND.isDeprecated();
-  THI.range = halfOpenToRange(
-  SM, syntax::Token::range(SM, DeclToks->front(), DeclToks->back())
-  .toCharRange(SM));
-  THI.selectionRange = halfOpenToRange(
-  SM, syntax::Token::range(SM, NameToks->front(), NameToks->back())
-  .toCharRange(SM));
+  THI.range = Range{sourceLocToPosition(SM, DeclRange->getBegin()),
+sourceLocToPosition(SM, DeclRange->getEnd())};
+  THI.selectionRange = Range{NameBegin, NameEnd};
   if (!THI.range.contains(THI.selectionRange)) {
 // 'selectionRange' must be contained in 'range', so in cases where clang
 // reports unrelated ranges we need to reconcile somehow.
@@ -1282,8 +1280,7 @@
 
 static void fillSuperTypes(const CXXRecordDecl &CXXRD, ASTContext &ASTCtx,
std::vector &SuperTypes,
-   RecursionProtectionSet &RPSet,
-   const syntax::TokenBuffer &TB) {
+   RecursionProtectionSet &RPSet) {
   // typeParents() will replace dependent template specializations
   // with their class template, so to avoid infinite recursion for
   // certain types of hierarchies, keep the templates encountered
@@ -1298,9 +1295,9 @@
 
   for (const CXXRecordDecl *ParentDecl : typeParents(&CXXRD)) {
 if (Optional ParentSym =
-declToTypeHierarchyItem(ASTCtx, *ParentDecl, TB)) {
+declToTypeHierarchyItem(ASTCtx, *Paren

[PATCH] D84144: [clangd] Remove TokenBuffer usage in TypeHierarchy

2020-07-20 Thread Aleksandr Platonov via Phabricator via cfe-commits
ArcsinX marked 2 inline comments as done.
ArcsinX added inline comments.



Comment at: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp:533
+
+  Annotations HeaderInPreambleAnnotations(R"cpp(
+struct Parent {

kadircet wrote:
> this doesn't need to be an `Annotation` and sorry for missing it in the first 
> pass but since this only has a single header, you can actually do something 
> like:
> 
> ```
> TestTU TU = TestTU::withCode(SourceAnnotations.code());
> TU.HeaderCode = "struct Parent { int a; }";
> ```
> 
> and also drop the include directive in `SourceAnnotations` as `TU.HeaderCode` 
> is implicitly included.
Seems now I need it to check selection range.



Comment at: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp:548
+  EXPECT_THAT(*Result, AllOf(WithName("Child"),
+ Parents(AllOf(WithName("Parent"), Parents();
+}

kadircet wrote:
> could you also make sure selection range is correct at least for `Parent` (as 
> main file ranges are tested elsewhere already), so that we don't regress it 
> in the future.
Added Parent selection range check.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84144



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


[PATCH] D84144: [clangd] Remove TokenBuffer usage in TypeHierarchy

2020-07-20 Thread Aleksandr Platonov via Phabricator via cfe-commits
ArcsinX added a comment.

In D84144#2161579 , @kadircet wrote:

> also please let me know if I should land this for you.


Yes, could you please land this for me? I do not have commit access.
Aleksandr Platonov 


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84144



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


[PATCH] D83961: [Analyzer] Fix bug report source locations in minimal output.

2020-07-20 Thread Kristóf Umann via Phabricator via cfe-commits
Szelethus added a comment.

I find the summary here a bit lacking. We detected this issue in D83120 
, where a lot of discussion can be found, so 
its worth linking in. On its own, I'm not immediately sold on whether this is 
the correct solution, and even if it is, how does it solve the problem. I bet 
you had to struggle a bit to understand the related machinery to fix this, it'd 
be invaluable to share the knowledge you gained here as well.

I took a look myself, and the issue fixed here seems to be that 
`PathDiagnostic`'s constructor doesn't set the associated 
`PathDiagnosticLocation` itself, and `generateEmptyDiagnosticForReport` pretty 
much resolves to that. The thing I'm still struggling with, is that I'm not 
terribly sure whether this the same issue raised in the previous patch.

> Fix of the following problem:
> If the bug report equivalence class contains multiple
> reports and no (minimal) analyzer output was requested
> it can happen that the wrong location is used for the warning.

I have two burning questions about this:

- Are we sure that we used the correct (with the shortest **bug path**) bug 
report, but associated it with the wrong location? Mind that everything you 
touched here, as I understand it, affects sorting, not uniqueing.
- If so, some (even if incorrect) location must've been used, where did that 
come from?

In D83961#2158128 , @balazske wrote:

> Big part of the test failures is with the `osx.cocoa.RetainCount` checker.


Every time :^)




Comment at: clang/lib/StaticAnalyzer/Core/BugReporter.cpp:3007
 // of the issue.
+// This can happen if report is BasicBugReport.
 if (PD->path.empty()) {

Is this the *only* instance when that happens? How about the `text-minimal` 
output?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83961



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


[PATCH] D83665: [OpenCL] Fixed missing address space for templated copy constructor

2020-07-20 Thread Ole Strohm via Phabricator via cfe-commits
olestrohm marked an inline comment as done.
olestrohm added inline comments.



Comment at: clang/lib/Sema/SemaTemplateDeduction.cpp:3811
+  if(S.getLangOpts().OpenCL)
+ArgType = S.deduceOpenCLPointeeAddrSpace(ArgType);
   ArgType = S.Context.getLValueReferenceType(ArgType);

Anastasia wrote:
> I feel we can just add an address space explicitly since we are creating the 
> type here for a known use case. However, does Arg actually have an address 
> space? I am just unsure whether we should use generic address space or 
> concrete address space.
No, there are no known address spaces at this point for the test case I've got. 
But as far as I understand the function isn't only used for the case we look at 
here, but there may be case where the argument has an address space.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83665



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


[PATCH] D81090: [AST][RecoveryExpr] Preserve the AST for invalid class constructions.

2020-07-20 Thread Haojian Wu via Phabricator via cfe-commits
hokein updated this revision to Diff 279176.
hokein added a comment.

rebase


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D81090

Files:
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/AST/ast-dump-recovery.cpp
  clang/test/SemaCXX/constant-expression-cxx11.cpp
  clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
  clang/test/SemaCXX/cxx1z-copy-omission.cpp


Index: clang/test/SemaCXX/cxx1z-copy-omission.cpp
===
--- clang/test/SemaCXX/cxx1z-copy-omission.cpp
+++ clang/test/SemaCXX/cxx1z-copy-omission.cpp
@@ -106,7 +106,7 @@
   sizeof(Indestructible{}); // expected-error {{deleted}}
   sizeof(make_indestructible()); // expected-error {{deleted}}
   sizeof(make_incomplete()); // expected-error {{incomplete}}
-  typeid(Indestructible{}); // expected-error {{deleted}}
+  typeid(Indestructible{}); // expected-error {{deleted}} expected-error {{you 
need to include }}
   typeid(make_indestructible()); // expected-error {{deleted}} \
  // expected-error {{need to include 
}}
   typeid(make_incomplete()); // expected-error {{incomplete}} \
Index: clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
===
--- clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
+++ clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
@@ -163,7 +163,7 @@
 // (for the second phase, no constructor is viable)
 G g1{1, 2, 3}; // expected-error {{no matching constructor}}
 (void) new G{1, 2, 3}; // expected-error {{no matching constructor}}
-(void) G{1, 2, 3} // expected-error {{no matching constructor}}
+(void) G{1, 2, 3}; // expected-error {{no matching constructor}}
 
 // valid (T deduced to <>).
 G g2({1, 2, 3});
Index: clang/test/SemaCXX/constant-expression-cxx11.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -2043,14 +2043,11 @@
 X::n; // expected-note {{in evaluation of exception 
specification for 'BadDefaultInit::A::A' needed here}}
   };
 
-  // FIXME: The "constexpr constructor must initialize all members" diagnostic
-  // here is bogus (we discard the k(k) initializer because the parameter 'k'
-  // has been marked invalid).
   struct B {
-constexpr B( // expected-warning {{initialize all members}}
+constexpr B(
 int k = X::n) : // expected-error {{default argument to 
function 'B' that is declared later}} expected-note {{here}}
   k(k) {}
-int k; // expected-note {{not initialized}}
+int k;
   };
 }
 
Index: clang/test/AST/ast-dump-recovery.cpp
===
--- clang/test/AST/ast-dump-recovery.cpp
+++ clang/test/AST/ast-dump-recovery.cpp
@@ -157,11 +157,14 @@
   // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
   // CHECK-NEXT:  `-InitListExpr
   Bar b2 = {1};
-  // FIXME: preserve the invalid initializer.
-  // CHECK: `-VarDecl {{.*}} b3 'Bar'
+  // CHECK: `-VarDecl {{.*}} b3 'Bar'
+  // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'Bar' contains-errors
+  // CHECK-NEXT:`-DeclRefExpr {{.*}} 'x' 'int'
   Bar b3 = Bar(x);
-  // FIXME: preserve the invalid initializer.
-  // CHECK: `-VarDecl {{.*}} b4 'Bar'
+  // CHECK: `-VarDecl {{.*}} b4 'Bar'
+  // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'Bar' contains-errors
+  // CHECK-NEXT:`-InitListExpr {{.*}} 'void'
+  // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'x' 'int'
   Bar b4 = Bar{x};
   // CHECK: `-VarDecl {{.*}} b5 'Bar'
   // CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} 'Bar' contains-errors 
'Bar'
@@ -174,6 +177,10 @@
   // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
   // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid'
   Bar b6 = Bar{invalid()};
+
+  // CHECK: `-RecoveryExpr {{.*}} 'Bar' contains-errors
+  // CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int' 1
+  Bar(1);
 }
 void InitializerForAuto() {
   // CHECK: `-VarDecl {{.*}} invalid a 'auto'
Index: clang/lib/Sema/SemaExprCXX.cpp
===
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -1389,6 +1389,9 @@
   if (!Result.isInvalid() && Result.get()->isInstantiationDependent() &&
   !Result.get()->isTypeDependent())
 Result = CorrectDelayedTyposInExpr(Result.get());
+  else if (Result.isInvalid())
+Result = CreateRecoveryExpr(TInfo->getTypeLoc().getBeginLoc(),
+RParenOrBraceLoc, exprs, Ty);
   return Result;
 }
 


Index: clang/test/SemaCXX/cxx1z-copy-omission.cpp
===
--- clang/test/SemaCXX/cxx1z-copy-omission.cpp
+++ clang/test/SemaCXX/cxx1z-copy-omission.cpp
@@ -106,7 +106,7 @@
   sizeof(Indestructible{}); // expect

[clang] 17ef788 - [AST][RecoveryExpr] Preserve the AST for invalid class constructions.

2020-07-20 Thread Haojian Wu via cfe-commits

Author: Haojian Wu
Date: 2020-07-20T13:11:15+02:00
New Revision: 17ef788df56096ca5affdfc29d562c103f0e534c

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

LOG: [AST][RecoveryExpr] Preserve the AST for invalid class constructions.

Differential Revision: https://reviews.llvm.org/D81090

Added: 


Modified: 
clang/lib/Sema/SemaExprCXX.cpp
clang/test/AST/ast-dump-recovery.cpp
clang/test/SemaCXX/constant-expression-cxx11.cpp
clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
clang/test/SemaCXX/cxx1z-copy-omission.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index d885920b6c14..212f5e4746d6 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1389,6 +1389,9 @@ Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep,
   if (!Result.isInvalid() && Result.get()->isInstantiationDependent() &&
   !Result.get()->isTypeDependent())
 Result = CorrectDelayedTyposInExpr(Result.get());
+  else if (Result.isInvalid())
+Result = CreateRecoveryExpr(TInfo->getTypeLoc().getBeginLoc(),
+RParenOrBraceLoc, exprs, Ty);
   return Result;
 }
 

diff  --git a/clang/test/AST/ast-dump-recovery.cpp 
b/clang/test/AST/ast-dump-recovery.cpp
index 740864a26481..cbae3fddf21e 100644
--- a/clang/test/AST/ast-dump-recovery.cpp
+++ b/clang/test/AST/ast-dump-recovery.cpp
@@ -157,11 +157,14 @@ void InvalidInitalizer(int x) {
   // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
   // CHECK-NEXT:  `-InitListExpr
   Bar b2 = {1};
-  // FIXME: preserve the invalid initializer.
-  // CHECK: `-VarDecl {{.*}} b3 'Bar'
+  // CHECK: `-VarDecl {{.*}} b3 'Bar'
+  // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'Bar' contains-errors
+  // CHECK-NEXT:`-DeclRefExpr {{.*}} 'x' 'int'
   Bar b3 = Bar(x);
-  // FIXME: preserve the invalid initializer.
-  // CHECK: `-VarDecl {{.*}} b4 'Bar'
+  // CHECK: `-VarDecl {{.*}} b4 'Bar'
+  // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'Bar' contains-errors
+  // CHECK-NEXT:`-InitListExpr {{.*}} 'void'
+  // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'x' 'int'
   Bar b4 = Bar{x};
   // CHECK: `-VarDecl {{.*}} b5 'Bar'
   // CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} 'Bar' contains-errors 
'Bar'
@@ -174,6 +177,10 @@ void InvalidInitalizer(int x) {
   // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
   // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid'
   Bar b6 = Bar{invalid()};
+
+  // CHECK: `-RecoveryExpr {{.*}} 'Bar' contains-errors
+  // CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int' 1
+  Bar(1);
 }
 void InitializerForAuto() {
   // CHECK: `-VarDecl {{.*}} invalid a 'auto'

diff  --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp 
b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index eac0256c4fb2..14d36543cb20 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -2043,14 +2043,11 @@ namespace BadDefaultInit {
 X::n; // expected-note {{in evaluation of exception 
specification for 'BadDefaultInit::A::A' needed here}}
   };
 
-  // FIXME: The "constexpr constructor must initialize all members" diagnostic
-  // here is bogus (we discard the k(k) initializer because the parameter 'k'
-  // has been marked invalid).
   struct B {
-constexpr B( // expected-warning {{initialize all members}}
+constexpr B(
 int k = X::n) : // expected-error {{default argument to 
function 'B' that is declared later}} expected-note {{here}}
   k(k) {}
-int k; // expected-note {{not initialized}}
+int k;
   };
 }
 

diff  --git a/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp 
b/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
index 513c670d392d..92e3676954a2 100644
--- a/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
+++ b/clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
@@ -163,7 +163,7 @@ namespace objects {
 // (for the second phase, no constructor is viable)
 G g1{1, 2, 3}; // expected-error {{no matching constructor}}
 (void) new G{1, 2, 3}; // expected-error {{no matching constructor}}
-(void) G{1, 2, 3} // expected-error {{no matching constructor}}
+(void) G{1, 2, 3}; // expected-error {{no matching constructor}}
 
 // valid (T deduced to <>).
 G g2({1, 2, 3});

diff  --git a/clang/test/SemaCXX/cxx1z-copy-omission.cpp 
b/clang/test/SemaCXX/cxx1z-copy-omission.cpp
index eceac810e72a..a850cf6143cd 100644
--- a/clang/test/SemaCXX/cxx1z-copy-omission.cpp
+++ b/clang/test/SemaCXX/cxx1z-copy-omission.cpp
@@ -106,7 +106,7 @@ void test_expressions(bool b) {
   sizeof(Indestructible{}); // expected-error {{deleted}}
   sizeof(make_indestructible()); // expected-error {{deleted}}
   sizeof(make_incomp

[Differential] D81090: [AST][RecoveryExpr] Preserve the AST for invalid class constructions.

2020-07-20 Thread Haojian Wu 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 rG17ef788df560: [AST][RecoveryExpr] Preserve the AST for 
invalid class constructions. (authored by hokein).

Changed prior to commit:
  https://reviews.llvm.org/D81090?vs=270402&id=279004#toc

Repository:
  rG LLVM Github Monorepo

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


  https://reviews.llvm.org/D81090

Files:
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/AST/ast-dump-recovery.cpp
  clang/test/SemaCXX/constant-expression-cxx11.cpp
  clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
  clang/test/SemaCXX/cxx1z-copy-omission.cpp



Index: clang/test/SemaCXX/cxx1z-copy-omission.cpp
===
--- clang/test/SemaCXX/cxx1z-copy-omission.cpp
+++ clang/test/SemaCXX/cxx1z-copy-omission.cpp
@@ -106,7 +106,7 @@
   sizeof(Indestructible{}); // expected-error {{deleted}}
   sizeof(make_indestructible()); // expected-error {{deleted}}
   sizeof(make_incomplete()); // expected-error {{incomplete}}
-  typeid(Indestructible{}); // expected-error {{deleted}}
+  typeid(Indestructible{}); // expected-error {{deleted}} expected-error {{you 
need to include }}
   typeid(make_indestructible()); // expected-error {{deleted}} \
  // expected-error {{need to include 
}}
   typeid(make_incomplete()); // expected-error {{incomplete}} \
Index: clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
===
--- clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
+++ clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
@@ -163,7 +163,7 @@
 // (for the second phase, no constructor is viable)
 G g1{1, 2, 3}; // expected-error {{no matching constructor}}
 (void) new G{1, 2, 3}; // expected-error {{no matching constructor}}
-(void) G{1, 2, 3} // expected-error {{no matching constructor}}
+(void) G{1, 2, 3}; // expected-error {{no matching constructor}}
 
 // valid (T deduced to <>).
 G g2({1, 2, 3});
Index: clang/test/SemaCXX/constant-expression-cxx11.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -2043,14 +2043,11 @@
 X::n; // expected-note {{in evaluation of exception 
specification for 'BadDefaultInit::A::A' needed here}}
   };
 
-  // FIXME: The "constexpr constructor must initialize all members" diagnostic
-  // here is bogus (we discard the k(k) initializer because the parameter 'k'
-  // has been marked invalid).
   struct B {
-constexpr B( // expected-warning {{initialize all members}}
+constexpr B(
 int k = X::n) : // expected-error {{default argument to 
function 'B' that is declared later}} expected-note {{here}}
   k(k) {}
-int k; // expected-note {{not initialized}}
+int k;
   };
 }
 
Index: clang/test/AST/ast-dump-recovery.cpp
===
--- clang/test/AST/ast-dump-recovery.cpp
+++ clang/test/AST/ast-dump-recovery.cpp
@@ -157,11 +157,14 @@
   // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
   // CHECK-NEXT:  `-InitListExpr
   Bar b2 = {1};
-  // FIXME: preserve the invalid initializer.
-  // CHECK: `-VarDecl {{.*}} b3 'Bar'
+  // CHECK: `-VarDecl {{.*}} b3 'Bar'
+  // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'Bar' contains-errors
+  // CHECK-NEXT:`-DeclRefExpr {{.*}} 'x' 'int'
   Bar b3 = Bar(x);
-  // FIXME: preserve the invalid initializer.
-  // CHECK: `-VarDecl {{.*}} b4 'Bar'
+  // CHECK: `-VarDecl {{.*}} b4 'Bar'
+  // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'Bar' contains-errors
+  // CHECK-NEXT:`-InitListExpr {{.*}} 'void'
+  // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'x' 'int'
   Bar b4 = Bar{x};
   // CHECK: `-VarDecl {{.*}} b5 'Bar'
   // CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} 'Bar' contains-errors 
'Bar'
@@ -174,6 +177,10 @@
   // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
   // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid'
   Bar b6 = Bar{invalid()};
+
+  // CHECK: `-RecoveryExpr {{.*}} 'Bar' contains-errors
+  // CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int' 1
+  Bar(1);
 }
 void InitializerForAuto() {
   // CHECK: `-VarDecl {{.*}} invalid a 'auto'
Index: clang/lib/Sema/SemaExprCXX.cpp
===
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -1389,6 +1389,9 @@
   if (!Result.isInvalid() && Result.get()->isInstantiationDependent() &&
   !Result.get()->isTypeDependent())
 Result = CorrectDelayedTyposInExpr(Result.get());
+  else if (Result.isInvalid())
+Result = CreateRecoveryExpr(TInfo->getTypeLoc().getBeginLoc(),
+RParenOrBraceLoc, exprs, Ty);
   return Result;
 }
 


Inde

[PATCH] D81090: [AST][RecoveryExpr] Preserve the AST for invalid class constructions.

2020-07-20 Thread Haojian Wu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG17ef788df560: [AST][RecoveryExpr] Preserve the AST for 
invalid class constructions. (authored by hokein).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D81090

Files:
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/AST/ast-dump-recovery.cpp
  clang/test/SemaCXX/constant-expression-cxx11.cpp
  clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
  clang/test/SemaCXX/cxx1z-copy-omission.cpp


Index: clang/test/SemaCXX/cxx1z-copy-omission.cpp
===
--- clang/test/SemaCXX/cxx1z-copy-omission.cpp
+++ clang/test/SemaCXX/cxx1z-copy-omission.cpp
@@ -106,7 +106,7 @@
   sizeof(Indestructible{}); // expected-error {{deleted}}
   sizeof(make_indestructible()); // expected-error {{deleted}}
   sizeof(make_incomplete()); // expected-error {{incomplete}}
-  typeid(Indestructible{}); // expected-error {{deleted}}
+  typeid(Indestructible{}); // expected-error {{deleted}} expected-error {{you 
need to include }}
   typeid(make_indestructible()); // expected-error {{deleted}} \
  // expected-error {{need to include 
}}
   typeid(make_incomplete()); // expected-error {{incomplete}} \
Index: clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
===
--- clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
+++ clang/test/SemaCXX/cxx0x-initializer-constructor.cpp
@@ -163,7 +163,7 @@
 // (for the second phase, no constructor is viable)
 G g1{1, 2, 3}; // expected-error {{no matching constructor}}
 (void) new G{1, 2, 3}; // expected-error {{no matching constructor}}
-(void) G{1, 2, 3} // expected-error {{no matching constructor}}
+(void) G{1, 2, 3}; // expected-error {{no matching constructor}}
 
 // valid (T deduced to <>).
 G g2({1, 2, 3});
Index: clang/test/SemaCXX/constant-expression-cxx11.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -2043,14 +2043,11 @@
 X::n; // expected-note {{in evaluation of exception 
specification for 'BadDefaultInit::A::A' needed here}}
   };
 
-  // FIXME: The "constexpr constructor must initialize all members" diagnostic
-  // here is bogus (we discard the k(k) initializer because the parameter 'k'
-  // has been marked invalid).
   struct B {
-constexpr B( // expected-warning {{initialize all members}}
+constexpr B(
 int k = X::n) : // expected-error {{default argument to 
function 'B' that is declared later}} expected-note {{here}}
   k(k) {}
-int k; // expected-note {{not initialized}}
+int k;
   };
 }
 
Index: clang/test/AST/ast-dump-recovery.cpp
===
--- clang/test/AST/ast-dump-recovery.cpp
+++ clang/test/AST/ast-dump-recovery.cpp
@@ -157,11 +157,14 @@
   // CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
   // CHECK-NEXT:  `-InitListExpr
   Bar b2 = {1};
-  // FIXME: preserve the invalid initializer.
-  // CHECK: `-VarDecl {{.*}} b3 'Bar'
+  // CHECK: `-VarDecl {{.*}} b3 'Bar'
+  // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'Bar' contains-errors
+  // CHECK-NEXT:`-DeclRefExpr {{.*}} 'x' 'int'
   Bar b3 = Bar(x);
-  // FIXME: preserve the invalid initializer.
-  // CHECK: `-VarDecl {{.*}} b4 'Bar'
+  // CHECK: `-VarDecl {{.*}} b4 'Bar'
+  // CHECK-NEXT:  `-RecoveryExpr {{.*}} 'Bar' contains-errors
+  // CHECK-NEXT:`-InitListExpr {{.*}} 'void'
+  // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'x' 'int'
   Bar b4 = Bar{x};
   // CHECK: `-VarDecl {{.*}} b5 'Bar'
   // CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} 'Bar' contains-errors 
'Bar'
@@ -174,6 +177,10 @@
   // CHECK-NEXT:   `-RecoveryExpr {{.*}} contains-errors
   // CHECK-NEXT: `-UnresolvedLookupExpr {{.*}} 'invalid'
   Bar b6 = Bar{invalid()};
+
+  // CHECK: `-RecoveryExpr {{.*}} 'Bar' contains-errors
+  // CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int' 1
+  Bar(1);
 }
 void InitializerForAuto() {
   // CHECK: `-VarDecl {{.*}} invalid a 'auto'
Index: clang/lib/Sema/SemaExprCXX.cpp
===
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -1389,6 +1389,9 @@
   if (!Result.isInvalid() && Result.get()->isInstantiationDependent() &&
   !Result.get()->isTypeDependent())
 Result = CorrectDelayedTyposInExpr(Result.get());
+  else if (Result.isInvalid())
+Result = CreateRecoveryExpr(TInfo->getTypeLoc().getBeginLoc(),
+RParenOrBraceLoc, exprs, Ty);
   return Result;
 }
 


Index: clang/test/SemaCXX/cxx1z-copy-omission.cpp
===
--- clang/test/SemaCXX/cxx1z-c

[PATCH] D84144: [clangd] Remove TokenBuffer usage in TypeHierarchy

2020-07-20 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp:533
+
+  Annotations HeaderInPreambleAnnotations(R"cpp(
+struct Parent {

ArcsinX wrote:
> kadircet wrote:
> > this doesn't need to be an `Annotation` and sorry for missing it in the 
> > first pass but since this only has a single header, you can actually do 
> > something like:
> > 
> > ```
> > TestTU TU = TestTU::withCode(SourceAnnotations.code());
> > TU.HeaderCode = "struct Parent { int a; }";
> > ```
> > 
> > and also drop the include directive in `SourceAnnotations` as 
> > `TU.HeaderCode` is implicitly included.
> Seems now I need it to check selection range.
right, you need annotations for the range, but you still can get away with just 
setting `TU.HeaderCode` instead of populating AdditionalFiles and including the 
header in the source. but not that important.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84144



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


[PATCH] D84146: [AST][RecoveryExpr] Add recovery-ast tests for C language, NFC.

2020-07-20 Thread Sam McCall via Phabricator via cfe-commits
sammccall accepted this revision.
sammccall added inline comments.
This revision is now accepted and ready to land.



Comment at: clang/test/AST/ast-dump-recovery.c:20
+// CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a'
+int prefix_inc = ++a;
+

why is this an interesting distinct case vs the one above?



Comment at: clang/test/AST/ast-dump-recovery.c:39
+// CHECK-NEXT:  `-FloatingLiteral {{.*}} 'double'
+int unary_bitinverse = ~(a + 0.0);
+

and this one



Comment at: clang/test/AST/ast-dump-recovery.c:55
+  // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a' 'const int'
+  static int foo = a++; // verify no crash on local static var decl.
+}

may or may not want to separate the crash tests out. Up to you, can do this 
later


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84146



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


[PATCH] D83551: [PATCH 2/4][Sema][AArch64] Add semantics for arm_sve_vector_bits attribute

2020-07-20 Thread Cullen Rhodes via Phabricator via cfe-commits
c-rhodes updated this revision to Diff 279178.
c-rhodes added a comment.

Changes:

- Remove internal type attributes (defined for each vector-size).
- Get the vector size from the `arm_sve_vector_bits` attribute via the 
`AttributedTypeLoc` associated with the typedef decl.
- Change `NumBits` argument for `ArmSveVectorBits` type attribute from int to 
unsigned.
- Only allow `ArmSveVectorBits` type attribute to be applied to typedefs (and 
added test).
- Set `let PragmaAttributeSupport = 0;` after specifying `Subjects` to fixed 
`clang/test/Misc/pragma-attribute-supported-attributes-list.test`.
- `vector-length sized` -> `vector-length-sized`.


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

https://reviews.llvm.org/D83551

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/Type.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/Sema/attr-arm-sve-vector-bits.c

Index: clang/test/Sema/attr-arm-sve-vector-bits.c
===
--- clang/test/Sema/attr-arm-sve-vector-bits.c
+++ clang/test/Sema/attr-arm-sve-vector-bits.c
@@ -60,3 +60,168 @@
 typedef float badtype3 __attribute__((arm_sve_vector_bits(N))); // expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 'float'}}
 typedef svint8x2_t badtype4 __attribute__((arm_sve_vector_bits(N)));// expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 'svint8x2_t' (aka '__clang_svint8x2_t')}}
 typedef svfloat32x3_t badtype5 __attribute__((arm_sve_vector_bits(N))); // expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 'svfloat32x3_t' (aka '__clang_svfloat32x3_t')}}
+
+// Attribute only applies to typedefs.
+svint8_t non_typedef_type __attribute__((arm_sve_vector_bits(N)));  // expected-error {{'arm_sve_vector_bits' attribute only applies to typedefs}}
+
+// Test that we can define non-local fixed-length SVE types (unsupported for
+// sizeless types).
+fixed_int8_t global_int8;
+fixed_bfloat16_t global_bfloat16;
+fixed_bool_t global_bool;
+
+extern fixed_int8_t extern_int8;
+extern fixed_bfloat16_t extern_bfloat16;
+extern fixed_bool_t extern_bool;
+
+static fixed_int8_t static_int8;
+static fixed_bfloat16_t static_bfloat16;
+static fixed_bool_t static_bool;
+
+fixed_int8_t *global_int8_ptr;
+extern fixed_int8_t *extern_int8_ptr;
+static fixed_int8_t *static_int8_ptr;
+__thread fixed_int8_t thread_int8;
+
+typedef fixed_int8_t int8_typedef;
+typedef fixed_int8_t *int8_ptr_typedef;
+
+// Test sized expressions
+int sizeof_int8 = sizeof(global_int8);
+int sizeof_int8_var = sizeof(*global_int8_ptr);
+int sizeof_int8_var_ptr = sizeof(global_int8_ptr);
+
+extern fixed_int8_t *extern_int8_ptr;
+
+int alignof_int8 = __alignof__(extern_int8);
+int alignof_int8_var = __alignof__(*extern_int8_ptr);
+int alignof_int8_var_ptr = __alignof__(extern_int8_ptr);
+
+void f(int c) {
+  fixed_int8_t fs8;
+  svint8_t ss8;
+
+  void *sel __attribute__((unused));
+  sel = c ? ss8 : fs8; // expected-error {{incompatible operand types ('svint8_t' (aka '__SVInt8_t') and 'fixed_int8_t' (aka '__SVInt8_t'))}}
+  sel = c ? fs8 : ss8; // expected-error {{incompatible operand types ('fixed_int8_t' (aka '__SVInt8_t') and 'svint8_t' (aka '__SVInt8_t'))}}
+}
+
+// --//
+// Sizeof
+
+#define VECTOR_SIZE ((N / 8))
+#define PRED_SIZE ((N / 64))
+
+_Static_assert(sizeof(fixed_int8_t) == VECTOR_SIZE, "");
+
+_Static_assert(sizeof(fixed_int16_t) == VECTOR_SIZE, "");
+_Static_assert(sizeof(fixed_int32_t) == VECTOR_SIZE, "");
+_Static_assert(sizeof(fixed_int64_t) == VECTOR_SIZE, "");
+
+_Static_assert(sizeof(fixed_uint8_t) == VECTOR_SIZE, "");
+_Static_assert(sizeof(fixed_uint16_t) == VECTOR_SIZE, "");
+_Static_assert(sizeof(fixed_uint32_t) == VECTOR_SIZE, "");
+_Static_assert(sizeof(fixed_uint64_t) == VECTOR_SIZE, "");
+
+_Static_assert(sizeof(fixed_float16_t) == VECTOR_SIZE, "");
+_Static_assert(sizeof(fixed_float32_t) == VECTOR_SIZE, "");
+_Static_assert(sizeof(fixed_float64_t) == VECTOR_SIZE, "");
+
+_Static_assert(sizeof(fixed_bfloat16_t) == VECTOR_SIZE, "");
+
+_Static_assert(sizeof(fixed_bool_t) == PRED_SIZE, "");
+
+// --//
+// Alignof
+
+#define VECTOR_ALIGN 16
+#define PRED_ALIGN 2
+
+_Static_assert(__alignof__(fixed_int8_t) == VECTOR_ALIGN, "");
+_Static_assert(__alignof__(fixed_int16_t) == VECTOR_ALIGN, "");
+_Static_assert(__alignof__(fixed_int32_t) == VECTOR_ALIGN, "");
+_Static_assert(__alignof__(fixed_int64_t) == VECTOR_ALIGN, "");
+
+_Static_assert(__alignof__(fixed_uint8_t) == VECTOR_ALIGN, "");
+_Static_assert(__alignof__(fixed_uint16_t) == VECTOR_ALIGN, "");
+_Static_assert(__alignof__(fixed_uint32_t) == VECTOR_ALIGN, "");
+_Static_assert(__a

[PATCH] D84144: [clangd] Remove TokenBuffer usage in TypeHierarchy

2020-07-20 Thread Aleksandr Platonov via Phabricator via cfe-commits
ArcsinX updated this revision to Diff 279180.
ArcsinX added a comment.

AdditionalFiles["header_in_preamble.h"] => HeaderCode


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84144

Files:
  clang-tools-extra/clangd/XRefs.cpp
  clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp

Index: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
===
--- clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
+++ clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
@@ -523,6 +523,33 @@
WithKind(SymbolKind::Struct), Children();
 }
 
+TEST(TypeHierarchy, Preamble) {
+  Annotations SourceAnnotations(R"cpp(
+struct Ch^ild : Parent {
+  int b;
+};)cpp");
+
+  Annotations HeaderInPreambleAnnotations(R"cpp(
+struct [[Parent]] {
+  int a;
+};)cpp");
+
+  TestTU TU = TestTU::withCode(SourceAnnotations.code());
+  TU.HeaderCode = HeaderInPreambleAnnotations.code().str();
+  auto AST = TU.build();
+
+  llvm::Optional Result = getTypeHierarchy(
+  AST, SourceAnnotations.point(), 1, TypeHierarchyDirection::Parents);
+
+  ASSERT_TRUE(Result);
+  EXPECT_THAT(
+  *Result,
+  AllOf(WithName("Child"),
+Parents(AllOf(WithName("Parent"),
+  SelectionRangeIs(HeaderInPreambleAnnotations.range()),
+  Parents();
+}
+
 SymbolID findSymbolIDByName(SymbolIndex *Index, llvm::StringRef Name,
 llvm::StringRef TemplateArgs = "") {
   SymbolID Result;
Index: clang-tools-extra/clangd/XRefs.cpp
===
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -1183,23 +1183,24 @@
 
 // FIXME(nridge): Reduce duplication between this function and declToSym().
 static llvm::Optional
-declToTypeHierarchyItem(ASTContext &Ctx, const NamedDecl &ND,
-const syntax::TokenBuffer &TB) {
+declToTypeHierarchyItem(ASTContext &Ctx, const NamedDecl &ND) {
   auto &SM = Ctx.getSourceManager();
   SourceLocation NameLoc = nameLocation(ND, Ctx.getSourceManager());
+  SourceLocation BeginLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getBeginLoc()));
+  SourceLocation EndLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getEndLoc()));
+  const auto DeclRange =
+  toHalfOpenFileRange(SM, Ctx.getLangOpts(), {BeginLoc, EndLoc});
+  if (!DeclRange)
+return llvm::None;
   auto FilePath =
   getCanonicalPath(SM.getFileEntryForID(SM.getFileID(NameLoc)), SM);
   auto TUPath = getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM);
   if (!FilePath || !TUPath)
 return llvm::None; // Not useful without a uri.
 
-  auto DeclToks = TB.spelledForExpanded(TB.expandedTokens(ND.getSourceRange()));
-  if (!DeclToks || DeclToks->empty())
-return llvm::None;
-
-  auto NameToks = TB.spelledForExpanded(TB.expandedTokens(NameLoc));
-  if (!NameToks || NameToks->empty())
-return llvm::None;
+  Position NameBegin = sourceLocToPosition(SM, NameLoc);
+  Position NameEnd = sourceLocToPosition(
+  SM, Lexer::getLocForEndOfToken(NameLoc, 0, SM, Ctx.getLangOpts()));
 
   index::SymbolInfo SymInfo = index::getSymbolInfo(&ND);
   // FIXME: this is not classifying constructors, destructors and operators
@@ -1210,12 +1211,9 @@
   THI.name = printName(Ctx, ND);
   THI.kind = SK;
   THI.deprecated = ND.isDeprecated();
-  THI.range = halfOpenToRange(
-  SM, syntax::Token::range(SM, DeclToks->front(), DeclToks->back())
-  .toCharRange(SM));
-  THI.selectionRange = halfOpenToRange(
-  SM, syntax::Token::range(SM, NameToks->front(), NameToks->back())
-  .toCharRange(SM));
+  THI.range = Range{sourceLocToPosition(SM, DeclRange->getBegin()),
+sourceLocToPosition(SM, DeclRange->getEnd())};
+  THI.selectionRange = Range{NameBegin, NameEnd};
   if (!THI.range.contains(THI.selectionRange)) {
 // 'selectionRange' must be contained in 'range', so in cases where clang
 // reports unrelated ranges we need to reconcile somehow.
@@ -1282,8 +1280,7 @@
 
 static void fillSuperTypes(const CXXRecordDecl &CXXRD, ASTContext &ASTCtx,
std::vector &SuperTypes,
-   RecursionProtectionSet &RPSet,
-   const syntax::TokenBuffer &TB) {
+   RecursionProtectionSet &RPSet) {
   // typeParents() will replace dependent template specializations
   // with their class template, so to avoid infinite recursion for
   // certain types of hierarchies, keep the templates encountered
@@ -1298,9 +1295,9 @@
 
   for (const CXXRecordDecl *ParentDecl : typeParents(&CXXRD)) {
 if (Optional ParentSym =
-declToTypeHierarchyItem(ASTCtx, *ParentDecl, TB)) {
+declToTypeHierarchyItem(ASTCtx, *ParentDecl)) {
   ParentSym->parents.emplace()

[PATCH] D83551: [PATCH 2/4][Sema][AArch64] Add semantics for arm_sve_vector_bits attribute

2020-07-20 Thread Cullen Rhodes via Phabricator via cfe-commits
c-rhodes marked an inline comment as done.
c-rhodes added inline comments.



Comment at: clang/include/clang/Basic/Attr.td:1541
 
+def ArmSveVectorBits128 : TypeAttr {
+  let Spellings = [];

c-rhodes wrote:
> aaron.ballman wrote:
> > c-rhodes wrote:
> > > aaron.ballman wrote:
> > > > c-rhodes wrote:
> > > > > c-rhodes wrote:
> > > > > > aaron.ballman wrote:
> > > > > > > aaron.ballman wrote:
> > > > > > > > c-rhodes wrote:
> > > > > > > > > sdesmalen wrote:
> > > > > > > > > > aaron.ballman wrote:
> > > > > > > > > > > sdesmalen wrote:
> > > > > > > > > > > > nit: Can you add a comment saying why these are 
> > > > > > > > > > > > undocumented (and have no spellings)
> > > > > > > > > > > Also, I think these are all missing `let SemaHandler = 
> > > > > > > > > > > 0;` and `let ASTNode = 0;`
> > > > > > > > > > > 
> > > > > > > > > > > Is there a reason why we need N different type attributes 
> > > > > > > > > > > instead of having a single type attribute which encodes 
> > > > > > > > > > > the N as an argument? I think this may simplify the patch 
> > > > > > > > > > > somewhat as you no longer need to switch over N as much.
> > > > > > > > > > > Is there a reason why we need N different type attributes 
> > > > > > > > > > > instead of having a single type attribute which encodes 
> > > > > > > > > > > the N as an argument?
> > > > > > > > > > AIUI this was a workaround for getting the value of N from 
> > > > > > > > > > an AttributedType, because this only has `getAttrKind` to 
> > > > > > > > > > return the attribute kind, but no way to get the 
> > > > > > > > > > corresponding argument/value. This seemed like a simple way 
> > > > > > > > > > to do that without having to create a new subclass for Type 
> > > > > > > > > > and having to support that in various places. Is the latter 
> > > > > > > > > > the approach you were thinking of? (or is there perhaps a 
> > > > > > > > > > simpler way?)
> > > > > > > > > > Also, I think these are all missing let SemaHandler = 0; 
> > > > > > > > > > and let ASTNode = 0;
> > > > > > > > > 
> > > > > > > > > Good to know. In SemaType I'm doing `CurType = 
> > > > > > > > > State.getAttributedType(A, CurType, CurType);` which gives an 
> > > > > > > > > `AttributedType` in the AST, should I still set `let ASTNode 
> > > > > > > > > = 0;` in this case?
> > > > > > > > > 
> > > > > > > > > > Is there a reason why we need N different type attributes 
> > > > > > > > > > instead of having a single type attribute which encodes the 
> > > > > > > > > > N as an argument?
> > > > > > > > > 
> > > > > > > > > As Sander mentioned, it seemed like the easiest solution, 
> > > > > > > > > interested to know if there's a better approach however
> > > > > > > > I was thinking specifically of creating a new `Type` subclass 
> > > > > > > > and supporting it rather than adding 5 new attributes that only 
> > > > > > > > vary by a bit-width (which means there's likely to be a 6th 
> > > > > > > > someday). It's not immediately clear to me whether that's a 
> > > > > > > > really big ask for little gain or not, though.
> > > > > > > Ah, you're right, we may still need `ASTNode` to be kept around 
> > > > > > > for that, good call.
> > > > > > > Also, I think these are all missing let SemaHandler = 0; and let 
> > > > > > > ASTNode = 0;
> > > > > > 
> > > > > > I've added `let SemaHandler = 0;` for the internal types and `let 
> > > > > > ASTNode = 0;` for the user-facing attr.
> > > > > > I was thinking specifically of creating a new Type subclass and 
> > > > > > supporting it rather than adding 5 new attributes that only vary by 
> > > > > > a bit-width (which means there's likely to be a 6th someday).
> > > > > 
> > > > > It would be nice if the `Attr` was accessible from the 
> > > > > `AttributedType`, similar to how it is for `Decl`s, so something like:
> > > > > ```  if (const auto *AT = T->getAs())
> > > > > if (ArmSveVectorBitsAttr *Attr = AT->getAttr())
> > > > >   unsigned Width = Attr->getNumBits();```
> > > > > Although I'm not sure if that makes sense or how easy it is. I do 
> > > > > agree adding 5 new attributes isn't ideal but for an initial 
> > > > > implementation it's nice and simple. Would you be ok with us 
> > > > > addressing this in a later patch?
> > > > > It would be nice if the Attr was accessible from the AttributedType, 
> > > > > similar to how it is for Decls, so something like:
> > > > 
> > > > You can do that through an `AttributedTypeLoc` object, which I think 
> > > > should be available from the situations you need to check this through 
> > > > a `TypeSourceInfo *` for the type. Then you can use 
> > > > `AttributedTypeLoc::getAttr()` to get the semantic attribute.
> > > > 
> > > > > Would you be ok with us addressing this in a later patch?
> > > > 
> > > > No and yes. It's a novel design to have a user-facing attribute that is 
> > > > never hooked up in the AST but is instead used to decide which 

[PATCH] D84136: [clangd] Fix visitation of ConceptSpecializationExpr in constrained-parameter

2020-07-20 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

just some drive-by comments.




Comment at: clang-tools-extra/clangd/unittests/FindTargetTests.cpp:433
+  )cpp";
+  Flags.push_back("-std=c++20");
+  EXPECT_DECLS("ConceptSpecializationExpr",

`Flags` is preserved between `EXPECT_DECLS` calls, so either use assignment or 
set it only once at the beginning of the test.



Comment at: clang/include/clang/AST/ExprConcepts.h:132
+// there may not be a template argument list.
+return ArgsAsWritten->RAngleLoc.isValid() ? ArgsAsWritten->RAngleLoc
+  : ConceptName.getEndLoc();

i think we should have some tests in clang, at least an ast-dump test in 
`clang/test/AST/` (for both cases) and possibly also in 
`clang/unittests/AST/SourceLocationTest.cpp`


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84136



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


[PATCH] D83912: [llvm-readobj] Update tests because of changes at llvm-readobj behavior

2020-07-20 Thread James Henderson via Phabricator via cfe-commits
jhenderson added a comment.

Hi @Elvina,

Just to let you know that I had to fix up three clang tests that were using the 
old behaviour too, prior to committing. I also noticed that you've got the 
stack the wrong way around - you needed to fix the tests before changing the 
behaviour in this case to avoid breaking the codebase, even if it was only 
briefly.

Anyway, these are now committed. I'll update the bug.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83912



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


[PATCH] D84144: [clangd] Remove TokenBuffer usage in TypeHierarchy

2020-07-20 Thread Aleksandr Platonov via Phabricator via cfe-commits
ArcsinX marked an inline comment as done.
ArcsinX added inline comments.



Comment at: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp:533
+
+  Annotations HeaderInPreambleAnnotations(R"cpp(
+struct Parent {

kadircet wrote:
> ArcsinX wrote:
> > kadircet wrote:
> > > this doesn't need to be an `Annotation` and sorry for missing it in the 
> > > first pass but since this only has a single header, you can actually do 
> > > something like:
> > > 
> > > ```
> > > TestTU TU = TestTU::withCode(SourceAnnotations.code());
> > > TU.HeaderCode = "struct Parent { int a; }";
> > > ```
> > > 
> > > and also drop the include directive in `SourceAnnotations` as 
> > > `TU.HeaderCode` is implicitly included.
> > Seems now I need it to check selection range.
> right, you need annotations for the range, but you still can get away with 
> just setting `TU.HeaderCode` instead of populating AdditionalFiles and 
> including the header in the source. but not that important.
Thanks. fixed


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84144



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


[PATCH] D84150: [clangd] Fix conversion from Windows UNC paths to file URI format.

2020-07-20 Thread Ilya Golovenko via Phabricator via cfe-commits
walrus created this revision.
Herald added subscribers: cfe-commits, kbobyrev, usaxena95, kadircet, arphaman, 
jkorous, MaskRay, ilya-biryukov.
Herald added a project: clang.

The fix improves handling of Windows UNC paths to align with Appendix E. 
Nonstandard Syntax Variations of RFC 8089. Before this fix it was difficult to 
use Windows UNC paths in compile_commands.json as such paths were converted to 
file URIs using 'file:authority/share/file.cpp' notation instead of 
recommended 'file://authority/share/file.cpp'. As an example, VS.Code cannot 
understand such file URIsm thus such features as go-to-definition, 
jump-to-file, hover tooltip, etc. stop working.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84150

Files:
  clang-tools-extra/clangd/URI.cpp
  clang-tools-extra/clangd/unittests/URITests.cpp

Index: clang-tools-extra/clangd/unittests/URITests.cpp
===
--- clang-tools-extra/clangd/unittests/URITests.cpp
+++ clang-tools-extra/clangd/unittests/URITests.cpp
@@ -76,6 +76,16 @@
 #endif
 }
 
+TEST(URITest, CreateUNC) {
+#ifdef _WIN32
+  EXPECT_THAT(createOrDie("test.org\\x\\y\\z"), "file://test.org/x/y/z");
+  EXPECT_THAT(createOrDie("10.0.0.1\\x\\y\\z"), "file://10.0.0.1/x/y/z");
+#else
+  EXPECT_THAT(createOrDie("//test.org/x/y/z"), "file://test.org/x/y/z");
+  EXPECT_THAT(createOrDie("//10.0.0.1/x/y/z"), "file://10.0.0.1/x/y/z");
+#endif
+}
+
 TEST(URITest, FailedCreate) {
   EXPECT_ERROR(URI::create("/x/y/z", "no"));
   // Path has to be absolute.
@@ -127,15 +137,29 @@
   EXPECT_THAT(resolveOrDie(parseOrDie("file:///c:/x/y/z")), "c:\\x\\y\\z");
 #else
   EXPECT_EQ(resolveOrDie(parseOrDie("file:/a/b/c")), "/a/b/c");
-  EXPECT_EQ(resolveOrDie(parseOrDie("file://auth/a/b/c")), "/a/b/c");
+  EXPECT_EQ(resolveOrDie(parseOrDie("file://auth/a/b/c")), "//auth/a/b/c");
   EXPECT_THAT(resolveOrDie(parseOrDie("file://au%3dth/%28x%29/y/%20z")),
-  "/(x)/y/ z");
+  "//au=th/(x)/y/ z");
   EXPECT_THAT(resolveOrDie(parseOrDie("file:///c:/x/y/z")), "c:/x/y/z");
 #endif
   EXPECT_EQ(resolveOrDie(parseOrDie("unittest:///a"), testPath("x")),
 testPath("a"));
 }
 
+TEST(URITest, ResolveUNC) {
+#ifdef _WIN32
+  EXPECT_THAT(resolveOrDie(parseOrDie("file://example.com/x/y/z")),
+  "example.com\\x\\y\\z");
+  EXPECT_THAT(resolveOrDie(parseOrDie("file://127.0.0.1/x/y/z")),
+  "127.0.0.1\\x\\y\\z");
+#else
+  EXPECT_THAT(resolveOrDie(parseOrDie("file://example.com/x/y/z")),
+  "//example.com/x/y/z");
+  EXPECT_THAT(resolveOrDie(parseOrDie("file://127.0.0.1/x/y/z")),
+  "//127.0.0.1/x/y/z");
+#endif
+}
+
 std::string resolvePathOrDie(llvm::StringRef AbsPath,
  llvm::StringRef HintPath = "") {
   auto Path = URI::resolvePath(AbsPath, HintPath);
Index: clang-tools-extra/clangd/URI.cpp
===
--- clang-tools-extra/clangd/URI.cpp
+++ clang-tools-extra/clangd/URI.cpp
@@ -26,6 +26,15 @@
  llvm::inconvertibleErrorCode());
 }
 
+bool hasDriveLetter(llvm::StringRef Path) {
+  return Path.size() > 1 && llvm::isAlpha(Path[0]) && Path[1] == ':';
+}
+
+bool isNetworkPath(llvm::StringRef Name) {
+  llvm::StringRef Sep = llvm::sys::path::get_separator();
+  return Name.consume_front(Sep) && Name.consume_front(Sep) && !Name.empty();
+}
+
 /// This manages file paths in the file system. All paths in the scheme
 /// are absolute (with leading '/').
 /// Note that this scheme is hardcoded into the library and not registered in
@@ -33,28 +42,39 @@
 class FileSystemScheme : public URIScheme {
 public:
   llvm::Expected
-  getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body,
+  getAbsolutePath(llvm::StringRef Authority, llvm::StringRef Body,
   llvm::StringRef /*HintPath*/) const override {
 if (!Body.startswith("/"))
   return make_string_error("File scheme: expect body to be an absolute "
"path starting with '/': " +
Body);
+llvm::SmallString<128> Path;
+// For Windows UNC paths e.g. \\server\share
+if (!Authority.empty())
+  ("//" + Authority).toVector(Path);
 // For Windows paths e.g. /X:
-if (Body.size() > 2 && Body[0] == '/' && Body[2] == ':')
+if (hasDriveLetter(Body.substr(1)))
   Body.consume_front("/");
-llvm::SmallVector Path(Body.begin(), Body.end());
+Path.append(Body);
 llvm::sys::path::native(Path);
-return std::string(Path.begin(), Path.end());
+return std::string(Path);
   }
 
   llvm::Expected
   uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
 std::string Body;
+llvm::StringRef Authority;
+llvm::StringRef Root = llvm::sys::path::root_name(AbsolutePath);
+// For Windows UNC paths e.g. \\server\share
+if (isNetworkPath(

[PATCH] D84150: [clangd] Fix conversion from Windows UNC paths to file URI format.

2020-07-20 Thread Ilya Golovenko via Phabricator via cfe-commits
ilya-golovenko added a comment.

This is an attempt to improve handling of Windows UNC paths in clangd. Any 
feedback is appreciated.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84150



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


[Differential] D84009: [Syntax] expose API for expansions overlapping a spelled token range.

2020-07-20 Thread Sam McCall 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 rGf0ab336e7455: [Syntax] expose API for expansions overlapping 
a spelled token range. (authored by sammccall).

Repository:
  rG LLVM Github Monorepo

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


  https://reviews.llvm.org/D84009

Files:
  clang/include/clang/Tooling/Syntax/Tokens.h
  clang/lib/Tooling/Syntax/Tokens.cpp
  clang/unittests/Tooling/Syntax/TokensTest.cpp

Index: clang/unittests/Tooling/Syntax/TokensTest.cpp
===
--- clang/unittests/Tooling/Syntax/TokensTest.cpp
+++ clang/unittests/Tooling/Syntax/TokensTest.cpp
@@ -53,6 +53,7 @@
 using namespace clang::syntax;
 
 using llvm::ValueIs;
+using ::testing::_;
 using ::testing::AllOf;
 using ::testing::Contains;
 using ::testing::ElementsAre;
@@ -755,7 +756,7 @@
   EXPECT_THAT(Buffer.expandedTokens(SourceRange()), testing::IsEmpty());
 }
 
-TEST_F(TokenBufferTest, ExpansionStartingAt) {
+TEST_F(TokenBufferTest, ExpansionsOverlapping) {
   // Object-like macro expansions.
   recordTokens(R"cpp(
 #define FOO 3+4
@@ -763,17 +764,25 @@
 int b = FOO 2;
   )cpp");
 
-  llvm::ArrayRef Foo1 = findSpelled("FOO 1").drop_back();
+  llvm::ArrayRef Foo1 = findSpelled("FOO 1");
   EXPECT_THAT(
   Buffer.expansionStartingAt(Foo1.data()),
-  ValueIs(IsExpansion(SameRange(Foo1),
+  ValueIs(IsExpansion(SameRange(Foo1.drop_back()),
   SameRange(findExpanded("3 + 4 1").drop_back();
+  EXPECT_THAT(
+  Buffer.expansionsOverlapping(Foo1),
+  ElementsAre(IsExpansion(SameRange(Foo1.drop_back()),
+  SameRange(findExpanded("3 + 4 1").drop_back();
 
-  llvm::ArrayRef Foo2 = findSpelled("FOO 2").drop_back();
+  llvm::ArrayRef Foo2 = findSpelled("FOO 2");
   EXPECT_THAT(
   Buffer.expansionStartingAt(Foo2.data()),
-  ValueIs(IsExpansion(SameRange(Foo2),
+  ValueIs(IsExpansion(SameRange(Foo2.drop_back()),
   SameRange(findExpanded("3 + 4 2").drop_back();
+  EXPECT_THAT(Buffer.expansionsOverlapping(
+  llvm::makeArrayRef(Foo1.begin(), Foo2.end())),
+  ElementsAre(IsExpansion(SameRange(Foo1.drop_back()), _),
+  IsExpansion(SameRange(Foo2.drop_back()), _)));
 
   // Function-like macro expansions.
   recordTokens(R"cpp(
@@ -798,6 +807,11 @@
   for (const auto &T : ID2.drop_front())
 EXPECT_EQ(Buffer.expansionStartingAt(&T), llvm::None);
 
+  EXPECT_THAT(Buffer.expansionsOverlapping(llvm::makeArrayRef(
+  findSpelled("1 + 2").data(), findSpelled("4").data())),
+  ElementsAre(IsExpansion(SameRange(ID1), _),
+  IsExpansion(SameRange(ID2), _)));
+
   // PP directives.
   recordTokens(R"cpp(
 #define FOO 1
@@ -823,6 +837,11 @@
   // Only the first spelled token should be found.
   for (const auto &T : PragmaOnce.drop_front())
 EXPECT_EQ(Buffer.expansionStartingAt(&T), llvm::None);
+
+  EXPECT_THAT(
+  Buffer.expansionsOverlapping(findSpelled("FOO ; # pragma")),
+  ElementsAre(IsExpansion(SameRange(findSpelled("FOO ;").drop_back()), _),
+  IsExpansion(SameRange(PragmaOnce), _)));
 }
 
 TEST_F(TokenBufferTest, TokensToFileRange) {
Index: clang/lib/Tooling/Syntax/Tokens.cpp
===
--- clang/lib/Tooling/Syntax/Tokens.cpp
+++ clang/lib/Tooling/Syntax/Tokens.cpp
@@ -249,22 +249,7 @@
 TokenBuffer::expandedForSpelled(llvm::ArrayRef Spelled) const {
   if (Spelled.empty())
 return {};
-  assert(Spelled.front().location().isFileID());
-
-  auto FID = sourceManager().getFileID(Spelled.front().location());
-  auto It = Files.find(FID);
-  assert(It != Files.end());
-
-  const MarkedFile &File = It->second;
-  // `Spelled` must be a subrange of `File.SpelledTokens`.
-  assert(File.SpelledTokens.data() <= Spelled.data());
-  assert(&Spelled.back() <=
- File.SpelledTokens.data() + File.SpelledTokens.size());
-#ifndef NDEBUG
-  auto T1 = Spelled.back().location();
-  auto T2 = File.SpelledTokens.back().location();
-  assert(T1 == T2 || sourceManager().isBeforeInTranslationUnit(T1, T2));
-#endif
+  const auto &File = fileForSpelled(Spelled);
 
   auto *FrontMapping = mappingStartingBeforeSpelled(File, &Spelled.front());
   unsigned SpelledFrontI = &Spelled.front() - File.SpelledTokens.data();
@@ -395,16 +380,39 @@
   : LastSpelled + 1);
 }
 
+TokenBuffer::Expansion TokenBuffer::makeExpansion(const MarkedFile &F,
+  const Mapping &M) const {
+  Expansion E;
+  E.Spelled = llvm::makeArrayRef(F.SpelledTokens.data() + M.BeginSpelled,
+ F.SpelledTokens.data() + M.EndSpelled);
+  E.Expanded = llvm::makeArrayRef(ExpandedTokens.data() + M.BeginExpanded,
+ 

[clang] f0ab336 - [Syntax] expose API for expansions overlapping a spelled token range.

2020-07-20 Thread Sam McCall via cfe-commits

Author: Sam McCall
Date: 2020-07-20T14:48:12+02:00
New Revision: f0ab336e745505f3bb7e8570f12937cf0fbc11aa

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

LOG: [Syntax] expose API for expansions overlapping a spelled token range.

Summary:
This allows efficiently accessing all expansions (without iterating over each
token and searching), and also identifying tokens within a range that are
affected by the preprocessor (which is how clangd will use it).

Subscribers: ilya-biryukov, kadircet, usaxena95, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D84009

Added: 


Modified: 
clang/include/clang/Tooling/Syntax/Tokens.h
clang/lib/Tooling/Syntax/Tokens.cpp
clang/unittests/Tooling/Syntax/TokensTest.cpp

Removed: 




diff  --git a/clang/include/clang/Tooling/Syntax/Tokens.h 
b/clang/include/clang/Tooling/Syntax/Tokens.h
index a7f9369ddfff..6e253abd6b3f 100644
--- a/clang/include/clang/Tooling/Syntax/Tokens.h
+++ b/clang/include/clang/Tooling/Syntax/Tokens.h
@@ -275,6 +275,10 @@ class TokenBuffer {
   /// macro expands to.
   llvm::Optional
   expansionStartingAt(const syntax::Token *Spelled) const;
+  /// Returns all expansions (partially) expanded from the specified tokens.
+  /// This is the expansions whose Spelled range intersects \p Spelled.
+  std::vector
+  expansionsOverlapping(llvm::ArrayRef Spelled) const;
 
   /// Lexed tokens of a file before preprocessing. E.g. for the following input
   /// #define DECL(name) int name = 10
@@ -352,6 +356,12 @@ class TokenBuffer {
   mappingStartingBeforeSpelled(const MarkedFile &F,
const syntax::Token *Spelled);
 
+  /// Convert a private Mapping to a public Expansion.
+  Expansion makeExpansion(const MarkedFile &, const Mapping &) const;
+  /// Returns the file that the Spelled tokens are taken from.
+  /// Asserts that they are non-empty, from a tracked file, and in-bounds.
+  const MarkedFile &fileForSpelled(llvm::ArrayRef Spelled) 
const;
+
   /// Token stream produced after preprocessing, conceputally this captures the
   /// same stream as 'clang -E' (excluding the preprocessor directives like
   /// #file, etc.).

diff  --git a/clang/lib/Tooling/Syntax/Tokens.cpp 
b/clang/lib/Tooling/Syntax/Tokens.cpp
index c6b904822b8b..a83cc2d52861 100644
--- a/clang/lib/Tooling/Syntax/Tokens.cpp
+++ b/clang/lib/Tooling/Syntax/Tokens.cpp
@@ -249,22 +249,7 @@ llvm::SmallVector, 1>
 TokenBuffer::expandedForSpelled(llvm::ArrayRef Spelled) const {
   if (Spelled.empty())
 return {};
-  assert(Spelled.front().location().isFileID());
-
-  auto FID = sourceManager().getFileID(Spelled.front().location());
-  auto It = Files.find(FID);
-  assert(It != Files.end());
-
-  const MarkedFile &File = It->second;
-  // `Spelled` must be a subrange of `File.SpelledTokens`.
-  assert(File.SpelledTokens.data() <= Spelled.data());
-  assert(&Spelled.back() <=
- File.SpelledTokens.data() + File.SpelledTokens.size());
-#ifndef NDEBUG
-  auto T1 = Spelled.back().location();
-  auto T2 = File.SpelledTokens.back().location();
-  assert(T1 == T2 || sourceManager().isBeforeInTranslationUnit(T1, T2));
-#endif
+  const auto &File = fileForSpelled(Spelled);
 
   auto *FrontMapping = mappingStartingBeforeSpelled(File, &Spelled.front());
   unsigned SpelledFrontI = &Spelled.front() - File.SpelledTokens.data();
@@ -395,16 +380,39 @@ 
TokenBuffer::spelledForExpanded(llvm::ArrayRef Expanded) const {
   : LastSpelled + 1);
 }
 
+TokenBuffer::Expansion TokenBuffer::makeExpansion(const MarkedFile &F,
+  const Mapping &M) const {
+  Expansion E;
+  E.Spelled = llvm::makeArrayRef(F.SpelledTokens.data() + M.BeginSpelled,
+ F.SpelledTokens.data() + M.EndSpelled);
+  E.Expanded = llvm::makeArrayRef(ExpandedTokens.data() + M.BeginExpanded,
+  ExpandedTokens.data() + M.EndExpanded);
+  return E;
+}
+
+const TokenBuffer::MarkedFile &
+TokenBuffer::fileForSpelled(llvm::ArrayRef Spelled) const {
+  assert(!Spelled.empty());
+  assert(Spelled.front().location().isFileID() && "not a spelled token");
+  auto FileIt = Files.find(SourceMgr->getFileID(Spelled.front().location()));
+  assert(FileIt != Files.end() && "file not tracked by token buffer");
+  const auto &File = FileIt->second;
+  assert(File.SpelledTokens.data() <= Spelled.data() &&
+ Spelled.end() <=
+ (File.SpelledTokens.data() + File.SpelledTokens.size()) &&
+ "Tokens not in spelled range");
+#ifndef NDEBUG
+  auto T1 = Spelled.back().location();
+  auto T2 = File.SpelledTokens.back().location();
+  assert(T1 == T2 || sourceManager().isBeforeInTranslationUnit(T1, T2));
+#endif
+  return File;
+

[PATCH] D84009: [Syntax] expose API for expansions overlapping a spelled token range.

2020-07-20 Thread Sam McCall via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGf0ab336e7455: [Syntax] expose API for expansions overlapping 
a spelled token range. (authored by sammccall).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84009

Files:
  clang/include/clang/Tooling/Syntax/Tokens.h
  clang/lib/Tooling/Syntax/Tokens.cpp
  clang/unittests/Tooling/Syntax/TokensTest.cpp

Index: clang/unittests/Tooling/Syntax/TokensTest.cpp
===
--- clang/unittests/Tooling/Syntax/TokensTest.cpp
+++ clang/unittests/Tooling/Syntax/TokensTest.cpp
@@ -53,6 +53,7 @@
 using namespace clang::syntax;
 
 using llvm::ValueIs;
+using ::testing::_;
 using ::testing::AllOf;
 using ::testing::Contains;
 using ::testing::ElementsAre;
@@ -755,7 +756,7 @@
   EXPECT_THAT(Buffer.expandedTokens(SourceRange()), testing::IsEmpty());
 }
 
-TEST_F(TokenBufferTest, ExpansionStartingAt) {
+TEST_F(TokenBufferTest, ExpansionsOverlapping) {
   // Object-like macro expansions.
   recordTokens(R"cpp(
 #define FOO 3+4
@@ -763,17 +764,25 @@
 int b = FOO 2;
   )cpp");
 
-  llvm::ArrayRef Foo1 = findSpelled("FOO 1").drop_back();
+  llvm::ArrayRef Foo1 = findSpelled("FOO 1");
   EXPECT_THAT(
   Buffer.expansionStartingAt(Foo1.data()),
-  ValueIs(IsExpansion(SameRange(Foo1),
+  ValueIs(IsExpansion(SameRange(Foo1.drop_back()),
   SameRange(findExpanded("3 + 4 1").drop_back();
+  EXPECT_THAT(
+  Buffer.expansionsOverlapping(Foo1),
+  ElementsAre(IsExpansion(SameRange(Foo1.drop_back()),
+  SameRange(findExpanded("3 + 4 1").drop_back();
 
-  llvm::ArrayRef Foo2 = findSpelled("FOO 2").drop_back();
+  llvm::ArrayRef Foo2 = findSpelled("FOO 2");
   EXPECT_THAT(
   Buffer.expansionStartingAt(Foo2.data()),
-  ValueIs(IsExpansion(SameRange(Foo2),
+  ValueIs(IsExpansion(SameRange(Foo2.drop_back()),
   SameRange(findExpanded("3 + 4 2").drop_back();
+  EXPECT_THAT(Buffer.expansionsOverlapping(
+  llvm::makeArrayRef(Foo1.begin(), Foo2.end())),
+  ElementsAre(IsExpansion(SameRange(Foo1.drop_back()), _),
+  IsExpansion(SameRange(Foo2.drop_back()), _)));
 
   // Function-like macro expansions.
   recordTokens(R"cpp(
@@ -798,6 +807,11 @@
   for (const auto &T : ID2.drop_front())
 EXPECT_EQ(Buffer.expansionStartingAt(&T), llvm::None);
 
+  EXPECT_THAT(Buffer.expansionsOverlapping(llvm::makeArrayRef(
+  findSpelled("1 + 2").data(), findSpelled("4").data())),
+  ElementsAre(IsExpansion(SameRange(ID1), _),
+  IsExpansion(SameRange(ID2), _)));
+
   // PP directives.
   recordTokens(R"cpp(
 #define FOO 1
@@ -823,6 +837,11 @@
   // Only the first spelled token should be found.
   for (const auto &T : PragmaOnce.drop_front())
 EXPECT_EQ(Buffer.expansionStartingAt(&T), llvm::None);
+
+  EXPECT_THAT(
+  Buffer.expansionsOverlapping(findSpelled("FOO ; # pragma")),
+  ElementsAre(IsExpansion(SameRange(findSpelled("FOO ;").drop_back()), _),
+  IsExpansion(SameRange(PragmaOnce), _)));
 }
 
 TEST_F(TokenBufferTest, TokensToFileRange) {
Index: clang/lib/Tooling/Syntax/Tokens.cpp
===
--- clang/lib/Tooling/Syntax/Tokens.cpp
+++ clang/lib/Tooling/Syntax/Tokens.cpp
@@ -249,22 +249,7 @@
 TokenBuffer::expandedForSpelled(llvm::ArrayRef Spelled) const {
   if (Spelled.empty())
 return {};
-  assert(Spelled.front().location().isFileID());
-
-  auto FID = sourceManager().getFileID(Spelled.front().location());
-  auto It = Files.find(FID);
-  assert(It != Files.end());
-
-  const MarkedFile &File = It->second;
-  // `Spelled` must be a subrange of `File.SpelledTokens`.
-  assert(File.SpelledTokens.data() <= Spelled.data());
-  assert(&Spelled.back() <=
- File.SpelledTokens.data() + File.SpelledTokens.size());
-#ifndef NDEBUG
-  auto T1 = Spelled.back().location();
-  auto T2 = File.SpelledTokens.back().location();
-  assert(T1 == T2 || sourceManager().isBeforeInTranslationUnit(T1, T2));
-#endif
+  const auto &File = fileForSpelled(Spelled);
 
   auto *FrontMapping = mappingStartingBeforeSpelled(File, &Spelled.front());
   unsigned SpelledFrontI = &Spelled.front() - File.SpelledTokens.data();
@@ -395,16 +380,39 @@
   : LastSpelled + 1);
 }
 
+TokenBuffer::Expansion TokenBuffer::makeExpansion(const MarkedFile &F,
+  const Mapping &M) const {
+  Expansion E;
+  E.Spelled = llvm::makeArrayRef(F.SpelledTokens.data() + M.BeginSpelled,
+ F.SpelledTokens.data() + M.EndSpelled);
+  E.Expanded = llvm::makeArrayRef(ExpandedTokens.data() + M.BeginExpanded,
+  ExpandedTokens.data() + M.EndE

[PATCH] D83652: Merge some of the PCH object support with modular codegen

2020-07-20 Thread Hans Wennborg via Phabricator via cfe-commits
hans added a comment.

In D83652#2159585 , @dblaikie wrote:

> @hans - could you perhaps give me a quick summary of commands I could use to 
> test this feature in Chromium (or anything else you might suggest) on a Linux 
> box? I don't have a Windows machine, or any projects that use PCH. (or if 
> you'd be willing to test this, that'd be great - see if the PCH object file 
> has the same symbols before/after this patch)


I tried to do this today, and then realized Chromium's PCH .obj files are 
basically empty these days. Back when I did D48426 
, dllexported inline functions were emitted in 
the pch .obj file, but then Chromium started using /Zc:dllexportInlines- which 
means we don't dllexport inlines anymore, and even if I remove that flag we've 
moved to only including libc++ headers in our PCH, and nothing is dllexport 
there.

After applying and building with your patch, the PCH .obj files look the same.

I also verified that building one of Chromium's test targets succeeds with this 
patch.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83652



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


[clang-tools-extra] 72f2fb1 - [clangd] Exclude preprocessed-to-nothing tokens from selection

2020-07-20 Thread Sam McCall via cfe-commits

Author: Sam McCall
Date: 2020-07-20T14:50:12+02:00
New Revision: 72f2fb1db4ea19b543265ceba67964174848a875

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

LOG: [clangd] Exclude preprocessed-to-nothing tokens from selection

This prevents selection of empty preprocessor entities (like #define directives,
or text in disabled sections) creating a selection in the parent element.

Summary: Based on D83508 by Aleksandr Platonov.

Reviewers: ArcsinX, kadircet

Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D84012

Added: 


Modified: 
clang-tools-extra/clangd/Selection.cpp
clang-tools-extra/clangd/unittests/SelectionTests.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Selection.cpp 
b/clang-tools-extra/clangd/Selection.cpp
index e94a3ca5a0c3..d1677e216ffc 100644
--- a/clang-tools-extra/clangd/Selection.cpp
+++ b/clang-tools-extra/clangd/Selection.cpp
@@ -220,14 +220,26 @@ class SelectionTester {
 SelFirst, AllSpelledTokens.end(), [&](const syntax::Token &Tok) {
   return SM.getFileOffset(Tok.location()) < SelEnd;
 });
+auto Sel = llvm::makeArrayRef(SelFirst, SelLimit);
+// Find which of these are preprocessed to nothing and should be ignored.
+std::vector PPIgnored(Sel.size(), false);
+for (const syntax::TokenBuffer::Expansion &X :
+ Buf.expansionsAffecting(Sel)) {
+  if (X.Expanded.empty()) {
+for (const syntax::Token &Tok : X.Spelled) {
+  if (&Tok >= SelFirst && &Tok < SelLimit)
+PPIgnored[&Tok - SelFirst] = true;
+}
+  }
+}
 // Precompute selectedness and offset for selected spelled tokens.
-for (const syntax::Token *T = SelFirst; T < SelLimit; ++T) {
-  if (shouldIgnore(*T))
+for (unsigned I = 0; I < Sel.size(); ++I) {
+  if (shouldIgnore(Sel[I]) || PPIgnored[I])
 continue;
   SpelledTokens.emplace_back();
   Tok &S = SpelledTokens.back();
-  S.Offset = SM.getFileOffset(T->location());
-  if (S.Offset >= SelBegin && S.Offset + T->length() <= SelEnd)
+  S.Offset = SM.getFileOffset(Sel[I].location());
+  if (S.Offset >= SelBegin && S.Offset + Sel[I].length() <= SelEnd)
 S.Selected = SelectionTree::Complete;
   else
 S.Selected = SelectionTree::Partial;

diff  --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp 
b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
index 051580ba6e49..6a9f587a7768 100644
--- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -177,11 +177,29 @@ TEST(SelectionTest, CommonAncestor) {
   {
   R"cpp(
 void foo();
-#define CALL_FUNCTION(X) X^()^
+#^define CALL_FUNCTION(X) X(^)
 void bar() { CALL_FUNCTION(foo); }
   )cpp",
   nullptr,
   },
+  {
+  R"cpp(
+void foo();
+#define CALL_FUNCTION(X) X()
+void bar() { CALL_FUNCTION(foo^)^; }
+  )cpp",
+  nullptr,
+  },
+  {
+  R"cpp(
+namespace ns {
+#if 0
+void fo^o() {}
+#endif
+}
+  )cpp",
+  nullptr,
+  },
   {
   R"cpp(
 struct S { S(const char*); };
@@ -388,7 +406,8 @@ TEST(SelectionTest, CommonAncestor) {
 void test(S2 s2) {
   s2[[-^>]]f();
 }
-  )cpp", "DeclRefExpr"} // DeclRefExpr to the "operator->" method.
+  )cpp",
+   "DeclRefExpr"} // DeclRefExpr to the "operator->" method.
   };
   for (const Case &C : Cases) {
 trace::TestTracer Tracer;
@@ -538,7 +557,7 @@ TEST(SelectionTest, IncludedFile) {
   auto AST = TU.build();
   auto T = makeSelectionTree(Case, AST);
 
-  EXPECT_EQ("WhileStmt", T.commonAncestor()->kind());
+  EXPECT_EQ(nullptr, T.commonAncestor());
 }
 
 TEST(SelectionTest, MacroArgExpansion) {



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


[Differential] D84012: [clangd] Exclude preprocessed-to-nothing tokens from selection

2020-07-20 Thread Sam McCall via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG72f2fb1db4ea: [clangd] Exclude preprocessed-to-nothing 
tokens from selection (authored by sammccall).

Repository:
  rG LLVM Github Monorepo

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


  https://reviews.llvm.org/D84012

Files:
  clang-tools-extra/clangd/Selection.cpp
  clang-tools-extra/clangd/unittests/SelectionTests.cpp



Index: clang-tools-extra/clangd/unittests/SelectionTests.cpp
===
--- clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -177,11 +177,29 @@
   {
   R"cpp(
 void foo();
-#define CALL_FUNCTION(X) X^()^
+#^define CALL_FUNCTION(X) X(^)
 void bar() { CALL_FUNCTION(foo); }
   )cpp",
   nullptr,
   },
+  {
+  R"cpp(
+void foo();
+#define CALL_FUNCTION(X) X()
+void bar() { CALL_FUNCTION(foo^)^; }
+  )cpp",
+  nullptr,
+  },
+  {
+  R"cpp(
+namespace ns {
+#if 0
+void fo^o() {}
+#endif
+}
+  )cpp",
+  nullptr,
+  },
   {
   R"cpp(
 struct S { S(const char*); };
@@ -388,7 +406,8 @@
 void test(S2 s2) {
   s2[[-^>]]f();
 }
-  )cpp", "DeclRefExpr"} // DeclRefExpr to the "operator->" method.
+  )cpp",
+   "DeclRefExpr"} // DeclRefExpr to the "operator->" method.
   };
   for (const Case &C : Cases) {
 trace::TestTracer Tracer;
@@ -538,7 +557,7 @@
   auto AST = TU.build();
   auto T = makeSelectionTree(Case, AST);
 
-  EXPECT_EQ("WhileStmt", T.commonAncestor()->kind());
+  EXPECT_EQ(nullptr, T.commonAncestor());
 }
 
 TEST(SelectionTest, MacroArgExpansion) {
Index: clang-tools-extra/clangd/Selection.cpp
===
--- clang-tools-extra/clangd/Selection.cpp
+++ clang-tools-extra/clangd/Selection.cpp
@@ -220,14 +220,26 @@
 SelFirst, AllSpelledTokens.end(), [&](const syntax::Token &Tok) {
   return SM.getFileOffset(Tok.location()) < SelEnd;
 });
+auto Sel = llvm::makeArrayRef(SelFirst, SelLimit);
+// Find which of these are preprocessed to nothing and should be ignored.
+std::vector PPIgnored(Sel.size(), false);
+for (const syntax::TokenBuffer::Expansion &X :
+ Buf.expansionsAffecting(Sel)) {
+  if (X.Expanded.empty()) {
+for (const syntax::Token &Tok : X.Spelled) {
+  if (&Tok >= SelFirst && &Tok < SelLimit)
+PPIgnored[&Tok - SelFirst] = true;
+}
+  }
+}
 // Precompute selectedness and offset for selected spelled tokens.
-for (const syntax::Token *T = SelFirst; T < SelLimit; ++T) {
-  if (shouldIgnore(*T))
+for (unsigned I = 0; I < Sel.size(); ++I) {
+  if (shouldIgnore(Sel[I]) || PPIgnored[I])
 continue;
   SpelledTokens.emplace_back();
   Tok &S = SpelledTokens.back();
-  S.Offset = SM.getFileOffset(T->location());
-  if (S.Offset >= SelBegin && S.Offset + T->length() <= SelEnd)
+  S.Offset = SM.getFileOffset(Sel[I].location());
+  if (S.Offset >= SelBegin && S.Offset + Sel[I].length() <= SelEnd)
 S.Selected = SelectionTree::Complete;
   else
 S.Selected = SelectionTree::Partial;


Index: clang-tools-extra/clangd/unittests/SelectionTests.cpp
===
--- clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -177,11 +177,29 @@
   {
   R"cpp(
 void foo();
-#define CALL_FUNCTION(X) X^()^
+#^define CALL_FUNCTION(X) X(^)
 void bar() { CALL_FUNCTION(foo); }
   )cpp",
   nullptr,
   },
+  {
+  R"cpp(
+void foo();
+#define CALL_FUNCTION(X) X()
+void bar() { CALL_FUNCTION(foo^)^; }
+  )cpp",
+  nullptr,
+  },
+  {
+  R"cpp(
+namespace ns {
+#if 0
+void fo^o() {}
+#endif
+}
+  )cpp",
+  nullptr,
+  },
   {
   R"cpp(
 struct S { S(const char*); };
@@ -388,7 +406,8 @@
 void test(S2 s2) {
   s2[[-^>]]f();
 }
-  )cpp", "DeclRefExpr"} // DeclRefExpr to the "operator->" method.
+  )cpp",
+   "DeclRefExpr"} // DeclRefExpr to the "operator->" method.
   };
   for (const Case &C : Cases) {
 trace::TestTracer Tracer;
@@ -538,7 +557,7 @@
   auto AST = TU.build();
   auto T = makeSelectionTree(Case, AST);
 
-  EXPECT_EQ("WhileStmt", T.commonAncestor()->kind());
+  EXPECT_EQ(nullptr, T.commonAncestor());
 }
 
 TEST(SelectionTest, MacroArgExpansion)

[PATCH] D84012: [clangd] Exclude preprocessed-to-nothing tokens from selection

2020-07-20 Thread Sam McCall via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG72f2fb1db4ea: [clangd] Exclude preprocessed-to-nothing 
tokens from selection (authored by sammccall).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84012

Files:
  clang-tools-extra/clangd/Selection.cpp
  clang-tools-extra/clangd/unittests/SelectionTests.cpp


Index: clang-tools-extra/clangd/unittests/SelectionTests.cpp
===
--- clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -177,11 +177,29 @@
   {
   R"cpp(
 void foo();
-#define CALL_FUNCTION(X) X^()^
+#^define CALL_FUNCTION(X) X(^)
 void bar() { CALL_FUNCTION(foo); }
   )cpp",
   nullptr,
   },
+  {
+  R"cpp(
+void foo();
+#define CALL_FUNCTION(X) X()
+void bar() { CALL_FUNCTION(foo^)^; }
+  )cpp",
+  nullptr,
+  },
+  {
+  R"cpp(
+namespace ns {
+#if 0
+void fo^o() {}
+#endif
+}
+  )cpp",
+  nullptr,
+  },
   {
   R"cpp(
 struct S { S(const char*); };
@@ -388,7 +406,8 @@
 void test(S2 s2) {
   s2[[-^>]]f();
 }
-  )cpp", "DeclRefExpr"} // DeclRefExpr to the "operator->" method.
+  )cpp",
+   "DeclRefExpr"} // DeclRefExpr to the "operator->" method.
   };
   for (const Case &C : Cases) {
 trace::TestTracer Tracer;
@@ -538,7 +557,7 @@
   auto AST = TU.build();
   auto T = makeSelectionTree(Case, AST);
 
-  EXPECT_EQ("WhileStmt", T.commonAncestor()->kind());
+  EXPECT_EQ(nullptr, T.commonAncestor());
 }
 
 TEST(SelectionTest, MacroArgExpansion) {
Index: clang-tools-extra/clangd/Selection.cpp
===
--- clang-tools-extra/clangd/Selection.cpp
+++ clang-tools-extra/clangd/Selection.cpp
@@ -220,14 +220,26 @@
 SelFirst, AllSpelledTokens.end(), [&](const syntax::Token &Tok) {
   return SM.getFileOffset(Tok.location()) < SelEnd;
 });
+auto Sel = llvm::makeArrayRef(SelFirst, SelLimit);
+// Find which of these are preprocessed to nothing and should be ignored.
+std::vector PPIgnored(Sel.size(), false);
+for (const syntax::TokenBuffer::Expansion &X :
+ Buf.expansionsAffecting(Sel)) {
+  if (X.Expanded.empty()) {
+for (const syntax::Token &Tok : X.Spelled) {
+  if (&Tok >= SelFirst && &Tok < SelLimit)
+PPIgnored[&Tok - SelFirst] = true;
+}
+  }
+}
 // Precompute selectedness and offset for selected spelled tokens.
-for (const syntax::Token *T = SelFirst; T < SelLimit; ++T) {
-  if (shouldIgnore(*T))
+for (unsigned I = 0; I < Sel.size(); ++I) {
+  if (shouldIgnore(Sel[I]) || PPIgnored[I])
 continue;
   SpelledTokens.emplace_back();
   Tok &S = SpelledTokens.back();
-  S.Offset = SM.getFileOffset(T->location());
-  if (S.Offset >= SelBegin && S.Offset + T->length() <= SelEnd)
+  S.Offset = SM.getFileOffset(Sel[I].location());
+  if (S.Offset >= SelBegin && S.Offset + Sel[I].length() <= SelEnd)
 S.Selected = SelectionTree::Complete;
   else
 S.Selected = SelectionTree::Partial;


Index: clang-tools-extra/clangd/unittests/SelectionTests.cpp
===
--- clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -177,11 +177,29 @@
   {
   R"cpp(
 void foo();
-#define CALL_FUNCTION(X) X^()^
+#^define CALL_FUNCTION(X) X(^)
 void bar() { CALL_FUNCTION(foo); }
   )cpp",
   nullptr,
   },
+  {
+  R"cpp(
+void foo();
+#define CALL_FUNCTION(X) X()
+void bar() { CALL_FUNCTION(foo^)^; }
+  )cpp",
+  nullptr,
+  },
+  {
+  R"cpp(
+namespace ns {
+#if 0
+void fo^o() {}
+#endif
+}
+  )cpp",
+  nullptr,
+  },
   {
   R"cpp(
 struct S { S(const char*); };
@@ -388,7 +406,8 @@
 void test(S2 s2) {
   s2[[-^>]]f();
 }
-  )cpp", "DeclRefExpr"} // DeclRefExpr to the "operator->" method.
+  )cpp",
+   "DeclRefExpr"} // DeclRefExpr to the "operator->" method.
   };
   for (const Case &C : Cases) {
 trace::TestTracer Tracer;
@@ -538,7 +557,7 @@
   auto AST = TU.build();
   auto T = makeSelectionTree(Case, AST);
 
-  EXPECT_EQ("WhileStmt", T.commonAncestor()->kind());
+  EXPECT_EQ(nullptr, T.commonAncestor());
 }
 
 TEST(SelectionTest, MacroArgExpansion) {
I

[PATCH] D84012: [clangd] Exclude preprocessed-to-nothing tokens from selection

2020-07-20 Thread Sam McCall via Phabricator via cfe-commits
sammccall marked an inline comment as done.
sammccall added inline comments.
Herald added a subscriber: kbobyrev.



Comment at: clang-tools-extra/clangd/unittests/SelectionTests.cpp:568
+#if 0
+void fu^nc();
+#endif

kadircet wrote:
> nit: i am not sure if this is worth it's own test
Moved into CommonAncestor tests. (We do need to test it somewhere, that's the 
point of this patch)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84012



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


[PATCH] D83508: [clangd][Hover] Don't use Decl if it is not related with tokens under cursor.

2020-07-20 Thread Sam McCall via Phabricator via cfe-commits
sammccall added a comment.
Herald added a subscriber: kbobyrev.

In D83508#2157954 , @ArcsinX wrote:

> In D83508#2157859 , @sammccall wrote:
>
> > Tried this out in D84012 /D84009 
> > . Works pretty well, and I think the API 
> > is a useful and natural addition to TokenBuffer.
>
>
> For my test cases it works well, so I think this problem is fixed.
>  Should I abandon this revision?


I've landed those two patches, so I think so.
Thanks for raising this and working through it, I hope I didn't step on your 
toes to much here; this was a gap in TokenBuffer that I'd been hoping to have 
an excuse to fill at some point.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83508



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


[clang] 684e416 - [AST][RecoveryExpr] Preserve the AST for invalid conditions.

2020-07-20 Thread Haojian Wu via cfe-commits

Author: Haojian Wu
Date: 2020-07-20T14:58:36+02:00
New Revision: 684e416ef1361fc3cc93bebbee1466b844751497

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

LOG: [AST][RecoveryExpr] Preserve the AST for invalid conditions.

Adjust an existing diagnostic test, which is an improvement of secondary 
diagnostic.

Differential Revision: https://reviews.llvm.org/D81163

Added: 


Modified: 
clang/lib/Sema/SemaExpr.cpp
clang/test/AST/ast-dump-recovery.cpp
clang/test/SemaTemplate/instantiate-expr-3.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 8fd0e2892b14..598aede14dd3 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -18458,9 +18458,12 @@ Sema::ConditionResult Sema::ActOnCondition(Scope *S, 
SourceLocation Loc,
 Cond = CheckSwitchCondition(Loc, SubExpr);
 break;
   }
-  if (Cond.isInvalid())
-return ConditionError();
-
+  if (Cond.isInvalid()) {
+Cond = CreateRecoveryExpr(SubExpr->getBeginLoc(), SubExpr->getEndLoc(),
+  {SubExpr});
+if (!Cond.get())
+  return ConditionError();
+  }
   // FIXME: FullExprArg doesn't have an invalid bit, so check nullness instead.
   FullExprArg FullExpr = MakeFullExpr(Cond.get(), Loc);
   if (!FullExpr.get())

diff  --git a/clang/test/AST/ast-dump-recovery.cpp 
b/clang/test/AST/ast-dump-recovery.cpp
index cbae3fddf21e..4d11bb29d5bf 100644
--- a/clang/test/AST/ast-dump-recovery.cpp
+++ b/clang/test/AST/ast-dump-recovery.cpp
@@ -229,3 +229,30 @@ void ValueCategory() {
   // CHECK:  RecoveryExpr {{.*}} 'int' contains-errors xvalue
   xvalue(); // call to a function (rvalue reference return type) yields an 
xvalue.
 }
+
+void InvalidCondition() {
+  // CHECK:  IfStmt {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}}  '' 
contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 
+  if (invalid()) {}
+
+  // CHECK:  WhileStmt {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}}  '' 
contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 
+  while (invalid()) {}
+
+  // CHECK:  SwitchStmt {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}} '' contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 
+  switch(invalid()) {
+case 1:
+  break;
+  }
+  // FIXME: figure out why the type of ConditionalOperator is not int.
+  // CHECK:  ConditionalOperator {{.*}} '' contains-errors
+  // CHECK-NEXT: |-RecoveryExpr {{.*}} '' contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}}
+  // CHECK-NEXT: |-IntegerLiteral {{.*}} 'int' 1
+  // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 2
+  invalid() ? 1 : 2;
+}

diff  --git a/clang/test/SemaTemplate/instantiate-expr-3.cpp 
b/clang/test/SemaTemplate/instantiate-expr-3.cpp
index 142e4ebcedc6..689fd22ea448 100644
--- a/clang/test/SemaTemplate/instantiate-expr-3.cpp
+++ b/clang/test/SemaTemplate/instantiate-expr-3.cpp
@@ -65,7 +65,7 @@ struct StatementExpr0 {
   void f(T t) {
 (void)({
 if (t) // expected-error{{contextually convertible}}
-  t = t + 17;
+  t = t + 17; // expected-error {{invalid operands to binary 
expression ('N1::X' and 'int')}}
 t + 12; // expected-error{{invalid operands}}
   });
   }



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


[Differential] D81163: [AST][RecoveryExpr] Preserve the AST for invalid conditions.

2020-07-20 Thread Haojian Wu 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 rG684e416ef136: [AST][RecoveryExpr] Preserve the AST for 
invalid conditions. (authored by hokein).

Changed prior to commit:
  https://reviews.llvm.org/D81163?vs=270413&id=279011#toc

Repository:
  rG LLVM Github Monorepo

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


  https://reviews.llvm.org/D81163

Files:
  clang/lib/Sema/SemaExpr.cpp
  clang/test/AST/ast-dump-recovery.cpp
  clang/test/SemaTemplate/instantiate-expr-3.cpp



Index: clang/test/SemaTemplate/instantiate-expr-3.cpp
===
--- clang/test/SemaTemplate/instantiate-expr-3.cpp
+++ clang/test/SemaTemplate/instantiate-expr-3.cpp
@@ -65,7 +65,7 @@
   void f(T t) {
 (void)({
 if (t) // expected-error{{contextually convertible}}
-  t = t + 17;
+  t = t + 17; // expected-error {{invalid operands to binary 
expression ('N1::X' and 'int')}}
 t + 12; // expected-error{{invalid operands}}
   });
   }
Index: clang/test/AST/ast-dump-recovery.cpp
===
--- clang/test/AST/ast-dump-recovery.cpp
+++ clang/test/AST/ast-dump-recovery.cpp
@@ -229,3 +229,30 @@
   // CHECK:  RecoveryExpr {{.*}} 'int' contains-errors xvalue
   xvalue(); // call to a function (rvalue reference return type) yields an 
xvalue.
 }
+
+void InvalidCondition() {
+  // CHECK:  IfStmt {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}}  '' 
contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 
+  if (invalid()) {}
+
+  // CHECK:  WhileStmt {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}}  '' 
contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 
+  while (invalid()) {}
+
+  // CHECK:  SwitchStmt {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}} '' contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 
+  switch(invalid()) {
+case 1:
+  break;
+  }
+  // FIXME: figure out why the type of ConditionalOperator is not int.
+  // CHECK:  ConditionalOperator {{.*}} '' contains-errors
+  // CHECK-NEXT: |-RecoveryExpr {{.*}} '' contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}}
+  // CHECK-NEXT: |-IntegerLiteral {{.*}} 'int' 1
+  // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 2
+  invalid() ? 1 : 2;
+}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -18458,9 +18458,12 @@
 Cond = CheckSwitchCondition(Loc, SubExpr);
 break;
   }
-  if (Cond.isInvalid())
-return ConditionError();
-
+  if (Cond.isInvalid()) {
+Cond = CreateRecoveryExpr(SubExpr->getBeginLoc(), SubExpr->getEndLoc(),
+  {SubExpr});
+if (!Cond.get())
+  return ConditionError();
+  }
   // FIXME: FullExprArg doesn't have an invalid bit, so check nullness instead.
   FullExprArg FullExpr = MakeFullExpr(Cond.get(), Loc);
   if (!FullExpr.get())


Index: clang/test/SemaTemplate/instantiate-expr-3.cpp
===
--- clang/test/SemaTemplate/instantiate-expr-3.cpp
+++ clang/test/SemaTemplate/instantiate-expr-3.cpp
@@ -65,7 +65,7 @@
   void f(T t) {
 (void)({
 if (t) // expected-error{{contextually convertible}}
-  t = t + 17;
+  t = t + 17; // expected-error {{invalid operands to binary expression ('N1::X' and 'int')}}
 t + 12; // expected-error{{invalid operands}}
   });
   }
Index: clang/test/AST/ast-dump-recovery.cpp
===
--- clang/test/AST/ast-dump-recovery.cpp
+++ clang/test/AST/ast-dump-recovery.cpp
@@ -229,3 +229,30 @@
   // CHECK:  RecoveryExpr {{.*}} 'int' contains-errors xvalue
   xvalue(); // call to a function (rvalue reference return type) yields an xvalue.
 }
+
+void InvalidCondition() {
+  // CHECK:  IfStmt {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}}  '' contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 
+  if (invalid()) {}
+
+  // CHECK:  WhileStmt {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}}  '' contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 
+  while (invalid()) {}
+
+  // CHECK:  SwitchStmt {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}} '' contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 
+  switch(invalid()) {
+case 1:
+  break;
+  }
+  // FIXME: figure out why the type of ConditionalOperator is not int.
+  // CHECK:  ConditionalOperator {{.*}} '' contains-errors
+  // CHECK-NEXT: |-RecoveryExpr {{.*}} '' contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}}
+  // CHECK-NEXT: |-IntegerLiteral {{.*}} 'int' 1
+  // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 2
+  invalid() ? 1 : 2;
+}
Index: clang/lib/Sema/SemaExpr.cpp
=

[PATCH] D81163: [AST][RecoveryExpr] Preserve the AST for invalid conditions.

2020-07-20 Thread Haojian Wu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG684e416ef136: [AST][RecoveryExpr] Preserve the AST for 
invalid conditions. (authored by hokein).

Changed prior to commit:
  https://reviews.llvm.org/D81163?vs=270413&id=279213#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D81163

Files:
  clang/lib/Sema/SemaExpr.cpp
  clang/test/AST/ast-dump-recovery.cpp
  clang/test/SemaTemplate/instantiate-expr-3.cpp


Index: clang/test/SemaTemplate/instantiate-expr-3.cpp
===
--- clang/test/SemaTemplate/instantiate-expr-3.cpp
+++ clang/test/SemaTemplate/instantiate-expr-3.cpp
@@ -65,7 +65,7 @@
   void f(T t) {
 (void)({
 if (t) // expected-error{{contextually convertible}}
-  t = t + 17;
+  t = t + 17; // expected-error {{invalid operands to binary 
expression ('N1::X' and 'int')}}
 t + 12; // expected-error{{invalid operands}}
   });
   }
Index: clang/test/AST/ast-dump-recovery.cpp
===
--- clang/test/AST/ast-dump-recovery.cpp
+++ clang/test/AST/ast-dump-recovery.cpp
@@ -229,3 +229,30 @@
   // CHECK:  RecoveryExpr {{.*}} 'int' contains-errors xvalue
   xvalue(); // call to a function (rvalue reference return type) yields an 
xvalue.
 }
+
+void InvalidCondition() {
+  // CHECK:  IfStmt {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}}  '' 
contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 
+  if (invalid()) {}
+
+  // CHECK:  WhileStmt {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}}  '' 
contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 
+  while (invalid()) {}
+
+  // CHECK:  SwitchStmt {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}} '' contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 
+  switch(invalid()) {
+case 1:
+  break;
+  }
+  // FIXME: figure out why the type of ConditionalOperator is not int.
+  // CHECK:  ConditionalOperator {{.*}} '' contains-errors
+  // CHECK-NEXT: |-RecoveryExpr {{.*}} '' contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}}
+  // CHECK-NEXT: |-IntegerLiteral {{.*}} 'int' 1
+  // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 2
+  invalid() ? 1 : 2;
+}
Index: clang/lib/Sema/SemaExpr.cpp
===
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -18458,9 +18458,12 @@
 Cond = CheckSwitchCondition(Loc, SubExpr);
 break;
   }
-  if (Cond.isInvalid())
-return ConditionError();
-
+  if (Cond.isInvalid()) {
+Cond = CreateRecoveryExpr(SubExpr->getBeginLoc(), SubExpr->getEndLoc(),
+  {SubExpr});
+if (!Cond.get())
+  return ConditionError();
+  }
   // FIXME: FullExprArg doesn't have an invalid bit, so check nullness instead.
   FullExprArg FullExpr = MakeFullExpr(Cond.get(), Loc);
   if (!FullExpr.get())


Index: clang/test/SemaTemplate/instantiate-expr-3.cpp
===
--- clang/test/SemaTemplate/instantiate-expr-3.cpp
+++ clang/test/SemaTemplate/instantiate-expr-3.cpp
@@ -65,7 +65,7 @@
   void f(T t) {
 (void)({
 if (t) // expected-error{{contextually convertible}}
-  t = t + 17;
+  t = t + 17; // expected-error {{invalid operands to binary expression ('N1::X' and 'int')}}
 t + 12; // expected-error{{invalid operands}}
   });
   }
Index: clang/test/AST/ast-dump-recovery.cpp
===
--- clang/test/AST/ast-dump-recovery.cpp
+++ clang/test/AST/ast-dump-recovery.cpp
@@ -229,3 +229,30 @@
   // CHECK:  RecoveryExpr {{.*}} 'int' contains-errors xvalue
   xvalue(); // call to a function (rvalue reference return type) yields an xvalue.
 }
+
+void InvalidCondition() {
+  // CHECK:  IfStmt {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}}  '' contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 
+  if (invalid()) {}
+
+  // CHECK:  WhileStmt {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}}  '' contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 
+  while (invalid()) {}
+
+  // CHECK:  SwitchStmt {{.*}}
+  // CHECK-NEXT: |-RecoveryExpr {{.*}} '' contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}} 
+  switch(invalid()) {
+case 1:
+  break;
+  }
+  // FIXME: figure out why the type of ConditionalOperator is not int.
+  // CHECK:  ConditionalOperator {{.*}} '' contains-errors
+  // CHECK-NEXT: |-RecoveryExpr {{.*}} '' contains-errors
+  // CHECK-NEXT: | `-UnresolvedLookupExpr {{.*}}
+  // CHECK-NEXT: |-IntegerLiteral {{.*}} 'int' 1
+  // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 2
+  invalid() ? 1 : 2;
+}
Index: clang/lib/Sema/SemaExpr.cpp
=

[PATCH] D83961: [Analyzer] Fix bug report source locations in minimal output.

2020-07-20 Thread Balázs Kéri via Phabricator via cfe-commits
balazske marked an inline comment as done.
balazske added a comment.

The problem in D83120  is fixed by this patch.
What I figured out from the code is that `BugReporter::FlushReport` calls 
`findReportInEquivalenceClass` that returns a report that has not necessary the 
shortest path. That report is get from the passed bug report class and a 
different instance is returned if the uniqueing is turned on or off. This 
report is used to fill the last location in the bug path, if the bug path is 
empty. So the location in the bug path changes dependent on the setting of 
uniqueing. The bug path here is empty if the analyzer-output is set to minimal 
(or not specified). Even in the minimal output case, function 
`PathDiagnosticBuilder::generate` is called if it is a path sensitive case. In 
that function the shortest path is used. So instead of returning an empty path 
from that function (what is filled later by FlushReport) the last part of the 
path can be filled here (and use the correct source location from the shortest 
path).
The problem can happen if not the report with shortest path is returned from 
`findReportInEquivalenceClass`, and analyzer-output is set to minimal or 
default. If the output is not minimal, the bug path is filled by the 
`PathDiagnosticBuilder::generate` with correct locations. So changing the 
output type can result in change of the warning location.
Other way to get the problem is change only the uniqueing setting in bug type 
and use minimal (or default) output. Then the example report can change and 
because this example report is used to get the bug location the location can 
change too (if the equivalence class contains paths with different end 
locations).




Comment at: clang/lib/StaticAnalyzer/Core/BugReporter.cpp:3007
 // of the issue.
+// This can happen if report is BasicBugReport.
 if (PD->path.empty()) {

Szelethus wrote:
> Is this the *only* instance when that happens? How about the `text-minimal` 
> output?
I am not totally sure on this but inserted an assert and all the tests passed 
without triggering it.
Is the text-minimal different from the default (when to `--analyzer-output` is 
given at all)?
I think it works like this: Function 
`PathSensitiveBugReporter::generateDiagnosticForConsumerMap` is called from 
here, then if it is not a `BasicBugReport` the function 
`PathDiagnosticBuilder::generate` will be called that is fixed now to return 
always with non-empty path.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83961



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


[PATCH] D71760: [POC][SVE] Allow code generation for fixed length vectorised loops [Patch 1/2].

2020-07-20 Thread Paul Walker via Phabricator via cfe-commits
paulwalker-arm updated this revision to Diff 279217.
paulwalker-arm added a comment.

Rebase.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71760

Files:
  clang/lib/Driver/ToolChains/Clang.cpp


Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -1721,9 +1721,16 @@
 StringRef Val = A->getValue();
 const Driver &D = getToolChain().getDriver();
 if (Val.equals("128") || Val.equals("256") || Val.equals("512") ||
-Val.equals("1024") || Val.equals("2048"))
+Val.equals("1024") || Val.equals("2048")) {
   CmdArgs.push_back(
   Args.MakeArgString(llvm::Twine("-msve-vector-bits=") + Val));
+  CmdArgs.push_back("-mllvm");
+  CmdArgs.push_back(
+  Args.MakeArgString("-aarch64-sve-vector-bits-min=" + Val));
+  // CmdArgs.push_back("-mllvm");
+  // CmdArgs.push_back(
+  //Args.MakeArgString("-aarch64-sve-vector-bits-max=" + Val));
+}
 // Silently drop requests for vector-length agnostic code as it's implied.
 else if (!Val.equals("scalable"))
   // Handle the unsupported values passed to msve-vector-bits.


Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -1721,9 +1721,16 @@
 StringRef Val = A->getValue();
 const Driver &D = getToolChain().getDriver();
 if (Val.equals("128") || Val.equals("256") || Val.equals("512") ||
-Val.equals("1024") || Val.equals("2048"))
+Val.equals("1024") || Val.equals("2048")) {
   CmdArgs.push_back(
   Args.MakeArgString(llvm::Twine("-msve-vector-bits=") + Val));
+  CmdArgs.push_back("-mllvm");
+  CmdArgs.push_back(
+  Args.MakeArgString("-aarch64-sve-vector-bits-min=" + Val));
+  // CmdArgs.push_back("-mllvm");
+  // CmdArgs.push_back(
+  //Args.MakeArgString("-aarch64-sve-vector-bits-max=" + Val));
+}
 // Silently drop requests for vector-length agnostic code as it's implied.
 else if (!Val.equals("scalable"))
   // Handle the unsupported values passed to msve-vector-bits.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 61d664c - Fix clangd build, NFC

2020-07-20 Thread Haojian Wu via cfe-commits

Author: Haojian Wu
Date: 2020-07-20T15:13:20+02:00
New Revision: 61d664c9383c53339db756278ec84fbacec2bf4b

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

LOG: Fix clangd build, NFC

Added: 


Modified: 
clang-tools-extra/clangd/Selection.cpp

Removed: 




diff  --git a/clang-tools-extra/clangd/Selection.cpp 
b/clang-tools-extra/clangd/Selection.cpp
index d1677e216ffc..2e3c491d561e 100644
--- a/clang-tools-extra/clangd/Selection.cpp
+++ b/clang-tools-extra/clangd/Selection.cpp
@@ -224,7 +224,7 @@ class SelectionTester {
 // Find which of these are preprocessed to nothing and should be ignored.
 std::vector PPIgnored(Sel.size(), false);
 for (const syntax::TokenBuffer::Expansion &X :
- Buf.expansionsAffecting(Sel)) {
+ Buf.expansionsOverlapping(Sel)) {
   if (X.Expanded.empty()) {
 for (const syntax::Token &Tok : X.Spelled) {
   if (&Tok >= SelFirst && &Tok < SelLimit)



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


[clang] 4b5b7c7 - [AST][RecoveryExpr] Fix a crash on opencl C++.

2020-07-20 Thread Haojian Wu via cfe-commits

Author: Haojian Wu
Date: 2020-07-20T15:15:30+02:00
New Revision: 4b5b7c75415be0837389fe694e1843422b4cd115

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

LOG: [AST][RecoveryExpr] Fix a crash on opencl C++.

Differential Revision: https://reviews.llvm.org/D84145

Added: 
clang/test/SemaOpenCL/recovery-expr.cl

Modified: 
clang/lib/Sema/SemaDecl.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 3e2b61ae8cdf..3413a420430c 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11067,8 +11067,14 @@ bool Sema::CheckForConstantInitializer(Expr *Init, 
QualType DclT) {
   // except that the aforementioned are allowed in unevaluated
   // expressions.  Everything else falls under the
   // "may accept other forms of constant expressions" exception.
-  // (We never end up here for C++, so the constant expression
-  // rules there don't matter.)
+  //
+  // Regular C++ code will not end up here (exceptions: language extensions,
+  // OpenCL C++ etc), so the constant expression rules there don't matter.
+  if (Init->isValueDependent()) {
+assert(Init->containsErrors() &&
+   "Dependent code should only occur in error-recovery path.");
+return true;
+  }
   const Expr *Culprit;
   if (Init->isConstantInitializer(Context, false, &Culprit))
 return false;

diff  --git a/clang/test/SemaOpenCL/recovery-expr.cl 
b/clang/test/SemaOpenCL/recovery-expr.cl
new file mode 100644
index ..902b10dbb578
--- /dev/null
+++ b/clang/test/SemaOpenCL/recovery-expr.cl
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=clc++ 
-frecovery-ast
+
+void kernel nocrash() {
+  constant int L1 = 0;
+
+  private int *constant L2 = L1++; // expected-error {{read-only variable is 
not assignable}}
+}



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


[PATCH] D84145: [AST][RecoveryExpr] Fix a crash on opencl C++.

2020-07-20 Thread Haojian Wu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG4b5b7c75415b: [AST][RecoveryExpr] Fix a crash on opencl C++. 
(authored by hokein).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84145

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/SemaOpenCL/recovery-expr.cl


Index: clang/test/SemaOpenCL/recovery-expr.cl
===
--- /dev/null
+++ clang/test/SemaOpenCL/recovery-expr.cl
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=clc++ 
-frecovery-ast
+
+void kernel nocrash() {
+  constant int L1 = 0;
+
+  private int *constant L2 = L1++; // expected-error {{read-only variable is 
not assignable}}
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11067,8 +11067,14 @@
   // except that the aforementioned are allowed in unevaluated
   // expressions.  Everything else falls under the
   // "may accept other forms of constant expressions" exception.
-  // (We never end up here for C++, so the constant expression
-  // rules there don't matter.)
+  //
+  // Regular C++ code will not end up here (exceptions: language extensions,
+  // OpenCL C++ etc), so the constant expression rules there don't matter.
+  if (Init->isValueDependent()) {
+assert(Init->containsErrors() &&
+   "Dependent code should only occur in error-recovery path.");
+return true;
+  }
   const Expr *Culprit;
   if (Init->isConstantInitializer(Context, false, &Culprit))
 return false;


Index: clang/test/SemaOpenCL/recovery-expr.cl
===
--- /dev/null
+++ clang/test/SemaOpenCL/recovery-expr.cl
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=clc++ -frecovery-ast
+
+void kernel nocrash() {
+  constant int L1 = 0;
+
+  private int *constant L2 = L1++; // expected-error {{read-only variable is not assignable}}
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -11067,8 +11067,14 @@
   // except that the aforementioned are allowed in unevaluated
   // expressions.  Everything else falls under the
   // "may accept other forms of constant expressions" exception.
-  // (We never end up here for C++, so the constant expression
-  // rules there don't matter.)
+  //
+  // Regular C++ code will not end up here (exceptions: language extensions,
+  // OpenCL C++ etc), so the constant expression rules there don't matter.
+  if (Init->isValueDependent()) {
+assert(Init->containsErrors() &&
+   "Dependent code should only occur in error-recovery path.");
+return true;
+  }
   const Expr *Culprit;
   if (Init->isConstantInitializer(Context, false, &Culprit))
 return false;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84146: [AST][RecoveryExpr] Add recovery-ast tests for C language, NFC.

2020-07-20 Thread Haojian Wu via Phabricator via cfe-commits
hokein updated this revision to Diff 279223.
hokein marked 4 inline comments as done.
hokein added a comment.

address review comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84146

Files:
  clang/test/AST/ast-dump-recovery.c


Index: clang/test/AST/ast-dump-recovery.c
===
--- /dev/null
+++ clang/test/AST/ast-dump-recovery.c
@@ -0,0 +1,41 @@
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast 
-fno-recovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
+
+int some_func(int);
+
+// CHECK: VarDecl {{.*}} unmatch_arg_call 'int' cinit
+// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
+int unmatch_arg_call = some_func();
+
+const int a = 1;
+
+// CHECK: VarDecl {{.*}} postfix_inc
+// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'a'
+int postfix_inc = a++;
+
+// CHECK: VarDecl {{.*}} unary_address
+// CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:  `-ParenExpr {{.*}}
+// CHECK-NEXT:`-BinaryOperator {{.*}} '+'
+// CHECK-NEXT:  |-ImplicitCastExpr
+// CHECK-NEXT:  | `-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int'
+int unary_address = &(a + 1);
+
+// CHECK:   VarDecl {{.*}} ternary 'int' cinit
+// CHECK-NEXT:  `-RecoveryExpr {{.*}}
+// CHECK-NEXT:|-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:|-TypoExpr {{.*}}
+// CHECK-NEXT:`-DeclRefExpr {{.*}} 'a'
+// FIXME: The TypoExpr should never be print, and should be downgraded to
+// RecoveryExpr -- typo correction is performed too early in C-only codepath,
+// which makes no correction when clang finishes the full expr 
(Sema::Sema::ActOnFinishFullExpr).
+// this will be fixed when we support dependent mechanism and delayed typo 
correction for C.
+int ternary = a ? undef : a;
+
+void test1() {
+  // CHECK: `-RecoveryExpr {{.*}} contains-errors
+  // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a' 'const int'
+  static int foo = a++; // verify no crash on local static var decl.
+}


Index: clang/test/AST/ast-dump-recovery.c
===
--- /dev/null
+++ clang/test/AST/ast-dump-recovery.c
@@ -0,0 +1,41 @@
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -fno-recovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
+
+int some_func(int);
+
+// CHECK: VarDecl {{.*}} unmatch_arg_call 'int' cinit
+// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
+int unmatch_arg_call = some_func();
+
+const int a = 1;
+
+// CHECK: VarDecl {{.*}} postfix_inc
+// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'a'
+int postfix_inc = a++;
+
+// CHECK: VarDecl {{.*}} unary_address
+// CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:  `-ParenExpr {{.*}}
+// CHECK-NEXT:`-BinaryOperator {{.*}} '+'
+// CHECK-NEXT:  |-ImplicitCastExpr
+// CHECK-NEXT:  | `-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int'
+int unary_address = &(a + 1);
+
+// CHECK:   VarDecl {{.*}} ternary 'int' cinit
+// CHECK-NEXT:  `-RecoveryExpr {{.*}}
+// CHECK-NEXT:|-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:|-TypoExpr {{.*}}
+// CHECK-NEXT:`-DeclRefExpr {{.*}} 'a'
+// FIXME: The TypoExpr should never be print, and should be downgraded to
+// RecoveryExpr -- typo correction is performed too early in C-only codepath,
+// which makes no correction when clang finishes the full expr (Sema::Sema::ActOnFinishFullExpr).
+// this will be fixed when we support dependent mechanism and delayed typo correction for C.
+int ternary = a ? undef : a;
+
+void test1() {
+  // CHECK: `-RecoveryExpr {{.*}} contains-errors
+  // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a' 'const int'
+  static int foo = a++; // verify no crash on local static var decl.
+}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84150: [clangd] Fix conversion from Windows UNC paths to file URI format.

2020-07-20 Thread Ilya Golovenko via Phabricator via cfe-commits
ilya-golovenko updated this revision to Diff 279224.
ilya-golovenko added a comment.

Consistent naming: Name => Path


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84150

Files:
  clang-tools-extra/clangd/URI.cpp


Index: clang-tools-extra/clangd/URI.cpp
===
--- clang-tools-extra/clangd/URI.cpp
+++ clang-tools-extra/clangd/URI.cpp
@@ -30,9 +30,9 @@
   return Path.size() > 1 && llvm::isAlpha(Path[0]) && Path[1] == ':';
 }
 
-bool isNetworkPath(llvm::StringRef Name) {
+bool isNetworkPath(llvm::StringRef Path) {
   llvm::StringRef Sep = llvm::sys::path::get_separator();
-  return Name.consume_front(Sep) && Name.consume_front(Sep) && !Name.empty();
+  return Path.consume_front(Sep) && Path.consume_front(Sep) && !Path.empty();
 }
 
 /// This manages file paths in the file system. All paths in the scheme


Index: clang-tools-extra/clangd/URI.cpp
===
--- clang-tools-extra/clangd/URI.cpp
+++ clang-tools-extra/clangd/URI.cpp
@@ -30,9 +30,9 @@
   return Path.size() > 1 && llvm::isAlpha(Path[0]) && Path[1] == ':';
 }
 
-bool isNetworkPath(llvm::StringRef Name) {
+bool isNetworkPath(llvm::StringRef Path) {
   llvm::StringRef Sep = llvm::sys::path::get_separator();
-  return Name.consume_front(Sep) && Name.consume_front(Sep) && !Name.empty();
+  return Path.consume_front(Sep) && Path.consume_front(Sep) && !Path.empty();
 }
 
 /// This manages file paths in the file system. All paths in the scheme
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 70e2c7a - [AST][RecoveryExpr] Add recovery-ast tests for C language, NFC.

2020-07-20 Thread Haojian Wu via cfe-commits

Author: Haojian Wu
Date: 2020-07-20T15:33:59+02:00
New Revision: 70e2c7ad2e891ccecbf59a0562586538de96aeaa

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

LOG: [AST][RecoveryExpr] Add recovery-ast tests for C language, NFC.

some examples are working already.

Differential Revision: https://reviews.llvm.org/D84146

Added: 
clang/test/AST/ast-dump-recovery.c

Modified: 


Removed: 




diff  --git a/clang/test/AST/ast-dump-recovery.c 
b/clang/test/AST/ast-dump-recovery.c
new file mode 100644
index ..b49c0103dbaf
--- /dev/null
+++ b/clang/test/AST/ast-dump-recovery.c
@@ -0,0 +1,41 @@
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast 
-fno-recovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
+
+int some_func(int);
+
+// CHECK: VarDecl {{.*}} unmatch_arg_call 'int' cinit
+// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
+int unmatch_arg_call = some_func();
+
+const int a = 1;
+
+// CHECK: VarDecl {{.*}} postfix_inc
+// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'a'
+int postfix_inc = a++;
+
+// CHECK: VarDecl {{.*}} unary_address
+// CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:  `-ParenExpr {{.*}}
+// CHECK-NEXT:`-BinaryOperator {{.*}} '+'
+// CHECK-NEXT:  |-ImplicitCastExpr
+// CHECK-NEXT:  | `-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int'
+int unary_address = &(a + 1);
+
+// CHECK:   VarDecl {{.*}} ternary 'int' cinit
+// CHECK-NEXT:  `-RecoveryExpr {{.*}}
+// CHECK-NEXT:|-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:|-TypoExpr {{.*}}
+// CHECK-NEXT:`-DeclRefExpr {{.*}} 'a'
+// FIXME: The TypoExpr should never be print, and should be downgraded to
+// RecoveryExpr -- typo correction is performed too early in C-only codepath,
+// which makes no correction when clang finishes the full expr 
(Sema::Sema::ActOnFinishFullExpr).
+// this will be fixed when we support dependent mechanism and delayed typo 
correction for C.
+int ternary = a ? undef : a;
+
+void test1() {
+  // CHECK: `-RecoveryExpr {{.*}} contains-errors
+  // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a' 'const int'
+  static int foo = a++; // verify no crash on local static var decl.
+}



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


[PATCH] D84146: [AST][RecoveryExpr] Add recovery-ast tests for C language, NFC.

2020-07-20 Thread Haojian Wu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG70e2c7ad2e89: [AST][RecoveryExpr] Add recovery-ast tests for 
C language, NFC. (authored by hokein).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84146

Files:
  clang/test/AST/ast-dump-recovery.c


Index: clang/test/AST/ast-dump-recovery.c
===
--- /dev/null
+++ clang/test/AST/ast-dump-recovery.c
@@ -0,0 +1,41 @@
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast 
-fno-recovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
+
+int some_func(int);
+
+// CHECK: VarDecl {{.*}} unmatch_arg_call 'int' cinit
+// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
+int unmatch_arg_call = some_func();
+
+const int a = 1;
+
+// CHECK: VarDecl {{.*}} postfix_inc
+// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'a'
+int postfix_inc = a++;
+
+// CHECK: VarDecl {{.*}} unary_address
+// CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:  `-ParenExpr {{.*}}
+// CHECK-NEXT:`-BinaryOperator {{.*}} '+'
+// CHECK-NEXT:  |-ImplicitCastExpr
+// CHECK-NEXT:  | `-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int'
+int unary_address = &(a + 1);
+
+// CHECK:   VarDecl {{.*}} ternary 'int' cinit
+// CHECK-NEXT:  `-RecoveryExpr {{.*}}
+// CHECK-NEXT:|-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:|-TypoExpr {{.*}}
+// CHECK-NEXT:`-DeclRefExpr {{.*}} 'a'
+// FIXME: The TypoExpr should never be print, and should be downgraded to
+// RecoveryExpr -- typo correction is performed too early in C-only codepath,
+// which makes no correction when clang finishes the full expr 
(Sema::Sema::ActOnFinishFullExpr).
+// this will be fixed when we support dependent mechanism and delayed typo 
correction for C.
+int ternary = a ? undef : a;
+
+void test1() {
+  // CHECK: `-RecoveryExpr {{.*}} contains-errors
+  // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a' 'const int'
+  static int foo = a++; // verify no crash on local static var decl.
+}


Index: clang/test/AST/ast-dump-recovery.c
===
--- /dev/null
+++ clang/test/AST/ast-dump-recovery.c
@@ -0,0 +1,41 @@
+// RUN: not %clang_cc1 -triple x86_64-unknown-unknown -frecovery-ast -fno-recovery-ast-type -ast-dump %s | FileCheck -strict-whitespace %s
+
+int some_func(int);
+
+// CHECK: VarDecl {{.*}} unmatch_arg_call 'int' cinit
+// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'some_func'
+int unmatch_arg_call = some_func();
+
+const int a = 1;
+
+// CHECK: VarDecl {{.*}} postfix_inc
+// CHECK-NEXT: `-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:   `-DeclRefExpr {{.*}} 'a'
+int postfix_inc = a++;
+
+// CHECK: VarDecl {{.*}} unary_address
+// CHECK-NEXT:`-RecoveryExpr {{.*}} contains-errors
+// CHECK-NEXT:  `-ParenExpr {{.*}}
+// CHECK-NEXT:`-BinaryOperator {{.*}} '+'
+// CHECK-NEXT:  |-ImplicitCastExpr
+// CHECK-NEXT:  | `-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:  `-IntegerLiteral {{.*}} 'int'
+int unary_address = &(a + 1);
+
+// CHECK:   VarDecl {{.*}} ternary 'int' cinit
+// CHECK-NEXT:  `-RecoveryExpr {{.*}}
+// CHECK-NEXT:|-DeclRefExpr {{.*}} 'a'
+// CHECK-NEXT:|-TypoExpr {{.*}}
+// CHECK-NEXT:`-DeclRefExpr {{.*}} 'a'
+// FIXME: The TypoExpr should never be print, and should be downgraded to
+// RecoveryExpr -- typo correction is performed too early in C-only codepath,
+// which makes no correction when clang finishes the full expr (Sema::Sema::ActOnFinishFullExpr).
+// this will be fixed when we support dependent mechanism and delayed typo correction for C.
+int ternary = a ? undef : a;
+
+void test1() {
+  // CHECK: `-RecoveryExpr {{.*}} contains-errors
+  // CHECK-NEXT:  `-DeclRefExpr {{.*}} 'a' 'const int'
+  static int foo = a++; // verify no crash on local static var decl.
+}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84140: [clang] Set the error-bit for ill-formed semantic InitListExpr.

2020-07-20 Thread Haojian Wu via Phabricator via cfe-commits
hokein updated this revision to Diff 279227.
hokein added a comment.

add "ErrorDependent" alias to `ExprDependence` enum.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84140

Files:
  clang-tools-extra/clangd/unittests/HoverTests.cpp
  clang/include/clang/AST/DependenceFlags.h
  clang/include/clang/AST/Expr.h
  clang/lib/AST/ComputeDependence.cpp
  clang/lib/Sema/SemaInit.cpp


Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -962,6 +962,8 @@
   FillInEmptyInitializations(Entity, FullyStructuredList,
  RequiresSecondPass, nullptr, 0);
   }
+  if (hadError && FullyStructuredList)
+FullyStructuredList->markError();
 }
 
 int InitListChecker::numArrayElements(QualType DeclType) {
Index: clang/lib/AST/ComputeDependence.cpp
===
--- clang/lib/AST/ComputeDependence.cpp
+++ clang/lib/AST/ComputeDependence.cpp
@@ -502,7 +502,7 @@
   // dependent type), or the type is known and dependent, or it has
   // type-dependent subexpressions.
   auto D = toExprDependence(E->getType()->getDependence()) |
-   ExprDependence::ValueInstantiation | ExprDependence::Error;
+   ExprDependence::ErrorDependent;
   // FIXME: remove the type-dependent bit from subexpressions, if the
   // RecoveryExpr has a non-dependent type.
   for (auto *S : E->subExpressions())
Index: clang/include/clang/AST/Expr.h
===
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -4690,6 +4690,13 @@
   setDependence(getDependence() | expr->getDependence());
   }
 
+  /// Mark the semantic form of the InitListExpr as error when the semantic
+  /// analysis fails.
+  void markError() {
+assert(isSemanticForm());
+setDependence(getDependence() | ExprDependence::ErrorDependent);
+  }
+
   /// Reserve space for some number of initializers.
   void reserveInits(const ASTContext &C, unsigned NumInits);
 
Index: clang/include/clang/AST/DependenceFlags.h
===
--- clang/include/clang/AST/DependenceFlags.h
+++ clang/include/clang/AST/DependenceFlags.h
@@ -41,6 +41,7 @@
 TypeInstantiation = Type | Instantiation,
 ValueInstantiation = Value | Instantiation,
 TypeValueInstantiation = Type | Value | Instantiation,
+ErrorDependent = Error | ValueInstantiation,
 
 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error)
   };
Index: clang-tools-extra/clangd/unittests/HoverTests.cpp
===
--- clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -957,6 +957,16 @@
   template  void foo() {
 (void)[[size^of]](T);
   })cpp",
+  R"cpp(// should not crash on invalid semantic form of init-list-expr.
+/*error-ok*/
+struct Foo {
+  int xyz = 0;
+};
+class Bar {};
+constexpr Foo s = ^{
+  .xyz = Bar(),
+};
+  )cpp",
   // literals
   "auto x = t^rue;",
   "auto x = '^A';",


Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -962,6 +962,8 @@
   FillInEmptyInitializations(Entity, FullyStructuredList,
  RequiresSecondPass, nullptr, 0);
   }
+  if (hadError && FullyStructuredList)
+FullyStructuredList->markError();
 }
 
 int InitListChecker::numArrayElements(QualType DeclType) {
Index: clang/lib/AST/ComputeDependence.cpp
===
--- clang/lib/AST/ComputeDependence.cpp
+++ clang/lib/AST/ComputeDependence.cpp
@@ -502,7 +502,7 @@
   // dependent type), or the type is known and dependent, or it has
   // type-dependent subexpressions.
   auto D = toExprDependence(E->getType()->getDependence()) |
-   ExprDependence::ValueInstantiation | ExprDependence::Error;
+   ExprDependence::ErrorDependent;
   // FIXME: remove the type-dependent bit from subexpressions, if the
   // RecoveryExpr has a non-dependent type.
   for (auto *S : E->subExpressions())
Index: clang/include/clang/AST/Expr.h
===
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -4690,6 +4690,13 @@
   setDependence(getDependence() | expr->getDependence());
   }
 
+  /// Mark the semantic form of the InitListExpr as error when the semantic
+  /// analysis fails.
+  void markError() {
+assert(isSemanticForm());
+setDependence(getDependence() |

[PATCH] D84012: [clangd] Exclude preprocessed-to-nothing tokens from selection

2020-07-20 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added inline comments.



Comment at: clang-tools-extra/clangd/unittests/SelectionTests.cpp:568
+#if 0
+void fu^nc();
+#endif

sammccall wrote:
> kadircet wrote:
> > nit: i am not sure if this is worth it's own test
> Moved into CommonAncestor tests. (We do need to test it somewhere, that's the 
> point of this patch)
sorry I was saying that having a separate TEST fixture wasn't worth it, not the 
test itself :D


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84012



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


[PATCH] D84005: Introduce ns_error_domain attribute.

2020-07-20 Thread Michael Forster via Phabricator via cfe-commits
MForster updated this revision to Diff 279228.
MForster marked 13 inline comments as done.
MForster added a comment.

- Run test also in C and C++ mode
- Address more review comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84005

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/Analysis/ns_error_enum.c

Index: clang/test/Analysis/ns_error_enum.c
===
--- /dev/null
+++ clang/test/Analysis/ns_error_enum.c
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -verify %s -x c -Wno-elaborated-enum-base
+// RUN: %clang_cc1 -verify %s -x c++ -Wno-elaborated-enum-base
+// RUN: %clang_cc1 -verify %s -x objective-c
+
+
+#define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
+#define NS_ENUM(_type, _name) CF_ENUM(_type, _name)
+
+#define NS_ERROR_ENUM(_type, _name, _domain)  \
+  enum _name : _type _name; enum __attribute__((ns_error_domain(_domain))) _name : _type
+
+typedef NS_ENUM(unsigned, MyEnum) {
+  MyFirst,
+  MySecond,
+};
+
+typedef NS_ENUM(invalidType, MyInvalidEnum) {
+// expected-error@-1{{unknown type name 'invalidType'}}
+// expected-error@-2{{unknown type name 'invalidType'}}
+  MyFirstInvalid,
+  MySecondInvalid,
+};
+
+const char *MyErrorDomain;
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnum, MyErrorDomain) {
+	MyErrFirst,
+	MyErrSecond,
+};
+struct __attribute__((ns_error_domain(MyErrorDomain))) MyStructErrorDomain {};
+
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalid, InvalidDomain) {
+	// expected-error@-1{{domain argument 'InvalidDomain' does not refer to global constant}}
+	MyErrFirstInvalid,
+	MyErrSecondInvalid,
+};
+
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalid, "domain-string");
+  // expected-error@-1{{domain argument must be an identifier}}
+
+int __attribute__((ns_error_domain(MyErrorDomain))) NotTagDecl;
+  // expected-error@-1{{ns_error_domain attribute only valid on enums, structs, and unions}}
+
+void foo() {}
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalidFunction, foo);
+  // expected-error@-1{{domain argument 'foo' does not refer to global constant}}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -5327,6 +5327,39 @@
   D->addAttr(::new (S.Context) ObjCRequiresSuperAttr(S.Context, Attrs));
 }
 
+static void handleNSErrorDomain(Sema &S, Decl *D, const ParsedAttr &Attr) {
+  if (!isa(D)) {
+S.Diag(D->getBeginLoc(), diag::err_nserrordomain_not_tagdecl)
+<< S.getLangOpts().CPlusPlus;
+return;
+  }
+  IdentifierLoc *identLoc =
+  Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr;
+  if (!identLoc || !identLoc->Ident) {
+// Try to locate the argument directly
+SourceLocation loc = Attr.getLoc();
+if (Attr.isArgExpr(0) && Attr.getArgAsExpr(0))
+  loc = Attr.getArgAsExpr(0)->getBeginLoc();
+
+S.Diag(loc, diag::err_nserrordomain_requires_identifier);
+return;
+  }
+
+  // Verify that the identifier is a valid decl in the C decl namespace
+  LookupResult lookupResult(S, DeclarationName(identLoc->Ident),
+SourceLocation(),
+Sema::LookupNameKind::LookupOrdinaryName);
+  if (!S.LookupName(lookupResult, S.TUScope) ||
+  !lookupResult.getAsSingle()) {
+S.Diag(identLoc->Loc, diag::err_nserrordomain_invalid_decl)
+<< identLoc->Ident;
+return;
+  }
+
+  D->addAttr(::new (S.Context)
+ NSErrorDomainAttr(S.Context, Attr, identLoc->Ident));
+}
+
 static void handleObjCBridgeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   IdentifierLoc *Parm = AL.isArgIdent(0) ? AL.getArgAsIdent(0) : nullptr;
 
@@ -7098,6 +7131,9 @@
   case ParsedAttr::AT_ObjCBoxable:
 handleObjCBoxable(S, D, AL);
 break;
+  case ParsedAttr::AT_NSErrorDomain:
+handleNSErrorDomain(S, D, AL);
+break;
   case ParsedAttr::AT_CFAuditedTransfer:
 handleSimpleAttributeWithExclusions(S, D, AL);
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9453,6 +9453,14 @@
 def err_nsreturns_retained_attribute_mismatch : Error<
   "overriding method has mismatched ns_returns_%select{not_retained|retained}0"
   " attributes">;
+def err_nserrordomain_not_tagdecl : Error<
+  "ns_error_domain attribute only valid on "
+  "%select{enums, structs, and unions|enums, structs, unions, and classes}0">;
+def err_nserrordomain_invalid_decl : Error<
+  "domain argument %0 does not refer to global constant">;
+def err_nserrordomain_requires_identifier : Error<
+  "domain argument m

[PATCH] D84005: Introduce ns_error_domain attribute.

2020-07-20 Thread Michael Forster via Phabricator via cfe-commits
MForster added inline comments.



Comment at: clang/include/clang/Basic/Attr.td:1860
+def NSErrorDomain : Attr {
+  let Spellings = [GNU<"ns_error_domain">];
+  let Args = [IdentifierArgument<"ErrorDomain">];

aaron.ballman wrote:
> gribozavr2 wrote:
> > aaron.ballman wrote:
> > > MForster wrote:
> > > > gribozavr2 wrote:
> > > > > Could we try to add a list of subjects here? It seems like it is a 
> > > > > type-only attribute, and most likely enum-only.
> > > > > 
> > > > > let Subjects = SubjectList<[Enum]>;
> > > > @milseman, could you comment on this? 
> > > > 
> > > > In the meantime I've added the restriction. Obviously this makes the 
> > > > tests fail. I will also test this change against the Swift unit tests.
> > > FWIW, this is not a attribute; it's a declaration attribute.
> > > 
> > > Is there a reason it's not inheritable?
> > > 
> > > I assume it's not getting a Clang spelling because Objective-C isn't 
> > > tracking C2x yet? (Though that spelling still seems useful to 
> > > Objective-C++ users in general for these NS attributes.)
> > > FWIW, this is not a attribute; it's a declaration attribute.
> > 
> > Sorry, yes, of course I meant to say "declaration attribute".
> > 
> > > Is there a reason it's not inheritable?
> > 
> > Good observation, I think it should be.
> > 
> > > I assume it's not getting a Clang spelling because Objective-C isn't 
> > > tracking C2x yet?
> > 
> > Cocoa users are expected to use the `NS_*` macros instead of using the 
> > attribute directly, so even if a C2x spelling was an option (IDK if it is), 
> > there would be very limited use for it.
> > Cocoa users are expected to use the NS_* macros instead of using the 
> > attribute directly, so even if a C2x spelling was an option (IDK if it is), 
> > there would be very limited use for it.
> 
> Okay, that's reasonable, thanks!
> Is there a reason it's not inheritable?

I made it inheritable. @milseman, any comment on whether that is appropriate? 



Comment at: clang/test/Analysis/ns_error_enum.m:1
+// RUN: %clang_cc1 -verify %s
+

aaron.ballman wrote:
> gribozavr2 wrote:
> > aaron.ballman wrote:
> > > MForster wrote:
> > > > gribozavr2 wrote:
> > > > > This file is a `.m` -- any specific reason? I'd call it `.c` and run 
> > > > > the test in C, Objective-C, and C++ modes (enums might work slightly 
> > > > > differently, the name lookup functionality might work differently).
> > > > The test doesn't compile in C or C++ (`non-defining declaration of 
> > > > enumeration with a fixed underlying type is only permitted as a 
> > > > standalone declaration; missing list of enumerators?`). Not sure if 
> > > > it's worth adapting.
> > > Enums with fixed underlying types exist in C++ and C, so I was expecting 
> > > the attribute to work there. If the attribute isn't supported in these 
> > > languages, should the attribute be tied to a language mode?
> > There are Apple SDK headers that parse in all language modes (C, 
> > Objective-C, C++, Objective-C++), so I think it is quite important to test 
> > this feature in all modes. I suspect the reason for the error is that 
> > different language modes require a slightly different macro definition.
> > There are Apple SDK headers that parse in all language modes (C, 
> > Objective-C, C++, Objective-C++), so I think it is quite important to test 
> > this feature in all modes.
> 
> In that case, I definitely agree. This should have multiple RUN lines to test 
> the various language modes.
>>There are Apple SDK headers that parse in all language modes (C, Objective-C, 
>>C++, Objective-C++), so I think it is quite important to test this feature in 
>>all modes.
>In that case, I definitely agree. This should have multiple RUN lines to test 
>the various language modes.

So, it seems that the error message is quite new. I suspect that the Apple SDK 
headers have not yet been updated. At least I'm getting the same error messages 
when running the test with the (rather elaborate) original definitions of 
`CF_ENUM` and `NS_ERROR_ENUM`. 

For now I have just disabled the diagnostic for C and C++ 
(`-Wno-elaborated-enum-base`). For ObjC it is disabled anyway.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84005



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


[PATCH] D67833: [OpenMP 5.0] Codegen support to pass user-defined mapper functions to runtime

2020-07-20 Thread Lingda Li via Phabricator via cfe-commits
lildmh added a comment.

In D67833#2161241 , @Meinersbur wrote:

> Seems that it already has been applied ;-)


Yes, thanks Michael. Hope everything goes well with you


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67833



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


[PATCH] D84150: [clangd] Fix conversion from Windows UNC paths to file URI format.

2020-07-20 Thread Ilya Golovenko via Phabricator via cfe-commits
ilya-golovenko updated this revision to Diff 279233.
ilya-golovenko added a comment.

Consistent naming: hasDriveLetter => isWindowsPath


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84150

Files:
  clang-tools-extra/clangd/URI.cpp


Index: clang-tools-extra/clangd/URI.cpp
===
--- clang-tools-extra/clangd/URI.cpp
+++ clang-tools-extra/clangd/URI.cpp
@@ -26,13 +26,13 @@
  llvm::inconvertibleErrorCode());
 }
 
-bool hasDriveLetter(llvm::StringRef Path) {
+bool isWindowsPath(llvm::StringRef Path) {
   return Path.size() > 1 && llvm::isAlpha(Path[0]) && Path[1] == ':';
 }
 
-bool isNetworkPath(llvm::StringRef Name) {
+bool isNetworkPath(llvm::StringRef Path) {
   llvm::StringRef Sep = llvm::sys::path::get_separator();
-  return Name.consume_front(Sep) && Name.consume_front(Sep) && !Name.empty();
+  return Path.consume_front(Sep) && Path.consume_front(Sep) && !Path.empty();
 }
 
 /// This manages file paths in the file system. All paths in the scheme
@@ -53,7 +53,7 @@
 if (!Authority.empty())
   ("//" + Authority).toVector(Path);
 // For Windows paths e.g. /X:
-if (hasDriveLetter(Body.substr(1)))
+if (isWindowsPath(Body.substr(1)))
   Body.consume_front("/");
 Path.append(Body);
 llvm::sys::path::native(Path);
@@ -71,7 +71,7 @@
   AbsolutePath.consume_front(Root);
 }
 // For Windows paths e.g. X:
-if (hasDriveLetter(Root))
+if (isWindowsPath(Root))
   Body = "/";
 Body += llvm::sys::path::convert_to_slash(AbsolutePath);
 return URI("file", Authority, Body);


Index: clang-tools-extra/clangd/URI.cpp
===
--- clang-tools-extra/clangd/URI.cpp
+++ clang-tools-extra/clangd/URI.cpp
@@ -26,13 +26,13 @@
  llvm::inconvertibleErrorCode());
 }
 
-bool hasDriveLetter(llvm::StringRef Path) {
+bool isWindowsPath(llvm::StringRef Path) {
   return Path.size() > 1 && llvm::isAlpha(Path[0]) && Path[1] == ':';
 }
 
-bool isNetworkPath(llvm::StringRef Name) {
+bool isNetworkPath(llvm::StringRef Path) {
   llvm::StringRef Sep = llvm::sys::path::get_separator();
-  return Name.consume_front(Sep) && Name.consume_front(Sep) && !Name.empty();
+  return Path.consume_front(Sep) && Path.consume_front(Sep) && !Path.empty();
 }
 
 /// This manages file paths in the file system. All paths in the scheme
@@ -53,7 +53,7 @@
 if (!Authority.empty())
   ("//" + Authority).toVector(Path);
 // For Windows paths e.g. /X:
-if (hasDriveLetter(Body.substr(1)))
+if (isWindowsPath(Body.substr(1)))
   Body.consume_front("/");
 Path.append(Body);
 llvm::sys::path::native(Path);
@@ -71,7 +71,7 @@
   AbsolutePath.consume_front(Root);
 }
 // For Windows paths e.g. X:
-if (hasDriveLetter(Root))
+if (isWindowsPath(Root))
   Body = "/";
 Body += llvm::sys::path::convert_to_slash(AbsolutePath);
 return URI("file", Authority, Body);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84005: Introduce ns_error_domain attribute.

2020-07-20 Thread Michael Forster via Phabricator via cfe-commits
MForster marked an inline comment as done.
MForster added inline comments.



Comment at: clang/include/clang/Basic/Attr.td:1860
+def NSErrorDomain : Attr {
+  let Spellings = [GNU<"ns_error_domain">];
+  let Args = [IdentifierArgument<"ErrorDomain">];

MForster wrote:
> aaron.ballman wrote:
> > gribozavr2 wrote:
> > > aaron.ballman wrote:
> > > > MForster wrote:
> > > > > gribozavr2 wrote:
> > > > > > Could we try to add a list of subjects here? It seems like it is a 
> > > > > > type-only attribute, and most likely enum-only.
> > > > > > 
> > > > > > let Subjects = SubjectList<[Enum]>;
> > > > > @milseman, could you comment on this? 
> > > > > 
> > > > > In the meantime I've added the restriction. Obviously this makes the 
> > > > > tests fail. I will also test this change against the Swift unit tests.
> > > > FWIW, this is not a attribute; it's a declaration attribute.
> > > > 
> > > > Is there a reason it's not inheritable?
> > > > 
> > > > I assume it's not getting a Clang spelling because Objective-C isn't 
> > > > tracking C2x yet? (Though that spelling still seems useful to 
> > > > Objective-C++ users in general for these NS attributes.)
> > > > FWIW, this is not a attribute; it's a declaration attribute.
> > > 
> > > Sorry, yes, of course I meant to say "declaration attribute".
> > > 
> > > > Is there a reason it's not inheritable?
> > > 
> > > Good observation, I think it should be.
> > > 
> > > > I assume it's not getting a Clang spelling because Objective-C isn't 
> > > > tracking C2x yet?
> > > 
> > > Cocoa users are expected to use the `NS_*` macros instead of using the 
> > > attribute directly, so even if a C2x spelling was an option (IDK if it 
> > > is), there would be very limited use for it.
> > > Cocoa users are expected to use the NS_* macros instead of using the 
> > > attribute directly, so even if a C2x spelling was an option (IDK if it 
> > > is), there would be very limited use for it.
> > 
> > Okay, that's reasonable, thanks!
> > Is there a reason it's not inheritable?
> 
> I made it inheritable. @milseman, any comment on whether that is appropriate? 
>> Could we try to add a list of subjects here? It seems like it is a type-only 
>> attribute, and most likely enum-only.
>>
>> let Subjects = SubjectList<[Enum]>;
>
> @milseman, could you comment on this?
>
> In the meantime I've added the restriction. Obviously this makes the tests 
> fail. I will also test this change against the Swift unit tests.

FWIW, no failures in the Swift tests.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84005



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


[PATCH] D81311: [RFC] LangRef: Define byref parameter attribute

2020-07-20 Thread Matt Arsenault via Phabricator via cfe-commits
arsenm closed this revision.
arsenm added a comment.

Merged with D83518  as 
5e999cbe8db0b50dc9828a1c062b4ffe84c5b137 



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

https://reviews.llvm.org/D81311



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


[PATCH] D84172: [clangd] Fix conversion from Windows UNC paths to file URI format.

2020-07-20 Thread Ilya Golovenko via Phabricator via cfe-commits
ilya-golovenko created this revision.
Herald added subscribers: cfe-commits, kbobyrev, usaxena95, kadircet, arphaman, 
jkorous, MaskRay, ilya-biryukov.
Herald added a project: clang.

The fix improves handling of Windows UNC paths to align with Appendix E. 
Nonstandard Syntax Variations of RFC 8089. Before this fix it was difficult to 
use Windows UNC paths in compile_commands.json as such paths were converted to 
file URIs using 'file:authority/share/file.cpp' notation instead of 
recommended 'file://authority/share/file.cpp'. As an example, VS.Code cannot 
understand such file URIsm thus such features as go-to-definition, 
jump-to-file, hover tooltip, etc. stop working.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84172

Files:
  clang-tools-extra/clangd/URI.cpp
  clang-tools-extra/clangd/unittests/URITests.cpp

Index: clang-tools-extra/clangd/unittests/URITests.cpp
===
--- clang-tools-extra/clangd/unittests/URITests.cpp
+++ clang-tools-extra/clangd/unittests/URITests.cpp
@@ -76,6 +76,16 @@
 #endif
 }
 
+TEST(URITest, CreateUNC) {
+#ifdef _WIN32
+  EXPECT_THAT(createOrDie("test.org\\x\\y\\z"), "file://test.org/x/y/z");
+  EXPECT_THAT(createOrDie("10.0.0.1\\x\\y\\z"), "file://10.0.0.1/x/y/z");
+#else
+  EXPECT_THAT(createOrDie("//test.org/x/y/z"), "file://test.org/x/y/z");
+  EXPECT_THAT(createOrDie("//10.0.0.1/x/y/z"), "file://10.0.0.1/x/y/z");
+#endif
+}
+
 TEST(URITest, FailedCreate) {
   EXPECT_ERROR(URI::create("/x/y/z", "no"));
   // Path has to be absolute.
@@ -127,15 +137,29 @@
   EXPECT_THAT(resolveOrDie(parseOrDie("file:///c:/x/y/z")), "c:\\x\\y\\z");
 #else
   EXPECT_EQ(resolveOrDie(parseOrDie("file:/a/b/c")), "/a/b/c");
-  EXPECT_EQ(resolveOrDie(parseOrDie("file://auth/a/b/c")), "/a/b/c");
+  EXPECT_EQ(resolveOrDie(parseOrDie("file://auth/a/b/c")), "//auth/a/b/c");
   EXPECT_THAT(resolveOrDie(parseOrDie("file://au%3dth/%28x%29/y/%20z")),
-  "/(x)/y/ z");
+  "//au=th/(x)/y/ z");
   EXPECT_THAT(resolveOrDie(parseOrDie("file:///c:/x/y/z")), "c:/x/y/z");
 #endif
   EXPECT_EQ(resolveOrDie(parseOrDie("unittest:///a"), testPath("x")),
 testPath("a"));
 }
 
+TEST(URITest, ResolveUNC) {
+#ifdef _WIN32
+  EXPECT_THAT(resolveOrDie(parseOrDie("file://example.com/x/y/z")),
+  "example.com\\x\\y\\z");
+  EXPECT_THAT(resolveOrDie(parseOrDie("file://127.0.0.1/x/y/z")),
+  "127.0.0.1\\x\\y\\z");
+#else
+  EXPECT_THAT(resolveOrDie(parseOrDie("file://example.com/x/y/z")),
+  "//example.com/x/y/z");
+  EXPECT_THAT(resolveOrDie(parseOrDie("file://127.0.0.1/x/y/z")),
+  "//127.0.0.1/x/y/z");
+#endif
+}
+
 std::string resolvePathOrDie(llvm::StringRef AbsPath,
  llvm::StringRef HintPath = "") {
   auto Path = URI::resolvePath(AbsPath, HintPath);
Index: clang-tools-extra/clangd/URI.cpp
===
--- clang-tools-extra/clangd/URI.cpp
+++ clang-tools-extra/clangd/URI.cpp
@@ -26,6 +26,15 @@
  llvm::inconvertibleErrorCode());
 }
 
+bool isWindowsPath(llvm::StringRef Path) {
+  return Path.size() > 1 && llvm::isAlpha(Path[0]) && Path[1] == ':';
+}
+
+bool isNetworkPath(llvm::StringRef Path) {
+  llvm::StringRef Sep = llvm::sys::path::get_separator();
+  return Path.consume_front(Sep) && Path.consume_front(Sep) && !Path.empty();
+}
+
 /// This manages file paths in the file system. All paths in the scheme
 /// are absolute (with leading '/').
 /// Note that this scheme is hardcoded into the library and not registered in
@@ -33,28 +42,39 @@
 class FileSystemScheme : public URIScheme {
 public:
   llvm::Expected
-  getAbsolutePath(llvm::StringRef /*Authority*/, llvm::StringRef Body,
+  getAbsolutePath(llvm::StringRef Authority, llvm::StringRef Body,
   llvm::StringRef /*HintPath*/) const override {
 if (!Body.startswith("/"))
   return make_string_error("File scheme: expect body to be an absolute "
"path starting with '/': " +
Body);
+llvm::SmallString<128> Path;
+// For Windows UNC paths e.g. \\server\share
+if (!Authority.empty())
+  ("//" + Authority).toVector(Path);
 // For Windows paths e.g. /X:
-if (Body.size() > 2 && Body[0] == '/' && Body[2] == ':')
+if (isWindowsPath(Body.substr(1)))
   Body.consume_front("/");
-llvm::SmallVector Path(Body.begin(), Body.end());
+Path.append(Body);
 llvm::sys::path::native(Path);
-return std::string(Path.begin(), Path.end());
+return std::string(Path);
   }
 
   llvm::Expected
   uriFromAbsolutePath(llvm::StringRef AbsolutePath) const override {
 std::string Body;
+llvm::StringRef Authority;
+llvm::StringRef Root = llvm::sys::path::root_name(AbsolutePath);
+// For Windows UNC paths e.g. \\server\share
+if (isNetwor

[PATCH] D84090: [clang-format] Add BitFieldColonSpacing option

2020-07-20 Thread Anders Waldenborg via Phabricator via cfe-commits
wanders updated this revision to Diff 279237.
wanders retitled this revision from "[clang-format] Add 
SpaceAroundBitFieldColon option" to "[clang-format] Add BitFieldColonSpacing 
option".
wanders edited the summary of this revision.
wanders added a comment.

Renamed option to "BitFieldColonSpacing" and made it an enum of: "Both", 
"None," "Before", "After"


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84090

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/TokenAnnotator.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -2165,6 +2165,34 @@
"  uchar : 8;\n"
"  uchar other;\n"
"};");
+  FormatStyle Style = getLLVMStyle();
+  Style.BitFieldColonSpacing = FormatStyle::BFCS_None;
+  verifyFormat("struct Bitfields {\n"
+   "  unsigned sClass:8;\n"
+   "  unsigned ValueKind:2;\n"
+   "  uchar other;\n"
+   "};",
+   Style);
+  verifyFormat("struct A {\n"
+   "  int a:1,\n"
+   "  b:2;\n"
+   "};",
+	   Style);
+  Style.BitFieldColonSpacing = FormatStyle::BFCS_Before;
+  verifyFormat("struct Bitfields {\n"
+   "  unsigned sClass :8;\n"
+   "  unsigned ValueKind :2;\n"
+   "  uchar other;\n"
+   "};",
+   Style);
+  Style.BitFieldColonSpacing = FormatStyle::BFCS_After;
+  verifyFormat("struct Bitfields {\n"
+   "  unsigned sClass: 8;\n"
+   "  unsigned ValueKind: 2;\n"
+   "  uchar other;\n"
+   "};",
+   Style);
+
 }
 
 TEST_F(FormatTest, FormatsNamespaces) {
@@ -12156,6 +12184,21 @@
"int   oneTwoThree : 23 = 0;",
Alignment);
 
+  Alignment.BitFieldColonSpacing = FormatStyle::BFCS_None;
+  verifyFormat("int const a  :5;\n"
+   "int   oneTwoThree:23;",
+   Alignment);
+
+  Alignment.BitFieldColonSpacing = FormatStyle::BFCS_Before;
+  verifyFormat("int const a   :5;\n"
+   "int   oneTwoThree :23;",
+   Alignment);
+
+  Alignment.BitFieldColonSpacing = FormatStyle::BFCS_After;
+  verifyFormat("int const a  : 5;\n"
+   "int   oneTwoThree: 23;",
+   Alignment);
+
   // Known limitations: ':' is only recognized as a bitfield colon when
   // followed by a number.
   /*
@@ -14004,6 +14047,16 @@
   CHECK_PARSE("IndentExternBlock: false", IndentExternBlock,
   FormatStyle::IEBS_NoIndent);
 
+  Style.BitFieldColonSpacing = FormatStyle::BFCS_None;
+  CHECK_PARSE("BitFieldColonSpacing: Both", BitFieldColonSpacing,
+  FormatStyle::BFCS_Both);
+  CHECK_PARSE("BitFieldColonSpacing: None", BitFieldColonSpacing,
+  FormatStyle::BFCS_None);
+  CHECK_PARSE("BitFieldColonSpacing: Before", BitFieldColonSpacing,
+  FormatStyle::BFCS_Before);
+  CHECK_PARSE("BitFieldColonSpacing: After", BitFieldColonSpacing,
+  FormatStyle::BFCS_After);
+
   // FIXME: This is required because parsing a configuration simply overwrites
   // the first N elements of the list instead of resetting it.
   Style.ForEachMacros.clear();
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -3251,6 +3251,8 @@
   if (Right.is(TT_RangeBasedForLoopColon) &&
   !Style.SpaceBeforeRangeBasedForLoopColon)
 return false;
+  if (Left.is(TT_BitFieldColon))
+return Style.BitFieldColonSpacing == FormatStyle::BFCS_Both || Style.BitFieldColonSpacing == FormatStyle::BFCS_After;
   if (Right.is(tok::colon)) {
 if (Line.First->isOneOf(tok::kw_case, tok::kw_default) ||
 !Right.getNextNonComment() || Right.getNextNonComment()->is(tok::semi))
@@ -3267,6 +3269,8 @@
   return false;
 if (Right.is(TT_CSharpNamedArgumentColon))
   return false;
+if (Right.is(TT_BitFieldColon))
+  return Style.BitFieldColonSpacing == FormatStyle::BFCS_Both || Style.BitFieldColonSpacing == FormatStyle::BFCS_Before;
 return true;
   }
   if (Left.is(TT_UnaryOperator)) {
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -366,6 +366,15 @@
   }
 };
 
+template <> struct ScalarEnumerationTraits {
+  static void enumeration(IO &IO, FormatStyle::BitFieldColonSpacingStyle &Value) {
+ 

[PATCH] D82598: [analyzer][Liveness][NFC] Get rid of statement liveness, because such a thing doesn't exist

2020-07-20 Thread Kristóf Umann via Phabricator via cfe-commits
Szelethus added a comment.

I chased my own tail for weeks before realizing that there is indeed another 
instance when a live **statement** is stored, other then 
`ObjCForCollectionStmt`...

  void clang_analyzer_eval(bool);
  
  void test_lambda_refcapture() {
int a = 6;
[&](int &a) { a = 42; }(a);
clang_analyzer_eval(a == 42); // expected-warning{{TRUE}}
  }
  
  // CHECK: [ B0 (live statements at block exit) ]
  // CHECK-EMPTY:
  // CHECK-EMPTY:
  // CHECK-NEXT: [ B1 (live statements at block exit) ]
  // CHECK-EMPTY:
  // CHECK-EMPTY:
  // CHECK-NEXT: [ B2 (live statements at block exit) ]
  // CHECK-EMPTY:
  // CHECK-NEXT: CompoundStmt {{.*}}
  // CHECK-NEXT: `-BinaryOperator {{.*}} 'int' lvalue '='
  // CHECK-NEXT:   |-DeclRefExpr {{.*}} 'int' lvalue ParmVar {{.*}} 'a' 'int &'
  // CHECK-NEXT:   `-IntegerLiteral {{.*}} 'int' 42


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D82598



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


[PATCH] D72705: [analyzer] Added new checker 'alpha.unix.ErrorReturn'.

2020-07-20 Thread Balázs Kéri via Phabricator via cfe-commits
balazske updated this revision to Diff 279248.
balazske added a comment.

NFC code improvements.
Detect expressions in conditions.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D72705

Files:
  clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
  clang/lib/StaticAnalyzer/Checkers/ErrorReturnChecker.cpp
  clang/test/Analysis/Inputs/system-header-simulator.h
  clang/test/Analysis/error-return.c

Index: clang/test/Analysis/error-return.c
===
--- /dev/null
+++ clang/test/Analysis/error-return.c
@@ -0,0 +1,181 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.unix.ErrorReturn -verify %s
+
+#include "Inputs/system-header-simulator.h"
+
+FILE *file();
+
+void test_EOFOrNeg_LT_Good() {
+  if (fputs("str", file()) < 0) {
+  }
+}
+
+void test_EOFOrNeg_LT_Bad() {
+  if (fputs("str", file()) < -1) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_GT_Good() {
+  if (fputs("str", file()) > -1) {
+  }
+}
+
+void test_EOFOrNeg_GT_Bad() {
+  if (fputs("str", file()) > 0) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_LE_Good() {
+  if (fputs("str", file()) <= -1) {
+  }
+}
+
+void test_EOFOrNeg_LE_Bad() {
+  if (fputs("str", file()) <= 0) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_GE_Good() {
+  if (fputs("str", file()) >= 0) {
+  }
+}
+
+void test_EOFOrNeg_GE_Bad() {
+  if (fputs("str", file()) >= -1) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_EQ_Good() {
+  if (fputs("str", file()) == -1) {
+  }
+}
+
+void test_EOFOrNeg_EQ_Bad() {
+  if (fputs("str", file()) == 0) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_NE_Good() {
+  if (fputs("str", file()) != -1) {
+  }
+}
+
+void test_EOFOrNeg_NE_Bad() {
+  if (fputs("str", file()) != 0) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_EQ_BadVal() {
+  if (fputs("str", file()) == -2) { // expected-warning{{Use of return value that was not checked}}
+  }
+  if (fputs("str", file()) == 1) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_VarAssign() {
+  int X = fputs("str", file());
+  if (X != 0) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_VarAssignInCond() {
+  int X;
+  if ((X = fputs("str", file())) != 0) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_VarAssign1() {
+  int X = fputs("str", file());
+  int Y = X;
+  if (Y != 0) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void badcheck(int X) {
+  if (X == 0) { } // expected-warning{{Use of return value that was not checked}}
+}
+
+void test_EOFOrNeg_Call() {
+  int X = fputs("str", file());
+  badcheck(X);
+}
+
+void test_EOFOrNeg_Syscall() {
+  int X = fputs("str", file());
+  fakeSystemHeaderCallIntVal(X); // expected-warning{{Use of return value that was not checked}}
+  fakeSystemHeaderCallIntVal(fputs("str", file())); // expected-warning{{Use of return value that was not checked}}
+}
+
+void test_EOFOrNeg_Use_LNot() {
+  int X = fputs("str", file());
+  if (!X) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_Use_Add() {
+  int X = fputs("str", file());
+  int Y = X + 1; // expected-warning{{Use of return value that was not checked}}
+}
+
+void test_EOFOrNeg_If() {
+  int X = fputs("str", file());
+  if (X) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_IfCond() {
+  if (fputs("str", file())) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_ForInit() {
+  for (fputs("str", file());;) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_ForCond() {
+  for (; fputs("str", file());) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_ForInc() {
+  for (;; fputs("str", file())) { // expected-warning{{Use of return value that was not checked}}
+  }
+}
+
+void test_EOFOrNeg_DoCond() {
+  do {
+  } while (fputs("str", file())); // expected-warning{{Use of return value that was not checked}}
+}
+
+void test_EOFOrNeg_WhileCond() {
+  while (fputs("str", file())) {
+  }; // expected-warning{{Use of return value that was not checked}}
+}
+
+void unknown1(int);
+
+void test_EOFOrNeg_EscapeCall() {
+  int X = fputs("str", file());
+  unknown1(X);
+  int Y = X + 1;
+}
+
+int GlobalInt;
+
+void test_EOFOrNeg_EscapeGlobalAssign() {
+  GlobalInt = fputs("str", file());
+  int X = GlobalInt + 1;
+}
+
+void test_EOFOrNeg_NoErrorAfterGood

[PATCH] D84172: [clangd] Fix conversion from Windows UNC paths to file URI format.

2020-07-20 Thread Sam McCall via Phabricator via cfe-commits
sammccall added a comment.

Thanks for doing this! And sorry about the shaky windows support...

(There are potentially other lurking issues due to filenames being used as keys 
internally, particularly case-insensitivity issues...)




Comment at: clang-tools-extra/clangd/URI.cpp:29
 
+bool isWindowsPath(llvm::StringRef Path) {
+  return Path.size() > 1 && llvm::isAlpha(Path[0]) && Path[1] == ':';

the UNC paths are also basically a windows thing, can we have 
hasWindowsDriveLetter and isWindowsNetworkPath (or isWindowsUNCPath)?



Comment at: clang-tools-extra/clangd/URI.cpp:34
+bool isNetworkPath(llvm::StringRef Path) {
+  llvm::StringRef Sep = llvm::sys::path::get_separator();
+  return Path.consume_front(Sep) && Path.consume_front(Sep) && !Path.empty();

conventionally LLVM tools accept both slashes on windows and `/` on other 
platforms - i.e. we should probably treat `//foo/bar` as a valid network path 
on windows unless there's a good reason not to.

So `Path.size() > 2 && llvm::sys::path::is_separator(Path[0]) && 
llvm::sys::path::is_separator(Path[1])`, I guess



Comment at: clang-tools-extra/clangd/URI.cpp:52
+llvm::SmallString<128> Path;
+// For Windows UNC paths e.g. \\server\share
+if (!Authority.empty())

These comments could be extended a little and be even more useful:

`Windows UNC paths e.g. \\server\share <=> file://server/share`



Comment at: clang-tools-extra/clangd/URI.cpp:56
 // For Windows paths e.g. /X:
-if (Body.size() > 2 && Body[0] == '/' && Body[2] == ':')
+if (isWindowsPath(Body.substr(1)))
   Body.consume_front("/");

this raises the question: what if both conditions are true?

file://abc/c:/foo

`\\abc\c:` seems much more plausible than the current `\\abcc:`, so I think 
this should be `else if`.



Comment at: clang-tools-extra/clangd/URI.cpp:67
+llvm::StringRef Authority;
+llvm::StringRef Root = llvm::sys::path::root_name(AbsolutePath);
+// For Windows UNC paths e.g. \\server\share

FWIW, I think we were previously parsing drive letters even on unix, and will 
no longer do so.
I don't think this is a real problem though.



Comment at: clang-tools-extra/clangd/unittests/URITests.cpp:149
 
+TEST(URITest, ResolveUNC) {
+#ifdef _WIN32

Could we add a test that the old four-slash version can still be resolved to a 
path?

It probably worked by accident - we probably weren't thinking about UNC paths 
at all. But someone still might depend on it now. I don't think this patch 
breaks it, just want to check.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84172



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


[clang] 33c9d03 - Upgrade SmallSets of pointer-like types to SmallPtrSet

2020-07-20 Thread Benjamin Kramer via cfe-commits

Author: Benjamin Kramer
Date: 2020-07-20T16:54:29+02:00
New Revision: 33c9d0320e96ba17a3c7e84e04e22536f4b0a9e8

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

LOG: Upgrade SmallSets of pointer-like types to SmallPtrSet

This is slightly more efficient. NFC.

Added: 


Modified: 
clang/include/clang/AST/DeclarationName.h
clang/include/clang/AST/Redeclarable.h
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp

Removed: 




diff  --git a/clang/include/clang/AST/DeclarationName.h 
b/clang/include/clang/AST/DeclarationName.h
index 82f6868e3a7e..a037e8b197bc 100644
--- a/clang/include/clang/AST/DeclarationName.h
+++ b/clang/include/clang/AST/DeclarationName.h
@@ -857,6 +857,16 @@ struct DenseMapInfo {
   }
 };
 
+template <> struct PointerLikeTypeTraits {
+  static inline void *getAsVoidPointer(clang::DeclarationName P) {
+return P.getAsOpaquePtr();
+  }
+  static inline clang::DeclarationName getFromVoidPointer(void *P) {
+return clang::DeclarationName::getFromOpaquePtr(P);
+  }
+  static constexpr int NumLowBitsAvailable = 0;
+};
+
 } // namespace llvm
 
 // The definition of AssumedTemplateStorage is factored out of TemplateName to

diff  --git a/clang/include/clang/AST/Redeclarable.h 
b/clang/include/clang/AST/Redeclarable.h
index 0975773dd2cb..87252337a0f4 100644
--- a/clang/include/clang/AST/Redeclarable.h
+++ b/clang/include/clang/AST/Redeclarable.h
@@ -370,6 +370,7 @@ template  class CanonicalDeclPtr {
 
 private:
   friend struct llvm::DenseMapInfo>;
+  friend struct llvm::PointerLikeTypeTraits>;
 
   decl_type *Ptr = nullptr;
 };
@@ -407,6 +408,20 @@ struct DenseMapInfo> {
   }
 };
 
+template 
+struct PointerLikeTypeTraits> {
+  static inline void *getAsVoidPointer(clang::CanonicalDeclPtr P) {
+return P.Ptr;
+  }
+  static inline clang::CanonicalDeclPtr getFromVoidPointer(void *P) 
{
+clang::CanonicalDeclPtr C;
+C.Ptr = PointerLikeTypeTraits::getFromVoidPtr(P);
+return C;
+  }
+  static constexpr int NumLowBitsAvailable =
+  PointerLikeTypeTraits::NumLowBitsAvailable;
+};
+
 } // namespace llvm
 
 #endif // LLVM_CLANG_AST_REDECLARABLE_H

diff  --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 2f2b52106f3d..735349c3de62 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -42,7 +42,7 @@
 #include "clang/Sema/TemplateInstCallback.h"
 #include "clang/Sema/TypoCorrection.h"
 #include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/TimeProfiler.h"
 
 using namespace clang;
@@ -1490,7 +1490,7 @@ class DeferredDiagnosticsEmitter
   typedef UsedDeclVisitor Inherited;
 
   // Whether the function is already in the current use-path.
-  llvm::SmallSet, 4> InUsePath;
+  llvm::SmallPtrSet, 4> InUsePath;
 
   // The current use-path.
   llvm::SmallVector, 4> UsePath;
@@ -1499,7 +1499,7 @@ class DeferredDiagnosticsEmitter
   // case not in OpenMP device context. Done[1] is for the case in OpenMP
   // device context. We need two sets because diagnostics emission may be
   // 
diff erent depending on whether it is in OpenMP device context.
-  llvm::SmallSet, 4> DoneMap[2];
+  llvm::SmallPtrSet, 4> DoneMap[2];
 
   // Emission state of the root node of the current use graph.
   bool ShouldEmitRootNode;

diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 212f5e4746d6..001fabff96ff 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -172,7 +172,7 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
   bool Failed = false;
 
   llvm::SmallVector FoundDecls;
-  llvm::SmallSet, 8> FoundDeclSet;
+  llvm::SmallPtrSet, 8> FoundDeclSet;
 
   // If we have an object type, it's because we are in a
   // pseudo-destructor-expression or a member access expression, and

diff  --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 8bf605e5e76b..1e7d432217d5 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -19028,7 +19028,7 @@ OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
   [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
   !findOMPAlloctraitT(*this, StartLoc, DSAStack))
 return nullptr;
-  llvm::SmallSet, 4> PredefinedAllocators;
+  llvm::SmallPtrSet, 4> PredefinedAllocators;
   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
 auto AllocatorKind = static_cast(I);
 StringRef Allocator =

diff  --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index 2345a12caeb2..a8803aeb1b8a 100644
--- a/c

[clang] f3f1ce4 - [Driver] Promote SmallSet of enum to a bitset. NFCI.

2020-07-20 Thread Benjamin Kramer via cfe-commits

Author: Benjamin Kramer
Date: 2020-07-20T16:54:30+02:00
New Revision: f3f1ce4fa9f49c9d862fcc873eed92fee02b0685

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

LOG: [Driver] Promote SmallSet of enum to a bitset. NFCI.

Added: 


Modified: 
clang/lib/Driver/ToolChains/Cuda.cpp
clang/lib/Driver/ToolChains/Cuda.h
clang/lib/Driver/ToolChains/ROCm.h

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/Cuda.cpp 
b/clang/lib/Driver/ToolChains/Cuda.cpp
index 110a0bca9bc1..d7933534a5d3 100644
--- a/clang/lib/Driver/ToolChains/Cuda.cpp
+++ b/clang/lib/Driver/ToolChains/Cuda.cpp
@@ -259,13 +259,13 @@ void CudaInstallationDetector::AddCudaIncludeArgs(
 void CudaInstallationDetector::CheckCudaVersionSupportsArch(
 CudaArch Arch) const {
   if (Arch == CudaArch::UNKNOWN || Version == CudaVersion::UNKNOWN ||
-  ArchsWithBadVersion.count(Arch) > 0)
+  ArchsWithBadVersion[(int)Arch])
 return;
 
   auto MinVersion = MinVersionForCudaArch(Arch);
   auto MaxVersion = MaxVersionForCudaArch(Arch);
   if (Version < MinVersion || Version > MaxVersion) {
-ArchsWithBadVersion.insert(Arch);
+ArchsWithBadVersion[(int)Arch] = true;
 D.Diag(diag::err_drv_cuda_version_unsupported)
 << CudaArchToString(Arch) << CudaVersionToString(MinVersion)
 << CudaVersionToString(MaxVersion) << InstallPath

diff  --git a/clang/lib/Driver/ToolChains/Cuda.h 
b/clang/lib/Driver/ToolChains/Cuda.h
index 873eb7338a30..6afc29f7acee 100644
--- a/clang/lib/Driver/ToolChains/Cuda.h
+++ b/clang/lib/Driver/ToolChains/Cuda.h
@@ -15,9 +15,9 @@
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
 #include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallSet.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/VersionTuple.h"
+#include 
 #include 
 #include 
 
@@ -41,7 +41,7 @@ class CudaInstallationDetector {
 
   // CUDA architectures for which we have raised an error in
   // CheckCudaVersionSupportsArch.
-  mutable llvm::SmallSet ArchsWithBadVersion;
+  mutable std::bitset<(int)CudaArch::LAST> ArchsWithBadVersion;
 
 public:
   CudaInstallationDetector(const Driver &D, const llvm::Triple &HostTriple,

diff  --git a/clang/lib/Driver/ToolChains/ROCm.h 
b/clang/lib/Driver/ToolChains/ROCm.h
index 962c72fedfe0..27c7d8b0ee54 100644
--- a/clang/lib/Driver/ToolChains/ROCm.h
+++ b/clang/lib/Driver/ToolChains/ROCm.h
@@ -13,7 +13,6 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/Options.h"
-#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/Triple.h"
@@ -103,10 +102,6 @@ class RocmInstallationDetector {
CorrectlyRoundedSqrt.isValid();
   }
 
-  // GPU architectures for which we have raised an error in
-  // CheckRocmVersionSupportsArch.
-  mutable llvm::SmallSet ArchsWithBadVersion;
-
   void scanLibDevicePath(llvm::StringRef Path);
   void ParseHIPVersionFile(llvm::StringRef V);
   SmallVector getInstallationPathCandidates();
@@ -124,12 +119,6 @@ class RocmInstallationDetector {
   bool DAZ, bool FiniteOnly, bool 
UnsafeMathOpt,
   bool FastRelaxedMath, bool CorrectSqrt) 
const;
 
-  /// Emit an error if Version does not support the given Arch.
-  ///
-  /// If either Version or Arch is unknown, does not emit an error.  Emits at
-  /// most one error per Arch.
-  void CheckRocmVersionSupportsArch(CudaArch Arch) const;
-
   /// Check whether we detected a valid HIP runtime.
   bool hasHIPRuntime() const { return HasHIPRuntime; }
 



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


[clang] 66aff32 - Issue error on invalid arithemtic conversions in C ternary

2020-07-20 Thread Erich Keane via cfe-commits

Author: Erich Keane
Date: 2020-07-20T08:02:37-07:00
New Revision: 66aff3239849507861d050c013cbe17c4a5781a7

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

LOG: Issue error on invalid arithemtic conversions in C ternary

As reported in PR46774, an invalid arithemetic conversion used in a C
ternary operator resulted in an assertion. This patch replaces that
assertion with a diagnostic stating that the conversion failed.

At the moment, I believe the only case of this happening is _ExtInt
types.

Added: 
clang/test/Sema/ext-int.c

Modified: 
clang/lib/Sema/SemaExpr.cpp
clang/test/SemaCXX/ext-int.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 598aede14dd3..0bed0ddf539b 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -8106,6 +8106,15 @@ QualType Sema::CheckConditionalOperands(ExprResult 
&Cond, ExprResult &LHS,
   // If both operands have arithmetic type, do the usual arithmetic conversions
   // to find a common type: C99 6.5.15p3,5.
   if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType()) {
+// Disallow invalid arithmetic conversions, such as those between ExtInts 
of
+// 
diff erent sizes, or between ExtInts and other types.
+if (ResTy.isNull() && (LHSTy->isExtIntType() || RHSTy->isExtIntType())) {
+  Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
+  << LHSTy << RHSTy << LHS.get()->getSourceRange()
+  << RHS.get()->getSourceRange();
+  return QualType();
+}
+
 LHS = ImpCastExprToType(LHS.get(), ResTy, PrepareScalarCast(LHS, ResTy));
 RHS = ImpCastExprToType(RHS.get(), ResTy, PrepareScalarCast(RHS, ResTy));
 

diff  --git a/clang/test/Sema/ext-int.c b/clang/test/Sema/ext-int.c
new file mode 100644
index ..6996942a204b
--- /dev/null
+++ b/clang/test/Sema/ext-int.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wimplicit-int-conversion -triple 
x86_64-gnu-linux
+
+typedef _ExtInt(31) EI31;
+
+void Ternary(_ExtInt(30) s30, EI31 s31a, _ExtInt(31) s31b,
+ _ExtInt(32) s32, int b) {
+  b ? s30 : s31a; // expected-error{{incompatible operand types}}
+  b ? s31a : s30; // expected-error{{incompatible operand types}}
+  b ? s32 : 0; // expected-error{{incompatible operand types}}
+  (void)(b ? s31a : s31b);
+  (void)(s30 ? s31a : s31b);
+}

diff  --git a/clang/test/SemaCXX/ext-int.cpp b/clang/test/SemaCXX/ext-int.cpp
index 14f11a6bb961..0f2a3b89be1f 100644
--- a/clang/test/SemaCXX/ext-int.cpp
+++ b/clang/test/SemaCXX/ext-int.cpp
@@ -275,3 +275,12 @@ void ImplicitCasts(_ExtInt(31) s31, _ExtInt(33) s33, int 
i) {
   // expected-warning@+1{{implicit conversion loses integer precision}}
   i = s33;
 }
+
+void Ternary(_ExtInt(30) s30, _ExtInt(31) s31a, _ExtInt(31) s31b,
+ _ExtInt(32) s32, bool b) {
+  b ? s30 : s31a; // expected-error{{incompatible operand types}}
+  b ? s31a : s30; // expected-error{{incompatible operand types}}
+  b ? s32 : (int)0; // expected-error{{incompatible operand types}}
+  (void)(b ? s31a : s31b);
+  (void)(s30 ? s31a : s31b);
+}



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


[PATCH] D84176: [CMake][CTE] Add "check-clang-tools-..." targets to test only a particular Clang extra tool

2020-07-20 Thread Whisperity via Phabricator via cfe-commits
whisperity created this revision.
whisperity added a reviewer: klimek.
whisperity added a project: clang-tools-extra.
Herald added subscribers: cfe-commits, martong, gamesh411, Szelethus, dkrupp, 
rnkovacs, mgorny.
Herald added a project: clang.

Create targets `check-clang-tools-clang-tidy`, `check-clang-tools-clang-query` 
similar to how `check-clang-sema`, `check-clang-parser`, etc. are 
auto-generated from the directory structure.

This allows running only a particular sub-tool's tests, not having to wait 
through the //entire// `check-clang-tools`'s execution.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84176

Files:
  clang-tools-extra/test/CMakeLists.txt


Index: clang-tools-extra/test/CMakeLists.txt
===
--- clang-tools-extra/test/CMakeLists.txt
+++ clang-tools-extra/test/CMakeLists.txt
@@ -90,3 +90,7 @@
   )
 
 set_target_properties(check-clang-tools PROPERTIES FOLDER "Clang extra tools' 
tests")
+
+add_lit_testsuites(CLANG-TOOLS ${CMAKE_CURRENT_SOURCE_DIR}
+  DEPENDS ${CLANG_TOOLS_TEST_DEPS}
+  )


Index: clang-tools-extra/test/CMakeLists.txt
===
--- clang-tools-extra/test/CMakeLists.txt
+++ clang-tools-extra/test/CMakeLists.txt
@@ -90,3 +90,7 @@
   )
 
 set_target_properties(check-clang-tools PROPERTIES FOLDER "Clang extra tools' tests")
+
+add_lit_testsuites(CLANG-TOOLS ${CMAKE_CURRENT_SOURCE_DIR}
+  DEPENDS ${CLANG_TOOLS_TEST_DEPS}
+  )
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84176: [CMake][CTE] Add "check-clang-tools-..." targets to test only a particular Clang extra tool

2020-07-20 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri added a comment.

Thank you, this would be very helpful.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84176



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


[PATCH] D83826: [clangd] Don't send invalid messages from remote index

2020-07-20 Thread Sam McCall via Phabricator via cfe-commits
sammccall accepted this revision.
sammccall added inline comments.
This revision is now accepted and ready to land.



Comment at: clang-tools-extra/clangd/index/remote/Client.cpp:68
+DeadlineWaitingTime(DeadlineTime) {
+ProtobufMarshaller = std::unique_ptr(
+new Marshaller(/*RemoteIndexRoot=*/"", 
/*LocalIndexRoot=*/ProjectRoot));

this is PratabufMarshaller.reset(new...) or just initialize it in the init list



Comment at: 
clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp:199
   Result.set_name(From.Name.str());
-  auto Definition = toProtobuf(From.Definition, IndexRoot);
-  if (Definition)
+  if (std::strlen(From.Definition.FileURI)) {
+auto Definition = toProtobuf(From.Definition);

nit: just if (*From.Definition.FileURI)?



Comment at: 
clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp:244
+  if (!Location) {
+elog("Can not convert Reference to potobuf (invalid location) {0}: {1}",
+ From, From.Location);

potobuf -> protobuf



Comment at: clang-tools-extra/clangd/index/remote/marshalling/Marshalling.h:67
 
-LookupRequest toProtobuf(const clangd::LookupRequest &From);
-FuzzyFindRequest toProtobuf(const clangd::FuzzyFindRequest &From,
-llvm::StringRef IndexRoot);
-RefsRequest toProtobuf(const clangd::RefsRequest &From);
+  void setLocalIndexRoot(llvm::StringRef NewRoot);
+  void setRemoteIndexRoot(llvm::StringRef NewRoot);

why are these needed?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83826



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


[PATCH] D83922: [OpenMP] Fix map clause for unused var: don't ignore it

2020-07-20 Thread Alexey Bataev via Phabricator via cfe-commits
ABataev added a comment.

Looks like it breaks unified_shared_memory/close_enter_exit.c test. Could check 
this, please?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83922



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


[PATCH] D83942: [analyzer][tests] Add a notion of project sizes

2020-07-20 Thread Valeriy Savchenko via Phabricator via cfe-commits
vsavchenko added a comment.

In D83942#2156320 , @NoQ wrote:

> > Sizes assigned to the projects in this commit, do not directly
> >  correspond to the number of lines or files in the project.
>
> Maybe `QUICK`/`NORMAL`/`SLOW` then? Or by purpose: 
> `BENCHMARK`/`DAILY`/`PARANOID`?


I am not against the idea of naming it differently, but then we need to get all 
whereabouts vocabulary straight.  What is the noun? Speed?  And what should be 
the command line option?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D83942



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


[PATCH] D84090: [clang-format] Add BitFieldColonSpacing option

2020-07-20 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay added a comment.

Nit:clang-format the patch

Here is a Tip as to what I do (In case it helps other):

1. I generate the diff off the staged items so I've already git added all the 
files I'm working on.

2. then I can do `git clang-format`, this will fix up any files in the diff 
that need formatting (you'll need to git add them again if they have)

3. I then check the documentation builds with `/usr/bin/sphinx-build -n ./docs 
./html`  (if the review contains rst files)

4. then I do  `git diff --cached -U99 > patch_to_submitt.diff`

5. I check the patch to ensure I'm not changing the mode of the files with 
`grep -A0 -B2 "new mode" patch_to_submitt.diff`

6. and this is the patch_tosubmitt.diff I upload to the review

These steps try to reduce the number of review fails I get based on 
clang-format issues (all of this is scripted so making a patch is repeatable, 
quick and easy and all based off whats in my staged area)

Apart from that this patch LGTM (Before and After are good names)

But please clang-format before pushing (including the tests)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D84090



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


[clang] 177e5ac - [Sema] Promote SmallSet of enum to bitset

2020-07-20 Thread Benjamin Kramer via cfe-commits

Author: Benjamin Kramer
Date: 2020-07-20T17:35:43+02:00
New Revision: 177e5acbe4b9ca0df3edd6b720ea8851c33baba2

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

LOG: [Sema] Promote SmallSet of enum to bitset

Even with 300 elements, this still consumes less stack space than the
SmallSet. NFCI.

Added: 


Modified: 
clang/lib/Sema/SemaType.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index ee7bf98e9ca6..38cb83938ad2 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -37,6 +37,7 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/Support/ErrorHandling.h"
+#include 
 
 using namespace clang;
 
@@ -6858,32 +6859,32 @@ static bool 
handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
 break;
   }
 
-  llvm::SmallSet Attrs;
+  std::bitset Attrs;
   attr::Kind NewAttrKind = A->getKind();
   QualType Desugared = Type;
   const AttributedType *AT = dyn_cast(Type);
   while (AT) {
-Attrs.insert(AT->getAttrKind());
+Attrs[AT->getAttrKind()] = true;
 Desugared = AT->getModifiedType();
 AT = dyn_cast(Desugared);
   }
 
   // You cannot specify duplicate type attributes, so if the attribute has
   // already been applied, flag it.
-  if (Attrs.count(NewAttrKind)) {
+  if (Attrs[NewAttrKind]) {
 S.Diag(PAttr.getLoc(), diag::warn_duplicate_attribute_exact) << PAttr;
 return true;
   }
-  Attrs.insert(NewAttrKind);
+  Attrs[NewAttrKind] = true;
 
   // You cannot have both __sptr and __uptr on the same type, nor can you
   // have __ptr32 and __ptr64.
-  if (Attrs.count(attr::Ptr32) && Attrs.count(attr::Ptr64)) {
+  if (Attrs[attr::Ptr32] && Attrs[attr::Ptr64]) {
 S.Diag(PAttr.getLoc(), diag::err_attributes_are_not_compatible)
 << "'__ptr32'"
 << "'__ptr64'";
 return true;
-  } else if (Attrs.count(attr::SPtr) && Attrs.count(attr::UPtr)) {
+  } else if (Attrs[attr::SPtr] && Attrs[attr::UPtr]) {
 S.Diag(PAttr.getLoc(), diag::err_attributes_are_not_compatible)
 << "'__sptr'"
 << "'__uptr'";
@@ -6909,12 +6910,12 @@ static bool 
handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
   LangAS ASIdx = LangAS::Default;
   uint64_t PtrWidth = S.Context.getTargetInfo().getPointerWidth(0);
   if (PtrWidth == 32) {
-if (Attrs.count(attr::Ptr64))
+if (Attrs[attr::Ptr64])
   ASIdx = LangAS::ptr64;
-else if (Attrs.count(attr::UPtr))
+else if (Attrs[attr::UPtr])
   ASIdx = LangAS::ptr32_uptr;
-  } else if (PtrWidth == 64 && Attrs.count(attr::Ptr32)) {
-if (Attrs.count(attr::UPtr))
+  } else if (PtrWidth == 64 && Attrs[attr::Ptr32]) {
+if (Attrs[attr::UPtr])
   ASIdx = LangAS::ptr32_uptr;
 else
   ASIdx = LangAS::ptr32_sptr;



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


[PATCH] D68997: Allow searching for prebuilt implicit modules.

2020-07-20 Thread Alexandre Rames via Phabricator via cfe-commits
arames updated this revision to Diff 279263.
arames added a comment.
Herald added a subscriber: dang.

Rebase on top-of-tree.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D68997

Files:
  clang/docs/Modules.rst
  clang/include/clang/Driver/Options.td
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Lex/HeaderSearchOptions.h
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInstance.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/Modules/Inputs/prebuilt-implicit-module/a.h
  clang/test/Modules/Inputs/prebuilt-implicit-module/module.modulemap
  clang/test/Modules/prebuilt-implicit-modules.m

Index: clang/test/Modules/prebuilt-implicit-modules.m
===
--- /dev/null
+++ clang/test/Modules/prebuilt-implicit-modules.m
@@ -0,0 +1,27 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c -fmodules %S/Inputs/prebuilt-implicit-module/module.modulemap -emit-module -fmodule-name=module_a -fmodules-cache-path=%t
+// RUN: find %t -name "module_a*.pcm" | grep module_a
+//
+// Check we use a prebuilt module when available, and do not build an implicit module.
+// RUN: rm -rf %t1
+// RUN: mkdir -p %t1
+// RUN: %clang_cc1 -x objective-c %s -I%S/Inputs/prebuilt-implicit-module -fmodules -fmodule-map-file=%S/Inputs/prebuilt-implicit-module/module.modulemap -fprebuilt-implicit-modules -fprebuilt-module-path=%t -fmodules-cache-path=%t1
+// RUN: find %t1 -name "module_a*.pcm" | not grep module_e
+//
+// Check that we correctly fall back to implicit modules if the prebuilt implicit module is not found.
+// RUN: %clang_cc1 -x objective-c %s -I%S/Inputs/prebuilt-implicit-module -fmodules -fmodule-map-file=%S/Inputs/prebuilt-implicit-module/module.modulemap -fprebuilt-implicit-modules -fprebuilt-module-path=%t -fmodules-cache-path=%t1 -fno-signed-char
+// RUN: find %t1 -name "module_a*.pcm" | grep module_a
+
+// Check that non-implicit prebuilt modules are always preferred to prebuilt implicit modules.
+// RUN: rm -rf %t2
+// RUN: mkdir -p %t2
+// RUN: %clang_cc1 -x objective-c -fmodules %S/Inputs/prebuilt-implicit-module/module.modulemap -emit-module -fmodule-name=module_a -fmodules-cache-path=%t
+// RUN: %clang_cc1 -x objective-c -fmodules %S/Inputs/prebuilt-implicit-module/module.modulemap -emit-module -fmodule-name=module_a -o %t/module_a.pcm -fno-signed-char
+// RUN: not %clang_cc1 -x objective-c %s -I%S/Inputs/prebuilt-implicit-module -fmodules -fmodule-map-file=%S/Inputs/prebuilt-implicit-module/module.modulemap -fprebuilt-implicit-modules -fprebuilt-module-path=%t -fmodules-cache-path=%t2
+// RUN: find %t2 -name "module_a*.pcm" | not grep module_a
+
+// expected-no-diagnostics
+@import module_a;
+int test() {
+  return a;
+}
Index: clang/test/Modules/Inputs/prebuilt-implicit-module/module.modulemap
===
--- /dev/null
+++ clang/test/Modules/Inputs/prebuilt-implicit-module/module.modulemap
@@ -0,0 +1 @@
+module module_a { header "a.h" }
Index: clang/test/Modules/Inputs/prebuilt-implicit-module/a.h
===
--- /dev/null
+++ clang/test/Modules/Inputs/prebuilt-implicit-module/a.h
@@ -0,0 +1 @@
+const int a = 1;
Index: clang/lib/Serialization/ASTWriter.cpp
===
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1321,6 +1321,7 @@
   Record.push_back(HSOpts.DisableModuleHash);
   Record.push_back(HSOpts.ImplicitModuleMaps);
   Record.push_back(HSOpts.ModuleMapFileHomeIsCwd);
+  Record.push_back(HSOpts.EnablePrebuiltImplicitModules);
   Record.push_back(HSOpts.UseBuiltinIncludes);
   Record.push_back(HSOpts.UseStandardSystemIncludes);
   Record.push_back(HSOpts.UseStandardCXXIncludes);
Index: clang/lib/Serialization/ASTReader.cpp
===
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -5849,6 +5849,7 @@
   HSOpts.DisableModuleHash = Record[Idx++];
   HSOpts.ImplicitModuleMaps = Record[Idx++];
   HSOpts.ModuleMapFileHomeIsCwd = Record[Idx++];
+  HSOpts.EnablePrebuiltImplicitModules = Record[Idx++];
   HSOpts.UseBuiltinIncludes = Record[Idx++];
   HSOpts.UseStandardSystemIncludes = Record[Idx++];
   HSOpts.UseStandardCXXIncludes = Record[Idx++];
Index: clang/lib/Lex/HeaderSearch.cpp
===
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -164,14 +164,41 @@
   return {};
 }
 
+std::string HeaderSearch::getPrebuiltImplicitModuleFileName(Module *Module) {
+  const FileEntry *ModuleMap =
+  getModuleMap().getModuleMapFileForUniquing

[Differential] D84067: Fix issue in typo handling which could lead clang to hang

2020-07-20 Thread David Goldman 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 rGdde98c82c0ad: Fix issue in typo handling which could lead 
clang to hang (authored by dgoldman).

Repository:
  rG LLVM Github Monorepo

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


  https://reviews.llvm.org/D84067

Files:
  clang/include/clang/Sema/SemaInternal.h
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/Sema/typo-correction-no-hang.cpp
  clang/test/Sema/typo-correction-recursive.cpp

Index: clang/test/Sema/typo-correction-recursive.cpp
===
--- clang/test/Sema/typo-correction-recursive.cpp
+++ clang/test/Sema/typo-correction-recursive.cpp
@@ -118,3 +118,15 @@
   asDeepASItGet().
   functionE();
 }
+
+struct Dog {
+  int age;  //expected-note{{'age' declared here}}
+  int size; //expected-note{{'size' declared here}}
+};
+
+int from_dog_years(int DogYears, int DogSize);
+int get_dog_years() {
+  struct Dog doggo;
+  return from_dog_years(doggo.agee,   //expected-error{{no member named 'agee' in 'Dog'; did you mean 'age'}}
+doggo.sizee); //expected-error{{no member named 'sizee' in 'Dog'; did you mean 'size'}}
+}
Index: clang/test/Sema/typo-correction-no-hang.cpp
===
--- /dev/null
+++ clang/test/Sema/typo-correction-no-hang.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// From `test/Sema/typo-correction.c` but for C++ since the behavior varies
+// between the two languages.
+struct rdar38642201 {
+  int fieldName;
+};
+
+void rdar38642201_callee(int x, int y);
+void rdar38642201_caller() {
+  struct rdar38642201 structVar;
+  rdar38642201_callee(
+  structVar1.fieldName1.member1,  //expected-error{{use of undeclared identifier 'structVar1'}}
+  structVar2.fieldName2.member2); //expected-error{{use of undeclared identifier 'structVar2'}}
+}
+
+// Similar reproducer.
+class A {
+public:
+  int minut() const = delete;
+  int hour() const = delete;
+
+  int longit() const; //expected-note{{'longit' declared here}}
+  int latit() const;
+};
+
+class B {
+public:
+  A depar() const { return A(); }
+};
+
+int Foo(const B &b) {
+  return b.deparT().hours() * 60 + //expected-error{{no member named 'deparT' in 'B'}}
+ b.deparT().minutes(); //expected-error{{no member named 'deparT' in 'B'}}
+}
+
+int Bar(const B &b) {
+  return b.depar().longitude() + //expected-error{{no member named 'longitude' in 'A'; did you mean 'longit'?}}
+ b.depar().latitude();   //expected-error{{no member named 'latitude' in 'A'}}
+}
Index: clang/lib/Sema/SemaExprCXX.cpp
===
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -7980,19 +7980,26 @@
 }
   }
 
-  /// If corrections for the first TypoExpr have been exhausted for a
-  /// given combination of the other TypoExprs, retry those corrections against
-  /// the next combination of substitutions for the other TypoExprs by advancing
-  /// to the next potential correction of the second TypoExpr. For the second
-  /// and subsequent TypoExprs, if its stream of corrections has been exhausted,
-  /// the stream is reset and the next TypoExpr's stream is advanced by one (a
-  /// TypoExpr's correction stream is advanced by removing the TypoExpr from the
-  /// TransformCache). Returns true if there is still any untried combinations
-  /// of corrections.
+  /// Try to advance the typo correction state of the first unfinished TypoExpr.
+  /// We allow advancement of the correction stream by removing it from the
+  /// TransformCache which allows `TransformTypoExpr` to advance during the
+  /// next transformation attempt.
+  ///
+  /// Any substitution attempts for the previous TypoExprs (which must have been
+  /// finished) will need to be retried since it's possible that they will now
+  /// be invalid given the latest advancement.
+  ///
+  /// We need to be sure that we're making progress - it's possible that the
+  /// tree is so malformed that the transform never makes it to the
+  /// `TransformTypoExpr`.
+  ///
+  /// Returns true if there are any untried correction combinations.
   bool CheckAndAdvanceTypoExprCorrectionStreams() {
 for (auto TE : TypoExprs) {
   auto &State = SemaRef.getTypoExprState(TE);
   TransformCache.erase(TE);
+  if (!State.Consumer->hasMadeAnyCorrectionProgress())
+return false;
   if (!State.Consumer->finished())
 return true;
   State.Consumer->resetCorrectionStream();
Index: clang/include/clang/Sema/SemaInternal.h
===
--- clang/include/clang/Sema/SemaInternal.h
+++ clang/include/clang/Sema/SemaInternal.h
@@ -168,6 +168,11 @@
 return TC;
   }
 
+  /// In the case of deeply invalid ex

  1   2   3   >