[PATCH] D37521: [Sema][Typo correction] Assertion failure in typo correction if chain of member function calls has multiple typos

2017-09-06 Thread Oleg Ranevskyy via Phabricator via cfe-commits
iid_iunknown created this revision.

This is a patch proposal for PR34507.

Typo resolution can create new TypoExprs while transforming an expression. 
These TypoExprs are not transformed, they are present in the resulting 
expression and cause the `DelayedTypos.empty() && "Uncorrected typos!"` 
assertion failure in `clang::Sema::~Sema()`. If clang is built without 
assertions, these TypoExprs are not reported causing incomplete diagnostics.

The patch checks the transformed expression for new TypoExprs and, if any 
found, transforms the expression again until either all TypoExprs are handled 
or the result becomes invalid.


Repository:
  rL LLVM

https://reviews.llvm.org/D37521

Files:
  lib/Sema/SemaExprCXX.cpp
  test/Sema/typo-correction-multiple-typos.cpp


Index: test/Sema/typo-correction-multiple-typos.cpp
===
--- test/Sema/typo-correction-multiple-typos.cpp
+++ test/Sema/typo-correction-multiple-typos.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// This file contains typo correction test which ensures that
+// multiple typos in a single member calls chain are correctly
+// diagnosed.
+
+class X
+{
+public:
+  void foo() const;  // expected-note {{'foo' declared here}}
+};
+
+class Y
+{
+public:
+  const X& getX() const { return m_x; } // expected-note {{'getX' declared 
here}}
+  int getN() const { return m_n; }
+private:
+  X m_x;
+  int m_n;
+};
+
+class Z
+{
+public:
+  const Y& getY0() const { return m_y0; } // expected-note {{'getY0' declared 
here}}
+  const Y& getY1() const { return m_y1; }
+
+private:
+  Y m_y0;
+  Y m_y1;
+};
+
+Z z_obj;
+
+void test()
+{
+  z_obj.getY2(). // expected-error {{no member named 'getY2' in 'Z'; did you 
mean 'getY0'}}
+getM().  // expected-error {{no member named 'getM' in 'Y'; did you 
mean 'getX'}}
+foe();   // expected-error {{no member named 'foe' in 'X'; did you 
mean 'foo'}}
+}
Index: lib/Sema/SemaExprCXX.cpp
===
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -7362,6 +7362,30 @@
 break;
 }
 
+// The transform is able to produce new TypoExprs while resolving the 
typos.
+// These new TypoExprs are not resolved by the transform, they do not get
+// into the TypoExprs container and are not reported, so they need to be
+// handled separately.
+// If the transform result is valid and contains newly created TypoExprs,
+// transform the result expression again until no new TypoExprs get created
+// or the result becomes an invalid expression. Return the longest valid
+// expression to report as many typos as possible.
+if (!Res.isInvalid()) {
+  while (true) {
+unsigned TyposCount = TypoExprs.size();
+FindTypoExprs(TypoExprs).TraverseStmt(Res.get());
+if (TypoExprs.size() == TyposCount)
+  // No new TypoExprs created by the transform
+  break;
+ExprResult TmpRes = TryTransform(Res.get());
+if (TmpRes.isInvalid())
+  // Further transform prodices an invalid Expr.
+  // Stop with the last valid result.
+  break;
+Res = TmpRes;
+  }
+}
+
 // Ensure none of the TypoExprs have multiple typo correction candidates
 // with the same edit length that pass all the checks and filters.
 // TODO: Properly handle various permutations of possible corrections when


Index: test/Sema/typo-correction-multiple-typos.cpp
===
--- test/Sema/typo-correction-multiple-typos.cpp
+++ test/Sema/typo-correction-multiple-typos.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// This file contains typo correction test which ensures that
+// multiple typos in a single member calls chain are correctly
+// diagnosed.
+
+class X
+{
+public:
+  void foo() const;  // expected-note {{'foo' declared here}}
+};
+
+class Y
+{
+public:
+  const X& getX() const { return m_x; } // expected-note {{'getX' declared here}}
+  int getN() const { return m_n; }
+private:
+  X m_x;
+  int m_n;
+};
+
+class Z
+{
+public:
+  const Y& getY0() const { return m_y0; } // expected-note {{'getY0' declared here}}
+  const Y& getY1() const { return m_y1; }
+
+private:
+  Y m_y0;
+  Y m_y1;
+};
+
+Z z_obj;
+
+void test()
+{
+  z_obj.getY2(). // expected-error {{no member named 'getY2' in 'Z'; did you mean 'getY0'}}
+getM().  // expected-error {{no member named 'getM' in 'Y'; did you mean 'getX'}}
+foe();   // expected-error {{no member named 'foe' in 'X'; did you mean 'foo'}}
+}
Index: lib/Sema/SemaExprCXX.cpp
===
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -7362,6 +7362,30 @@
 break;
 }
 
+// The transform is able to produce new TypoExprs while resolving the typos.
+// These new TypoExprs 

[PATCH] D37336: [clang-cl] Explicitly set object format to COFF in CL mode

2017-08-31 Thread Oleg Ranevskyy via Phabricator via cfe-commits
iid_iunknown added a comment.

Thanks for reviewing this!


Repository:
  rL LLVM

https://reviews.llvm.org/D37336



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


[PATCH] D37336: [clang-cl] Explicitly set object format to COFF in CL mode

2017-08-31 Thread Oleg Ranevskyy via Phabricator via cfe-commits
iid_iunknown added a comment.

> Do you think you can write a test for your patch that will work on the 
> buildbots we have?

I am afraid, this is not possible with the existing buildbots. `--target` does 
not affect the default triple. There is `LLVM_TARGET_TRIPLE_ENV` that allows to 
override the default triple at runtime, but LLVM must be configured to support 
it and none of the Windows buildbots do this. I see no other way to implement 
such a test, unfortunately.


Repository:
  rL LLVM

https://reviews.llvm.org/D37336



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


[PATCH] D37336: [clang-cl] Explicitly set object format to COFF in CL mode

2017-08-31 Thread Oleg Ranevskyy via Phabricator via cfe-commits
iid_iunknown added a comment.

In https://reviews.llvm.org/D37336#857802, @hans wrote:

> But why isn't that failure showing on some buildbot, then?


The test needs `system-windows` to run:

  // REQUIRES: system-windows

There is no windows buildbot that builds clang defaulted to the AArch64 target.


Repository:
  rL LLVM

https://reviews.llvm.org/D37336



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


[PATCH] D37336: [clang-cl] Explicitly set object format to COFF in CL mode

2017-08-31 Thread Oleg Ranevskyy via Phabricator via cfe-commits
iid_iunknown created this revision.
Herald added subscribers: kristof.beyls, aemerson.

Currently object format is taken from the default target triple. For toolchains 
with a non-COFF default target this may result in an object format 
inappropriate for pc-windows and lead to compilation issues.

For example, the default triple `aarch64-linux-elf` may produce something like 
`aarch64-pc-windows-msvc19.0.24215-elf` in CL mode. Clang creates 
`MicrosoftARM64TargetInfo` for such triple with data layout 
`e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128`. On the other hand, the 
AArch64 backend in `computeDataLayout` detects a non-COFF target and selects 
`e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128` as data layout for little 
endian. Different layouts used by clang and the backend cause an error:

  error: backend data layout 
'e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128'
   does not match expected target description 
'e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128'

This can be observed on the clang's Driver/cl-pch.c test with AArch64 as a 
default target.

This patch enforces COFF in CL mode.


Repository:
  rL LLVM

https://reviews.llvm.org/D37336

Files:
  lib/Driver/Driver.cpp


Index: lib/Driver/Driver.cpp
===
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -663,6 +663,7 @@
 T.setOS(llvm::Triple::Win32);
 T.setVendor(llvm::Triple::PC);
 T.setEnvironment(llvm::Triple::MSVC);
+T.setObjectFormat(llvm::Triple::COFF);
 DefaultTargetTriple = T.str();
   }
   if (const Arg *A = Args.getLastArg(options::OPT_target))


Index: lib/Driver/Driver.cpp
===
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -663,6 +663,7 @@
 T.setOS(llvm::Triple::Win32);
 T.setVendor(llvm::Triple::PC);
 T.setEnvironment(llvm::Triple::MSVC);
+T.setObjectFormat(llvm::Triple::COFF);
 DefaultTargetTriple = T.str();
   }
   if (const Arg *A = Args.getLastArg(options::OPT_target))
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D34430: [Clang][TypoCorrection] Clang hangs in typo correction

2017-07-10 Thread Oleg Ranevskyy via Phabricator via cfe-commits
iid_iunknown added a comment.

A gentle reminder about this patch.


Repository:
  rL LLVM

https://reviews.llvm.org/D34430



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


[PATCH] D34430: [Clang][TypoCorrection] Clang hangs in typo correction

2017-06-21 Thread Oleg Ranevskyy via Phabricator via cfe-commits
iid_iunknown added a comment.

No hang with this patch on the test case from PR33484. Clang reports a number 
of expected compilation errors instead.


Repository:
  rL LLVM

https://reviews.llvm.org/D34430



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


[PATCH] D34430: [Clang][TypoCorrection] Clang hangs in typo correction

2017-06-20 Thread Oleg Ranevskyy via Phabricator via cfe-commits
iid_iunknown updated this revision to Diff 103297.
iid_iunknown added a comment.

Fixed white spaces.


Repository:
  rL LLVM

https://reviews.llvm.org/D34430

Files:
  lib/Sema/SemaExprCXX.cpp


Index: lib/Sema/SemaExprCXX.cpp
===
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -7246,10 +7246,13 @@
   /// TransformCache). Returns true if there is still any untried combinations
   /// of corrections.
   bool CheckAndAdvanceTypoExprCorrectionStreams() {
+bool CheckLimitExceeded =
+SemaRef.TyposCorrected >=
+SemaRef.getDiagnostics().getDiagnosticOptions().SpellCheckingLimit;
 for (auto TE : TypoExprs) {
   auto  = SemaRef.getTypoExprState(TE);
   TransformCache.erase(TE);
-  if (!State.Consumer->finished())
+  if (!CheckLimitExceeded && !State.Consumer->finished())
 return true;
   State.Consumer->resetCorrectionStream();
 }


Index: lib/Sema/SemaExprCXX.cpp
===
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -7246,10 +7246,13 @@
   /// TransformCache). Returns true if there is still any untried combinations
   /// of corrections.
   bool CheckAndAdvanceTypoExprCorrectionStreams() {
+bool CheckLimitExceeded =
+SemaRef.TyposCorrected >=
+SemaRef.getDiagnostics().getDiagnosticOptions().SpellCheckingLimit;
 for (auto TE : TypoExprs) {
   auto  = SemaRef.getTypoExprState(TE);
   TransformCache.erase(TE);
-  if (!State.Consumer->finished())
+  if (!CheckLimitExceeded && !State.Consumer->finished())
 return true;
   State.Consumer->resetCorrectionStream();
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D34430: [Clang][TypoCorrection] Clang hangs in typo correction

2017-06-20 Thread Oleg Ranevskyy via Phabricator via cfe-commits
iid_iunknown created this revision.
iid_iunknown added a project: clang.

This is a patch for PR33484.
The clang's typo correction logic may fall into an infinite loop when reaching 
the typo correction limit.

When some complex expression has multiple typos in it, clang finds possible 
corrections for each typo and processes various permutations of these 
corrections. The typo corrections counter is incremented during the process and 
compared to the max allowed limit (50 by default). Hang may happen if the limit 
is reached in the middle of complex expression processing. In this case 
transform of the current part of the expression fails, making clang ignore its 
subsequent parts and bail out to the main transform loop in 
`TransformTypos::Transform(Expr *E)`. On the next iteration, clang fails at the 
very beginning of transform and no longer reaches the rest of the expression 
immediately bailing out to the main loop. The transform cannot advance since 
this moment. As the loop exit condition requires either a fully successful 
transform or having all the permutations processed, it can never become true.

Yet another reproducer with a readable C++ code:

  namespace
  {
struct V
{
  float x;
};
  
class H
{
public:
  const V& getV() const { return mV; }
  int getN() const { return mN; }
private:
  V mV;
  int mN;
};
  
class T
{
public:
  const H& getH0() const { return mH0; }
  const H& getH1() const { return mH1; }
  
  const V& getV0() const { return mH0.getV(); }
  const V& getV1() const { return mH1.getV(); }
  
private:
  H mH0;
  H mH1;
};

T sT;
H sH;
  }
  
  void func()
  {
( sT.getH2().getM() > sH.getM() ?
  sT.getH3() :
  0 );
  }

Here, both the condition and LHS of `?:` have typos. If the limit is exceeded, 
the transform will fail on the condition and will no longer proceed to LHS and 
process its substitutions.

The patch adds a limit check into the main loop exit condition.


Repository:
  rL LLVM

https://reviews.llvm.org/D34430

Files:
  lib/Sema/SemaExprCXX.cpp


Index: lib/Sema/SemaExprCXX.cpp
===
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -7246,10 +7246,13 @@
   /// TransformCache). Returns true if there is still any untried combinations
   /// of corrections.
   bool CheckAndAdvanceTypoExprCorrectionStreams() {
+   bool CheckLimitExceeded =
+SemaRef.TyposCorrected >=
+SemaRef.getDiagnostics().getDiagnosticOptions().SpellCheckingLimit;
 for (auto TE : TypoExprs) {
   auto  = SemaRef.getTypoExprState(TE);
   TransformCache.erase(TE);
-  if (!State.Consumer->finished())
+ if (!CheckLimitExceeded && !State.Consumer->finished())
 return true;
   State.Consumer->resetCorrectionStream();
 }


Index: lib/Sema/SemaExprCXX.cpp
===
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -7246,10 +7246,13 @@
   /// TransformCache). Returns true if there is still any untried combinations
   /// of corrections.
   bool CheckAndAdvanceTypoExprCorrectionStreams() {
+	bool CheckLimitExceeded =
+SemaRef.TyposCorrected >=
+SemaRef.getDiagnostics().getDiagnosticOptions().SpellCheckingLimit;
 for (auto TE : TypoExprs) {
   auto  = SemaRef.getTypoExprState(TE);
   TransformCache.erase(TE);
-  if (!State.Consumer->finished())
+	  if (!CheckLimitExceeded && !State.Consumer->finished())
 return true;
   State.Consumer->resetCorrectionStream();
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D16901: [Clang driver, ARM] Do not add +long-calls in PIC mode

2016-12-28 Thread Oleg Ranevskyy via Phabricator via cfe-commits
iid_iunknown abandoned this revision.
iid_iunknown added a comment.

Abandoning the patch as it is too old.


Repository:
  rL LLVM

https://reviews.llvm.org/D16901



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