[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-05-30 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 100796.
jyu2 added a comment.

Okay this CFG version of this change.  In this change I am basic using same 
algorithm with -Winfinite-recursion.

In addition to my original implementation,  I add handler type checking which 
basic using  https://reviews.llvm.org/D19201 method.

There are couple things I am worry about this implementation:
1> compile time...
2> Correctness...  
3> Stack overflow for large CFG...


https://reviews.llvm.org/D3

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/AnalysisBasedWarnings.cpp
  test/CXX/except/except.spec/p11.cpp
  test/SemaCXX/warn-throw-out-noexcept-func.cpp

Index: lib/Sema/AnalysisBasedWarnings.cpp
===
--- lib/Sema/AnalysisBasedWarnings.cpp
+++ lib/Sema/AnalysisBasedWarnings.cpp
@@ -279,6 +279,158 @@
 }
 
 //===--===//
+// Check for throw in a non-throwing function.
+//===--===//
+enum ThrowState {
+  FoundNoPathForThrow,
+  FoundPathForThrow,
+  FoundPathWithNoThrowOutFunction,
+};
+
+static bool mayThrowBeCaughted(const CXXThrowExpr *Throw,
+   const CXXCatchStmt *Catch) {
+  bool MayCaught = false;
+  const auto *ThrowType = Throw->getSubExpr()->getType().getTypePtrOrNull();
+  const auto *CaughtType = Catch->getCaughtType().getTypePtrOrNull();
+
+  if (CaughtType == nullptr)
+return true;
+  if (CaughtType == ThrowType)
+return true;
+
+  const auto *CaughtAsRecordType = CaughtType->getPointeeCXXRecordDecl();
+  const auto *ThrowTypeAsRecordType = ThrowType->getAsCXXRecordDecl();
+  if (CaughtAsRecordType && ThrowTypeAsRecordType) {
+if (CaughtAsRecordType == ThrowTypeAsRecordType)
+  MayCaught = true;
+MayCaught = ThrowTypeAsRecordType->isDerivedFrom(CaughtAsRecordType);
+  }
+  return MayCaught;
+}
+
+static bool mayThrowBeCaughtedByHandlers(const CXXThrowExpr *CE,
+ const CXXTryStmt *TryStmt) {
+  bool Caught = false;
+  for (unsigned h = 0; h < TryStmt->getNumHandlers(); ++h) {
+const CXXCatchStmt *CS = TryStmt->getHandler(h);
+if (mayThrowBeCaughted(CE, CS)) {
+  Caught = true;
+  break;
+}
+  }
+  return Caught;
+}
+
+static bool hasThrowOutNothrowingFuncInPath(CFGBlock &Block,
+SourceLocation *OpLoc) {
+  bool HasThrowOutFunc = false;
+  for (const auto &B : Block) {
+if (B.getKind() != CFGElement::Statement)
+  continue;
+const CXXThrowExpr *CE =
+dyn_cast(B.getAs()->getStmt());
+if (!CE)
+  continue;
+else
+  HasThrowOutFunc = true;
+
+(*OpLoc) = CE->getThrowLoc();
+for (CFGBlock::const_succ_iterator I = Block.succ_begin(),
+   E = Block.succ_end();
+ I != E; ++I) {
+  if (*I && (*I)->getTerminator() &&
+  isa((*I)->getTerminator())) {
+const CXXTryStmt *Terminator = cast((*I)->getTerminator());
+if (mayThrowBeCaughtedByHandlers(CE, Terminator)) {
+  HasThrowOutFunc = false;
+  break;
+}
+  }
+}
+  }
+  return HasThrowOutFunc;
+}
+
+static bool hasThrowOutNonThrowingFunc(const FunctionDecl *FD,
+   SourceLocation *OpLoc, CFG *cfg) {
+
+  const unsigned ExitID = cfg->getExit().getBlockID();
+
+  SmallVector States(cfg->getNumBlockIDs(),
+ FoundNoPathForThrow);
+  States[cfg->getEntry().getBlockID()] = FoundPathWithNoThrowOutFunction;
+
+  SmallVector Stack;
+  Stack.push_back(&cfg->getEntry());
+  while (!Stack.empty()) {
+CFGBlock *CurBlock = Stack.back();
+Stack.pop_back();
+
+unsigned ID = CurBlock->getBlockID();
+ThrowState CurState = States[ID];
+if (CurState == FoundPathWithNoThrowOutFunction) {
+  // Found a path to the exit node without a throw exression.
+  if (ExitID == ID)
+continue;
+
+  if (hasThrowOutNothrowingFuncInPath(*CurBlock, OpLoc)) {
+CurState = FoundPathForThrow;
+  }
+}
+
+// Loop over successor blocks and add them to the Stack if their state
+// changes.
+
+for (auto I = CurBlock->succ_begin(), E = CurBlock->succ_end(); I != E; ++I)
+  if (*I) {
+unsigned next_ID = (*I)->getBlockID();
+if (next_ID == ExitID && CurState == FoundPathForThrow) {
+  States[next_ID] = CurState;
+} else if (States[next_ID] < CurState) {
+  States[next_ID] = CurState;
+  Stack.push_back(*I);
+}
+  }
+  }
+  // Return true if the exit node is reachable, and only reachable through
+  // a throw expression.
+  return States[ExitID] == FoundPathForThrow;
+}
+
+static void EmitDiagForCXXThrowInNonThrowingFunc(SourceLocation OpLoc, Sema &S,
+ const FunctionDecl *

[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-06-01 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 101167.
jyu2 marked an inline comment as done.
jyu2 added a comment.

Update to address review comments.


https://reviews.llvm.org/D3

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/AnalysisBasedWarnings.cpp
  test/CXX/except/except.spec/p11.cpp
  test/SemaCXX/warn-throw-out-noexcept-func.cpp

Index: lib/Sema/AnalysisBasedWarnings.cpp
===
--- lib/Sema/AnalysisBasedWarnings.cpp
+++ lib/Sema/AnalysisBasedWarnings.cpp
@@ -279,6 +279,150 @@
 }
 
 //===--===//
+// Check for throw in a non-throwing function.
+//===--===//
+enum ThrowState {
+  FoundNoPathForThrow,
+  FoundPathForThrow,
+  FoundPathWithNoThrowOutFunction,
+};
+
+static bool isThrowBeCaught(const CXXThrowExpr *Throw,
+const CXXCatchStmt *Catch) {
+  bool isCaught = false;
+  const Type *ThrowType = Throw->getSubExpr()->getType().getTypePtrOrNull();
+  const Type *CaughtType = Catch->getCaughtType().getTypePtrOrNull();
+
+   if (ThrowType->isReferenceType())
+ ThrowType = ThrowType->castAs()
+ ->getPointeeType()
+ ->getUnqualifiedDesugaredType();
+  if (CaughtType && CaughtType->isReferenceType())
+ CaughtType = CaughtType->castAs()
+  ->getPointeeType()
+  ->getUnqualifiedDesugaredType();
+  if (CaughtType == nullptr || CaughtType == ThrowType)
+return true;
+
+   const CXXRecordDecl *CaughtAsRecordType =
+   CaughtType->getPointeeCXXRecordDecl();
+  const CXXRecordDecl *ThrowTypeAsRecordType = ThrowType->getAsCXXRecordDecl();
+  if (CaughtAsRecordType && ThrowTypeAsRecordType)
+isCaught = ThrowTypeAsRecordType->isDerivedFrom(CaughtAsRecordType);
+  return isCaught;
+}
+
+static bool isThrowBeCaughtByHandlers(const CXXThrowExpr *CE,
+  const CXXTryStmt *TryStmt) {
+  for (unsigned H = 0; H < TryStmt->getNumHandlers(); ++H) {
+const CXXCatchStmt *CS = TryStmt->getHandler(H);
+if (isThrowBeCaught(CE, CS))
+  return true;
+  }
+  return false;
+}
+
+static bool doesThrowEscapePath(CFGBlock &Block, SourceLocation *OpLoc) {
+  bool HasThrowOutFunc = false;
+  for (const clang::CFGElement &B : Block) {
+if (B.getKind() != CFGElement::Statement)
+  continue;
+const CXXThrowExpr *CE =
+dyn_cast(B.getAs()->getStmt());
+if (!CE)
+  continue;
+else
+  HasThrowOutFunc = true;
+
+*OpLoc = CE->getThrowLoc();
+for (const CFGBlock::AdjacentBlock I : Block.succs())
+  if (I && I->getTerminator() && isa(I->getTerminator())) {
+const CXXTryStmt *Terminator = cast(I->getTerminator());
+if (isThrowBeCaughtByHandlers(CE, Terminator))
+  return false;
+  }
+  }
+  return HasThrowOutFunc;
+}
+
+static bool hasThrowOutNonThrowingFunc(const FunctionDecl *FD,
+   SourceLocation *OpLoc, CFG *cfg) {
+
+  const unsigned ExitID = cfg->getExit().getBlockID();
+
+  SmallVector States(cfg->getNumBlockIDs(),
+ FoundNoPathForThrow);
+  States[cfg->getEntry().getBlockID()] = FoundPathWithNoThrowOutFunction;
+
+  SmallVector Stack;
+  Stack.push_back(&cfg->getEntry());
+  while (!Stack.empty()) {
+CFGBlock *CurBlock = Stack.back();
+Stack.pop_back();
+
+unsigned ID = CurBlock->getBlockID();
+ThrowState CurState = States[ID];
+if (CurState == FoundPathWithNoThrowOutFunction) {
+  if (ExitID == ID)
+continue;
+
+  if (doesThrowEscapePath(*CurBlock, OpLoc))
+CurState = FoundPathForThrow;
+}
+
+// Loop over successor blocks and add them to the Stack if their state
+// changes.
+for (const CFGBlock::AdjacentBlock I : CurBlock->succs())
+  if (I) {
+unsigned next_ID = (I)->getBlockID();
+if (next_ID == ExitID && CurState == FoundPathForThrow) {
+  States[next_ID] = CurState;
+} else if (States[next_ID] < CurState) {
+  States[next_ID] = CurState;
+  Stack.push_back(I);
+}
+  }
+  }
+  // Return true if the exit node is reachable, and only reachable through
+  // a throw expression.
+  return States[ExitID] == FoundPathForThrow;
+}
+
+static void EmitDiagForCXXThrowInNonThrowingFunc(SourceLocation OpLoc, Sema &S,
+ const FunctionDecl *FD) {
+  if (!S.getSourceManager().isInSystemHeader(OpLoc)) {
+S.Diag(OpLoc, diag::warn_throw_in_noexcept_func) << FD;
+if (S.getLangOpts().CPlusPlus11 &&
+(isa(FD) ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Delete ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete))
+  S.Diag(FD->getLocation(), diag::note_throw_in_dtor);
+else
+  S.Diag(FD->getLocat

[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-06-01 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked 8 inline comments as done.
jyu2 added inline comments.



Comment at: lib/Sema/AnalysisBasedWarnings.cpp:334
+  continue;
+else
+  HasThrowOutFunc = true;

aaron.ballman wrote:
> You can drop the `else` here and just set `HasThrowOutFunc` to true.
Can not do that, don't if block has throw expression yet. 


https://reviews.llvm.org/D3



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


[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-06-01 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

In https://reviews.llvm.org/D3#770238, @aaron.ballman wrote:

> In https://reviews.llvm.org/D3#768332, @jyu2 wrote:
>
> > Okay this CFG version of this change.  In this change I am basic using same 
> > algorithm with -Winfinite-recursion.
> >
> > In addition to my original implementation,  I add handler type checking 
> > which basic using  https://reviews.llvm.org/D19201 method.
>
>
> Thank you, I think this is a step in the right direction!
>
> > There are couple things I am worry about this implementation:
> >  1> compile time...
>
> Do you have any timing data on whether this has a negative performance impact?
>
> > 2> Correctness...
>
> Your implementation looks reasonable to me, but with further review (and good 
> tests), we should have a better grasp on correctness.
>
> > 3> Stack overflow for large CFG...
>
> I would be surprised if that were a problem, but is something we could 
> address if it ever arises.


Hope that is okay.


https://reviews.llvm.org/D3



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


[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-06-01 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked 12 inline comments as done.
jyu2 added inline comments.



Comment at: include/clang/Basic/DiagnosticSemaKinds.td:6341
+: Warning<"%0 has a non-throwing exception specification but can still "
+  "throw, may result in unexpected program termination.">, 
+  InGroup;

aaron.ballman wrote:
> throw, may -> throw, which may
> 
> Also, remove the period at the end of the diagnostic.
use you suggested.



Comment at: lib/Sema/AnalysisBasedWarnings.cpp:290
+
+static bool mayThrowBeCaughted(const CXXThrowExpr *Throw,
+   const CXXCatchStmt *Catch) {

aaron.ballman wrote:
> Caughted -> Caught
:-(



Comment at: lib/Sema/AnalysisBasedWarnings.cpp:304
+  if (CaughtAsRecordType && ThrowTypeAsRecordType) {
+if (CaughtAsRecordType == ThrowTypeAsRecordType)
+  MayCaught = true;

aaron.ballman wrote:
> This does not seem quite correct. Consider:
> ```
> struct S{};
> 
> void f() {
>   try {
> throw S{};
>   } catch (const S *s) {
>   }
> }
> ```
Good catch.  Remove that check.


https://reviews.llvm.org/D3



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


[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-06-02 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked 2 inline comments as done.
jyu2 added inline comments.



Comment at: lib/Sema/AnalysisBasedWarnings.cpp:334
+  continue;
+else
+  HasThrowOutFunc = true;

jyu2 wrote:
> aaron.ballman wrote:
> > You can drop the `else` here and just set `HasThrowOutFunc` to true.
> Can not do that, don't if block has throw expression yet. 
Yes, Eric just point out, you are right, I can remove the line of "else"


https://reviews.llvm.org/D3



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


[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-06-05 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 101373.
jyu2 added a comment.

Add more test include 1> throw/catch reference types. 2> try block. 
3>unreachable code.


https://reviews.llvm.org/D3

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/AnalysisBasedWarnings.cpp
  test/CXX/except/except.spec/p11.cpp
  test/SemaCXX/warn-throw-out-noexcept-func.cpp

Index: lib/Sema/AnalysisBasedWarnings.cpp
===
--- lib/Sema/AnalysisBasedWarnings.cpp
+++ lib/Sema/AnalysisBasedWarnings.cpp
@@ -279,6 +279,148 @@
 }
 
 //===--===//
+// Check for throw in a non-throwing function.
+//===--===//
+enum ThrowState {
+  FoundNoPathForThrow,
+  FoundPathForThrow,
+  FoundPathWithNoThrowOutFunction,
+};
+
+static bool isThrowBeCaught(const CXXThrowExpr *Throw,
+const CXXCatchStmt *Catch) {
+  bool isCaught = false;
+  const Type *ThrowType = Throw->getSubExpr()->getType().getTypePtrOrNull();
+  const Type *CaughtType = Catch->getCaughtType().getTypePtrOrNull();
+
+  if (ThrowType->isReferenceType())
+ThrowType = ThrowType->castAs()
+ ->getPointeeType()
+ ->getUnqualifiedDesugaredType();
+  if (CaughtType && CaughtType->isReferenceType())
+CaughtType = CaughtType->castAs()
+  ->getPointeeType()
+  ->getUnqualifiedDesugaredType();
+  if (CaughtType == nullptr || CaughtType == ThrowType)
+return true;
+
+  const CXXRecordDecl *CaughtAsRecordType =
+   CaughtType->getPointeeCXXRecordDecl();
+  const CXXRecordDecl *ThrowTypeAsRecordType = ThrowType->getAsCXXRecordDecl();
+  if (CaughtAsRecordType && ThrowTypeAsRecordType)
+isCaught = ThrowTypeAsRecordType->isDerivedFrom(CaughtAsRecordType);
+  return isCaught;
+}
+
+static bool isThrowBeCaughtByHandlers(const CXXThrowExpr *CE,
+  const CXXTryStmt *TryStmt) {
+  for (unsigned H = 0; H < TryStmt->getNumHandlers(); ++H) {
+const CXXCatchStmt *CS = TryStmt->getHandler(H);
+if (isThrowBeCaught(CE, CS))
+  return true;
+  }
+  return false;
+}
+
+static bool doesThrowEscapePath(CFGBlock &Block, SourceLocation *OpLoc) {
+  bool HasThrowOutFunc = false;
+  for (const clang::CFGElement &B : Block) {
+if (B.getKind() != CFGElement::Statement)
+  continue;
+const CXXThrowExpr *CE =
+dyn_cast(B.getAs()->getStmt());
+if (!CE)
+  continue;
+
+HasThrowOutFunc = true;
+*OpLoc = CE->getThrowLoc();
+for (const CFGBlock::AdjacentBlock I : Block.succs())
+  if (I && I->getTerminator() && isa(I->getTerminator())) {
+const CXXTryStmt *Terminator = cast(I->getTerminator());
+if (isThrowBeCaughtByHandlers(CE, Terminator))
+  return false;
+  }
+  }
+  return HasThrowOutFunc;
+}
+
+static bool hasThrowOutNonThrowingFunc(SourceLocation *OpLoc, CFG *cfg) {
+
+  const unsigned ExitID = cfg->getExit().getBlockID();
+
+  SmallVector States(cfg->getNumBlockIDs(),
+ FoundNoPathForThrow);
+  States[cfg->getEntry().getBlockID()] = FoundPathWithNoThrowOutFunction;
+
+  SmallVector Stack;
+  Stack.push_back(&cfg->getEntry());
+  while (!Stack.empty()) {
+CFGBlock *CurBlock = Stack.back();
+Stack.pop_back();
+
+unsigned ID = CurBlock->getBlockID();
+ThrowState CurState = States[ID];
+if (CurState == FoundPathWithNoThrowOutFunction) {
+  if (ExitID == ID)
+continue;
+
+  if (doesThrowEscapePath(*CurBlock, OpLoc))
+CurState = FoundPathForThrow;
+}
+
+// Loop over successor blocks and add them to the Stack if their state
+// changes.
+for (const CFGBlock::AdjacentBlock I : CurBlock->succs())
+  if (I) {
+unsigned next_ID = (I)->getBlockID();
+if (next_ID == ExitID && CurState == FoundPathForThrow) {
+  States[next_ID] = CurState;
+} else if (States[next_ID] < CurState) {
+  States[next_ID] = CurState;
+  Stack.push_back(I);
+}
+  }
+  }
+  // Return true if the exit node is reachable, and only reachable through
+  // a throw expression.
+  return States[ExitID] == FoundPathForThrow;
+}
+
+static void EmitDiagForCXXThrowInNonThrowingFunc(SourceLocation OpLoc, Sema &S,
+ const FunctionDecl *FD) {
+  if (!S.getSourceManager().isInSystemHeader(OpLoc)) {
+S.Diag(OpLoc, diag::warn_throw_in_noexcept_func) << FD;
+if (S.getLangOpts().CPlusPlus11 &&
+(isa(FD) ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Delete ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete))
+  S.Diag(FD->getLocation(), diag::note_throw_in_dtor);
+else
+  S.Diag(FD->getLocation(), diag::note_throw_in_function);
+  }
+}
+
+static void chec

[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-06-15 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 102754.
jyu2 added a comment.

Address Aaron's comments.


https://reviews.llvm.org/D3

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/AnalysisBasedWarnings.cpp
  test/CXX/except/except.spec/p11.cpp
  test/SemaCXX/warn-throw-out-noexcept-func.cpp

Index: lib/Sema/AnalysisBasedWarnings.cpp
===
--- lib/Sema/AnalysisBasedWarnings.cpp
+++ lib/Sema/AnalysisBasedWarnings.cpp
@@ -279,6 +279,152 @@
 }
 
 //===--===//
+// Check for throw in a non-throwing function.
+//===--===//
+enum ThrowState {
+  FoundNoPathForThrow,
+  FoundPathForThrow,
+  FoundPathWithNoThrowOutFunction,
+};
+
+static bool isThrowCaught(const CXXThrowExpr *Throw,
+  const CXXCatchStmt *Catch) {
+  const Type *CaughtType = Catch->getCaughtType().getTypePtrOrNull();
+  const Type *ThrowType = nullptr;
+  if (Throw->getSubExpr())
+ThrowType = Throw->getSubExpr()->getType().getTypePtrOrNull();
+
+  if (ThrowType == nullptr)
+return false;
+  if (ThrowType && ThrowType->isReferenceType())
+ThrowType = ThrowType->castAs()
+->getPointeeType()
+->getUnqualifiedDesugaredType();
+  if (CaughtType == nullptr)
+return true;
+  if (CaughtType && CaughtType->isReferenceType())
+CaughtType = CaughtType->castAs()
+ ->getPointeeType()
+ ->getUnqualifiedDesugaredType();
+  if (CaughtType == ThrowType)
+return true;
+  const CXXRecordDecl *CaughtAsRecordType =
+  CaughtType->getPointeeCXXRecordDecl();
+  const CXXRecordDecl *ThrowTypeAsRecordType = ThrowType->getAsCXXRecordDecl();
+  if (CaughtAsRecordType && ThrowTypeAsRecordType)
+return ThrowTypeAsRecordType->isDerivedFrom(CaughtAsRecordType);
+  return false;
+}
+
+static bool isThrowCaughtByHandlers(const CXXThrowExpr *CE,
+const CXXTryStmt *TryStmt) {
+  for (unsigned H = 0, E = TryStmt->getNumHandlers(); H < E; ++H) {
+if (isThrowCaught(CE, TryStmt->getHandler(H)))
+  return true;
+  }
+  return false;
+}
+
+static bool doesThrowEscapePath(CFGBlock Block, SourceLocation &OpLoc) {
+  for (const clang::CFGElement &B : Block) {
+if (B.getKind() != CFGElement::Statement)
+  continue;
+const CXXThrowExpr *CE =
+dyn_cast(B.getAs()->getStmt());
+if (!CE)
+  continue;
+
+OpLoc = CE->getThrowLoc();
+for (const auto &I : Block.succs()) {
+  if (!I.isReachable())
+continue;
+  if (const CXXTryStmt *Terminator =
+  dyn_cast_or_null(I->getTerminator()))
+if (isThrowCaughtByHandlers(CE, Terminator))
+  return false;
+}
+return true;
+  }
+  return false;
+}
+
+static bool hasThrowOutNonThrowingFunc(SourceLocation &OpLoc, CFG *BodyCFG) {
+
+  unsigned ExitID = BodyCFG->getExit().getBlockID();
+
+  SmallVector States(BodyCFG->getNumBlockIDs(),
+ FoundNoPathForThrow);
+  States[BodyCFG->getEntry().getBlockID()] = FoundPathWithNoThrowOutFunction;
+
+  SmallVector Stack;
+  Stack.push_back(&BodyCFG->getEntry());
+  while (!Stack.empty()) {
+CFGBlock *CurBlock = Stack.back();
+Stack.pop_back();
+
+unsigned ID = CurBlock->getBlockID();
+ThrowState CurState = States[ID];
+if (CurState == FoundPathWithNoThrowOutFunction) {
+  if (ExitID == ID)
+continue;
+
+  if (doesThrowEscapePath(*CurBlock, OpLoc))
+CurState = FoundPathForThrow;
+}
+
+// Loop over successor blocks and add them to the Stack if their state
+// changes.
+for (const auto &I : CurBlock->succs())
+  if (I.isReachable()) {
+unsigned NextID = I->getBlockID();
+if (NextID == ExitID && CurState == FoundPathForThrow) {
+  States[NextID] = CurState;
+} else if (States[NextID] < CurState) {
+  States[NextID] = CurState;
+  Stack.push_back(I);
+}
+  }
+  }
+  // Return true if the exit node is reachable, and only reachable through
+  // a throw expression.
+  return States[ExitID] == FoundPathForThrow;
+}
+
+static void EmitDiagForCXXThrowInNonThrowingFunc(SourceLocation OpLoc, Sema &S,
+ const FunctionDecl *FD) {
+  if (!S.getSourceManager().isInSystemHeader(OpLoc)) {
+S.Diag(OpLoc, diag::warn_throw_in_noexcept_func) << FD;
+if (S.getLangOpts().CPlusPlus11 &&
+(isa(FD) ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Delete ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete))
+  S.Diag(FD->getLocation(), diag::note_throw_in_dtor);
+else
+  S.Diag(FD->getLocation(), diag::note_throw_in_function);
+  }
+}
+
+static void checkThrowInNonThrowingFunc(Sema &S, const FunctionDecl *FD,
+ 

[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-06-15 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 102759.
jyu2 marked 13 inline comments as done.

https://reviews.llvm.org/D3

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/AnalysisBasedWarnings.cpp
  test/CXX/except/except.spec/p11.cpp
  test/SemaCXX/warn-throw-out-noexcept-func.cpp

Index: lib/Sema/AnalysisBasedWarnings.cpp
===
--- lib/Sema/AnalysisBasedWarnings.cpp
+++ lib/Sema/AnalysisBasedWarnings.cpp
@@ -279,6 +279,152 @@
 }
 
 //===--===//
+// Check for throw in a non-throwing function.
+//===--===//
+enum ThrowState {
+  FoundNoPathForThrow,
+  FoundPathForThrow,
+  FoundPathWithNoThrowOutFunction,
+};
+
+static bool isThrowCaught(const CXXThrowExpr *Throw,
+  const CXXCatchStmt *Catch) {
+  const Type *CaughtType = Catch->getCaughtType().getTypePtrOrNull();
+  const Type *ThrowType = nullptr;
+  if (Throw->getSubExpr())
+ThrowType = Throw->getSubExpr()->getType().getTypePtrOrNull();
+
+  if (ThrowType == nullptr)
+return false;
+  if (ThrowType && ThrowType->isReferenceType())
+ThrowType = ThrowType->castAs()
+->getPointeeType()
+->getUnqualifiedDesugaredType();
+  if (CaughtType == nullptr)
+return true;
+  if (CaughtType && CaughtType->isReferenceType())
+CaughtType = CaughtType->castAs()
+ ->getPointeeType()
+ ->getUnqualifiedDesugaredType();
+  if (CaughtType == ThrowType)
+return true;
+  const CXXRecordDecl *CaughtAsRecordType =
+  CaughtType->getPointeeCXXRecordDecl();
+  const CXXRecordDecl *ThrowTypeAsRecordType = ThrowType->getAsCXXRecordDecl();
+  if (CaughtAsRecordType && ThrowTypeAsRecordType)
+return ThrowTypeAsRecordType->isDerivedFrom(CaughtAsRecordType);
+  return false;
+}
+
+static bool isThrowCaughtByHandlers(const CXXThrowExpr *CE,
+const CXXTryStmt *TryStmt) {
+  for (unsigned H = 0, E = TryStmt->getNumHandlers(); H < E; ++H) {
+if (isThrowCaught(CE, TryStmt->getHandler(H)))
+  return true;
+  }
+  return false;
+}
+
+static bool doesThrowEscapePath(CFGBlock Block, SourceLocation &OpLoc) {
+  for (const auto &B : Block) {
+if (B.getKind() != CFGElement::Statement)
+  continue;
+const CXXThrowExpr *CE =
+dyn_cast(B.getAs()->getStmt());
+if (!CE)
+  continue;
+
+OpLoc = CE->getThrowLoc();
+for (const auto &I : Block.succs()) {
+  if (!I.isReachable())
+continue;
+  if (const CXXTryStmt *Terminator =
+  dyn_cast_or_null(I->getTerminator()))
+if (isThrowCaughtByHandlers(CE, Terminator))
+  return false;
+}
+return true;
+  }
+  return false;
+}
+
+static bool hasThrowOutNonThrowingFunc(SourceLocation &OpLoc, CFG *BodyCFG) {
+
+  unsigned ExitID = BodyCFG->getExit().getBlockID();
+
+  SmallVector States(BodyCFG->getNumBlockIDs(),
+ FoundNoPathForThrow);
+  States[BodyCFG->getEntry().getBlockID()] = FoundPathWithNoThrowOutFunction;
+
+  SmallVector Stack;
+  Stack.push_back(&BodyCFG->getEntry());
+  while (!Stack.empty()) {
+CFGBlock *CurBlock = Stack.back();
+Stack.pop_back();
+
+unsigned ID = CurBlock->getBlockID();
+ThrowState CurState = States[ID];
+if (CurState == FoundPathWithNoThrowOutFunction) {
+  if (ExitID == ID)
+continue;
+
+  if (doesThrowEscapePath(*CurBlock, OpLoc))
+CurState = FoundPathForThrow;
+}
+
+// Loop over successor blocks and add them to the Stack if their state
+// changes.
+for (const auto &I : CurBlock->succs())
+  if (I.isReachable()) {
+unsigned NextID = I->getBlockID();
+if (NextID == ExitID && CurState == FoundPathForThrow) {
+  States[NextID] = CurState;
+} else if (States[NextID] < CurState) {
+  States[NextID] = CurState;
+  Stack.push_back(I);
+}
+  }
+  }
+  // Return true if the exit node is reachable, and only reachable through
+  // a throw expression.
+  return States[ExitID] == FoundPathForThrow;
+}
+
+static void EmitDiagForCXXThrowInNonThrowingFunc(SourceLocation OpLoc, Sema &S,
+ const FunctionDecl *FD) {
+  if (!S.getSourceManager().isInSystemHeader(OpLoc)) {
+S.Diag(OpLoc, diag::warn_throw_in_noexcept_func) << FD;
+if (S.getLangOpts().CPlusPlus11 &&
+(isa(FD) ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Delete ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete))
+  S.Diag(FD->getLocation(), diag::note_throw_in_dtor);
+else
+  S.Diag(FD->getLocation(), diag::note_throw_in_function);
+  }
+}
+
+static void checkThrowInNonThrowingFunc(Sema &S, const FunctionDecl *FD,
+

[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-06-15 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked 7 inline comments as done.
jyu2 added inline comments.



Comment at: lib/Sema/AnalysisBasedWarnings.cpp:296
+
+  if (ThrowType->isReferenceType())
+ThrowType = ThrowType->castAs()

aaron.ballman wrote:
> If `ThrowType` can be null, there should be a null pointer check here. If it 
> cannot be null, you should use `getTypePtr()` above instead of 
> `getTypePtrOrNull()`.
Good catch.  Add code and test to handle this



Comment at: lib/Sema/AnalysisBasedWarnings.cpp:312
+isCaught = ThrowTypeAsRecordType->isDerivedFrom(CaughtAsRecordType);
+  return isCaught;
+}

aaron.ballman wrote:
> There's really no point to using a local variable for this. You can return 
> `true` above and return `false` here.
Right.  Changed



Comment at: lib/Sema/AnalysisBasedWarnings.cpp:315
+
+static bool isThrowBeCaughtByHandlers(const CXXThrowExpr *CE,
+  const CXXTryStmt *TryStmt) {

aaron.ballman wrote:
> `isThrowCaughtByHandlers` (drop the Be)
removed "Be"


https://reviews.llvm.org/D3



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


[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-06-16 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 102828.
jyu2 added a comment.

Thanks Aaron!!!   I just upload new patch to address your comments.  I now 
understand your point on when I can use auto.


https://reviews.llvm.org/D3

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/AnalysisBasedWarnings.cpp
  test/CXX/except/except.spec/p11.cpp
  test/SemaCXX/warn-throw-out-noexcept-func.cpp

Index: lib/Sema/AnalysisBasedWarnings.cpp
===
--- lib/Sema/AnalysisBasedWarnings.cpp
+++ lib/Sema/AnalysisBasedWarnings.cpp
@@ -279,6 +279,150 @@
 }
 
 //===--===//
+// Check for throw in a non-throwing function.
+//===--===//
+enum ThrowState {
+  FoundNoPathForThrow,
+  FoundPathForThrow,
+  FoundPathWithNoThrowOutFunction,
+};
+
+static bool isThrowCaught(const CXXThrowExpr *Throw,
+  const CXXCatchStmt *Catch) {
+  const Type *ThrowType = nullptr;
+  if (Throw->getSubExpr())
+ThrowType = Throw->getSubExpr()->getType().getTypePtrOrNull();
+  if (!ThrowType)
+return false;
+  const Type *CaughtType = Catch->getCaughtType().getTypePtrOrNull();
+  if (!CaughtType)
+return true;
+  if (ThrowType->isReferenceType())
+ThrowType = ThrowType->castAs()
+->getPointeeType()
+->getUnqualifiedDesugaredType();
+  if (CaughtType->isReferenceType())
+CaughtType = CaughtType->castAs()
+ ->getPointeeType()
+ ->getUnqualifiedDesugaredType();
+  if (CaughtType == ThrowType)
+return true;
+  const CXXRecordDecl *CaughtAsRecordType =
+  CaughtType->getPointeeCXXRecordDecl();
+  const CXXRecordDecl *ThrowTypeAsRecordType = ThrowType->getAsCXXRecordDecl();
+  if (CaughtAsRecordType && ThrowTypeAsRecordType)
+return ThrowTypeAsRecordType->isDerivedFrom(CaughtAsRecordType);
+  return false;
+}
+
+static bool isThrowCaughtByHandlers(const CXXThrowExpr *CE,
+const CXXTryStmt *TryStmt) {
+  for (unsigned H = 0, E = TryStmt->getNumHandlers(); H < E; ++H) {
+if (isThrowCaught(CE, TryStmt->getHandler(H)))
+  return true;
+  }
+  return false;
+}
+
+static bool doesThrowEscapePath(CFGBlock Block, SourceLocation &OpLoc) {
+  for (const auto &B : Block) {
+if (B.getKind() != CFGElement::Statement)
+  continue;
+const auto *CE = dyn_cast(B.getAs()->getStmt());
+if (!CE)
+  continue;
+
+OpLoc = CE->getThrowLoc();
+for (const auto &I : Block.succs()) {
+  if (!I.isReachable())
+continue;
+  if (const auto *Terminator =
+  dyn_cast_or_null(I->getTerminator()))
+if (isThrowCaughtByHandlers(CE, Terminator))
+  return false;
+}
+return true;
+  }
+  return false;
+}
+
+static bool hasThrowOutNonThrowingFunc(SourceLocation &OpLoc, CFG *BodyCFG) {
+
+  unsigned ExitID = BodyCFG->getExit().getBlockID();
+
+  SmallVector States(BodyCFG->getNumBlockIDs(),
+ FoundNoPathForThrow);
+  States[BodyCFG->getEntry().getBlockID()] = FoundPathWithNoThrowOutFunction;
+
+  SmallVector Stack;
+  Stack.push_back(&BodyCFG->getEntry());
+  while (!Stack.empty()) {
+CFGBlock *CurBlock = Stack.back();
+Stack.pop_back();
+
+unsigned ID = CurBlock->getBlockID();
+ThrowState CurState = States[ID];
+if (CurState == FoundPathWithNoThrowOutFunction) {
+  if (ExitID == ID)
+continue;
+
+  if (doesThrowEscapePath(*CurBlock, OpLoc))
+CurState = FoundPathForThrow;
+}
+
+// Loop over successor blocks and add them to the Stack if their state
+// changes.
+for (const auto &I : CurBlock->succs())
+  if (I.isReachable()) {
+unsigned NextID = I->getBlockID();
+if (NextID == ExitID && CurState == FoundPathForThrow) {
+  States[NextID] = CurState;
+} else if (States[NextID] < CurState) {
+  States[NextID] = CurState;
+  Stack.push_back(I);
+}
+  }
+  }
+  // Return true if the exit node is reachable, and only reachable through
+  // a throw expression.
+  return States[ExitID] == FoundPathForThrow;
+}
+
+static void EmitDiagForCXXThrowInNonThrowingFunc(Sema &S, SourceLocation OpLoc,
+ const FunctionDecl *FD) {
+  if (!S.getSourceManager().isInSystemHeader(OpLoc)) {
+S.Diag(OpLoc, diag::warn_throw_in_noexcept_func) << FD;
+if (S.getLangOpts().CPlusPlus11 &&
+(isa(FD) ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Delete ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete))
+  S.Diag(FD->getLocation(), diag::note_throw_in_dtor);
+else
+  S.Diag(FD->getLocation(), diag::note_throw_in_function);
+  }
+}
+
+static void checkThrowInNonThrowingFunc(Sema &S, const FunctionDecl 

[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-06-16 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added inline comments.



Comment at: test/SemaCXX/warn-throw-out-noexcept-func.cpp:1
+// RUN: %clang_cc1 %s  -fdelayed-template-parsing -fcxx-exceptions 
-fexceptions -fsyntax-only -Wexceptions -verify -std=c++11
+struct A {

aaron.ballman wrote:
> aaron.ballman wrote:
> > aaron.ballman wrote:
> > > Please drop the svn auto props.
> > This does not appear to be done.
> This file still has the svn auto props.
I am so sorry.  Remove it.



Comment at: test/SemaCXX/warn-throw-out-noexcept-func.cpp:1
+// RUN: %clang_cc1 %s  -fdelayed-template-parsing -fcxx-exceptions 
-fexceptions -fsyntax-only -Wexceptions -verify -std=c++11
+struct A {

aaron.ballman wrote:
> rnk wrote:
> > aaron.ballman wrote:
> > > I believe you can drop the -fcxx-exceptions as it should be implied by 
> > > -fexceptions.
> > It isn't at the -cc1 level, you need -fcxx-exceptions there. -fexceptions 
> > controls landingpad cleanup emission.
> Ah, thank you Reid, I forgot about that.
I can remove -fexceptions, since I only care for syntax.



Comment at: test/SemaCXX/warn-throw-out-noexcept-func.cpp:27
+}
+
+struct N : A {

aaron.ballman wrote:
> Can you add a test case like:
> ```
> struct Throws {
>   ~Throws() noexcept(false);
> };
> 
> struct ShouldDiagnose {
>   Throws T;
>   ~ShouldDiagnose() {}
> };
> ```
> I would expect `~ShouldDiagnose()` to be diagnosed as allowing exceptions to 
> escape because of the destructor for `Throws`.
In C++11, destructors are implicitly throw() unless any member or base of the 
type has a destructor with a different exception specification.

In the case of:
struct Throws {
  ~Throws() noexcept(false);
};

struct ShouldDiagnose {
  Throws T;
  ~ShouldDiagnose() {}
};

You should not see diagnose for   ~ShouldDiagnose() , since   ShouldDiagnose 
has a member ofr Throws which has destructor with noexcept(false); therefor
  ~ShouldDiagnose has  noexcept(false).

But I add test case which remove (false) part.


https://reviews.llvm.org/D3



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


[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-06-16 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 102868.
jyu2 added a comment.

Update patch


https://reviews.llvm.org/D3

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/AnalysisBasedWarnings.cpp
  test/CXX/except/except.spec/p11.cpp
  test/SemaCXX/warn-throw-out-noexcept-func.cpp

Index: lib/Sema/AnalysisBasedWarnings.cpp
===
--- lib/Sema/AnalysisBasedWarnings.cpp
+++ lib/Sema/AnalysisBasedWarnings.cpp
@@ -279,6 +279,150 @@
 }
 
 //===--===//
+// Check for throw in a non-throwing function.
+//===--===//
+enum ThrowState {
+  FoundNoPathForThrow,
+  FoundPathForThrow,
+  FoundPathWithNoThrowOutFunction,
+};
+
+static bool isThrowCaught(const CXXThrowExpr *Throw,
+  const CXXCatchStmt *Catch) {
+  const Type *ThrowType = nullptr;
+  if (Throw->getSubExpr())
+ThrowType = Throw->getSubExpr()->getType().getTypePtrOrNull();
+  if (!ThrowType)
+return false;
+  const Type *CaughtType = Catch->getCaughtType().getTypePtrOrNull();
+  if (!CaughtType)
+return true;
+  if (ThrowType->isReferenceType())
+ThrowType = ThrowType->castAs()
+->getPointeeType()
+->getUnqualifiedDesugaredType();
+  if (CaughtType->isReferenceType())
+CaughtType = CaughtType->castAs()
+ ->getPointeeType()
+ ->getUnqualifiedDesugaredType();
+  if (CaughtType == ThrowType)
+return true;
+  const CXXRecordDecl *CaughtAsRecordType =
+  CaughtType->getPointeeCXXRecordDecl();
+  const CXXRecordDecl *ThrowTypeAsRecordType = ThrowType->getAsCXXRecordDecl();
+  if (CaughtAsRecordType && ThrowTypeAsRecordType)
+return ThrowTypeAsRecordType->isDerivedFrom(CaughtAsRecordType);
+  return false;
+}
+
+static bool isThrowCaughtByHandlers(const CXXThrowExpr *CE,
+const CXXTryStmt *TryStmt) {
+  for (unsigned H = 0, E = TryStmt->getNumHandlers(); H < E; ++H) {
+if (isThrowCaught(CE, TryStmt->getHandler(H)))
+  return true;
+  }
+  return false;
+}
+
+static bool doesThrowEscapePath(CFGBlock Block, SourceLocation &OpLoc) {
+  for (const auto &B : Block) {
+if (B.getKind() != CFGElement::Statement)
+  continue;
+const auto *CE = dyn_cast(B.getAs()->getStmt());
+if (!CE)
+  continue;
+
+OpLoc = CE->getThrowLoc();
+for (const auto &I : Block.succs()) {
+  if (!I.isReachable())
+continue;
+  if (const auto *Terminator =
+  dyn_cast_or_null(I->getTerminator()))
+if (isThrowCaughtByHandlers(CE, Terminator))
+  return false;
+}
+return true;
+  }
+  return false;
+}
+
+static bool hasThrowOutNonThrowingFunc(SourceLocation &OpLoc, CFG *BodyCFG) {
+
+  unsigned ExitID = BodyCFG->getExit().getBlockID();
+
+  SmallVector States(BodyCFG->getNumBlockIDs(),
+ FoundNoPathForThrow);
+  States[BodyCFG->getEntry().getBlockID()] = FoundPathWithNoThrowOutFunction;
+
+  SmallVector Stack;
+  Stack.push_back(&BodyCFG->getEntry());
+  while (!Stack.empty()) {
+CFGBlock *CurBlock = Stack.back();
+Stack.pop_back();
+
+unsigned ID = CurBlock->getBlockID();
+ThrowState CurState = States[ID];
+if (CurState == FoundPathWithNoThrowOutFunction) {
+  if (ExitID == ID)
+continue;
+
+  if (doesThrowEscapePath(*CurBlock, OpLoc))
+CurState = FoundPathForThrow;
+}
+
+// Loop over successor blocks and add them to the Stack if their state
+// changes.
+for (const auto &I : CurBlock->succs())
+  if (I.isReachable()) {
+unsigned NextID = I->getBlockID();
+if (NextID == ExitID && CurState == FoundPathForThrow) {
+  States[NextID] = CurState;
+} else if (States[NextID] < CurState) {
+  States[NextID] = CurState;
+  Stack.push_back(I);
+}
+  }
+  }
+  // Return true if the exit node is reachable, and only reachable through
+  // a throw expression.
+  return States[ExitID] == FoundPathForThrow;
+}
+
+static void EmitDiagForCXXThrowInNonThrowingFunc(Sema &S, SourceLocation OpLoc,
+ const FunctionDecl *FD) {
+  if (!S.getSourceManager().isInSystemHeader(OpLoc)) {
+S.Diag(OpLoc, diag::warn_throw_in_noexcept_func) << FD;
+if (S.getLangOpts().CPlusPlus11 &&
+(isa(FD) ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Delete ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete))
+  S.Diag(FD->getLocation(), diag::note_throw_in_dtor);
+else
+  S.Diag(FD->getLocation(), diag::note_throw_in_function);
+  }
+}
+
+static void checkThrowInNonThrowingFunc(Sema &S, const FunctionDecl *FD,
+AnalysisDeclContext &AC) {
+  CFG *BodyCFG = AC.getCFG();
+  if

[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-06-16 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added inline comments.



Comment at: test/SemaCXX/warn-throw-out-noexcept-func.cpp:27
+}
+
+struct N : A {

aaron.ballman wrote:
> jyu2 wrote:
> > aaron.ballman wrote:
> > > Can you add a test case like:
> > > ```
> > > struct Throws {
> > >   ~Throws() noexcept(false);
> > > };
> > > 
> > > struct ShouldDiagnose {
> > >   Throws T;
> > >   ~ShouldDiagnose() {}
> > > };
> > > ```
> > > I would expect `~ShouldDiagnose()` to be diagnosed as allowing exceptions 
> > > to escape because of the destructor for `Throws`.
> > In C++11, destructors are implicitly throw() unless any member or base of 
> > the type has a destructor with a different exception specification.
> > 
> > In the case of:
> > struct Throws {
> >   ~Throws() noexcept(false);
> > };
> > 
> > struct ShouldDiagnose {
> >   Throws T;
> >   ~ShouldDiagnose() {}
> > };
> > 
> > You should not see diagnose for   ~ShouldDiagnose() , since   
> > ShouldDiagnose has a member ofr Throws which has destructor with 
> > noexcept(false); therefor
> >   ~ShouldDiagnose has  noexcept(false).
> > 
> > But I add test case which remove (false) part.
> Good point! A test case with `noexcept(false)` would be handy as would one 
> where `~ShouldDiagnose()` is marked `noexcept(true)` explicitly rather than 
> picking up the `noexcept(false)` implicitly.
Okay I add two tests ShouldDiagnoes and ShouldNotDiagnoes. 


https://reviews.llvm.org/D3



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


[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier

2017-06-16 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 102877.
jyu2 added a comment.

update patch


https://reviews.llvm.org/D3

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/AnalysisBasedWarnings.cpp
  test/CXX/except/except.spec/p11.cpp
  test/SemaCXX/warn-throw-out-noexcept-func.cpp

Index: lib/Sema/AnalysisBasedWarnings.cpp
===
--- lib/Sema/AnalysisBasedWarnings.cpp
+++ lib/Sema/AnalysisBasedWarnings.cpp
@@ -279,6 +279,150 @@
 }
 
 //===--===//
+// Check for throw in a non-throwing function.
+//===--===//
+enum ThrowState {
+  FoundNoPathForThrow,
+  FoundPathForThrow,
+  FoundPathWithNoThrowOutFunction,
+};
+
+static bool isThrowCaught(const CXXThrowExpr *Throw,
+  const CXXCatchStmt *Catch) {
+  const Type *ThrowType = nullptr;
+  if (Throw->getSubExpr())
+ThrowType = Throw->getSubExpr()->getType().getTypePtrOrNull();
+  if (!ThrowType)
+return false;
+  const Type *CaughtType = Catch->getCaughtType().getTypePtrOrNull();
+  if (!CaughtType)
+return true;
+  if (ThrowType->isReferenceType())
+ThrowType = ThrowType->castAs()
+->getPointeeType()
+->getUnqualifiedDesugaredType();
+  if (CaughtType->isReferenceType())
+CaughtType = CaughtType->castAs()
+ ->getPointeeType()
+ ->getUnqualifiedDesugaredType();
+  if (CaughtType == ThrowType)
+return true;
+  const CXXRecordDecl *CaughtAsRecordType =
+  CaughtType->getPointeeCXXRecordDecl();
+  const CXXRecordDecl *ThrowTypeAsRecordType = ThrowType->getAsCXXRecordDecl();
+  if (CaughtAsRecordType && ThrowTypeAsRecordType)
+return ThrowTypeAsRecordType->isDerivedFrom(CaughtAsRecordType);
+  return false;
+}
+
+static bool isThrowCaughtByHandlers(const CXXThrowExpr *CE,
+const CXXTryStmt *TryStmt) {
+  for (unsigned H = 0, E = TryStmt->getNumHandlers(); H < E; ++H) {
+if (isThrowCaught(CE, TryStmt->getHandler(H)))
+  return true;
+  }
+  return false;
+}
+
+static bool doesThrowEscapePath(CFGBlock Block, SourceLocation &OpLoc) {
+  for (const auto &B : Block) {
+if (B.getKind() != CFGElement::Statement)
+  continue;
+const auto *CE = dyn_cast(B.getAs()->getStmt());
+if (!CE)
+  continue;
+
+OpLoc = CE->getThrowLoc();
+for (const auto &I : Block.succs()) {
+  if (!I.isReachable())
+continue;
+  if (const auto *Terminator =
+  dyn_cast_or_null(I->getTerminator()))
+if (isThrowCaughtByHandlers(CE, Terminator))
+  return false;
+}
+return true;
+  }
+  return false;
+}
+
+static bool hasThrowOutNonThrowingFunc(SourceLocation &OpLoc, CFG *BodyCFG) {
+
+  unsigned ExitID = BodyCFG->getExit().getBlockID();
+
+  SmallVector States(BodyCFG->getNumBlockIDs(),
+ FoundNoPathForThrow);
+  States[BodyCFG->getEntry().getBlockID()] = FoundPathWithNoThrowOutFunction;
+
+  SmallVector Stack;
+  Stack.push_back(&BodyCFG->getEntry());
+  while (!Stack.empty()) {
+CFGBlock *CurBlock = Stack.back();
+Stack.pop_back();
+
+unsigned ID = CurBlock->getBlockID();
+ThrowState CurState = States[ID];
+if (CurState == FoundPathWithNoThrowOutFunction) {
+  if (ExitID == ID)
+continue;
+
+  if (doesThrowEscapePath(*CurBlock, OpLoc))
+CurState = FoundPathForThrow;
+}
+
+// Loop over successor blocks and add them to the Stack if their state
+// changes.
+for (const auto &I : CurBlock->succs())
+  if (I.isReachable()) {
+unsigned NextID = I->getBlockID();
+if (NextID == ExitID && CurState == FoundPathForThrow) {
+  States[NextID] = CurState;
+} else if (States[NextID] < CurState) {
+  States[NextID] = CurState;
+  Stack.push_back(I);
+}
+  }
+  }
+  // Return true if the exit node is reachable, and only reachable through
+  // a throw expression.
+  return States[ExitID] == FoundPathForThrow;
+}
+
+static void EmitDiagForCXXThrowInNonThrowingFunc(Sema &S, SourceLocation OpLoc,
+ const FunctionDecl *FD) {
+  if (!S.getSourceManager().isInSystemHeader(OpLoc)) {
+S.Diag(OpLoc, diag::warn_throw_in_noexcept_func) << FD;
+if (S.getLangOpts().CPlusPlus11 &&
+(isa(FD) ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Delete ||
+ FD->getDeclName().getCXXOverloadedOperator() == OO_Array_Delete))
+  S.Diag(FD->getLocation(), diag::note_throw_in_dtor);
+else
+  S.Diag(FD->getLocation(), diag::note_throw_in_function);
+  }
+}
+
+static void checkThrowInNonThrowingFunc(Sema &S, const FunctionDecl *FD,
+AnalysisDeclContext &AC) {
+  CFG *BodyCFG = AC.getCFG();
+  if

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in LLVM

2019-01-11 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 181342.
jyu2 added a comment.

1>  I add code for CFG.cpp and a test for that, as efriedman request.
2>  changes are respond the comments I received


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Expr.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/ExprObjC.h
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm-goto.c
  test/Parser/asm-goto.cpp
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp

Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,21 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+}
Index: test/Parser/asm.cpp
===
--- test/Parser/asm.cpp
+++ test/Parser/asm.cpp
@@ -7,3 +7,28 @@
 int foo5 asm (U"bar5"); // expected-error {{cannot use unicode string literal in 'asm'}}
 int foo6 asm ("bar6"_x); // expected-error {{string literal with user-defined suffix cannot be used here}}
 int foo6 asm ("" L"bar7"); // expected-error {{cannot use wide string literal in 'asm'}}
+
+int zoo ()
+{
+  int x,cond,*e;
+  // expected-error@+1 {{expected ')'}}
+  asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
+  // expected-error@+1 {{expected identifie}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" : );
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" );
+  // expected-error@+1 {{use of undeclared label 'x'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :x);
+  // expected-error@+1 {{use of undeclared label 'b'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :b);
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm goto ("testl %0, %0; jne %l3;" :: "r"(cond)::label_true, loop)
+  // expected-error@+1 {{unknown symbolic operand name in inline assembly string}}
+  asm goto ("decl %0; jnz %l[b]" :: "m"(x) : "memory" : a);
+label_true:
+loop:
+a:
+  return 0;
+}
Index: test/Parser/asm.c
===
--- test/Parser/asm.c
+++ test/Parser/asm.c
@@ -16,6 +16,31 @@
   asm _Atomic (""); // expected-warning {{ignored _Atomic qualifier on asm}}
 }
 
+int zoo ()
+{
+  int x,cond,*e;
+  // expected-error@+1 {{expected ')'}}
+  asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
+  // expected-error@+1 {{expected ':'}}
+  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
+  // expected-error@+1 {{expected identifie}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" : );
+  // expected-error@+1 {{expected ':'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" );
+  // expected-error@+1 {{use of undeclared label 'x'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :x);
+  // expected-error@+1 {{use of undeclared label 'b'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :b);
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm goto

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in LLVM

2019-01-11 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked 7 inline comments as done.
jyu2 added inline comments.



Comment at: lib/CodeGen/CGStmt.cpp:2182
+}
+  }
+

nickdesaulniers wrote:
> If this new block was moved closer to the new one on L2227, I assume they 
> could be combined and possibly `IsGCCAsmGoto` be removed?  The code currently 
> in between doesn't appear at first site to depend on info from this block, 
> though maybe I may be missing it.
The labels need be processed before Clobbers



Comment at: lib/Parse/ParseStmtAsm.cpp:830-858
+  if (AteExtraColon || Tok.is(tok::colon)) {
+if (AteExtraColon)
+  AteExtraColon = false;
+else
+  ConsumeToken();
+
+if (!AteExtraColon && Tok.isNot(tok::identifier)) {

nickdesaulniers wrote:
> ```
> if (x || y) {
>   if (x) foo();
>   else bar();
>   if (!x && ...) baz();
>   if (!x && ...) quux();
> ```
> is maybe more readable as:
> ```
> if (x) foo();
> else if (y)
>   bar();
>   baz();
>   quux();
> ```
This is better?



Comment at: lib/Sema/SemaStmtAsm.cpp:470
+if (NS->isGCCAsmGoto() &&
+Exprs[ConstraintIdx]->getStmtClass() == Stmt::AddrLabelExprClass)
+  break;

efriedma wrote:
> This looks suspicious; an AddrLabelExpr could be an input or output, e.g. 
> `"r"(&&foo)`.
Syntax for asm goto:
 Syntax:
   asm [volatile] goto ( AssemblerTemplate
   :
   : InputOperands
   : Clobbers
   : GotoLabels)

 Only input is allowed.  Output is not allowed



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

https://reviews.llvm.org/D56571



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in LLVM

2019-01-11 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked an inline comment as done.
jyu2 added inline comments.



Comment at: lib/Sema/SemaStmtAsm.cpp:470
+if (NS->isGCCAsmGoto() &&
+Exprs[ConstraintIdx]->getStmtClass() == Stmt::AddrLabelExprClass)
+  break;

efriedma wrote:
> jyu2 wrote:
> > efriedma wrote:
> > > This looks suspicious; an AddrLabelExpr could be an input or output, e.g. 
> > > `"r"(&&foo)`.
> > Syntax for asm goto:
> >  Syntax:
> >asm [volatile] goto ( AssemblerTemplate
> >:
> >: InputOperands
> >: Clobbers
> >: GotoLabels)
> > 
> >  Only input is allowed.  Output is not allowed
> > 
> That doesn't really address my point here... ignore the "or output" part of 
> the comment.
Sorry did not realize that.  Thank you so much for catching that.  Need to add 
other condition "ConstraintIdx > NS->getNumInputs() - 1", change to :

if (NS->isGCCAsmGoto() && ConstraintIdx > NS->getNumInputs() - 1 &&
Exprs[ConstraintIdx]->getStmtClass() == Stmt::AddrLabelExprClass)
  break;

Is this ok with you?  Thanks


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

https://reviews.llvm.org/D56571



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in LLVM

2019-01-11 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 181403.
jyu2 added a comment.

Couple of change to respond Eli’s comments.


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Expr.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/ExprObjC.h
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm-goto.c
  test/Parser/asm-goto.cpp
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp

Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,21 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+}
Index: test/Parser/asm.cpp
===
--- test/Parser/asm.cpp
+++ test/Parser/asm.cpp
@@ -7,3 +7,28 @@
 int foo5 asm (U"bar5"); // expected-error {{cannot use unicode string literal in 'asm'}}
 int foo6 asm ("bar6"_x); // expected-error {{string literal with user-defined suffix cannot be used here}}
 int foo6 asm ("" L"bar7"); // expected-error {{cannot use wide string literal in 'asm'}}
+
+int zoo ()
+{
+  int x,cond,*e;
+  // expected-error@+1 {{expected ')'}}
+  asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
+  // expected-error@+1 {{expected identifie}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" : );
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" );
+  // expected-error@+1 {{use of undeclared label 'x'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :x);
+  // expected-error@+1 {{use of undeclared label 'b'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :b);
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm goto ("testl %0, %0; jne %l3;" :: "r"(cond)::label_true, loop)
+  // expected-error@+1 {{unknown symbolic operand name in inline assembly string}}
+  asm goto ("decl %0; jnz %l[b]" :: "m"(x) : "memory" : a);
+label_true:
+loop:
+a:
+  return 0;
+}
Index: test/Parser/asm.c
===
--- test/Parser/asm.c
+++ test/Parser/asm.c
@@ -16,6 +16,31 @@
   asm _Atomic (""); // expected-warning {{ignored _Atomic qualifier on asm}}
 }
 
+int zoo ()
+{
+  int x,cond,*e;
+  // expected-error@+1 {{expected ')'}}
+  asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
+  // expected-error@+1 {{expected ':'}}
+  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
+  // expected-error@+1 {{expected identifie}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" : );
+  // expected-error@+1 {{expected ':'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" );
+  // expected-error@+1 {{use of undeclared label 'x'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :x);
+  // expected-error@+1 {{use of undeclared label 'b'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :b);
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm goto ("testl %0, %0; jne %l3;" :: "r"(cond)::label_true, loop)
+  // expected-error@+1

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in LLVM

2019-01-11 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked 3 inline comments as done.
jyu2 added inline comments.



Comment at: lib/Analysis/CFG.cpp:1474
+  appendScopeBegin(JT.block, VD, G);
+  addSuccessor(B, JT.block);
+}

efriedma wrote:
> Please don't copy-paste code.
:-(  changed



Comment at: lib/Sema/SemaStmtAsm.cpp:470
+if (NS->isGCCAsmGoto() &&
+Exprs[ConstraintIdx]->getStmtClass() == Stmt::AddrLabelExprClass)
+  break;

efriedma wrote:
> jyu2 wrote:
> > efriedma wrote:
> > > jyu2 wrote:
> > > > efriedma wrote:
> > > > > This looks suspicious; an AddrLabelExpr could be an input or output, 
> > > > > e.g. `"r"(&&foo)`.
> > > > Syntax for asm goto:
> > > >  Syntax:
> > > >asm [volatile] goto ( AssemblerTemplate
> > > >:
> > > >: InputOperands
> > > >: Clobbers
> > > >: GotoLabels)
> > > > 
> > > >  Only input is allowed.  Output is not allowed
> > > > 
> > > That doesn't really address my point here... ignore the "or output" part 
> > > of the comment.
> > Sorry did not realize that.  Thank you so much for catching that.  Need to 
> > add other condition "ConstraintIdx > NS->getNumInputs() - 1", change to :
> > 
> > if (NS->isGCCAsmGoto() && ConstraintIdx > NS->getNumInputs() - 1 &&
> > Exprs[ConstraintIdx]->getStmtClass() == Stmt::AddrLabelExprClass)
> >   break;
> > 
> > Is this ok with you?  Thanks
> That's the right idea. But I still see a few issues at that point:
> 
> 1. The AddrLabelExprClass check is redundant.
> 2. "NS->getNumInputs() - 1" can overflow; probably should use "ConstraintIdx 
> >= NS->getNumInputs()".
> 3. "break" exits the loop completely (so it skips validating all constraints 
> written after the label).
> 4. The code needs to verify that the user correctly specified the "l" 
> constraint modifier.
Sorry not done yet.  


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

https://reviews.llvm.org/D56571



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in LLVM

2019-01-11 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked 2 inline comments as done.
jyu2 added inline comments.



Comment at: lib/Sema/SemaStmtAsm.cpp:470
+if (NS->isGCCAsmGoto() &&
+Exprs[ConstraintIdx]->getStmtClass() == Stmt::AddrLabelExprClass)
+  break;

jyu2 wrote:
> efriedma wrote:
> > jyu2 wrote:
> > > efriedma wrote:
> > > > jyu2 wrote:
> > > > > efriedma wrote:
> > > > > > This looks suspicious; an AddrLabelExpr could be an input or 
> > > > > > output, e.g. `"r"(&&foo)`.
> > > > > Syntax for asm goto:
> > > > >  Syntax:
> > > > >asm [volatile] goto ( AssemblerTemplate
> > > > >:
> > > > >: InputOperands
> > > > >: Clobbers
> > > > >: GotoLabels)
> > > > > 
> > > > >  Only input is allowed.  Output is not allowed
> > > > > 
> > > > That doesn't really address my point here... ignore the "or output" 
> > > > part of the comment.
> > > Sorry did not realize that.  Thank you so much for catching that.  Need 
> > > to add other condition "ConstraintIdx > NS->getNumInputs() - 1", change 
> > > to :
> > > 
> > > if (NS->isGCCAsmGoto() && ConstraintIdx > NS->getNumInputs() - 1 &&
> > > Exprs[ConstraintIdx]->getStmtClass() == Stmt::AddrLabelExprClass)
> > >   break;
> > > 
> > > Is this ok with you?  Thanks
> > That's the right idea. But I still see a few issues at that point:
> > 
> > 1. The AddrLabelExprClass check is redundant.
> > 2. "NS->getNumInputs() - 1" can overflow; probably should use 
> > "ConstraintIdx >= NS->getNumInputs()".
> > 3. "break" exits the loop completely (so it skips validating all 
> > constraints written after the label).
> > 4. The code needs to verify that the user correctly specified the "l" 
> > constraint modifier.
> Sorry not done yet.  
For you comment 4:

The code needs to verify that the user correctly specified the "l" constraint 
modifier.  We already emit error like following?

Do you mean, we need more checking here?  Thanks. 

n.c:4:35: error: unknown symbolic operand name in inline assembly string
  asm goto ("frob %%r5, %1; jc %l[error]; mov (%2), %%r5"
~~^~~
n.c:8:15: error: use of undeclared label 'error1'
: error1);

Test is:
int frob(int x)
{
  int y;
  asm goto ("frob %%r5, %1; jc %l[error]; mov (%2), %%r5"
: /* No outputs. */
: "r"(x), "r"(&y)
: "memory"
: error1);
  return y;
error:
  return -1;
}




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

https://reviews.llvm.org/D56571



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-01-14 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked an inline comment as done.
jyu2 added inline comments.



Comment at: lib/Sema/SemaStmtAsm.cpp:470
+if (NS->isGCCAsmGoto() &&
+Exprs[ConstraintIdx]->getStmtClass() == Stmt::AddrLabelExprClass)
+  break;

efriedma wrote:
> jyu2 wrote:
> > jyu2 wrote:
> > > efriedma wrote:
> > > > jyu2 wrote:
> > > > > efriedma wrote:
> > > > > > jyu2 wrote:
> > > > > > > efriedma wrote:
> > > > > > > > This looks suspicious; an AddrLabelExpr could be an input or 
> > > > > > > > output, e.g. `"r"(&&foo)`.
> > > > > > > Syntax for asm goto:
> > > > > > >  Syntax:
> > > > > > >asm [volatile] goto ( AssemblerTemplate
> > > > > > >:
> > > > > > >: InputOperands
> > > > > > >: Clobbers
> > > > > > >: GotoLabels)
> > > > > > > 
> > > > > > >  Only input is allowed.  Output is not allowed
> > > > > > > 
> > > > > > That doesn't really address my point here... ignore the "or output" 
> > > > > > part of the comment.
> > > > > Sorry did not realize that.  Thank you so much for catching that.  
> > > > > Need to add other condition "ConstraintIdx > NS->getNumInputs() - 1", 
> > > > > change to :
> > > > > 
> > > > > if (NS->isGCCAsmGoto() && ConstraintIdx > NS->getNumInputs() - 1 &&
> > > > > Exprs[ConstraintIdx]->getStmtClass() == 
> > > > > Stmt::AddrLabelExprClass)
> > > > >   break;
> > > > > 
> > > > > Is this ok with you?  Thanks
> > > > That's the right idea. But I still see a few issues at that point:
> > > > 
> > > > 1. The AddrLabelExprClass check is redundant.
> > > > 2. "NS->getNumInputs() - 1" can overflow; probably should use 
> > > > "ConstraintIdx >= NS->getNumInputs()".
> > > > 3. "break" exits the loop completely (so it skips validating all 
> > > > constraints written after the label).
> > > > 4. The code needs to verify that the user correctly specified the "l" 
> > > > constraint modifier.
> > > Sorry not done yet.  
> > For you comment 4:
> > 
> > The code needs to verify that the user correctly specified the "l" 
> > constraint modifier.  We already emit error like following?
> > 
> > Do you mean, we need more checking here?  Thanks. 
> > 
> > n.c:4:35: error: unknown symbolic operand name in inline assembly string
> >   asm goto ("frob %%r5, %1; jc %l[error]; mov (%2), %%r5"
> > ~~^~~
> > n.c:8:15: error: use of undeclared label 'error1'
> > : error1);
> > 
> > Test is:
> > int frob(int x)
> > {
> >   int y;
> >   asm goto ("frob %%r5, %1; jc %l[error]; mov (%2), %%r5"
> > : /* No outputs. */
> > : "r"(x), "r"(&y)
> > : "memory"
> > : error1);
> >   return y;
> > error:
> >   return -1;
> > }
> > 
> > 
> I mean, there needs to be a diagnostic for the following:
> 
> ```
> asm goto ("jne %h0"x);
> ```
> 
> On a related note, there should also be a diagnostic for the following 
> somewhere:
> 
> ```
> asm ("jne %l0"::"r"(0));
> ```
Hi Eli,

Thanks for your review.

For case:
asm goto ("jne %h0"x);

Without define label x, both clang and my current implementation give error of 
"use of undeclared label"

if x is defined: gcc give error 
asm_goto>!gcc
gcc n.c
n.c: Assembler messages:
n.c:4: Error: operand type mismatch for `jne'

My current implementation don't emit error.  I think this is need to be done in 
LLVM.  Am I right here?

For the case:
asm ("jne %l0"::"r"(0));

gcc don't allow any modifier 'l' with  asm stmt but it allows with asm goto.  
Is that something you are look for?  Thanks.

So I add code in AST/Stmt.cpp to emit error.
.
 return diag::err_asm_invalid_escape;
  } else if (!this->isGCCAsmGoto() && EscapedChar == 'l' &&
 isDigit(*CurPtr)) {
DiagOffs = CurPtr-StrStart;
return diag::err_asm_invalid_operand_number;
  }



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

https://reviews.llvm.org/D56571



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-01-14 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 181702.
jyu2 added a comment.

Add code to diagnostic error for use of the "l" modifier that does not point to 
a label in the label list.


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Expr.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/ExprObjC.h
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticASTKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm-goto.c
  test/Parser/asm-goto.cpp
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp

Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,27 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{invalid operand number which isn't point to a goto label in asm string}}
+  asm ("jne %l0"::"r"(&&lab));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  // expected-error@+1 {{invalid operand number which isn't point to a goto label in asm string}}
+  asm goto ("jne %l0"::"r"(x)::lab);
+}
Index: test/Parser/asm.cpp
===
--- test/Parser/asm.cpp
+++ test/Parser/asm.cpp
@@ -7,3 +7,28 @@
 int foo5 asm (U"bar5"); // expected-error {{cannot use unicode string literal in 'asm'}}
 int foo6 asm ("bar6"_x); // expected-error {{string literal with user-defined suffix cannot be used here}}
 int foo6 asm ("" L"bar7"); // expected-error {{cannot use wide string literal in 'asm'}}
+
+int zoo ()
+{
+  int x,cond,*e;
+  // expected-error@+1 {{expected ')'}}
+  asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
+  // expected-error@+1 {{expected identifie}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" : );
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" );
+  // expected-error@+1 {{use of undeclared label 'x'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :x);
+  // expected-error@+1 {{use of undeclared label 'b'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :b);
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm goto ("testl %0, %0; jne %l3;" :: "r"(cond)::label_true, loop)
+  // expected-error@+1 {{unknown symbolic operand name in inline assembly string}}
+  asm goto ("decl %0; jnz %l[b]" :: "m"(x) : "memory" : a);
+label_true:
+loop:
+a:
+  return 0;
+}
Index: test/Parser/asm.c
===
--- test/Parser/asm.c
+++ test/Parser/asm.c
@@ -16,6 +16,31 @@
   asm _Atomic (""); // expected-warning {{ignored _Atomic qualifier on asm}}
 }
 
+int zoo ()
+{
+  int x,cond,*e;
+  // expected-error@+1 {{expected ')'}}
+  asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
+  // expected-error@+1 {{expected ':'}}
+  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
+  // expected-error@+1 {{expected identifie}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" 

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-01-14 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked an inline comment as done.
jyu2 added inline comments.



Comment at: lib/Sema/SemaStmtAsm.cpp:470
+if (NS->isGCCAsmGoto() &&
+Exprs[ConstraintIdx]->getStmtClass() == Stmt::AddrLabelExprClass)
+  break;

efriedma wrote:
> jyu2 wrote:
> > efriedma wrote:
> > > jyu2 wrote:
> > > > jyu2 wrote:
> > > > > efriedma wrote:
> > > > > > jyu2 wrote:
> > > > > > > efriedma wrote:
> > > > > > > > jyu2 wrote:
> > > > > > > > > efriedma wrote:
> > > > > > > > > > This looks suspicious; an AddrLabelExpr could be an input 
> > > > > > > > > > or output, e.g. `"r"(&&foo)`.
> > > > > > > > > Syntax for asm goto:
> > > > > > > > >  Syntax:
> > > > > > > > >asm [volatile] goto ( AssemblerTemplate
> > > > > > > > >:
> > > > > > > > >: InputOperands
> > > > > > > > >: Clobbers
> > > > > > > > >: GotoLabels)
> > > > > > > > > 
> > > > > > > > >  Only input is allowed.  Output is not allowed
> > > > > > > > > 
> > > > > > > > That doesn't really address my point here... ignore the "or 
> > > > > > > > output" part of the comment.
> > > > > > > Sorry did not realize that.  Thank you so much for catching that. 
> > > > > > >  Need to add other condition "ConstraintIdx > NS->getNumInputs() 
> > > > > > > - 1", change to :
> > > > > > > 
> > > > > > > if (NS->isGCCAsmGoto() && ConstraintIdx > NS->getNumInputs() - 1 
> > > > > > > &&
> > > > > > > Exprs[ConstraintIdx]->getStmtClass() == 
> > > > > > > Stmt::AddrLabelExprClass)
> > > > > > >   break;
> > > > > > > 
> > > > > > > Is this ok with you?  Thanks
> > > > > > That's the right idea. But I still see a few issues at that point:
> > > > > > 
> > > > > > 1. The AddrLabelExprClass check is redundant.
> > > > > > 2. "NS->getNumInputs() - 1" can overflow; probably should use 
> > > > > > "ConstraintIdx >= NS->getNumInputs()".
> > > > > > 3. "break" exits the loop completely (so it skips validating all 
> > > > > > constraints written after the label).
> > > > > > 4. The code needs to verify that the user correctly specified the 
> > > > > > "l" constraint modifier.
> > > > > Sorry not done yet.  
> > > > For you comment 4:
> > > > 
> > > > The code needs to verify that the user correctly specified the "l" 
> > > > constraint modifier.  We already emit error like following?
> > > > 
> > > > Do you mean, we need more checking here?  Thanks. 
> > > > 
> > > > n.c:4:35: error: unknown symbolic operand name in inline assembly string
> > > >   asm goto ("frob %%r5, %1; jc %l[error]; mov (%2), %%r5"
> > > > ~~^~~
> > > > n.c:8:15: error: use of undeclared label 'error1'
> > > > : error1);
> > > > 
> > > > Test is:
> > > > int frob(int x)
> > > > {
> > > >   int y;
> > > >   asm goto ("frob %%r5, %1; jc %l[error]; mov (%2), %%r5"
> > > > : /* No outputs. */
> > > > : "r"(x), "r"(&y)
> > > > : "memory"
> > > > : error1);
> > > >   return y;
> > > > error:
> > > >   return -1;
> > > > }
> > > > 
> > > > 
> > > I mean, there needs to be a diagnostic for the following:
> > > 
> > > ```
> > > asm goto ("jne %h0"x);
> > > ```
> > > 
> > > On a related note, there should also be a diagnostic for the following 
> > > somewhere:
> > > 
> > > ```
> > > asm ("jne %l0"::"r"(0));
> > > ```
> > Hi Eli,
> > 
> > Thanks for your review.
> > 
> > For case:
> > asm goto ("jne %h0"x);
> > 
> > Without define label x, both clang and my current implementation give error 
> > of "use of undeclared label"
> > 
> > if x is defined: gcc give error 
> > asm_goto>!gcc
> > gcc n.c
> > n.c: Assembler messages:
> > n.c:4: Error: operand type mismatch for `jne'
> > 
> > My current implementation don't emit error.  I think this is need to be 
> > done in LLVM.  Am I right here?
> > 
> > For the case:
> > asm ("jne %l0"::"r"(0));
> > 
> > gcc don't allow any modifier 'l' with  asm stmt but it allows with asm 
> > goto.  Is that something you are look for?  Thanks.
> > 
> > So I add code in AST/Stmt.cpp to emit error.
> > .
> >  return diag::err_asm_invalid_escape;
> >   } else if (!this->isGCCAsmGoto() && EscapedChar == 'l' &&
> >  isDigit(*CurPtr)) {
> > DiagOffs = CurPtr-StrStart;
> > return diag::err_asm_invalid_operand_number;
> >   }
> > 
> For the first one, I was trying with Aarch64 gcc; I guess x86 doesn't emit 
> the same error?  `void f() { x: asm goto ("jne %i0"x);}` should be the 
> same for both.
> 
> > gcc don't allow any modifier 'l' with asm stmt but it allows with asm goto. 
> > Is that something you are look for? Thanks.
> 
> We should reject any use of the "l" modifier that does not point to a label 
> in the label list.  So we should also reject `void f(){x:asm goto ("jne 
> %l0"::"r"(&&x)::x);}`.
Hi Eli,

Thank you so much to point this out.  I add code for emit

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-01-15 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 181862.
jyu2 added a comment.

I add additional test.


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Expr.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/ExprObjC.h
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticASTKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm-goto.c
  test/Parser/asm-goto.cpp
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp

Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,28 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{invalid operand number which isn't point to a goto label in asm string}}
+  asm ("jne %l0"::"r"(&&lab));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  // expected-error@+1 {{invalid operand number which isn't point to a goto label in asm string}}
+  asm goto ("jne %l0"::"r"(x)::lab);
+  asm goto ("jne %l0"lab);
+}
Index: test/Parser/asm.cpp
===
--- test/Parser/asm.cpp
+++ test/Parser/asm.cpp
@@ -7,3 +7,28 @@
 int foo5 asm (U"bar5"); // expected-error {{cannot use unicode string literal in 'asm'}}
 int foo6 asm ("bar6"_x); // expected-error {{string literal with user-defined suffix cannot be used here}}
 int foo6 asm ("" L"bar7"); // expected-error {{cannot use wide string literal in 'asm'}}
+
+int zoo ()
+{
+  int x,cond,*e;
+  // expected-error@+1 {{expected ')'}}
+  asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
+  // expected-error@+1 {{expected identifie}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" : );
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" );
+  // expected-error@+1 {{use of undeclared label 'x'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :x);
+  // expected-error@+1 {{use of undeclared label 'b'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :b);
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm goto ("testl %0, %0; jne %l3;" :: "r"(cond)::label_true, loop)
+  // expected-error@+1 {{unknown symbolic operand name in inline assembly string}}
+  asm goto ("decl %0; jnz %l[b]" :: "m"(x) : "memory" : a);
+label_true:
+loop:
+a:
+  return 0;
+}
Index: test/Parser/asm.c
===
--- test/Parser/asm.c
+++ test/Parser/asm.c
@@ -16,6 +16,31 @@
   asm _Atomic (""); // expected-warning {{ignored _Atomic qualifier on asm}}
 }
 
+int zoo ()
+{
+  int x,cond,*e;
+  // expected-error@+1 {{expected ')'}}
+  asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
+  // expected-error@+1 {{expected ':'}}
+  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
+  // expected-error@+1 {{expected identifie}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" : );
+  // expected-error@+1 {{expected ':'}}
+  asm 

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-01-15 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked 2 inline comments as done.
jyu2 added inline comments.



Comment at: lib/Sema/SemaStmtAsm.cpp:470
+if (NS->isGCCAsmGoto() &&
+Exprs[ConstraintIdx]->getStmtClass() == Stmt::AddrLabelExprClass)
+  break;

efriedma wrote:
> jyu2 wrote:
> > efriedma wrote:
> > > jyu2 wrote:
> > > > efriedma wrote:
> > > > > jyu2 wrote:
> > > > > > jyu2 wrote:
> > > > > > > efriedma wrote:
> > > > > > > > jyu2 wrote:
> > > > > > > > > efriedma wrote:
> > > > > > > > > > jyu2 wrote:
> > > > > > > > > > > efriedma wrote:
> > > > > > > > > > > > This looks suspicious; an AddrLabelExpr could be an 
> > > > > > > > > > > > input or output, e.g. `"r"(&&foo)`.
> > > > > > > > > > > Syntax for asm goto:
> > > > > > > > > > >  Syntax:
> > > > > > > > > > >asm [volatile] goto ( AssemblerTemplate
> > > > > > > > > > >:
> > > > > > > > > > >: InputOperands
> > > > > > > > > > >: Clobbers
> > > > > > > > > > >: GotoLabels)
> > > > > > > > > > > 
> > > > > > > > > > >  Only input is allowed.  Output is not allowed
> > > > > > > > > > > 
> > > > > > > > > > That doesn't really address my point here... ignore the "or 
> > > > > > > > > > output" part of the comment.
> > > > > > > > > Sorry did not realize that.  Thank you so much for catching 
> > > > > > > > > that.  Need to add other condition "ConstraintIdx > 
> > > > > > > > > NS->getNumInputs() - 1", change to :
> > > > > > > > > 
> > > > > > > > > if (NS->isGCCAsmGoto() && ConstraintIdx > NS->getNumInputs() 
> > > > > > > > > - 1 &&
> > > > > > > > > Exprs[ConstraintIdx]->getStmtClass() == 
> > > > > > > > > Stmt::AddrLabelExprClass)
> > > > > > > > >   break;
> > > > > > > > > 
> > > > > > > > > Is this ok with you?  Thanks
> > > > > > > > That's the right idea. But I still see a few issues at that 
> > > > > > > > point:
> > > > > > > > 
> > > > > > > > 1. The AddrLabelExprClass check is redundant.
> > > > > > > > 2. "NS->getNumInputs() - 1" can overflow; probably should use 
> > > > > > > > "ConstraintIdx >= NS->getNumInputs()".
> > > > > > > > 3. "break" exits the loop completely (so it skips validating 
> > > > > > > > all constraints written after the label).
> > > > > > > > 4. The code needs to verify that the user correctly specified 
> > > > > > > > the "l" constraint modifier.
> > > > > > > Sorry not done yet.  
> > > > > > For you comment 4:
> > > > > > 
> > > > > > The code needs to verify that the user correctly specified the "l" 
> > > > > > constraint modifier.  We already emit error like following?
> > > > > > 
> > > > > > Do you mean, we need more checking here?  Thanks. 
> > > > > > 
> > > > > > n.c:4:35: error: unknown symbolic operand name in inline assembly 
> > > > > > string
> > > > > >   asm goto ("frob %%r5, %1; jc %l[error]; mov (%2), %%r5"
> > > > > > ~~^~~
> > > > > > n.c:8:15: error: use of undeclared label 'error1'
> > > > > > : error1);
> > > > > > 
> > > > > > Test is:
> > > > > > int frob(int x)
> > > > > > {
> > > > > >   int y;
> > > > > >   asm goto ("frob %%r5, %1; jc %l[error]; mov (%2), %%r5"
> > > > > > : /* No outputs. */
> > > > > > : "r"(x), "r"(&y)
> > > > > > : "memory"
> > > > > > : error1);
> > > > > >   return y;
> > > > > > error:
> > > > > >   return -1;
> > > > > > }
> > > > > > 
> > > > > > 
> > > > > I mean, there needs to be a diagnostic for the following:
> > > > > 
> > > > > ```
> > > > > asm goto ("jne %h0"x);
> > > > > ```
> > > > > 
> > > > > On a related note, there should also be a diagnostic for the 
> > > > > following somewhere:
> > > > > 
> > > > > ```
> > > > > asm ("jne %l0"::"r"(0));
> > > > > ```
> > > > Hi Eli,
> > > > 
> > > > Thanks for your review.
> > > > 
> > > > For case:
> > > > asm goto ("jne %h0"x);
> > > > 
> > > > Without define label x, both clang and my current implementation give 
> > > > error of "use of undeclared label"
> > > > 
> > > > if x is defined: gcc give error 
> > > > asm_goto>!gcc
> > > > gcc n.c
> > > > n.c: Assembler messages:
> > > > n.c:4: Error: operand type mismatch for `jne'
> > > > 
> > > > My current implementation don't emit error.  I think this is need to be 
> > > > done in LLVM.  Am I right here?
> > > > 
> > > > For the case:
> > > > asm ("jne %l0"::"r"(0));
> > > > 
> > > > gcc don't allow any modifier 'l' with  asm stmt but it allows with asm 
> > > > goto.  Is that something you are look for?  Thanks.
> > > > 
> > > > So I add code in AST/Stmt.cpp to emit error.
> > > > .
> > > >  return diag::err_asm_invalid_escape;
> > > >   } else if (!this->isGCCAsmGoto() && EscapedChar == 'l' &&
> > > >  isDigit(*CurPtr)) {
> > > > DiagOffs = CurPtr-StrStart;
> > > > return diag::err_asm_invalid_operand_number;
> > > >   }
> > > > 
> > > For the fir

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-01-15 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 181973.
jyu2 marked an inline comment as done.
jyu2 added a comment.

Change error message.


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Expr.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/ExprObjC.h
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticASTKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm-goto.c
  test/Parser/asm-goto.cpp
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp

Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,28 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{operand with 'l' modifier must refer to a label}}
+  asm ("jne %l0"::"r"(&&lab));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  // expected-error@+1 {{operand with 'l' modifier must refer to a label}}
+  asm goto ("jne %l0"::"r"(x)::lab);
+  asm goto ("jne %l0"lab);
+}
Index: test/Parser/asm.cpp
===
--- test/Parser/asm.cpp
+++ test/Parser/asm.cpp
@@ -7,3 +7,28 @@
 int foo5 asm (U"bar5"); // expected-error {{cannot use unicode string literal in 'asm'}}
 int foo6 asm ("bar6"_x); // expected-error {{string literal with user-defined suffix cannot be used here}}
 int foo6 asm ("" L"bar7"); // expected-error {{cannot use wide string literal in 'asm'}}
+
+int zoo ()
+{
+  int x,cond,*e;
+  // expected-error@+1 {{expected ')'}}
+  asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
+  // expected-error@+1 {{expected identifie}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" : );
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" );
+  // expected-error@+1 {{use of undeclared label 'x'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :x);
+  // expected-error@+1 {{use of undeclared label 'b'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :b);
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm goto ("testl %0, %0; jne %l3;" :: "r"(cond)::label_true, loop)
+  // expected-error@+1 {{unknown symbolic operand name in inline assembly string}}
+  asm goto ("decl %0; jnz %l[b]" :: "m"(x) : "memory" : a);
+label_true:
+loop:
+a:
+  return 0;
+}
Index: test/Parser/asm.c
===
--- test/Parser/asm.c
+++ test/Parser/asm.c
@@ -16,6 +16,31 @@
   asm _Atomic (""); // expected-warning {{ignored _Atomic qualifier on asm}}
 }
 
+int zoo ()
+{
+  int x,cond,*e;
+  // expected-error@+1 {{expected ')'}}
+  asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
+  // expected-error@+1 {{expected ':'}}
+  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
+  // expected-error@+1 {{expected identifie}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" : );
+  // expected-error@+1 {{expected ':'}}
+  asm goto ("d

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-01-30 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 184349.
jyu2 marked an inline comment as done.
jyu2 added a comment.

Change test for BE IR change.


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Expr.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/ExprObjC.h
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticASTKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm-goto.c
  test/Parser/asm-goto.cpp
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp

Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,28 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{operand with 'l' modifier must refer to a label}}
+  asm ("jne %l0"::"r"(&&lab));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  // expected-error@+1 {{operand with 'l' modifier must refer to a label}}
+  asm goto ("jne %l0"::"r"(x)::lab);
+  asm goto ("jne %l0"lab);
+}
Index: test/Parser/asm.cpp
===
--- test/Parser/asm.cpp
+++ test/Parser/asm.cpp
@@ -7,3 +7,28 @@
 int foo5 asm (U"bar5"); // expected-error {{cannot use unicode string literal in 'asm'}}
 int foo6 asm ("bar6"_x); // expected-error {{string literal with user-defined suffix cannot be used here}}
 int foo6 asm ("" L"bar7"); // expected-error {{cannot use wide string literal in 'asm'}}
+
+int zoo ()
+{
+  int x,cond,*e;
+  // expected-error@+1 {{expected ')'}}
+  asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
+  // expected-error@+1 {{expected identifie}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" : );
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" );
+  // expected-error@+1 {{use of undeclared label 'x'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :x);
+  // expected-error@+1 {{use of undeclared label 'b'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :b);
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm goto ("testl %0, %0; jne %l3;" :: "r"(cond)::label_true, loop)
+  // expected-error@+1 {{unknown symbolic operand name in inline assembly string}}
+  asm goto ("decl %0; jnz %l[b]" :: "m"(x) : "memory" : a);
+label_true:
+loop:
+a:
+  return 0;
+}
Index: test/Parser/asm.c
===
--- test/Parser/asm.c
+++ test/Parser/asm.c
@@ -16,6 +16,31 @@
   asm _Atomic (""); // expected-warning {{ignored _Atomic qualifier on asm}}
 }
 
+int zoo ()
+{
+  int x,cond,*e;
+  // expected-error@+1 {{expected ')'}}
+  asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
+  // expected-error@+1 {{expected ':'}}
+  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
+  // expected-error@+1 {{expected identifie}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" : );
+  // expected-error@+1 {{expected ':'}}
+  asm 

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-03-04 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 189205.
jyu2 added a comment.

Rebased


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/JumpDiagnostics.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm-goto.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp
  test/Sema/scope-check.c

Index: test/Sema/scope-check.c
===
--- test/Sema/scope-check.c
+++ test/Sema/scope-check.c
@@ -232,3 +232,19 @@
 
 // rdar://9024687
 int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
+
+//Asm goto:
+int test16(int n)
+{
+  // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm volatile goto("testl %0, %0; jne %l1;" :: "r"(n)::label_true, loop);
+  // expected-note@+2 {{jump bypasses initialization of variable length array}}
+  // expected-note@+1 {{possible target of asm goto statement}}
+  return ({int a[n];label_true: 2;});
+  // expected-note@+1 {{jump bypasses initialization of variable length array}}
+  int b[n];
+// expected-note@+1 {{possible target of asm goto statement}}
+loop:
+  return 0;
+}
Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,24 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  asm goto ("jne %l0"lab);
+}
Index: test/Sema/asm-goto.cpp
===
--- /dev/null
+++ test/Sema/asm-goto.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
+
+struct NonTrivial {
+  ~NonTrivial();
+  int f(int);
+private:
+  int k;
+};
+void JumpDiagnostics(int n) {
+// expected-error@+1 {{cannot jump from this goto statement to its label}}
+  goto DirectJump;
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp1;
+
+DirectJump:
+// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" Later);
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp2;
+// expected-note@+1 {{possible target of asm goto statement}}
+Later:
+  return;
+}
+
+struct S { ~S(); };
+void foo(int a) {
+  if (a) {
+FOO:
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+S s;
+void *p = &&BAR;
+// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" BAR);
+// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
+goto *p;
+p = &&FOO;
+goto *p;
+r

[PATCH] D58160: MS ABI: adding template static member in the linker directive section to make sure init function can be called before main.

2019-03-18 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

In D58160#1433458 , @rnk wrote:

> lgtm


Thank you so much Reid!


Repository:
  rL LLVM

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

https://reviews.llvm.org/D58160



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


[PATCH] D58160: MS ABI: adding template static member in the linker directive section to make sure init function can be called before main.

2019-04-03 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 closed this revision.
jyu2 added a comment.

Closed by commit rG0b28b8b09be7 
: 
Bug-40323: MS ABI adding template static member in the linker directive 
section… (authored by jyu2).


Repository:
  rL LLVM

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

https://reviews.llvm.org/D58160



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


[PATCH] D60912: MS ABI: handle inline static data member as template static data member

2019-04-19 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 created this revision.
jyu2 added reviewers: rnk, majnemer, erichkeane, cfe-commits.
Herald added a project: clang.

MS only run time problem with inline static data member.
A inline static data member’s init function gets called multiple time.

To fix this, using template static data members initialization method instead.  
So that inline static data member initialize function can be put into COMDAT 
group with global being initialized.  And also put static data member in the 
linker directive.  So that the function can be called before main, even the 
that variable is not been referenced.

The bug is report in:
https://bugs.llvm.org/show_bug.cgi?id=37903


Repository:
  rC Clang

https://reviews.llvm.org/D60912

Files:
  lib/CodeGen/CGDeclCXX.cpp
  test/CodeGenCXX/microsoft-abi-template-static-init.cpp

Index: test/CodeGenCXX/microsoft-abi-template-static-init.cpp
===
--- /dev/null
+++ test/CodeGenCXX/microsoft-abi-template-static-init.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -std=c++17 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-win32 -fms-extensions -std=c++17 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -fms-extensions -std=c++17 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-msvc -std=c++17 -fms-extensions -emit-llvm -o - | FileCheck %s
+
+struct S {
+  S();
+  ~S();
+};
+
+template  struct __declspec(dllexport) ExportedTemplate {
+  static S s;
+};
+template  S ExportedTemplate::s;
+void useExportedTemplate(ExportedTemplate x) {
+  (void)x.s;
+}
+int f();
+namespace selectany_init {
+// MS don't put selectany static var in the linker directive, init routine
+// f() is not getting called if x is not referenced.
+int __declspec(selectany) x = f();
+}
+
+namespace explicit_template_instantiation {
+template  struct A { static  int x; };
+template  int A::x = f();
+template struct A;
+}
+
+namespace implicit_template_instantiation {
+template  struct A { static  int x; };
+template   int A::x = f();
+int g() { return A::x; }
+}
+
+
+template 
+struct X_ {
+  static T ioo;
+  static T init();
+};
+template  T X_::ioo = X_::init();
+template struct X_;
+
+template 
+struct X {
+  static T ioo;
+  static T init();
+};
+// template specialized static data don't need in llvm.used,
+// the static init routine get call from _GLOBAL__sub_I_ routines.
+template <> int X::ioo = X::init();
+template struct X;
+class a {
+public:
+  a();
+};
+// For the static var inside unnamed namespace, the object is local to TU.
+// No need to put static var in the linker directive.
+// The static init routine is called before main.
+namespace {
+template  class aj {
+public:
+  static a al;
+};
+template  a aj::al;
+class b : aj<3> {
+  void c();
+};
+void b::c() { al; }
+}
+
+// C++17, inline static data member also need to use
+struct A
+{
+  A();
+  ~A();
+};
+
+struct S1
+{
+  inline static A aoo; // C++17 inline variable, thus also a definition
+};
+
+// CHECK: @llvm.used = appending global [5 x i8*] [i8* bitcast (i32* @"?x@?$A@H@explicit_template_instantiation@@2HA" to i8*), i8* bitcast (i32* @"?ioo@?$X_@H@@2HA" to i8*), i8* getelementptr inbounds (%struct.A, %struct.A* @"?aoo@S1@@2UA@@A", i32 0, i32 0), i8* getelementptr inbounds (%struct.S, %struct.S* @"?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0), i8* bitcast (i32* @"?x@?$A@H@implicit_template_instantiation@@2HA" to i8*)], section "llvm.metadata"
Index: lib/CodeGen/CGDeclCXX.cpp
===
--- lib/CodeGen/CGDeclCXX.cpp
+++ lib/CodeGen/CGDeclCXX.cpp
@@ -467,7 +467,10 @@
   } else if (auto *IPA = D->getAttr()) {
 OrderGlobalInits Key(IPA->getPriority(), PrioritizedCXXGlobalInits.size());
 PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
-  } else if (isTemplateInstantiation(D->getTemplateSpecializationKind())) {
+  } else if (isTemplateInstantiation(D->getTemplateSpecializationKind()) ||
+ (getTarget().getCXXABI().isMicrosoft() &&
+  D->isInlineSpecified() && D->isStaticDataMember() &&
+  getLangOpts().CPlusPlus17)) {
 // C++ [basic.start.init]p2:
 //   Definitions of explicitly specialized class template static data
 //   members have ordered initialization. Other class template static data
@@ -481,6 +484,11 @@
 // minor startup time optimization.  In the MS C++ ABI, there are no guard
 // variables, so this COMDAT key is required for correctness.
 AddGlobalCtor(Fn, 65535, COMDATKey);
+if (getTarget().getCXXABI().isMicrosoft() && COMDATKey) {
+  // In The MS C++, MS add template static data member in the linker
+  // drective.
+  addUsedGlobal(COMDATKey);
+}
   } else if (D->hasAttr()) {
 // SelectAny globals will be comdat-folded. Put the initializer into a
 // COMDAT group associated with the glo

[PATCH] D60912: MS ABI: handle inline static data member as template static data member

2019-04-19 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

In D60912#1472983 , @rnk wrote:

> Thanks, I think there's another case to handle, though.


Hi Reid,
Thank you so much for the review.

Yes, I check the following test case, both gnu and cl call foo twice.  Do we 
want to do differently with that?  Thanks.  Jennifer
I add MS only, since we are generate same with gnu.  Sure remove that should 
work at run time.  But I am not sure if we have abi issues when mix-match 
object.  I will look more about that.Thanks.

bug-37903>g++ x.cpp x1.cpp -std=c++17
bug-37903>./a.out
foo
foo

bug-37903>cat x.h
extern "C" int printf(const char*,...);
int foo();
inline static int aoo = foo(); // C++17 inline variable, thus also a definition
bug-37903>cat x.cpp
#include "x.h"
int foo()
{

  printf("foo\n");
  return 1;

}
int main()
{
}
bug-37903>cat x1.cpp
#include "x.h"


Repository:
  rC Clang

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

https://reviews.llvm.org/D60912



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


[PATCH] D60912: MS ABI: handle inline static data member as template static data member

2019-04-19 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

In D60912#1472987 , @rnk wrote:

> In D60912#1472986 , @jyu2 wrote:
>
> > inline static int aoo = foo(); // C++17 inline variable, thus also a 
> > definition
>
>
> This is a `static inline` global variable, so it technically creates two 
> different globals, so calling foo twice is intended behavior. I think we 
> really want to look at the GVA linkage instead of trying to list all the 
> reasons why something might have weak linkage. Take a look at 
> `shouldBeInCOMDAT` in CodeGenModule.cpp, I think it has the logic we want.


Yes, that is good.  I will do that way.  Thanks.  
Jennifer


Repository:
  rC Clang

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

https://reviews.llvm.org/D60912



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


[PATCH] D60930: [codeview] Fix symbol names for dynamic initializers and atexit stubs

2019-04-22 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

Looks good to me.  We are basically de-mangled name for those __E  initialize 
global’s  function and __F destroy global's function.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D60930



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


[PATCH] D60912: MS ABI: handle inline static data member and inline variable as template static data member

2019-04-23 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 196346.
jyu2 retitled this revision from "MS ABI: handle inline static data member as 
template static data member" to "MS ABI: handle inline static data member and 
inline variable as template static data member".
jyu2 edited the summary of this revision.
jyu2 added a comment.

Hi Reid,
Thanks for your review and catch what I were missing for inline variable 
part(only inline static data member were fix in previous patch). 
As you suggested, instead using GVA_DiscardableODR to put inline variable's 
initialization function or inline static member's initialization functions into 
to COMDAT group with global being initialized.

The  GVA_DiscardableODR is for weak linkage of inline variables.

Let me know if you see problems.
Thank you so much!
Thanks.


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

https://reviews.llvm.org/D60912

Files:
  lib/CodeGen/CGDeclCXX.cpp
  test/CodeGenCXX/microsoft-abi-template-static-init.cpp
  test/Modules/initializers.cpp

Index: test/Modules/initializers.cpp
===
--- test/Modules/initializers.cpp
+++ test/Modules/initializers.cpp
@@ -235,7 +235,6 @@
 
 // CHECK-IMPORT: define {{.*}} @[[TU_INIT]]()
 // CHECK-IMPORT: call void @[[A_INIT]]()
-// CHECK-IMPORT: call void @[[B_INIT]]()
 
 // CHECK-IMPORT: define {{.*}} @__tls_init()
 // CHECK-IMPORT: call void @[[C_INIT]]()
Index: test/CodeGenCXX/microsoft-abi-template-static-init.cpp
===
--- /dev/null
+++ test/CodeGenCXX/microsoft-abi-template-static-init.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -fms-extensions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-msvc  -fms-extensions -emit-llvm -o - | FileCheck %s
+
+struct S {
+  S();
+  ~S();
+};
+
+template  struct __declspec(dllexport) ExportedTemplate {
+  static S s;
+};
+template  S ExportedTemplate::s;
+void useExportedTemplate(ExportedTemplate x) {
+  (void)x.s;
+}
+int f();
+namespace selectany_init {
+// MS don't put selectany static var in the linker directive, init routine
+// f() is not getting called if x is not referenced.
+int __declspec(selectany) x = f();
+inline int __declspec(selectany) x1 = f();
+}
+
+namespace explicit_template_instantiation {
+template  struct A { static  int x; };
+template  int A::x = f();
+template struct A;
+}
+
+namespace implicit_template_instantiation {
+template  struct A { static  int x; };
+template   int A::x = f();
+int g() { return A::x; }
+}
+
+
+template 
+struct X_ {
+  static T ioo;
+  static T init();
+};
+template  T X_::ioo = X_::init();
+template struct X_;
+
+template 
+struct X {
+  static T ioo;
+  static T init();
+};
+// template specialized static data don't need in llvm.used,
+// the static init routine get call from _GLOBAL__sub_I_ routines.
+template <> int X::ioo = X::init();
+template struct X;
+class a {
+public:
+  a();
+};
+// For the static var inside unnamed namespace, the object is local to TU.
+// No need to put static var in the linker directive.
+// The static init routine is called before main.
+namespace {
+template  class aj {
+public:
+  static a al;
+};
+template  a aj::al;
+class b : aj<3> {
+  void c();
+};
+void b::c() { al; }
+}
+
+// C++17, inline static data member also need to use
+struct A
+{
+  A();
+  ~A();
+};
+
+struct S1
+{
+  inline static A aoo; // C++17 inline variable, thus also a definition
+};
+
+int foo();
+inline int zoo = foo();
+inline static int boo = foo();
+
+
+// CHECK: @llvm.used = appending global [7 x i8*] [i8* bitcast (i32* @"?x1@selectany_init@@3HA" to i8*), i8* bitcast (i32* @"?x@?$A@H@explicit_template_instantiation@@2HA" to i8*), i8* bitcast (i32* @"?ioo@?$X_@H@@2HA" to i8*), i8* getelementptr inbounds (%struct.A, %struct.A* @"?aoo@S1@@2UA@@A", i32 0, i32 0), i8* bitcast (i32* @"?zoo@@3HA" to i8*), i8* getelementptr inbounds (%struct.S, %struct.S* @"?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0), i8* bitcast (i32* @"?x@?$A@H@implicit_template_instantiation@@2HA" to i8*)], section "llvm.metadata"
Index: lib/CodeGen/CGDeclCXX.cpp
===
--- lib/CodeGen/CGDeclCXX.cpp
+++ lib/CodeGen/CGDeclCXX.cpp
@@ -467,7 +467,8 @@
   } else if (auto *IPA = D->getAttr()) {
 OrderGlobalInits Key(IPA->getPriority(), PrioritizedCXXGlobalInits.size());
 PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
-  } else if (isTemplateInstantiation(D->getTemplateSpecializationKind())) {
+  } else if (isTemplateInstantiation(D->getTemplateSpecializationKind()) ||
+ getContext().GetGVALinkageForVariable(D) == GVA_DiscardableODR) {
 // C++ [basic.start.init]p2:
 //   Definiti

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-04-24 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

In D56571#1476266 , @nickdesaulniers 
wrote:

> @compudj email me the preprocessed output of basic_percpu_ops_test.c and I'll 
> take a look. (Should be able to find my email via `git log`).


@nickdesaulniers, thanks for looking into  this.  It look like error come from: 
llvm/lib/MC/MCParser/AsmParser.cpp:1118.

Please let me know if that is clang problem.

Thanks.
Jennifer


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

https://reviews.llvm.org/D56571



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


[PATCH] D60912: MS ABI: handle inline static data member and inline variable as template static data member

2019-04-25 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked an inline comment as done.
jyu2 added inline comments.



Comment at: lib/CodeGen/CGDeclCXX.cpp:470-471
 PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
-  } else if (isTemplateInstantiation(D->getTemplateSpecializationKind())) {
+  } else if (isTemplateInstantiation(D->getTemplateSpecializationKind()) ||
+ getContext().GetGVALinkageForVariable(D) == GVA_DiscardableODR) {
 // C++ [basic.start.init]p2:

rnk wrote:
> I think this can be simplified by removing the `isTemplateInstantiation` 
> check and then checking for GVA_DiscardableODR or GVA_StrongODR. That will 
> handle the cases of explicit template instantiation that you have below.
> 
> It's up to you if you want to implement the simplification. The current code 
> is correct, I don't believe it's possible to create a GVA_StrongODR global 
> variable with a dynamic initializer without template instantiation (phew).
Thanks Reid!  I also think GVA_StrongODR which is set for template 
instantiation, but I am not too sure about it.  Since we already handle 
template by calling isTemplateInstantiation, and add GVA_DiscardableODR.  I'd 
like to with this.  If we see other problem.  We can always add it up.

Thank you so much for your review.




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

https://reviews.llvm.org/D60912



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


[PATCH] D60912: MS ABI: handle inline static data member and inline variable as template static data member

2019-04-25 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 closed this revision.
jyu2 added a comment.

committed rGc19f4f806972 
: Fix bug 
37903:MS ABI: handle inline static data member and inline variable as… 
(authored by jyu2).


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

https://reviews.llvm.org/D60912



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-04 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 commandeered this revision.
jyu2 edited reviewers, added: craig.topper; removed: jyu2.
jyu2 added inline comments.



Comment at: lib/Analysis/CFG.cpp:2126
+  if (cast(S)->isGCCAsmGoto())
+return VisitGCCAsmStmt(cast(S));
+  return VisitStmt(S, asc);

rsmith wrote:
> This is not an appropriate function name for a function that is only called 
> on `asm goto`. Given the convention here is to match the `Stmt` class 
> hierarchy with the `Visit` functions, the branch on `asm goto` should be in 
> the callee.
Changed.



Comment at: lib/CodeGen/CGStmt.cpp:1884
+template 
+void CodeGenFunction::UpdateCallInst(
+T &Result, bool HasSideEffect, bool ReadOnly, bool ReadNone,

efriedma wrote:
> rsmith wrote:
> > This is not a reasonable function name for a function that is specific to 
> > `AsmStmt`s. Please also make this a (static) non-member function, since it 
> > cannot be called outside this source file.
> Does this really need to be a template function?  I think all the functions 
> you're calling on "Result" are members of CallBase.
How about UpdateAsmCallInst?



Comment at: lib/CodeGen/CGStmt.cpp:1884
+template 
+void CodeGenFunction::UpdateCallInst(
+T &Result, bool HasSideEffect, bool ReadOnly, bool ReadNone,

jyu2 wrote:
> efriedma wrote:
> > rsmith wrote:
> > > This is not a reasonable function name for a function that is specific to 
> > > `AsmStmt`s. Please also make this a (static) non-member function, since 
> > > it cannot be called outside this source file.
> > Does this really need to be a template function?  I think all the functions 
> > you're calling on "Result" are members of CallBase.
> How about UpdateAsmCallInst?
Yes. I am using CallBase instead template.



Comment at: lib/CodeGen/CGStmt.cpp:2188
+ std::to_string(NumGccAsmGotoStmts));
+  NumGccAsmGotoStmts++;
+}

efriedma wrote:
> The NumGccAsmGotoStmts variable is pointless; if names are enabled, 
> createBasicBlock will automatically number all the blocks named "normal".
Okay changed.  Thanks.



Comment at: lib/CodeGen/CGStmt.cpp:2238-2245
+UpdateCallInst(*Result, HasSideEffect, ReadOnly,
+ ReadNone, S, ResultRegTypes, RegResults);
+EmitBlock(Fallthrough);
   } else {
-for (unsigned i = 0, e = ResultRegTypes.size(); i != e; ++i) {
-  llvm::Value *Tmp = Builder.CreateExtractValue(Result, i, "asmresult");
-  RegResults.push_back(Tmp);
-}
+llvm::CallInst *Result =
+Builder.CreateCall(IA, Args, getBundlesForFunclet(IA));
+UpdateCallInst(*Result, HasSideEffect, ReadOnly, ReadNone,

rsmith wrote:
> No need to explicitly specify the template argument here; it's deducible.
Thanks.  Changed.



Comment at: lib/Parse/ParseStmtAsm.cpp:833-837
+if (Tok.isNot(tok::identifier)) {
+  Diag(Tok, diag::err_expected) << tok::identifier;
+  SkipUntil(tok::r_paren, StopAtSemi);
+  return StmtError();
+}

rsmith wrote:
> This should be inside the loop below.
Yes.  Change.



Comment at: test/Parser/asm-goto.c:1
+// RUN: %clang_cc1 %s
+

efriedma wrote:
> What is this testing?
Just testing asm goto can parser those input operands and labels.  Not error 
checking.  

Error checking is in Sema/asm-goto


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

https://reviews.llvm.org/D56571



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-04 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 185094.
jyu2 added a comment.

1> Add code for scope checking
2> Using CastInterator
3> CFG change to remove duplicate Block list


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticASTKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/JumpDiagnostics.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp
  test/Sema/scope-check.c

Index: test/Sema/scope-check.c
===
--- test/Sema/scope-check.c
+++ test/Sema/scope-check.c
@@ -232,3 +232,18 @@
 
 // rdar://9024687
 int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
+
+
+//Asm goto:
+int test16(int n)
+{
+  // expected-error@+2 {{cannot jump from this goto statement to its label}}
+  // expected-error@+1 {{cannot jump from this goto statement to its label}}
+  asm volatile goto("testl %0, %0; jne %l1;" :: "r"(n)::label_true, loop);
+  // expected-note@+1 {{jump bypasses initialization of variable length array}}
+  return ({int a[n];label_true: 2;});
+  // expected-note@+1 {{jump bypasses initialization of variable length array}}
+  int b[n];
+loop:
+  return 0;
+}
Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,28 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{operand with 'l' modifier must refer to a label}}
+  asm ("jne %l0"::"r"(&&lab));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  // expected-error@+1 {{operand with 'l' modifier must refer to a label}}
+  asm goto ("jne %l0"::"r"(x)::lab);
+  asm goto ("jne %l0"lab);
+}
Index: test/Parser/asm.cpp
===
--- test/Parser/asm.cpp
+++ test/Parser/asm.cpp
@@ -7,3 +7,54 @@
 int foo5 asm (U"bar5"); // expected-error {{cannot use unicode string literal in 'asm'}}
 int foo6 asm ("bar6"_x); // expected-error {{string literal with user-defined suffix cannot be used here}}
 int foo6 asm ("" L"bar7"); // expected-error {{cannot use wide string literal in 'asm'}}
+
+int zoo ()
+{
+  int x,cond,*e;
+  // expected-error@+1 {{expected ')'}}
+  asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
+  // expected-error@+1 {{expected identifie}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" : );
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" );
+  // expected-error@+1 {{use of undeclared label 'x'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :x);
+  // expected-error@+1 {{use of undeclared label 'b'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :b);
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm goto ("testl %0, %0; jne %l3;" :: "r"(cond)::label_true, loop)
+  // expected-error@+1 {{unknown symbolic operand name in inline

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-04 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked 12 inline comments as done.
jyu2 added inline comments.



Comment at: include/clang/AST/Stmt.h:1008
+ (*iterator_adaptor_base::I)->getStmtClass() <= lastExprConstant);
+  return *reinterpret_cast(iterator_adaptor_base::I);
 }

rsmith wrote:
> Ugh. This cast violates strict aliasing, and even in the absence of strict 
> aliasing won't work unless the `Stmt` base class is at offset 0 in `T`. The 
> preceding assert is also wrong, as it's asserting that `*I` is an `Expr`, not 
> that it's a `T`.
> 
> After r352925, you can use `CastIterator` instead; that should 
> substantially reduce the churn in this patch.
Hi Richard,
Thanks for explain for this. And thank you so much for proving CastIterator!!  
I change the code to use this.




Comment at: include/clang/AST/Stmt.h:2842
+
+  bool isGCCAsmGoto() const {
+return NumLabels > 0;

rsmith wrote:
> This is already inside a class `GCCAsmStmt`; the `GCC` here seems unnecessary.
Remove GCC



Comment at: include/clang/AST/Stmt.h:2860
+  StringRef getLabelName(unsigned i) const;
+  Expr *getExpr(unsigned i) const;
+  using labels_iterator = ExprIterator;

rsmith wrote:
> Please give this a better name; `getExpr` is pretty meaningless.
should I change to getOperandExpr?
Thanks.



Comment at: lib/Analysis/CFG.cpp:1474
+  appendScopeBegin(JT.block, VD, G);
+  addSuccessor(B, JT.block);
+}

jyu2 wrote:
> efriedma wrote:
> > Please don't copy-paste code.
> :-(  changed
I did this during in VisitGCCAsmStmt by not call addSuccessor when we need 
backpatch the the labels.



Comment at: lib/Analysis/CFG.cpp:1466
+  LabelMapTy::iterator LI = LabelMap.find(E->getLabel());
+  if (LI == LabelMap.end()) continue;
+  JT = LI->second;

rsmith wrote:
> If this happens for every iteration of the loop, `VD` is used uninitialized 
> after the loop.
I am totally wrong.  Changed



Comment at: lib/Parse/ParseStmtAsm.cpp:839
+if (Tok.isNot(tok::r_paren)) {
+  while (1) {
+LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),

rsmith wrote:
> `while (true)`
Yes.  Changed.
Thanks.


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

https://reviews.llvm.org/D56571



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-04 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked 2 inline comments as done.
jyu2 added inline comments.



Comment at: lib/Sema/JumpDiagnostics.cpp:347
+  LabelAndGotoScopes[S] = ParentScope;
+  Jumps.push_back(S);
+}

efriedma wrote:
> This doesn't look right; I think we need to add it to IndirectJumps instead.  
> This probably impacts a testcase like the following:
> 
> ```
> struct S { ~S(); };
> int f() {
>   {
> S s;
> asm goto(""BAR);
> return 1;
>   }
> BAR:
>   return 0;
> }
> ```
> 
> (gcc currently accepts this and skips running the destructor, but I'm pretty 
> sure that's a bug.)
Hi Eli,
I see both g++ and clang++ with my change call ~S.  Am I missing something?  
Thanks.

1>clang++ j.cpp
1>./a.out
~S()
1>g++ j.cpp
1>./a.out
~S()

Here is the test case:
1>cat j.cpp
extern "C" int printf (const char *,...);
struct S { ~S() {printf("~S()\n");}; };
int f() {
  {
S s;
asm goto(""BAR);
return 1;
  }
BAR:
  return 0;
}

int main()
{
  f();
}



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

https://reviews.llvm.org/D56571



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-04 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 185206.
jyu2 marked 8 inline comments as done.
jyu2 added a comment.

More review comments addressed.


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticASTKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/JumpDiagnostics.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp
  test/Sema/scope-check.c

Index: test/Sema/scope-check.c
===
--- test/Sema/scope-check.c
+++ test/Sema/scope-check.c
@@ -232,3 +232,18 @@
 
 // rdar://9024687
 int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
+
+
+//Asm goto:
+int test16(int n)
+{
+  // expected-error@+2 {{cannot jump from this goto statement to its label}}
+  // expected-error@+1 {{cannot jump from this goto statement to its label}}
+  asm volatile goto("testl %0, %0; jne %l1;" :: "r"(n)::label_true, loop);
+  // expected-note@+1 {{jump bypasses initialization of variable length array}}
+  return ({int a[n];label_true: 2;});
+  // expected-note@+1 {{jump bypasses initialization of variable length array}}
+  int b[n];
+loop:
+  return 0;
+}
Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,28 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{operand with 'l' modifier must refer to a label}}
+  asm ("jne %l0"::"r"(&&lab));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  // expected-error@+1 {{operand with 'l' modifier must refer to a label}}
+  asm goto ("jne %l0"::"r"(x)::lab);
+  asm goto ("jne %l0"lab);
+}
Index: test/Parser/asm.cpp
===
--- test/Parser/asm.cpp
+++ test/Parser/asm.cpp
@@ -7,3 +7,54 @@
 int foo5 asm (U"bar5"); // expected-error {{cannot use unicode string literal in 'asm'}}
 int foo6 asm ("bar6"_x); // expected-error {{string literal with user-defined suffix cannot be used here}}
 int foo6 asm ("" L"bar7"); // expected-error {{cannot use wide string literal in 'asm'}}
+
+int zoo ()
+{
+  int x,cond,*e;
+  // expected-error@+1 {{expected ')'}}
+  asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
+  // expected-error@+1 {{expected identifie}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" : );
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" );
+  // expected-error@+1 {{use of undeclared label 'x'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :x);
+  // expected-error@+1 {{use of undeclared label 'b'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :b);
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm goto ("testl %0, %0; jne %l3;" :: "r"(cond)::label_true, loop)
+  // expected-error@+1 {{unknown symbolic operand name in inline assembly string}}
+  asm go

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-04 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added inline comments.



Comment at: lib/AST/Stmt.cpp:457-460
   this->NumOutputs = NumOutputs;
   this->NumInputs = NumInputs;
   this->NumClobbers = NumClobbers;
+  this->NumLabels = NumLabels;

rsmith wrote:
> Please assert that you don't have both outputs and labels here. (If you did, 
> you would assign them the same slots within `Exprs`.)
> 
> You also seem to be missing `Sema` enforcement of the rule that you cannot 
> have both outputs and labels. (If you want to actually support that as an 
> intentional extension to the GCC functionality, you should change the 
> implementation of `GCCAsmStmt` to use different slots for outputs and labels, 
> add some tests, and add a `-Wgcc-compat` warning for that case. Seems better 
> to just add an error for it for now.)
This is enforcement during the parer.  

for example:
a.c:12:23: error: expected ':'
asm goto ("decl %0;" :"a": "m"(cond) : "memory" );

Do you think this is enough for now?
Thanks.
Jennifer



Comment at: lib/Analysis/CFG.cpp:1445-1458
+  LabelMapTy::iterator LI = LabelMap.find(G->getLabel());;
+  // If there is no target for the goto, then we are looking at an
+  // incomplete AST.  Handle this by not registering a successor.
+  if (LI == LabelMap.end()) continue;
 
-JumpTarget JT = LI->second;
-prependAutomaticObjLifetimeWithTerminator(B, I->scopePosition,
-  JT.scopePosition);
-prependAutomaticObjDtorsWithTerminator(B, I->scopePosition,
-   JT.scopePosition);
-const VarDecl *VD = prependAutomaticObjScopeEndWithTerminator(
-B, I->scopePosition, JT.scopePosition);
-appendScopeBegin(JT.block, VD, G);
-addSuccessor(B, JT.block);
+  JumpTarget JT = LI->second;
+  prependAutomaticObjLifetimeWithTerminator(B, I->scopePosition,

rsmith wrote:
> Please factor out this duplicated code into a local lambda rather than 
> copy-pasting it.
Thanks.  Changed.



Comment at: lib/Analysis/CFG.cpp:1461
+if (auto *G = dyn_cast(B->getTerminator())) {
+  if (G->isAsmGoto()) {
+for (auto *E : G->labels()) {

rsmith wrote:
> This check is redundant; there will be no labels if it's not an `asm goto` so 
> you can just perform the below loop unconditionally.
Okay removed.  Thanks.



Comment at: lib/Analysis/CFG.cpp:3139-3141
+  // We will need to backpatch this block later.
+  BackpatchBlocks.push_back(JumpSource(Block, ScopePos));
+  return Block;

rsmith wrote:
> Do we not need the handling for the other labels if we hit this condition for 
> one label?
It is handled in backpatch processing which go though each label and build CFG.



Comment at: lib/Sema/JumpDiagnostics.cpp:347
+  LabelAndGotoScopes[S] = ParentScope;
+  Jumps.push_back(S);
+}

efriedma wrote:
> jyu2 wrote:
> > efriedma wrote:
> > > This doesn't look right; I think we need to add it to IndirectJumps 
> > > instead.  This probably impacts a testcase like the following:
> > > 
> > > ```
> > > struct S { ~S(); };
> > > int f() {
> > >   {
> > > S s;
> > > asm goto(""BAR);
> > > return 1;
> > >   }
> > > BAR:
> > >   return 0;
> > > }
> > > ```
> > > 
> > > (gcc currently accepts this and skips running the destructor, but I'm 
> > > pretty sure that's a bug.)
> > Hi Eli,
> > I see both g++ and clang++ with my change call ~S.  Am I missing something? 
> >  Thanks.
> > 
> > 1>clang++ j.cpp
> > 1>./a.out
> > ~S()
> > 1>g++ j.cpp
> > 1>./a.out
> > ~S()
> > 
> > Here is the test case:
> > 1>cat j.cpp
> > extern "C" int printf (const char *,...);
> > struct S { ~S() {printf("~S()\n");}; };
> > int f() {
> >   {
> > S s;
> > asm goto(""BAR);
> > return 1;
> >   }
> > BAR:
> >   return 0;
> > }
> > 
> > int main()
> > {
> >   f();
> > }
> > 
> Oh, sorry, I wasn't paying attention to the actual contents of the asm.  If 
> you modify the asm goto slightly, to `asm goto("jmp %0"BAR);`, you'll see 
> that the destructor doesn't run, at least with gcc.  (This is different from 
> the way `goto BAR;` works.)
Thanks.  I see, the cleanup code is not generated for asm goto.

For clang with our current implementation, llvm emit error for this.  But the 
error message isn't clear.

You are right, we should emit error in clang.  I will look into tomorrow. 

Thanks.



Comment at: lib/Sema/SemaStmtAsm.cpp:656
+  // Check for duplicate asm operand name between input, output and label 
lists.
+  typedef std::pair  MyItemType;
+  SmallVector MyList;

rsmith wrote:
> No space after `pair`, please.
Sorry, changed.



Comment at: lib/Sema/SemaStmtAsm.cpp:659-662
+  for (unsigned i = 0, e = NumOutputs + NumInputs + NumLabels; i != e; ++i)
+if (NS->getIdentifier(i) && !NS->getIdentifier(i)->getName().

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-05 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 185360.
jyu2 added a comment.

1>emit better error for use of output constraints.
2> Add assert for NumLabels and NumOutputs are both larger than 0.


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticASTKinds.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/JumpDiagnostics.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp
  test/Sema/scope-check.c

Index: test/Sema/scope-check.c
===
--- test/Sema/scope-check.c
+++ test/Sema/scope-check.c
@@ -232,3 +232,18 @@
 
 // rdar://9024687
 int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
+
+
+//Asm goto:
+int test16(int n)
+{
+  // expected-error@+2 {{cannot jump from this goto statement to its label}}
+  // expected-error@+1 {{cannot jump from this goto statement to its label}}
+  asm volatile goto("testl %0, %0; jne %l1;" :: "r"(n)::label_true, loop);
+  // expected-note@+1 {{jump bypasses initialization of variable length array}}
+  return ({int a[n];label_true: 2;});
+  // expected-note@+1 {{jump bypasses initialization of variable length array}}
+  int b[n];
+loop:
+  return 0;
+}
Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,28 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{operand with 'l' modifier must refer to a label}}
+  asm ("jne %l0"::"r"(&&lab));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  // expected-error@+1 {{operand with 'l' modifier must refer to a label}}
+  asm goto ("jne %l0"::"r"(x)::lab);
+  asm goto ("jne %l0"lab);
+}
Index: test/Parser/asm.cpp
===
--- test/Parser/asm.cpp
+++ test/Parser/asm.cpp
@@ -7,3 +7,54 @@
 int foo5 asm (U"bar5"); // expected-error {{cannot use unicode string literal in 'asm'}}
 int foo6 asm ("bar6"_x); // expected-error {{string literal with user-defined suffix cannot be used here}}
 int foo6 asm ("" L"bar7"); // expected-error {{cannot use wide string literal in 'asm'}}
+
+int zoo ()
+{
+  int x,cond,*e;
+  // expected-error@+1 {{expected ')'}}
+  asm ("mov %[e], %[e]" : : [e] "rm" (*e)::a)
+  // expected-error@+1  {{'asm goto' cannot have output constraints}}
+  asm goto ("decl %0; jnz %l[a]" :"=r"(x): "m"(x) : "memory" : a);
+  // expected-error@+1 {{expected identifie}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" : );
+  // expected-error@+1  {{expected ':'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" );
+  // expected-error@+1 {{use of undeclared label 'x'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :x);
+  // expected-error@+1 {{use of undeclared label 'b'}}
+  asm goto ("decl %0;" :: "m"(x) : "memory" :b);
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm goto ("testl %0, %0; jne %l3;" :: 

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-05 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked 2 inline comments as done.
jyu2 added inline comments.



Comment at: lib/AST/Stmt.cpp:457-460
   this->NumOutputs = NumOutputs;
   this->NumInputs = NumInputs;
   this->NumClobbers = NumClobbers;
+  this->NumLabels = NumLabels;

rsmith wrote:
> jyu2 wrote:
> > rsmith wrote:
> > > Please assert that you don't have both outputs and labels here. (If you 
> > > did, you would assign them the same slots within `Exprs`.)
> > > 
> > > You also seem to be missing `Sema` enforcement of the rule that you 
> > > cannot have both outputs and labels. (If you want to actually support 
> > > that as an intentional extension to the GCC functionality, you should 
> > > change the implementation of `GCCAsmStmt` to use different slots for 
> > > outputs and labels, add some tests, and add a `-Wgcc-compat` warning for 
> > > that case. Seems better to just add an error for it for now.)
> > This is enforcement during the parer.  
> > 
> > for example:
> > a.c:12:23: error: expected ':'
> > asm goto ("decl %0;" :"a": "m"(cond) : "memory" );
> > 
> > Do you think this is enough for now?
> > Thanks.
> > Jennifer
> Thanks, I see it now. Please still add the assert here.
> 
> I'd also like a custom diagnostic for that parse error; it'd seem easy and 
> useful to add an "asm goto cannot have output constraints" error.
Okay added.



Comment at: lib/CodeGen/CGStmt.cpp:2236
+llvm::CallBrInst *Result =
+Builder.CreateCallBr(FTy, IA, Fallthrough, Transfer, Args);
+UpdateAsmCallInst(cast(*Result), HasSideEffect, ReadOnly,

craig.topper wrote:
> I don't think we need to pass FTy here now. I made that change before 
> @jyknight added FunctionCallee that should be able to find the type from the 
> InlineAsm. The CallBr IRBuilder code should have a FunctionCallee Create 
> function as of yesterday.
Removed.


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

https://reviews.llvm.org/D56571



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-05 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 185477.
jyu2 marked 4 inline comments as done.
jyu2 added a comment.

More change from review.

Add scope checking for asm-goto.


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticASTKinds.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/JumpDiagnostics.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm-goto.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp
  test/Sema/scope-check.c

Index: test/Sema/scope-check.c
===
--- test/Sema/scope-check.c
+++ test/Sema/scope-check.c
@@ -232,3 +232,19 @@
 
 // rdar://9024687
 int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
+
+//Asm goto:
+int test16(int n)
+{
+  // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm volatile goto("testl %0, %0; jne %l1;" :: "r"(n)::label_true, loop);
+  // expected-note@+2 {{jump bypasses initialization of variable length array}}
+  // expected-note@+1 {{possible target of asm goto statement}}
+  return ({int a[n];label_true: 2;});
+  // expected-note@+1 {{jump bypasses initialization of variable length array}}
+  int b[n];
+// expected-note@+1 {{possible target of asm goto statement}}
+loop:
+  return 0;
+}
Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,28 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{operand with 'l' modifier must refer to a label}}
+  asm ("jne %l0"::"r"(&&lab));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  // expected-error@+1 {{operand with 'l' modifier must refer to a label}}
+  asm goto ("jne %l0"::"r"(x)::lab);
+  asm goto ("jne %l0"lab);
+}
Index: test/Sema/asm-goto.cpp
===
--- /dev/null
+++ test/Sema/asm-goto.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
+
+struct NonTrivial {
+  ~NonTrivial();
+  int f(int);
+private:
+  int k;
+};
+void JumpDiagnostics(int n) {
+// expected-error@+1 {{cannot jump from this goto statement to its label}}
+  goto DirectJump;
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp1;
+
+DirectJump:
+// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" Later);
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp2;
+// expected-note@+1 {{possible target of asm goto statement}}
+Later:
+  return;
+}
+
+struct S { ~S(); };
+void foo(int a) {
+  if (a) {
+FOO:
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-05 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added inline comments.



Comment at: lib/AST/Stmt.cpp:457-458
+  this->NumLabels = NumLabels;
+  assert((NumLabels != 0 && NumOutputs == 0) ||
+ (NumOutputs != 0 && NumLabels == 0));
 

rsmith wrote:
> This can be simplified a little:
> ```
> assert(!(NumOutputs && NumLabels) && "asm goto cannot have outputs");
> ```
Thanks.  Yes, this is better than me.  Changed



Comment at: lib/AST/Stmt.cpp:628
+  DiagOffs = CurPtr-StrStart-1;
+  return diag::err_asm_invalid_operand_for_goto_labels;
+}

rsmith wrote:
> I'm curious why we're checking this here, when all the other validation for 
> the modifier letter happens in LLVM. Does this check need to be done 
> differently from the others?
This is to verify following in spec:
=
To reference a label in the assembler template, prefix it with ‘%l’ (lowercase 
‘L’) followed by its (zero-based) position in GotoLabels plus the number of 
input operands. For example, if the asm has three inputs and references two 
labels, refer to the first label as ‘%l3’ and the second as ‘%l4’).

Was request from Eli.



Comment at: lib/CodeGen/CGStmt.cpp:2186
+  }
+  StringRef Name = "normal";
+  Fallthrough = createBasicBlock(Name);

rsmith wrote:
> Nit: I think something like "asm.fallthrough" or "asm.cont" would be a more 
> obvious name for the fall-through block.
Changed.



Comment at: lib/Sema/SemaStmtAsm.cpp:659-671
+if (NS->getIdentifier(i))
+  MyList.emplace_back(std::make_pair(NS->getIdentifier(i)->getName(),
+ Exprs[i]));
+  for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; ++i)
+if (NS->getIdentifier(i))
+  MyList.emplace_back(std::make_pair(NS->getIdentifier(i)->getName(),
+ Exprs[i]));

rsmith wrote:
> This is still exposing / relying on an implementation detail of `GCCAsmStmt`. 
> Please replace `getIdentifier` with `getOuptutIdentifier` / 
> `getInputIdentifier` / `getLabelIdentifier`, adjust the indexing to match, 
> and remove `GCCAsmStmt::getIdentifier`. Or alternatively, iterate over 
> `Names` here rather than walking the parts of the `GCCAsmStmt`.
Changed.  Like this!!!


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

https://reviews.llvm.org/D56571



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-05 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 185489.
jyu2 added a comment.

small fix.


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticASTKinds.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/JumpDiagnostics.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm-goto.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp
  test/Sema/scope-check.c

Index: test/Sema/scope-check.c
===
--- test/Sema/scope-check.c
+++ test/Sema/scope-check.c
@@ -232,3 +232,19 @@
 
 // rdar://9024687
 int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
+
+//Asm goto:
+int test16(int n)
+{
+  // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm volatile goto("testl %0, %0; jne %l1;" :: "r"(n)::label_true, loop);
+  // expected-note@+2 {{jump bypasses initialization of variable length array}}
+  // expected-note@+1 {{possible target of asm goto statement}}
+  return ({int a[n];label_true: 2;});
+  // expected-note@+1 {{jump bypasses initialization of variable length array}}
+  int b[n];
+// expected-note@+1 {{possible target of asm goto statement}}
+loop:
+  return 0;
+}
Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,28 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{operand with 'l' modifier must refer to a label}}
+  asm ("jne %l0"::"r"(&&lab));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  // expected-error@+1 {{operand with 'l' modifier must refer to a label}}
+  asm goto ("jne %l0"::"r"(x)::lab);
+  asm goto ("jne %l0"lab);
+}
Index: test/Sema/asm-goto.cpp
===
--- /dev/null
+++ test/Sema/asm-goto.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
+
+struct NonTrivial {
+  ~NonTrivial();
+  int f(int);
+private:
+  int k;
+};
+void JumpDiagnostics(int n) {
+// expected-error@+1 {{cannot jump from this goto statement to its label}}
+  goto DirectJump;
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp1;
+
+DirectJump:
+// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" Later);
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp2;
+// expected-note@+1 {{possible target of asm goto statement}}
+Later:
+  return;
+}
+
+struct S { ~S(); };
+void foo(int a) {
+  if (a) {
+FOO:
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+S s;
+void *p = &&BAR;
+// expected-er

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-07 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 marked an inline comment as done.
jyu2 added inline comments.



Comment at: lib/AST/Stmt.cpp:628
+  DiagOffs = CurPtr-StrStart-1;
+  return diag::err_asm_invalid_operand_for_goto_labels;
+}

rsmith wrote:
> jyu2 wrote:
> > rsmith wrote:
> > > I'm curious why we're checking this here, when all the other validation 
> > > for the modifier letter happens in LLVM. Does this check need to be done 
> > > differently from the others?
> > This is to verify following in spec:
> > =
> > To reference a label in the assembler template, prefix it with ‘%l’ 
> > (lowercase ‘L’) followed by its (zero-based) position in GotoLabels plus 
> > the number of input operands. For example, if the asm has three inputs and 
> > references two labels, refer to the first label as ‘%l3’ and the second as 
> > ‘%l4’).
> > 
> > Was request from Eli.
> Sorry, I think my question was unclear. I understand why you need to do this 
> check somewhere. My question is why this check needs to be *here*, given that 
> all the other checks for the modifier letter are performed elsewhere. 
> Splitting the checks up between multiple locations makes the system harder to 
> maintain.
> 
> As it happens, there's a FIXME for this here: 
> http://llvm.org/doxygen/AsmPrinterInlineAsm_8cpp_source.html#l00436 -- and a 
> test case like `void f(void *a) { asm("mov %l0, %%eax" :: "r"(a)); }` 
> currently causes LLVM to assert in a function that's supposed to be 
> validating these modifier letters and producing a clean error if they're bad. 
> So I think that's an LLVM bug, and fixing that LLVM bug would enforce the 
> property we need here (that `%lN` only names labels).
> 
> 
> [It's not clear to me whether we should be enforcing that `%lN` only names 
> label //operands//, which would require the check to be in Clang rather than 
> LLVM; GCC doesn't do that, and for instance accepts
> 
> ```
> void f() { asm goto("jmp %l0" :: "i"(&&foo)::foo); foo:; }
> ```
> 
> (at least for x86_64), though this construct doesn't seem hugely useful given 
> that the input operand would need to be a literal address-of-label expression 
> and you'd need to name the target label as a label operand anyway.]
Hi Richard,

Thanks for the detail explanation. 
I agree with you.  Our compiler FE don't emit error for this also.

I'd happy to remove this, If we all agree.  

Hi Eli, 
what do you think?

Thanks.
Jennifer  



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

https://reviews.llvm.org/D56571



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-07 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 185911.
jyu2 marked an inline comment as done.
jyu2 added a comment.

Remove check for %lN
Fix missing successor of asm goto in CFG build.


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/JumpDiagnostics.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm-goto.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp
  test/Sema/scope-check.c

Index: test/Sema/scope-check.c
===
--- test/Sema/scope-check.c
+++ test/Sema/scope-check.c
@@ -232,3 +232,19 @@
 
 // rdar://9024687
 int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
+
+//Asm goto:
+int test16(int n)
+{
+  // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm volatile goto("testl %0, %0; jne %l1;" :: "r"(n)::label_true, loop);
+  // expected-note@+2 {{jump bypasses initialization of variable length array}}
+  // expected-note@+1 {{possible target of asm goto statement}}
+  return ({int a[n];label_true: 2;});
+  // expected-note@+1 {{jump bypasses initialization of variable length array}}
+  int b[n];
+// expected-note@+1 {{possible target of asm goto statement}}
+loop:
+  return 0;
+}
Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,24 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  asm goto ("jne %l0"lab);
+}
Index: test/Sema/asm-goto.cpp
===
--- /dev/null
+++ test/Sema/asm-goto.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
+
+struct NonTrivial {
+  ~NonTrivial();
+  int f(int);
+private:
+  int k;
+};
+void JumpDiagnostics(int n) {
+// expected-error@+1 {{cannot jump from this goto statement to its label}}
+  goto DirectJump;
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp1;
+
+DirectJump:
+// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" Later);
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp2;
+// expected-note@+1 {{possible target of asm goto statement}}
+Later:
+  return;
+}
+
+struct S { ~S(); };
+void foo(int a) {
+  if (a) {
+FOO:
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+S s;
+void *p = &&BAR;
+// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" BAR);
+// expected-error@+1 {{cannot jump from this indirec

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-07 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added inline comments.



Comment at: lib/Analysis/CFG.cpp:3137
+
+  Block = createBlock(false);
+  Block->setTerminator(G);

efriedma wrote:
> efriedma wrote:
> > Passing add_successor=false seems suspect; this could probably use more 
> > test coverage.
> Did you ever look at this?
Sorry, I missed this. 

Yes. add_successor has to be true, since asm goto is kind of contional goto.   
I changed.

Thanks.





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

https://reviews.llvm.org/D56571



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-11 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 186356.
jyu2 added a comment.

I find some ambiguous error for asm-goto out of scope.
Instead call VerifyIndirectOrAsmJumps one time, call that function twice one 
for indirect-goto one for asm-goto.

Let me know if you see any problems.

Thanks for all the review.
Jennifer


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/JumpDiagnostics.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm-goto.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp
  test/Sema/scope-check.c

Index: test/Sema/scope-check.c
===
--- test/Sema/scope-check.c
+++ test/Sema/scope-check.c
@@ -232,3 +232,19 @@
 
 // rdar://9024687
 int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
+
+//Asm goto:
+int test16(int n)
+{
+  // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm volatile goto("testl %0, %0; jne %l1;" :: "r"(n)::label_true, loop);
+  // expected-note@+2 {{jump bypasses initialization of variable length array}}
+  // expected-note@+1 {{possible target of asm goto statement}}
+  return ({int a[n];label_true: 2;});
+  // expected-note@+1 {{jump bypasses initialization of variable length array}}
+  int b[n];
+// expected-note@+1 {{possible target of asm goto statement}}
+loop:
+  return 0;
+}
Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,24 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  asm goto ("jne %l0"lab);
+}
Index: test/Sema/asm-goto.cpp
===
--- /dev/null
+++ test/Sema/asm-goto.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
+
+struct NonTrivial {
+  ~NonTrivial();
+  int f(int);
+private:
+  int k;
+};
+void JumpDiagnostics(int n) {
+// expected-error@+1 {{cannot jump from this goto statement to its label}}
+  goto DirectJump;
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp1;
+
+DirectJump:
+// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" Later);
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp2;
+// expected-note@+1 {{possible target of asm goto statement}}
+Later:
+  return;
+}
+
+struct S { ~S(); };
+void foo(int a) {
+  if (a) {
+FOO:
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+S s;
+void *p = &&BAR;
+// expected-error@+1 {{cannot jump from this as

[PATCH] D58160: Fix runtime problem from //bugs.llvm.org/show_bug.cgi?id=40323

2019-02-12 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 created this revision.
jyu2 added reviewers: cfe-commits, rnk, majnemer, erichkeane.
Herald added subscribers: llvm-commits, jdoerfert.
Herald added a project: LLVM.

A MS only run time problem, because the init function for template static 
member is not getting called when the template static member is not reference.  
To be able to evoke the init function, MS put the template static member in the 
linker directive section, that cause init function gets call.   As Rick 
suggest;  add template static data member to llvm.used that cause compiler to 
emit a similar -include directive into the linker directive section.

//bugs.llvm.org/show_bug.cgi?id=40323


Repository:
  rL LLVM

https://reviews.llvm.org/D58160

Files:
  lib/CodeGen/CGDeclCXX.cpp
  test/CodeGenCXX/microsoft-abi-template-static-init.cpp


Index: test/CodeGenCXX/microsoft-abi-template-static-init.cpp
===
--- /dev/null
+++ test/CodeGenCXX/microsoft-abi-template-static-init.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -emit-llvm -o - | 
FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-win32 -fms-extensions -emit-llvm -o - 
| FileCheck %s
+// RUN: %clang_cc1 %s -triple=i686-pc-windows-msvc -fms-extensions -emit-llvm 
-o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-msvc -fms-extensions 
-emit-llvm -o - | FileCheck %s
+
+struct S {
+  S();
+  ~S();
+};
+
+template  struct __declspec(dllexport) ExportedTemplate {
+  static S s;
+};
+template  S ExportedTemplate::s;
+void useExportedTemplate(ExportedTemplate x) {
+  (void)x.s;
+}
+int f();
+namespace selectany_init {
+// MS don't put selectany static var in the linker directive, init routine
+// f() is not getting called if x is not referenced.
+int __declspec(selectany) x = f();
+}
+
+namespace explicit_template_instantiation {
+template  struct A { static  int x; };
+template  int A::x = f();
+template struct A;
+}
+
+namespace implicit_template_instantiation {
+template  struct A { static  int x; };
+template   int A::x = f();
+int g() { return A::x; }
+}
+
+
+template 
+struct X_ {
+  static T ioo;
+  static T init();
+};
+template  T X_::ioo = X_::init();
+template struct X_;
+
+template 
+struct X {
+  static T ioo;
+  static T init();
+};
+// template specialized static data don't need in llvm.used,
+// the static init routine get call from _GLOBAL__sub_I_ routines.
+template <> int X::ioo = X::init();
+template struct X;
+// CHECK: @llvm.global_ctors = appending global [6 x { i32, void ()*, i8* }] 
[{ i32, void ()*, i8* } { i32 65535, void ()* @"??__Ex@selectany_init@@YAXXZ", 
i8* bitcast (i32* @"?x@selectany_init@@3HA" to i8*) }, { i32, void ()*, i8* } { 
i32 65535, void ()* 
@"??__E?x@?$A@H@explicit_template_instantiation@@2HA@@YAXXZ", i8* bitcast (i32* 
@"?x@?$A@H@explicit_template_instantiation@@2HA" to i8*) }, { i32, void ()*, 
i8* } { i32 65535, void ()* @"??__E?ioo@?$X_@H@@2HA@@YAXXZ", i8* bitcast (i32* 
@"?ioo@?$X_@H@@2HA" to i8*) }, { i32, void ()*, i8* } { i32 65535, void ()* 
@"??__E?s@?$ExportedTemplate@H@@2US@@A@@YAXXZ", i8* getelementptr inbounds 
(%struct.S, %struct.S* @"?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0) }, { 
i32, void ()*, i8* } { i32 65535, void ()* 
@"??__E?x@?$A@H@implicit_template_instantiation@@2HA@@YAXXZ", i8* bitcast (i32* 
@"?x@?$A@H@implicit_template_instantiation@@2HA" to i8*) }, { i32, void ()*, 
i8* } { i32 65535, void ()* 
@_GLOBAL__sub_I_microsoft_abi_template_static_init.cpp, i8* null }]
+// CHECK: @llvm.used = appending global [4 x i8*] [i8* bitcast (i32* 
@"?x@?$A@H@explicit_template_instantiation@@2HA" to i8*), i8* bitcast (i32* 
@"?ioo@?$X_@H@@2HA" to i8*), i8* getelementptr inbounds (%struct.S, %struct.S* 
@"?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0), i8* bitcast (i32* 
@"?x@?$A@H@implicit_template_instantiation@@2HA" to i8*)], section 
"llvm.metadata"
+
Index: lib/CodeGen/CGDeclCXX.cpp
===
--- lib/CodeGen/CGDeclCXX.cpp
+++ lib/CodeGen/CGDeclCXX.cpp
@@ -481,6 +481,12 @@
 // minor startup time optimization.  In the MS C++ ABI, there are no guard
 // variables, so this COMDAT key is required for correctness.
 AddGlobalCtor(Fn, 65535, COMDATKey);
+if (getTarget().getCXXABI().isMicrosoft()) {
+  // In The MS C++, MS add template static data member in the linker
+  // drective.
+  assert(COMDATKey);
+  addUsedGlobal(COMDATKey);
+}
   } else if (D->hasAttr()) {
 // SelectAny globals will be comdat-folded. Put the initializer into a
 // COMDAT group associated with the global, so the initializers get folded


Index: test/CodeGenCXX/microsoft-abi-template-static-init.cpp
===
--- /dev/null
+++ test/CodeGenCXX/microsoft-abi-template-static-init.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -emit-llvm -o - | File

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-12 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 186577.
jyu2 added a comment.

Cleanup CFG code, remove obj-lifetime code when build CFE for asm-goto.


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/JumpDiagnostics.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm-goto.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp
  test/Sema/scope-check.c

Index: test/Sema/scope-check.c
===
--- test/Sema/scope-check.c
+++ test/Sema/scope-check.c
@@ -232,3 +232,19 @@
 
 // rdar://9024687
 int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
+
+//Asm goto:
+int test16(int n)
+{
+  // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm volatile goto("testl %0, %0; jne %l1;" :: "r"(n)::label_true, loop);
+  // expected-note@+2 {{jump bypasses initialization of variable length array}}
+  // expected-note@+1 {{possible target of asm goto statement}}
+  return ({int a[n];label_true: 2;});
+  // expected-note@+1 {{jump bypasses initialization of variable length array}}
+  int b[n];
+// expected-note@+1 {{possible target of asm goto statement}}
+loop:
+  return 0;
+}
Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,24 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  asm goto ("jne %l0"lab);
+}
Index: test/Sema/asm-goto.cpp
===
--- /dev/null
+++ test/Sema/asm-goto.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
+
+struct NonTrivial {
+  ~NonTrivial();
+  int f(int);
+private:
+  int k;
+};
+void JumpDiagnostics(int n) {
+// expected-error@+1 {{cannot jump from this goto statement to its label}}
+  goto DirectJump;
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp1;
+
+DirectJump:
+// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" Later);
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp2;
+// expected-note@+1 {{possible target of asm goto statement}}
+Later:
+  return;
+}
+
+struct S { ~S(); };
+void foo(int a) {
+  if (a) {
+FOO:
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+S s;
+void *p = &&BAR;
+// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" BAR);
+// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possi

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-15 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 187036.
jyu2 marked an inline comment as done.
jyu2 added a comment.

Review comment addressed


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/JumpDiagnostics.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm-goto.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp
  test/Sema/scope-check.c

Index: test/Sema/scope-check.c
===
--- test/Sema/scope-check.c
+++ test/Sema/scope-check.c
@@ -232,3 +232,19 @@
 
 // rdar://9024687
 int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
+
+//Asm goto:
+int test16(int n)
+{
+  // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm volatile goto("testl %0, %0; jne %l1;" :: "r"(n)::label_true, loop);
+  // expected-note@+2 {{jump bypasses initialization of variable length array}}
+  // expected-note@+1 {{possible target of asm goto statement}}
+  return ({int a[n];label_true: 2;});
+  // expected-note@+1 {{jump bypasses initialization of variable length array}}
+  int b[n];
+// expected-note@+1 {{possible target of asm goto statement}}
+loop:
+  return 0;
+}
Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,24 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  asm goto ("jne %l0"lab);
+}
Index: test/Sema/asm-goto.cpp
===
--- /dev/null
+++ test/Sema/asm-goto.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
+
+struct NonTrivial {
+  ~NonTrivial();
+  int f(int);
+private:
+  int k;
+};
+void JumpDiagnostics(int n) {
+// expected-error@+1 {{cannot jump from this goto statement to its label}}
+  goto DirectJump;
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp1;
+
+DirectJump:
+// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" Later);
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp2;
+// expected-note@+1 {{possible target of asm goto statement}}
+Later:
+  return;
+}
+
+struct S { ~S(); };
+void foo(int a) {
+  if (a) {
+FOO:
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+S s;
+void *p = &&BAR;
+// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" BAR);
+// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targ

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-15 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added inline comments.



Comment at: lib/Sema/JumpDiagnostics.cpp:675
+  // asm-goto.
+  //if (!IsAsmGoto && IndirectJumpTargets.empty()) {
+  if (JumpTargets.empty()) {

efriedma wrote:
> Commented-out code?
> 
> We probably don't need a diagnostic for an asm goto which doesn't have any 
> labels.  If we do, it shouldn't be here.
:-(

Yes, you are right!  We don't need a diagnostic for asm goto.  The error will 
be giving during parser.  I changed.

Thank you so much for your review.
  



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

https://reviews.llvm.org/D56571



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-15 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added inline comments.



Comment at: lib/AST/StmtProfile.cpp:324
 VisitStringLiteral(S->getClobberStringLiteral(I));
+  ID.AddInteger(S->getNumLabels());
 }

rsmith wrote:
> Don't we also need to profile the labels themselves?
How this can be lost? :-( 

Changed.



Comment at: lib/Analysis/CFG.cpp:1472
+  continue;
+addSuccessor(B, JT.block);
+  }

rsmith wrote:
> It looks like we're not modeling the destructors for local variables as 
> running on these CFG edges any more. Is that intentional?
Yes.  That it is my intention.  Since clean up code are not generated for 
asm-goto.



Comment at: lib/Sema/JumpDiagnostics.cpp:810
 return;
-  S.Diag(Jump->getGotoLoc(), diag::err_indirect_goto_in_protected_scope);
-  S.Diag(Target->getStmt()->getIdentLoc(), diag::note_indirect_goto_target);
+  bool IsAsmGoto = dyn_cast(Jump) != nullptr;
+  S.Diag(Jump->getBeginLoc(), diag::err_indirect_goto_in_protected_scope)

rsmith wrote:
> `isa(Jump)`
Yes!! changed. 



Comment at: lib/Sema/JumpDiagnostics.cpp:857
   if (!Diagnosed && !ToScopesCXX98Compat.empty()) {
-S.Diag(Jump->getGotoLoc(),
-   diag::warn_cxx98_compat_indirect_goto_in_protected_scope);
-S.Diag(Target->getStmt()->getIdentLoc(), diag::note_indirect_goto_target);
+bool IsAsmGoto = dyn_cast(Jump) != nullptr;
+S.Diag(Jump->getBeginLoc(),

rsmith wrote:
> Use `isa` here too.
changed



Comment at: lib/Sema/SemaStmtAsm.cpp:656-657
+  // Check for duplicate asm operand name between input, output and label 
lists.
+  typedef std::pair MyItemType;
+  SmallVector MyList;
+  for (unsigned i = 0, e = NumOutputs + NumInputs + NumLabels; i != e; ++i)

rsmith wrote:
> `MyItemType` and `MyList` aren't useful names for a reader of this code. 
> Please use a better name. Maybe `NamedOperand` and `NamedOperandList`?
Changed.


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

https://reviews.llvm.org/D56571



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-15 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 187124.
jyu2 marked 5 inline comments as done.
jyu2 added a comment.
Herald added a subscriber: rnkovacs.

Review comments addressed.


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/JumpDiagnostics.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm-goto.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp
  test/Sema/scope-check.c

Index: test/Sema/scope-check.c
===
--- test/Sema/scope-check.c
+++ test/Sema/scope-check.c
@@ -232,3 +232,19 @@
 
 // rdar://9024687
 int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
+
+//Asm goto:
+int test16(int n)
+{
+  // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm volatile goto("testl %0, %0; jne %l1;" :: "r"(n)::label_true, loop);
+  // expected-note@+2 {{jump bypasses initialization of variable length array}}
+  // expected-note@+1 {{possible target of asm goto statement}}
+  return ({int a[n];label_true: 2;});
+  // expected-note@+1 {{jump bypasses initialization of variable length array}}
+  int b[n];
+// expected-note@+1 {{possible target of asm goto statement}}
+loop:
+  return 0;
+}
Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,24 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  asm goto ("jne %l0"lab);
+}
Index: test/Sema/asm-goto.cpp
===
--- /dev/null
+++ test/Sema/asm-goto.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
+
+struct NonTrivial {
+  ~NonTrivial();
+  int f(int);
+private:
+  int k;
+};
+void JumpDiagnostics(int n) {
+// expected-error@+1 {{cannot jump from this goto statement to its label}}
+  goto DirectJump;
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp1;
+
+DirectJump:
+// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" Later);
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp2;
+// expected-note@+1 {{possible target of asm goto statement}}
+Later:
+  return;
+}
+
+struct S { ~S(); };
+void foo(int a) {
+  if (a) {
+FOO:
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+S s;
+void *p = &&BAR;
+// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" BAR);
+// expected-error@+1 {{cannot jump from this indirect got

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-02-22 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 188021.
jyu2 added a comment.

Rebase


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

https://reviews.llvm.org/D56571

Files:
  include/clang/AST/Stmt.h
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Analysis/CFG.cpp
  lib/CodeGen/CGStmt.cpp
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/JumpDiagnostics.cpp
  lib/Sema/SemaStmtAsm.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Analysis/asm-goto.cpp
  test/CodeGen/asm-goto.c
  test/CodeGen/asm.c
  test/CodeGen/inline-asm-mixed-style.c
  test/Coverage/c-language-features.inc
  test/PCH/asm.h
  test/Parser/asm.c
  test/Parser/asm.cpp
  test/Sema/asm-goto.cpp
  test/Sema/asm.c
  test/Sema/inline-asm-validate-tmpl.cpp
  test/Sema/scope-check.c

Index: test/Sema/scope-check.c
===
--- test/Sema/scope-check.c
+++ test/Sema/scope-check.c
@@ -232,3 +232,19 @@
 
 // rdar://9024687
 int test16(int [sizeof &&z]); // expected-error {{use of address-of-label extension outside of a function body}}
+
+//Asm goto:
+int test16(int n)
+{
+  // expected-error@+2 {{cannot jump from this asm goto statement to one of its possible targets}}
+  // expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm volatile goto("testl %0, %0; jne %l1;" :: "r"(n)::label_true, loop);
+  // expected-note@+2 {{jump bypasses initialization of variable length array}}
+  // expected-note@+1 {{possible target of asm goto statement}}
+  return ({int a[n];label_true: 2;});
+  // expected-note@+1 {{jump bypasses initialization of variable length array}}
+  int b[n];
+// expected-note@+1 {{possible target of asm goto statement}}
+loop:
+  return 0;
+}
Index: test/Sema/inline-asm-validate-tmpl.cpp
===
--- test/Sema/inline-asm-validate-tmpl.cpp
+++ test/Sema/inline-asm-validate-tmpl.cpp
@@ -23,3 +23,13 @@
 	asm("rol %1, %0" :"=r"(value): "I"(N + 1));
 }
 int	foo() { testc<2>(10); }
+
+// these should compile without error
+template  bool testd()
+{
+  __asm goto ("" : : : : lab);
+  return true;
+lab:
+  return false;
+}
+bool foox() { return testd<0> (); }
Index: test/Sema/asm.c
===
--- test/Sema/asm.c
+++ test/Sema/asm.c
@@ -295,3 +295,24 @@
   return r0 + r1;
 }
 
+void test18()
+{
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("" : : : : lab, lab, lab2, lab);
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm goto ("xorw %[lab], %[lab]; je %l[lab]" : : [lab] "i" (0) : : lab);
+lab:;
+lab2:;
+  int x,x1;
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x),[lab] "+r" (x) : [lab1] "r" (x));
+  // expected-error@+2 {{duplicate use of asm operand name "lab"}}
+  // expected-note@+1 {{asm operand name "lab" first referenced here}}
+  asm ("" : [lab] "=r" (x1) : [lab] "r" (x));
+  // expected-error@+1 {{invalid operand number in inline asm string}}
+  asm ("jne %l0":::);
+  asm goto ("jne %l0"lab);
+}
Index: test/Sema/asm-goto.cpp
===
--- /dev/null
+++ test/Sema/asm-goto.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
+
+struct NonTrivial {
+  ~NonTrivial();
+  int f(int);
+private:
+  int k;
+};
+void JumpDiagnostics(int n) {
+// expected-error@+1 {{cannot jump from this goto statement to its label}}
+  goto DirectJump;
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp1;
+
+DirectJump:
+// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" Later);
+// expected-note@+1 {{jump bypasses variable with a non-trivial destructor}}
+  NonTrivial tnp2;
+// expected-note@+1 {{possible target of asm goto statement}}
+Later:
+  return;
+}
+
+struct S { ~S(); };
+void foo(int a) {
+  if (a) {
+FOO:
+// expected-note@+2 {{jump exits scope of variable with non-trivial destructor}}
+// expected-note@+1 {{jump exits scope of variable with non-trivial destructor}}
+S s;
+void *p = &&BAR;
+// expected-error@+1 {{cannot jump from this asm goto statement to one of its possible targets}}
+  asm goto("jmp %l0;" BAR);
+// expected-error@+1 {{cannot jump from this indirect goto statement to one of its possible targets}}
+goto *p;
+p = &&FOO;
+goto *p;
+re

[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-06-01 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

jyu2 committed rG954ec09aed4f 
: clang 
support gnu asm goto

In D56571#1523895 , @nickdesaulniers 
wrote:

> Was this committed accidentally?
>
> Today in master I see:
>
> - r362106: Revert "clang support gnu asm goto." Erich Keane 
> 
> - r362059: Mark CodeGen/asm-goto.c as x86 specific after r362045 Fangrui Song 
> 
> - r362045: clang support gnu asm goto. Jennifer Yu 
>
>   and yet this Phabricator review is still open.
>
>   It may be easier to rebase this into a monorepo checkout, then commit with 
> `git llvm push`. 
> https://llvm.org/docs/GettingStarted.html#for-developers-to-commit-changes-from-git
>
>   As @kees  noted, for new test files that contain x86 assembly, they need a 
> `-triple` that specifies an x86 target, otherwise the implicit target is 
> based on the host, which may not be x86.  We still want to verify that 
> non-x86 host can cross compile to x86 correctly.  Sorry we did not catch this 
> earlier in code review.


Thanks Kees and Nick!  I am currently work on those tests to see if I can make 
them more generic.  All my test using x86 instruction.  So that is not working 
for arm or arm64 target.  Will update you once I am done for this.


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

https://reviews.llvm.org/D56571



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


[PATCH] D56571: [RFC prototype] Implementation of asm-goto support in clang

2019-06-04 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 closed this revision.
jyu2 added a comment.

jyu2 committed rGb8fee677bf8e 
: Re-check 
in clang support gun asm goto after fixing tests. (authored by jyu2).


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

https://reviews.llvm.org/D56571



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


[PATCH] D79743: [clang][asm goto][slh] Warn if asm goto + SLH

2020-05-19 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 accepted this revision.
jyu2 added a comment.
This revision is now accepted and ready to land.

LGTM.  Please changed format for td file.




Comment at: clang/include/clang/Basic/DiagnosticCommonKinds.td:247
+
+  def warn_slh_does_not_support_asm_goto : Warning<
+"Speculative load hardening does not protect functions with asm goto">, 
InGroup>;

Just need run clang-format:
def warn_slh_does_not_support_asm_goto
  : Warning<"Speculative load hardening does not protect functions with "
"asm goto">,
InGroup>;



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D79743



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


[PATCH] D82832: Correctly generate invert xor value for Binary Atomics of int size > 64

2020-07-07 Thread Jennifer Yu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6cf0dac1ca3f: orrectly generate invert xor value for Binary 
Atomics of int size > 64 (authored by jyu2).
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D82832

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/Atomics.c


Index: clang/test/CodeGen/Atomics.c
===
--- clang/test/CodeGen/Atomics.c
+++ clang/test/CodeGen/Atomics.c
@@ -10,6 +10,8 @@
 unsigned int ui;
 signed long long sll;
 unsigned long long ull;
+__int128 s128;
+unsigned  __int128 u128;
 
 void test_op_ignore (void) // CHECK-LABEL: define void @test_op_ignore
 {
@@ -48,6 +50,8 @@
   (void) __sync_fetch_and_xor (&ui, 1); // CHECK: atomicrmw xor i32
   (void) __sync_fetch_and_xor (&sll, 1); // CHECK: atomicrmw xor i64
   (void) __sync_fetch_and_xor (&ull, 1); // CHECK: atomicrmw xor i64
+  (void) __sync_fetch_and_xor (&u128, 1); // CHECK: atomicrmw xor i128
+  (void) __sync_fetch_and_xor (&s128, 1); // CHECK: atomicrmw xor i128
 
   (void) __sync_fetch_and_nand (&sc, 1); // CHECK: atomicrmw nand i8
   (void) __sync_fetch_and_nand (&uc, 1); // CHECK: atomicrmw nand i8
@@ -168,27 +172,43 @@
   sc = __sync_nand_and_fetch (&sc, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   uc = __sync_nand_and_fetch (&uc, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   ss = __sync_nand_and_fetch (&ss, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   us = __sync_nand_and_fetch (&us, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   si = __sync_nand_and_fetch (&si, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   ui = __sync_nand_and_fetch (&ui, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   sll = __sync_nand_and_fetch (&sll, uc); // CHECK: atomicrmw nand
   // CHECK: and
   // CHECK: xor
+  // CHECK: -1
   ull = __sync_nand_and_fetch (&ull, uc); // CHECK: atomicrmw nand
   // CHECK: and
   // CHECK: xor
+  // CHECK: -1
+  u128 = __sync_nand_and_fetch (&u128, uc); // CHECK: atomicrmw nand
+  // CHECK: and
+  // CHECK: xor
+  // CHECK: -1
+  s128 = __sync_nand_and_fetch (&s128, uc); // CHECK: atomicrmw nand
+  // CHECK: and
+  // CHECK: xor
+  // CHECK: -1
 
   sc = __sync_and_and_fetch (&sc, uc); // CHECK: atomicrmw and
   uc = __sync_and_and_fetch (&uc, uc); // CHECK: atomicrmw and
Index: clang/lib/CodeGen/CGBuiltin.cpp
===
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -219,8 +219,9 @@
   Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent);
   Result = CGF.Builder.CreateBinOp(Op, Result, Args[1]);
   if (Invert)
-Result = CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result,
- llvm::ConstantInt::get(IntType, -1));
+Result =
+CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result,
+llvm::ConstantInt::getAllOnesValue(IntType));
   Result = EmitFromInt(CGF, Result, T, ValueType);
   return RValue::get(Result);
 }


Index: clang/test/CodeGen/Atomics.c
===
--- clang/test/CodeGen/Atomics.c
+++ clang/test/CodeGen/Atomics.c
@@ -10,6 +10,8 @@
 unsigned int ui;
 signed long long sll;
 unsigned long long ull;
+__int128 s128;
+unsigned  __int128 u128;
 
 void test_op_ignore (void) // CHECK-LABEL: define void @test_op_ignore
 {
@@ -48,6 +50,8 @@
   (void) __sync_fetch_and_xor (&ui, 1); // CHECK

[PATCH] D82832: Correctly generate invert xor value for Binary Atomics of int size > 64

2020-07-07 Thread Jennifer Yu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6cf0dac1ca3f: orrectly generate invert xor value for Binary 
Atomics of int size > 64 (authored by jyu2).
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D82832

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/Atomics.c


Index: clang/test/CodeGen/Atomics.c
===
--- clang/test/CodeGen/Atomics.c
+++ clang/test/CodeGen/Atomics.c
@@ -10,6 +10,8 @@
 unsigned int ui;
 signed long long sll;
 unsigned long long ull;
+__int128 s128;
+unsigned  __int128 u128;
 
 void test_op_ignore (void) // CHECK-LABEL: define void @test_op_ignore
 {
@@ -48,6 +50,8 @@
   (void) __sync_fetch_and_xor (&ui, 1); // CHECK: atomicrmw xor i32
   (void) __sync_fetch_and_xor (&sll, 1); // CHECK: atomicrmw xor i64
   (void) __sync_fetch_and_xor (&ull, 1); // CHECK: atomicrmw xor i64
+  (void) __sync_fetch_and_xor (&u128, 1); // CHECK: atomicrmw xor i128
+  (void) __sync_fetch_and_xor (&s128, 1); // CHECK: atomicrmw xor i128
 
   (void) __sync_fetch_and_nand (&sc, 1); // CHECK: atomicrmw nand i8
   (void) __sync_fetch_and_nand (&uc, 1); // CHECK: atomicrmw nand i8
@@ -168,27 +172,43 @@
   sc = __sync_nand_and_fetch (&sc, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   uc = __sync_nand_and_fetch (&uc, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   ss = __sync_nand_and_fetch (&ss, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   us = __sync_nand_and_fetch (&us, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   si = __sync_nand_and_fetch (&si, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   ui = __sync_nand_and_fetch (&ui, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   sll = __sync_nand_and_fetch (&sll, uc); // CHECK: atomicrmw nand
   // CHECK: and
   // CHECK: xor
+  // CHECK: -1
   ull = __sync_nand_and_fetch (&ull, uc); // CHECK: atomicrmw nand
   // CHECK: and
   // CHECK: xor
+  // CHECK: -1
+  u128 = __sync_nand_and_fetch (&u128, uc); // CHECK: atomicrmw nand
+  // CHECK: and
+  // CHECK: xor
+  // CHECK: -1
+  s128 = __sync_nand_and_fetch (&s128, uc); // CHECK: atomicrmw nand
+  // CHECK: and
+  // CHECK: xor
+  // CHECK: -1
 
   sc = __sync_and_and_fetch (&sc, uc); // CHECK: atomicrmw and
   uc = __sync_and_and_fetch (&uc, uc); // CHECK: atomicrmw and
Index: clang/lib/CodeGen/CGBuiltin.cpp
===
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -219,8 +219,9 @@
   Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent);
   Result = CGF.Builder.CreateBinOp(Op, Result, Args[1]);
   if (Invert)
-Result = CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result,
- llvm::ConstantInt::get(IntType, -1));
+Result =
+CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result,
+llvm::ConstantInt::getAllOnesValue(IntType));
   Result = EmitFromInt(CGF, Result, T, ValueType);
   return RValue::get(Result);
 }


Index: clang/test/CodeGen/Atomics.c
===
--- clang/test/CodeGen/Atomics.c
+++ clang/test/CodeGen/Atomics.c
@@ -10,6 +10,8 @@
 unsigned int ui;
 signed long long sll;
 unsigned long long ull;
+__int128 s128;
+unsigned  __int128 u128;
 
 void test_op_ignore (void) // CHECK-LABEL: define void @test_op_ignore
 {
@@ -48,6 +50,8 @@
   (void) __sync_fetch_and_xor (&ui, 1); // CHECK

[PATCH] D82832: Correctly generate invert xor value for Binary Atomics of int size > 64

2020-06-29 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 created this revision.
jyu2 added reviewers: hfinkel, erichkeane, rjmccall, cfe-commits.
Herald added a subscriber: jfb.

When using __sync_nand_and_fetch with __int128, a problem is found that
the wrong value for the 'invert' value gets emitted to the xor in case
where the int size is greater than 64 bits.

This is because uses of llvm::ConstantInt::get which zero extends the
greater than 64 bits, so instead -1 that we require, it end up
getting 18446744073709551615

This patch replaces the call to llvm::ConstantInt::get with the call
to llvm::Constant::getAllOnesValue which works for all integer types.


Repository:
  rC Clang

https://reviews.llvm.org/D82832

Files:
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/test/CodeGen/Atomics.c


Index: clang/test/CodeGen/Atomics.c
===
--- clang/test/CodeGen/Atomics.c
+++ clang/test/CodeGen/Atomics.c
@@ -10,6 +10,8 @@
 unsigned int ui;
 signed long long sll;
 unsigned long long ull;
+__int128 s128;
+unsigned  __int128 u128;
 
 void test_op_ignore (void) // CHECK-LABEL: define void @test_op_ignore
 {
@@ -48,6 +50,8 @@
   (void) __sync_fetch_and_xor (&ui, 1); // CHECK: atomicrmw xor i32
   (void) __sync_fetch_and_xor (&sll, 1); // CHECK: atomicrmw xor i64
   (void) __sync_fetch_and_xor (&ull, 1); // CHECK: atomicrmw xor i64
+  (void) __sync_fetch_and_xor (&u128, 1); // CHECK: atomicrmw xor i128
+  (void) __sync_fetch_and_xor (&s128, 1); // CHECK: atomicrmw xor i128
 
   (void) __sync_fetch_and_nand (&sc, 1); // CHECK: atomicrmw nand i8
   (void) __sync_fetch_and_nand (&uc, 1); // CHECK: atomicrmw nand i8
@@ -168,27 +172,43 @@
   sc = __sync_nand_and_fetch (&sc, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   uc = __sync_nand_and_fetch (&uc, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   ss = __sync_nand_and_fetch (&ss, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   us = __sync_nand_and_fetch (&us, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   si = __sync_nand_and_fetch (&si, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   ui = __sync_nand_and_fetch (&ui, uc); // CHECK: atomicrmw nand
 // CHECK: and
 // CHECK: xor
+// CHECK: -1
   sll = __sync_nand_and_fetch (&sll, uc); // CHECK: atomicrmw nand
   // CHECK: and
   // CHECK: xor
+  // CHECK: -1
   ull = __sync_nand_and_fetch (&ull, uc); // CHECK: atomicrmw nand
   // CHECK: and
   // CHECK: xor
+  // CHECK: -1
+  u128 = __sync_nand_and_fetch (&u128, uc); // CHECK: atomicrmw nand
+  // CHECK: and
+  // CHECK: xor
+  // CHECK: -1
+  s128 = __sync_nand_and_fetch (&s128, uc); // CHECK: atomicrmw nand
+  // CHECK: and
+  // CHECK: xor
+  // CHECK: -1
 
   sc = __sync_and_and_fetch (&sc, uc); // CHECK: atomicrmw and
   uc = __sync_and_and_fetch (&uc, uc); // CHECK: atomicrmw and
Index: clang/lib/CodeGen/CGBuiltin.cpp
===
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -219,8 +219,9 @@
   Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent);
   Result = CGF.Builder.CreateBinOp(Op, Result, Args[1]);
   if (Invert)
-Result = CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result,
- llvm::ConstantInt::get(IntType, -1));
+Result =
+CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result,
+llvm::ConstantInt::getAllOnesValue(IntType));
   Result = EmitFromInt(CGF, Result, T, ValueType);
   return RValue::get(Result);
 }


Index: clang/test/CodeGen/Atomics.c
===
--- clang/test/CodeGen/Atomic

[PATCH] D79743: [clang][asm goto][slh] Warn if asm goto + SLH

2020-05-13 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

Two questions:
1>  What happen under SLH, will asm goto gets removed, or a runtime problem?
2>  Should we emit error or warning in the Parser instead?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D79743



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


[PATCH] D79743: [clang][asm goto][slh] Warn if asm goto + SLH

2020-05-13 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

In D79743#2034945 , @zbrid wrote:

> In D79743#2034792 , @jyu2 wrote:
>
> > Two questions:
> >  1> What happen under SLH, will asm goto gets removed, or a runtime problem?
> >  2> Should we emit error or warning in the Parser instead?
>
>
>
>
> 1. SLH crashes with an unhelpful error message.
> 2. I'd be happy to emit the warning in the Parser. Could you give me a 
> pointer to where in the parser would be appropriate? I'm not super familiar 
> with the clang codebase. Also why do you think the parser would be a better 
> place? (Asking to learn since I'm new to this area)


Understand, no problem!
Do you mean runtime crash? If so, I think error should be emit, so that 
programmer can remove use of "asm goto" and recompile.

It to me,  you can emit error somewhere in ParseAsmStatement when “goto” is 
parsed.  Let me know if you have problem.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D79743



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


[PATCH] D79743: [clang][asm goto][slh] Warn if asm goto + SLH

2020-05-14 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

I don’t know what consequences is of using asm goto under SLH.

In general, if asm-goto is not allowed, the diagnostic should be emitted during 
the parser.  If asm-goto is not allowed under specified condition, the 
diagnostic should be emitted during sema.  Diagnostic should not be emitted in 
the lower(codegen) in general (exception may be for target related).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D79743



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


[PATCH] D79743: [clang][asm goto][slh] Warn if asm goto + SLH

2020-05-19 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

This looks good to me.  Could you also add a test to use this new DiagGroup 
(-Wno-slh-asm-goto)?

Thanks.

Jennifer


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D79743



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


[PATCH] D127803: Generate the capture for field when the field is used in openmp region with implicit default in the member function.

2022-06-29 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 441039.
jyu2 added a comment.

Thanks Alexey for the review.
Add change in TreeTransform.h to rebuilt member expression.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127803

Files:
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/OpenMP/default_firstprivate_ast_print.cpp
  clang/test/OpenMP/default_private_ast_print.cpp

Index: clang/test/OpenMP/default_private_ast_print.cpp
===
--- clang/test/OpenMP/default_private_ast_print.cpp
+++ clang/test/OpenMP/default_private_ast_print.cpp
@@ -96,4 +96,57 @@
   // DUMP-NEXT:  -DeclRefExpr {{.*}} 'a'
   // DUMP-NEXT:  -DeclRefExpr {{.*}} 'yy'
 }
+
+void zoo(int);
+struct A {
+  int z;
+  int f;
+  A();
+  ~A();
+  void foo() {
+#pragma omp parallel private(z) default(private)
+{
+  z++;
+  f++;
+  zoo(z + f);
+  f++;
+}
+  }
+  // PRINT:#pragma omp parallel private(this->z) default(private)
+  // DUMP: -OMPParallelDirective
+  // DUMP-NEXT:  -OMPPrivateClause
+  // DUMP-NEXT:-DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:  -OMPDefaultClause
+  // DUMP-NEXT:  -OMPPrivateClause
+  // DUMP-NEXT:-DeclRefExpr {{.*}} 'f'
+  // DUMP: -CXXThisExpr {{.*}} 'A *' implicit this
+  void bar() {
+#pragma omp parallel private(z) default(private)
+{
+#pragma omp parallel private(z) default(private)
+  {
+z++;
+f++;
+zoo(z + f);
+f++;
+  }
+}
+  }
+  // PRINT:#pragma omp parallel private(this->z) default(private)
+  // PRINT:  #pragma omp parallel private(this->z) default(private)
+  // DUMP: -OMPParallelDirective
+  // DUMP-NEXT:  -OMPPrivateClause
+  // DUMP-NEXT:-DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:  -OMPDefaultClause
+  // DUMP:   -OMPParallelDirective
+  // DUMP-NEXT:-OMPPrivateClause
+  // DUMP-NEXT:   -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:-OMPDefaultClause
+  // DUMP-NEXT:-OMPPrivateClause {{.*}} 
+  // DUMP-NEXT:   -DeclRefExpr {{.*}} 'f'
+  // DUMP: -CXXThisExpr
+  // DUMP: -MemberExpr
+  // DUMP-NEXT:   -CXXThisExpr
+  // DUMP: -CXXThisExpr
+};
 #endif // HEADER
Index: clang/test/OpenMP/default_firstprivate_ast_print.cpp
===
--- clang/test/OpenMP/default_firstprivate_ast_print.cpp
+++ clang/test/OpenMP/default_firstprivate_ast_print.cpp
@@ -45,7 +45,8 @@
 // PRINT-NEXT:  this->targetDev++;
 // CHECK-NEXT: }
 // DUMP: -OMPParallelDirective
-// DUMP->NEXT: -OMPDefaultClause
+// DUMP-NEXT: -OMPDefaultClause
+// DUMP-NOT:   -OMPFirstprivateClause
   }
   // PRINT: template<> void apply<32U>()
   // PRINT: #pragma omp parallel default(firstprivate)
@@ -54,6 +55,8 @@
   // CHECK-NEXT: }
   // DUMP: -OMPParallelDirective
   // DUMP-NEXT: -OMPDefaultClause
+  // DUMP-NEXT: -OMPFirstprivateClause
+  // DUMP-NEXT:   -DeclRefExpr {{.*}} 'targetDev'
 };
 
 void use_template() {
@@ -99,4 +102,60 @@
   // DUMP-NEXT: -DeclRefExpr {{.*}} 'yy'
   // DUMP-NEXT: -DeclRefExpr {{.*}} 'y'
 }
+void zoo(int);
+struct A {
+  int z;
+  int f;
+  A();
+  ~A();
+  void foo() {
+#pragma omp parallel firstprivate(z) default(firstprivate)
+{
+  z++;
+  f++;
+  zoo(z + f);
+  f++;
+}
+  }
+  // PRINT:  #pragma omp parallel firstprivate(this->z) default(firstprivate)
+  // DUMP:   -OMPParallelDirective
+  // DUMP-NEXT: -OMPFirstprivateClause
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT: -OMPDefaultClause
+  // DUMP-NEXT: -OMPFirstprivateClause {{.*}} 
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+  // DUMP:  -CXXThisExpr {{.*}} 'A *' implicit this
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+  void bar() {
+#pragma omp parallel firstprivate(z) default(firstprivate)
+{
+#pragma omp parallel private(z) default(firstprivate)
+  {
+z++;
+f++;
+zoo(z + f);
+f++;
+  }
+}
+  }
+  // PRINT:  #pragma omp parallel firstprivate(this->z) default(firstprivate)
+  // PRINT:#pragma omp parallel private(this->z) default(firstprivate)
+  // DUMP: -OMPParallelDirective
+  // DUMP-NEXT: -OMPFirstprivateClause
+  // DUMP-NEXT:  -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:  -OMPDefaultClause
+  // DUMP:-OMPParallelDirective
+  // DUMP-NEXT:-OMPPrivateClaus
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT: -OMPDefaultClause
+  // DUMP-NEXT: -OMPFirstprivateClause {{.*}} 
+  // DUMP-NEXT:  -DeclRefExpr {{.*}} 'f'
+  // DUMP:   -CXXThisExpr {{.*}} 'A *' implicit this
+  // DUMP-NEXT:  -DeclRefExpr {{.*}} 'f'
+  // DUMP: -MemberExpr {{.*}}
+  // DUMP-NEXT:  -CXXThisExpr
+  // DUMP:   -CXXThisExpr {{.*}} 'A *' implicit this
+  // DUMP-NEXT:  -DeclRefExpr 

[PATCH] D127803: Generate the capture for field when the field is used in openmp region with implicit default in the member function.

2022-06-29 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 441257.
jyu2 added a comment.

Thanks Alexey for the review.  
This is to address Alexey's comments,


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

https://reviews.llvm.org/D127803

Files:
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/OpenMP/default_firstprivate_ast_print.cpp
  clang/test/OpenMP/default_private_ast_print.cpp

Index: clang/test/OpenMP/default_private_ast_print.cpp
===
--- clang/test/OpenMP/default_private_ast_print.cpp
+++ clang/test/OpenMP/default_private_ast_print.cpp
@@ -96,4 +96,57 @@
   // DUMP-NEXT:  -DeclRefExpr {{.*}} 'a'
   // DUMP-NEXT:  -DeclRefExpr {{.*}} 'yy'
 }
+
+void zoo(int);
+struct A {
+  int z;
+  int f;
+  A();
+  ~A();
+  void foo() {
+#pragma omp parallel private(z) default(private)
+{
+  z++;
+  f++;
+  zoo(z + f);
+  f++;
+}
+  }
+  // PRINT:#pragma omp parallel private(this->z) default(private)
+  // DUMP: -OMPParallelDirective
+  // DUMP-NEXT:  -OMPPrivateClause
+  // DUMP-NEXT:-DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:  -OMPDefaultClause
+  // DUMP-NEXT:  -OMPPrivateClause
+  // DUMP-NEXT:-DeclRefExpr {{.*}} 'f'
+  // DUMP: -CXXThisExpr {{.*}} 'A *' implicit this
+  void bar() {
+#pragma omp parallel private(z) default(private)
+{
+#pragma omp parallel private(z) default(private)
+  {
+z++;
+f++;
+zoo(z + f);
+f++;
+  }
+}
+  }
+  // PRINT:#pragma omp parallel private(this->z) default(private)
+  // PRINT:  #pragma omp parallel private(this->z) default(private)
+  // DUMP: -OMPParallelDirective
+  // DUMP-NEXT:  -OMPPrivateClause
+  // DUMP-NEXT:-DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:  -OMPDefaultClause
+  // DUMP:   -OMPParallelDirective
+  // DUMP-NEXT:-OMPPrivateClause
+  // DUMP-NEXT:   -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:-OMPDefaultClause
+  // DUMP-NEXT:-OMPPrivateClause {{.*}} 
+  // DUMP-NEXT:   -DeclRefExpr {{.*}} 'f'
+  // DUMP: -CXXThisExpr
+  // DUMP: -MemberExpr
+  // DUMP-NEXT:   -CXXThisExpr
+  // DUMP: -CXXThisExpr
+};
 #endif // HEADER
Index: clang/test/OpenMP/default_firstprivate_ast_print.cpp
===
--- clang/test/OpenMP/default_firstprivate_ast_print.cpp
+++ clang/test/OpenMP/default_firstprivate_ast_print.cpp
@@ -45,7 +45,8 @@
 // PRINT-NEXT:  this->targetDev++;
 // CHECK-NEXT: }
 // DUMP: -OMPParallelDirective
-// DUMP->NEXT: -OMPDefaultClause
+// DUMP-NEXT: -OMPDefaultClause
+// DUMP-NOT:   -OMPFirstprivateClause
   }
   // PRINT: template<> void apply<32U>()
   // PRINT: #pragma omp parallel default(firstprivate)
@@ -54,6 +55,8 @@
   // CHECK-NEXT: }
   // DUMP: -OMPParallelDirective
   // DUMP-NEXT: -OMPDefaultClause
+  // DUMP-NEXT: -OMPFirstprivateClause
+  // DUMP-NEXT:   -DeclRefExpr {{.*}} 'targetDev'
 };
 
 void use_template() {
@@ -99,4 +102,60 @@
   // DUMP-NEXT: -DeclRefExpr {{.*}} 'yy'
   // DUMP-NEXT: -DeclRefExpr {{.*}} 'y'
 }
+void zoo(int);
+struct A {
+  int z;
+  int f;
+  A();
+  ~A();
+  void foo() {
+#pragma omp parallel firstprivate(z) default(firstprivate)
+{
+  z++;
+  f++;
+  zoo(z + f);
+  f++;
+}
+  }
+  // PRINT:  #pragma omp parallel firstprivate(this->z) default(firstprivate)
+  // DUMP:   -OMPParallelDirective
+  // DUMP-NEXT: -OMPFirstprivateClause
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT: -OMPDefaultClause
+  // DUMP-NEXT: -OMPFirstprivateClause {{.*}} 
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+  // DUMP:  -CXXThisExpr {{.*}} 'A *' implicit this
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+  void bar() {
+#pragma omp parallel firstprivate(z) default(firstprivate)
+{
+#pragma omp parallel private(z) default(firstprivate)
+  {
+z++;
+f++;
+zoo(z + f);
+f++;
+  }
+}
+  }
+  // PRINT:  #pragma omp parallel firstprivate(this->z) default(firstprivate)
+  // PRINT:#pragma omp parallel private(this->z) default(firstprivate)
+  // DUMP: -OMPParallelDirective
+  // DUMP-NEXT: -OMPFirstprivateClause
+  // DUMP-NEXT:  -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:  -OMPDefaultClause
+  // DUMP:-OMPParallelDirective
+  // DUMP-NEXT:-OMPPrivateClaus
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT: -OMPDefaultClause
+  // DUMP-NEXT: -OMPFirstprivateClause {{.*}} 
+  // DUMP-NEXT:  -DeclRefExpr {{.*}} 'f'
+  // DUMP:   -CXXThisExpr {{.*}} 'A *' implicit this
+  // DUMP-NEXT:  -DeclRefExpr {{.*}} 'f'
+  // DUMP: -MemberExpr {{.*}}
+  // DUMP-NEXT:  -CXXThisExpr
+  // DUMP:   -CXXThisExpr {{.*}} 'A *' implicit this
+  // DUMP-NEXT:  -DeclRefExpr {{.*}} 'z'
+};
 #endif // HEADER
Index: clang/lib/Sema/Tree

[PATCH] D127803: Generate the capture for field when the field is used in openmp region with implicit default in the member function.

2022-06-30 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added inline comments.



Comment at: clang/lib/Sema/SemaOpenMP.cpp:17480
 DeclRefExpr *Ref = nullptr;
-if (!VD && !CurContext->isDependentContext())
-  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
-DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
+if (!VD && !CurContext->isDependentContext()) {
+  auto *FD = dyn_cast(D);

jyu2 wrote:
> ABataev wrote:
> > A check here not for curcontext dependent but for FD being dependent?
> I can not this to work.  Since the private copy only build under only build 
> non-dependent context. 
> 
> 
fix typo:
I can not get this to work, since the private copy only build under 
non-dependent context.



Comment at: clang/lib/Sema/TreeTransform.h:122
+  /// the RebuildME uses to set if member expression needs to be rebuilt.
+  bool RebuildME = false;
+

ABataev wrote:
> I think we don't need to add a new field here. Can instead we have a check 
> for regions with default clauses, if possible?
It seems during the TransformMemberExpr, I can not get Directives info for omp 
regions to check.  Could you give me hand? 
Thanks.  



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

https://reviews.llvm.org/D127803

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


[PATCH] D127803: Generate the capture for field when the field is used in openmp region with implicit default in the member function.

2022-06-30 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 441565.
jyu2 added a comment.

Thanks Alexey for the review.  This patch to address his comment.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127803

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/OpenMP/default_firstprivate_ast_print.cpp
  clang/test/OpenMP/default_private_ast_print.cpp

Index: clang/test/OpenMP/default_private_ast_print.cpp
===
--- clang/test/OpenMP/default_private_ast_print.cpp
+++ clang/test/OpenMP/default_private_ast_print.cpp
@@ -96,4 +96,57 @@
   // DUMP-NEXT:  -DeclRefExpr {{.*}} 'a'
   // DUMP-NEXT:  -DeclRefExpr {{.*}} 'yy'
 }
+
+void zoo(int);
+struct A {
+  int z;
+  int f;
+  A();
+  ~A();
+  void foo() {
+#pragma omp parallel private(z) default(private)
+{
+  z++;
+  f++;
+  zoo(z + f);
+  f++;
+}
+  }
+  // PRINT:#pragma omp parallel private(this->z) default(private)
+  // DUMP: -OMPParallelDirective
+  // DUMP-NEXT:  -OMPPrivateClause
+  // DUMP-NEXT:-DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:  -OMPDefaultClause
+  // DUMP-NEXT:  -OMPPrivateClause
+  // DUMP-NEXT:-DeclRefExpr {{.*}} 'f'
+  // DUMP: -CXXThisExpr {{.*}} 'A *' implicit this
+  void bar() {
+#pragma omp parallel private(z) default(private)
+{
+#pragma omp parallel private(z) default(private)
+  {
+z++;
+f++;
+zoo(z + f);
+f++;
+  }
+}
+  }
+  // PRINT:#pragma omp parallel private(this->z) default(private)
+  // PRINT:  #pragma omp parallel private(this->z) default(private)
+  // DUMP: -OMPParallelDirective
+  // DUMP-NEXT:  -OMPPrivateClause
+  // DUMP-NEXT:-DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:  -OMPDefaultClause
+  // DUMP:   -OMPParallelDirective
+  // DUMP-NEXT:-OMPPrivateClause
+  // DUMP-NEXT:   -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:-OMPDefaultClause
+  // DUMP-NEXT:-OMPPrivateClause {{.*}} 
+  // DUMP-NEXT:   -DeclRefExpr {{.*}} 'f'
+  // DUMP: -CXXThisExpr
+  // DUMP: -MemberExpr
+  // DUMP-NEXT:   -CXXThisExpr
+  // DUMP: -CXXThisExpr
+};
 #endif // HEADER
Index: clang/test/OpenMP/default_firstprivate_ast_print.cpp
===
--- clang/test/OpenMP/default_firstprivate_ast_print.cpp
+++ clang/test/OpenMP/default_firstprivate_ast_print.cpp
@@ -45,7 +45,8 @@
 // PRINT-NEXT:  this->targetDev++;
 // CHECK-NEXT: }
 // DUMP: -OMPParallelDirective
-// DUMP->NEXT: -OMPDefaultClause
+// DUMP-NEXT: -OMPDefaultClause
+// DUMP-NOT:   -OMPFirstprivateClause
   }
   // PRINT: template<> void apply<32U>()
   // PRINT: #pragma omp parallel default(firstprivate)
@@ -54,6 +55,8 @@
   // CHECK-NEXT: }
   // DUMP: -OMPParallelDirective
   // DUMP-NEXT: -OMPDefaultClause
+  // DUMP-NEXT: -OMPFirstprivateClause
+  // DUMP-NEXT:   -DeclRefExpr {{.*}} 'targetDev'
 };
 
 void use_template() {
@@ -99,4 +102,60 @@
   // DUMP-NEXT: -DeclRefExpr {{.*}} 'yy'
   // DUMP-NEXT: -DeclRefExpr {{.*}} 'y'
 }
+void zoo(int);
+struct A {
+  int z;
+  int f;
+  A();
+  ~A();
+  void foo() {
+#pragma omp parallel firstprivate(z) default(firstprivate)
+{
+  z++;
+  f++;
+  zoo(z + f);
+  f++;
+}
+  }
+  // PRINT:  #pragma omp parallel firstprivate(this->z) default(firstprivate)
+  // DUMP:   -OMPParallelDirective
+  // DUMP-NEXT: -OMPFirstprivateClause
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT: -OMPDefaultClause
+  // DUMP-NEXT: -OMPFirstprivateClause {{.*}} 
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+  // DUMP:  -CXXThisExpr {{.*}} 'A *' implicit this
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+  void bar() {
+#pragma omp parallel firstprivate(z) default(firstprivate)
+{
+#pragma omp parallel private(z) default(firstprivate)
+  {
+z++;
+f++;
+zoo(z + f);
+f++;
+  }
+}
+  }
+  // PRINT:  #pragma omp parallel firstprivate(this->z) default(firstprivate)
+  // PRINT:#pragma omp parallel private(this->z) default(firstprivate)
+  // DUMP: -OMPParallelDirective
+  // DUMP-NEXT: -OMPFirstprivateClause
+  // DUMP-NEXT:  -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:  -OMPDefaultClause
+  // DUMP:-OMPParallelDirective
+  // DUMP-NEXT:-OMPPrivateClaus
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT: -OMPDefaultClause
+  // DUMP-NEXT: -OMPFirstprivateClause {{.*}} 
+  // DUMP-NEXT:  -DeclRefExpr {{.*}} 'f'
+  // DUMP:   -CXXThisExpr {{.*}} 'A *' implicit this
+  // DUMP-NEXT:  -DeclRefExpr {{.*}} 'f'
+  // DUMP: -MemberExpr {{.*}}
+  // DUMP-NEXT:  -CXXThisExpr
+  // DUMP:   -CXXThisExpr {{.*}} 'A *' implicit this
+  // DUMP-NEXT:  -De

[PATCH] D127803: Generate the capture for field when the field is used in openmp region with implicit default in the member function.

2022-06-30 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added inline comments.



Comment at: clang/lib/Sema/SemaOpenMP.cpp:212
+};
+/// List of captuer fields
+llvm::SmallVector

ABataev wrote:
> Captured?
Fixed.  Thanks.



Comment at: clang/lib/Sema/TreeTransform.h:122
+  /// the RebuildME uses to set if member expression needs to be rebuilt.
+  bool RebuildME = false;
+

ABataev wrote:
> jyu2 wrote:
> > ABataev wrote:
> > > I think we don't need to add a new field here. Can instead we have a 
> > > check for regions with default clauses, if possible?
> > It seems during the TransformMemberExpr, I can not get Directives info for 
> > omp regions to check.  Could you give me hand? 
> > Thanks.  
> > 
> Yes, we do not rebuild the DSA stack at the time of the instantiation. Can 
> you just check that we're inside OpenMPCapturedRegion? Something like 
> getCurCapturedRegion()->CapRegionKind == CR_OpenMP? Or walk the stack of 
> regions to find the outer OpenMP region, if any.
Thank you so much for the help.  I add new function in Sema to do this.  Hope 
that is okay with you.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127803

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


[PATCH] D127803: Generate the capture for field when the field is used in openmp region with implicit default in the member function.

2022-07-01 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added inline comments.



Comment at: clang/lib/Sema/SemaOpenMP.cpp:2273-2274
+bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) {
+  if (getCurCapturedRegion() &&
+  getCurCapturedRegion()->CapRegionKind == CR_OpenMP) {
+DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(

ABataev wrote:
> What if we have another outer OpenMP region, something like lambda inside 
> OpenMP region?
My understanding is that hasDSA will go up to find innermost openmp region 
which has default clause.  Am I right here?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127803

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


[PATCH] D127803: Generate the capture for field when the field is used in openmp region with implicit default in the member function.

2022-07-01 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added inline comments.



Comment at: clang/lib/Sema/SemaOpenMP.cpp:2273-2274
+bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) {
+  if (getCurCapturedRegion() &&
+  getCurCapturedRegion()->CapRegionKind == CR_OpenMP) {
+DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(

ABataev wrote:
> jyu2 wrote:
> > ABataev wrote:
> > > What if we have another outer OpenMP region, something like lambda inside 
> > > OpenMP region?
> > My understanding is that hasDSA will go up to find innermost openmp region 
> > which has default clause.  Am I right here?
> Yes, if you're immediate captured region is OpenMP region. But what if you're 
> inside lambda, which is inside OpenMP region? In this case 
> getCurCapturedRegion()->CapRegionKind != CR_OpenMP. Will it still work, could 
> add a test for this situation?
Good catch!!  Thank you so much!!  You are right.  I removed check for 
CR_OpenMP.  Just let hasDSA to find out.  And add test for this.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127803

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


[PATCH] D127803: Generate the capture for field when the field is used in openmp region with implicit default in the member function.

2022-07-01 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 441765.
jyu2 added a comment.

Thank Alexey for the review.  This is remove check for omp region just use 
hasDSA.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127803

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/OpenMP/default_firstprivate_ast_print.cpp
  clang/test/OpenMP/default_private_ast_print.cpp

Index: clang/test/OpenMP/default_private_ast_print.cpp
===
--- clang/test/OpenMP/default_private_ast_print.cpp
+++ clang/test/OpenMP/default_private_ast_print.cpp
@@ -96,4 +96,57 @@
   // DUMP-NEXT:  -DeclRefExpr {{.*}} 'a'
   // DUMP-NEXT:  -DeclRefExpr {{.*}} 'yy'
 }
+
+void zoo(int);
+struct A {
+  int z;
+  int f;
+  A();
+  ~A();
+  void foo() {
+#pragma omp parallel private(z) default(private)
+{
+  z++;
+  f++;
+  zoo(z + f);
+  f++;
+}
+  }
+  // PRINT:#pragma omp parallel private(this->z) default(private)
+  // DUMP: -OMPParallelDirective
+  // DUMP-NEXT:  -OMPPrivateClause
+  // DUMP-NEXT:-DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:  -OMPDefaultClause
+  // DUMP-NEXT:  -OMPPrivateClause
+  // DUMP-NEXT:-DeclRefExpr {{.*}} 'f'
+  // DUMP: -CXXThisExpr {{.*}} 'A *' implicit this
+  void bar() {
+#pragma omp parallel private(z) default(private)
+{
+#pragma omp parallel private(z) default(private)
+  {
+z++;
+f++;
+zoo(z + f);
+f++;
+  }
+}
+  }
+  // PRINT:#pragma omp parallel private(this->z) default(private)
+  // PRINT:  #pragma omp parallel private(this->z) default(private)
+  // DUMP: -OMPParallelDirective
+  // DUMP-NEXT:  -OMPPrivateClause
+  // DUMP-NEXT:-DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:  -OMPDefaultClause
+  // DUMP:   -OMPParallelDirective
+  // DUMP-NEXT:-OMPPrivateClause
+  // DUMP-NEXT:   -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:-OMPDefaultClause
+  // DUMP-NEXT:-OMPPrivateClause {{.*}} 
+  // DUMP-NEXT:   -DeclRefExpr {{.*}} 'f'
+  // DUMP: -CXXThisExpr
+  // DUMP: -MemberExpr
+  // DUMP-NEXT:   -CXXThisExpr
+  // DUMP: -CXXThisExpr
+};
 #endif // HEADER
Index: clang/test/OpenMP/default_firstprivate_ast_print.cpp
===
--- clang/test/OpenMP/default_firstprivate_ast_print.cpp
+++ clang/test/OpenMP/default_firstprivate_ast_print.cpp
@@ -38,22 +38,31 @@
   void apply() {
 #pragma omp parallel default(firstprivate)
 {
-  targetDev++;
+  [=]() -> int {
+return targetDev++;
+  }();
 }
 // PRINT: #pragma omp parallel default(firstprivate)
 // PRINT-NEXT: {
-// PRINT-NEXT:  this->targetDev++;
-// CHECK-NEXT: }
+// PRINT-NEXT:  [=]() -> int {
+// PRINT-NEXT: return this->targetDev++;
+// PRINT-NEXT:  }();
+// PRINT-NEXT: }
 // DUMP: -OMPParallelDirective
-// DUMP->NEXT: -OMPDefaultClause
+// DUMP-NEXT: -OMPDefaultClause
+// DUMP-NOT:   -OMPFirstprivateClause
   }
   // PRINT: template<> void apply<32U>()
   // PRINT: #pragma omp parallel default(firstprivate)
   // PRINT-NEXT: {
-  // PRINT-NEXT:  this->targetDev++;
+  // PRINT-NEXT:  [=]() -> int {
+  // PRINT-NEXT: return this->targetDev++;
+  // PRINT-NEXT:  }();
   // CHECK-NEXT: }
   // DUMP: -OMPParallelDirective
   // DUMP-NEXT: -OMPDefaultClause
+  // DUMP-NEXT: -OMPFirstprivateClause
+  // DUMP-NEXT:   -DeclRefExpr {{.*}} 'targetDev'
 };
 
 void use_template() {
@@ -99,4 +108,60 @@
   // DUMP-NEXT: -DeclRefExpr {{.*}} 'yy'
   // DUMP-NEXT: -DeclRefExpr {{.*}} 'y'
 }
+void zoo(int);
+struct A {
+  int z;
+  int f;
+  A();
+  ~A();
+  void foo() {
+#pragma omp parallel firstprivate(z) default(firstprivate)
+{
+  z++;
+  f++;
+  zoo(z + f);
+  f++;
+}
+  }
+  // PRINT:  #pragma omp parallel firstprivate(this->z) default(firstprivate)
+  // DUMP:   -OMPParallelDirective
+  // DUMP-NEXT: -OMPFirstprivateClause
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT: -OMPDefaultClause
+  // DUMP-NEXT: -OMPFirstprivateClause {{.*}} 
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+  // DUMP:  -CXXThisExpr {{.*}} 'A *' implicit this
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+  void bar() {
+#pragma omp parallel firstprivate(z) default(firstprivate)
+{
+#pragma omp parallel private(z) default(firstprivate)
+  {
+z++;
+f++;
+zoo(z + f);
+f++;
+  }
+}
+  }
+  // PRINT:  #pragma omp parallel firstprivate(this->z) default(firstprivate)
+  // PRINT:#pragma omp parallel private(this->z) default(firstprivate)
+  // DUMP: -OMPParallelDirective
+  // DUMP-NEXT: -OMPFirstprivateClause
+  // DUMP-NEXT:  -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:  

[PATCH] D127803: Generate the capture for field when the field is used in openmp region with implicit default in the member function.

2022-07-01 Thread Jennifer Yu via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG927156a67445: Generate the capture for the field when the 
field is used in openmp (authored by jyu2).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127803

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/OpenMP/default_firstprivate_ast_print.cpp
  clang/test/OpenMP/default_private_ast_print.cpp

Index: clang/test/OpenMP/default_private_ast_print.cpp
===
--- clang/test/OpenMP/default_private_ast_print.cpp
+++ clang/test/OpenMP/default_private_ast_print.cpp
@@ -96,4 +96,57 @@
   // DUMP-NEXT:  -DeclRefExpr {{.*}} 'a'
   // DUMP-NEXT:  -DeclRefExpr {{.*}} 'yy'
 }
+
+void zoo(int);
+struct A {
+  int z;
+  int f;
+  A();
+  ~A();
+  void foo() {
+#pragma omp parallel private(z) default(private)
+{
+  z++;
+  f++;
+  zoo(z + f);
+  f++;
+}
+  }
+  // PRINT:#pragma omp parallel private(this->z) default(private)
+  // DUMP: -OMPParallelDirective
+  // DUMP-NEXT:  -OMPPrivateClause
+  // DUMP-NEXT:-DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:  -OMPDefaultClause
+  // DUMP-NEXT:  -OMPPrivateClause
+  // DUMP-NEXT:-DeclRefExpr {{.*}} 'f'
+  // DUMP: -CXXThisExpr {{.*}} 'A *' implicit this
+  void bar() {
+#pragma omp parallel private(z) default(private)
+{
+#pragma omp parallel private(z) default(private)
+  {
+z++;
+f++;
+zoo(z + f);
+f++;
+  }
+}
+  }
+  // PRINT:#pragma omp parallel private(this->z) default(private)
+  // PRINT:  #pragma omp parallel private(this->z) default(private)
+  // DUMP: -OMPParallelDirective
+  // DUMP-NEXT:  -OMPPrivateClause
+  // DUMP-NEXT:-DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:  -OMPDefaultClause
+  // DUMP:   -OMPParallelDirective
+  // DUMP-NEXT:-OMPPrivateClause
+  // DUMP-NEXT:   -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT:-OMPDefaultClause
+  // DUMP-NEXT:-OMPPrivateClause {{.*}} 
+  // DUMP-NEXT:   -DeclRefExpr {{.*}} 'f'
+  // DUMP: -CXXThisExpr
+  // DUMP: -MemberExpr
+  // DUMP-NEXT:   -CXXThisExpr
+  // DUMP: -CXXThisExpr
+};
 #endif // HEADER
Index: clang/test/OpenMP/default_firstprivate_ast_print.cpp
===
--- clang/test/OpenMP/default_firstprivate_ast_print.cpp
+++ clang/test/OpenMP/default_firstprivate_ast_print.cpp
@@ -38,22 +38,31 @@
   void apply() {
 #pragma omp parallel default(firstprivate)
 {
-  targetDev++;
+  [=]() -> int {
+return targetDev++;
+  }();
 }
 // PRINT: #pragma omp parallel default(firstprivate)
 // PRINT-NEXT: {
-// PRINT-NEXT:  this->targetDev++;
-// CHECK-NEXT: }
+// PRINT-NEXT:  [=]() -> int {
+// PRINT-NEXT: return this->targetDev++;
+// PRINT-NEXT:  }();
+// PRINT-NEXT: }
 // DUMP: -OMPParallelDirective
-// DUMP->NEXT: -OMPDefaultClause
+// DUMP-NEXT: -OMPDefaultClause
+// DUMP-NOT:   -OMPFirstprivateClause
   }
   // PRINT: template<> void apply<32U>()
   // PRINT: #pragma omp parallel default(firstprivate)
   // PRINT-NEXT: {
-  // PRINT-NEXT:  this->targetDev++;
+  // PRINT-NEXT:  [=]() -> int {
+  // PRINT-NEXT: return this->targetDev++;
+  // PRINT-NEXT:  }();
   // CHECK-NEXT: }
   // DUMP: -OMPParallelDirective
   // DUMP-NEXT: -OMPDefaultClause
+  // DUMP-NEXT: -OMPFirstprivateClause
+  // DUMP-NEXT:   -DeclRefExpr {{.*}} 'targetDev'
 };
 
 void use_template() {
@@ -99,4 +108,60 @@
   // DUMP-NEXT: -DeclRefExpr {{.*}} 'yy'
   // DUMP-NEXT: -DeclRefExpr {{.*}} 'y'
 }
+void zoo(int);
+struct A {
+  int z;
+  int f;
+  A();
+  ~A();
+  void foo() {
+#pragma omp parallel firstprivate(z) default(firstprivate)
+{
+  z++;
+  f++;
+  zoo(z + f);
+  f++;
+}
+  }
+  // PRINT:  #pragma omp parallel firstprivate(this->z) default(firstprivate)
+  // DUMP:   -OMPParallelDirective
+  // DUMP-NEXT: -OMPFirstprivateClause
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT: -OMPDefaultClause
+  // DUMP-NEXT: -OMPFirstprivateClause {{.*}} 
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+  // DUMP:  -CXXThisExpr {{.*}} 'A *' implicit this
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'z'
+  // DUMP-NEXT: -DeclRefExpr {{.*}} 'f'
+  void bar() {
+#pragma omp parallel firstprivate(z) default(firstprivate)
+{
+#pragma omp parallel private(z) default(firstprivate)
+  {
+z++;
+f++;
+zoo(z + f);
+f++;
+  }
+}
+  }
+  // PRINT:  #pragma omp parallel firstprivate(this->z) default(firstprivate)
+  // PRINT:#pragma omp parallel private(this->z) default(firstprivate)
+  // DUMP: -OMPParallelDirective

[PATCH] D122338: [OPENMP] Eliminate extra set of simd variant function attribute.

2022-03-23 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 created this revision.
jyu2 added reviewers: ABataev, mikerice.
jyu2 added projects: OpenMP, clang.
Herald added subscribers: guansong, yaxunl.
Herald added a project: All.
jyu2 requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added a subscriber: sstefan1.

Current clang generates extra set of simd variant function attribute
with extra 'v' encoding.
For example:
_ZGVbN2v__Z5add_1Pf vs _ZGVbN2vv__Z5add_1Pf
The problem is due to declaration of ParamAttrs following:

  llvm::SmallVector ParamAttrs(ParamPositions.size());

where ParamPositions.size() is grown after following assignment:

  Pos = ParamPositions[PVD];

the ParamPositions is define as

  llvm::DenseMap ParamPositions;

To fix this using ParamPos(whith is number of parameters) instead.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D122338

Files:
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/test/OpenMP/declare_simd_codegen.cpp


Index: clang/test/OpenMP/declare_simd_codegen.cpp
===
--- clang/test/OpenMP/declare_simd_codegen.cpp
+++ clang/test/OpenMP/declare_simd_codegen.cpp
@@ -153,6 +153,23 @@
 // CHECK-DAG: "_ZGVdN4v__Z5add_1Pf"
 // CHECK-DAG: "_ZGVeN8v__Z5add_1Pf"
 
+// CHECK-NOT: _ZGVbN2vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeN8vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbN4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeN16l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVbM4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeM16l32v__Z5add_1Pf
+
 // CHECK-DAG: "_ZGVbM2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
 // CHECK-DAG: "_ZGVbN2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
 // CHECK-DAG: "_ZGVcM4va16va16vv__Z1hIiEvPT_S1_S1_S1_"
Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp
===
--- clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -11979,7 +11979,7 @@
   }
   while (FD) {
 for (const auto *Attr : FD->specific_attrs()) {
-  llvm::SmallVector ParamAttrs(ParamPositions.size());
+  llvm::SmallVector ParamAttrs(ParamPos);
   // Mark uniform parameters.
   for (const Expr *E : Attr->uniforms()) {
 E = E->IgnoreParenImpCasts();


Index: clang/test/OpenMP/declare_simd_codegen.cpp
===
--- clang/test/OpenMP/declare_simd_codegen.cpp
+++ clang/test/OpenMP/declare_simd_codegen.cpp
@@ -153,6 +153,23 @@
 // CHECK-DAG: "_ZGVdN4v__Z5add_1Pf"
 // CHECK-DAG: "_ZGVeN8v__Z5add_1Pf"
 
+// CHECK-NOT: _ZGVbN2vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeN8vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbN4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeN16l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVbM4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeM16l32v__Z5add_1Pf
+
 // CHECK-DAG: "_ZGVbM2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
 // CHECK-DAG: "_ZGVbN2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
 // CHECK-DAG: "_ZGVcM4va16va16vv__Z1hIiEvPT_S1_S1_S1_"
Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp
===
--- clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -11979,7 +11979,7 @@
   }
   while (FD) {
 for (const auto *Attr : FD->specific_attrs()) {
-  llvm::SmallVector ParamAttrs(ParamPositions.size());
+  llvm::SmallVector ParamAttrs(ParamPos);
   // Mark uniform parameters.
   for (const Expr *E : Attr->uniforms()) {
 E = E->IgnoreParenImpCasts();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D122338: [OPENMP] Eliminate extra set of simd variant function attribute.

2022-03-23 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

In D122338#3403414 , @ABataev wrote:

> If ParamPositions grows, it means that the item is not found. Is it correct 
> behavior if the compiler inserts new item in the ParamPositions map?

I see.  Thanks!  Then it seems ParamPositions need to be set for each function 
decl otherwise PVD can not find.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122338

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


[PATCH] D122338: [OPENMP] Eliminate extra set of simd variant function attribute.

2022-03-23 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 417746.
jyu2 edited the summary of this revision.

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

https://reviews.llvm.org/D122338

Files:
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/test/OpenMP/declare_simd_codegen.cpp


Index: clang/test/OpenMP/declare_simd_codegen.cpp
===
--- clang/test/OpenMP/declare_simd_codegen.cpp
+++ clang/test/OpenMP/declare_simd_codegen.cpp
@@ -153,6 +153,23 @@
 // CHECK-DAG: "_ZGVdN4v__Z5add_1Pf"
 // CHECK-DAG: "_ZGVeN8v__Z5add_1Pf"
 
+// CHECK-NOT: _ZGVbN2vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeN8vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbN4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeN16l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVbM4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeM16l32v__Z5add_1Pf
+
 // CHECK-DAG: "_ZGVbM2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
 // CHECK-DAG: "_ZGVbN2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
 // CHECK-DAG: "_ZGVcM4va16va16vv__Z1hIiEvPT_S1_S1_S1_"
Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp
===
--- clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -11968,16 +11968,16 @@
   llvm::Function *Fn) {
   ASTContext &C = CGM.getContext();
   FD = FD->getMostRecentDecl();
-  // Map params to their positions in function decl.
-  llvm::DenseMap ParamPositions;
-  if (isa(FD))
-ParamPositions.try_emplace(FD, 0);
-  unsigned ParamPos = ParamPositions.size();
-  for (const ParmVarDecl *P : FD->parameters()) {
-ParamPositions.try_emplace(P->getCanonicalDecl(), ParamPos);
-++ParamPos;
-  }
   while (FD) {
+// Map params to their positions in function decl.
+llvm::DenseMap ParamPositions;
+if (isa(FD))
+  ParamPositions.try_emplace(FD, 0);
+unsigned ParamPos = ParamPositions.size();
+for (const ParmVarDecl *P : FD->parameters()) {
+  ParamPositions.try_emplace(P->getCanonicalDecl(), ParamPos);
+  ++ParamPos;
+}
 for (const auto *Attr : FD->specific_attrs()) {
   llvm::SmallVector ParamAttrs(ParamPositions.size());
   // Mark uniform parameters.


Index: clang/test/OpenMP/declare_simd_codegen.cpp
===
--- clang/test/OpenMP/declare_simd_codegen.cpp
+++ clang/test/OpenMP/declare_simd_codegen.cpp
@@ -153,6 +153,23 @@
 // CHECK-DAG: "_ZGVdN4v__Z5add_1Pf"
 // CHECK-DAG: "_ZGVeN8v__Z5add_1Pf"
 
+// CHECK-NOT: _ZGVbN2vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeN8vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbN4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeN16l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVbM4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeM16l32v__Z5add_1Pf
+
 // CHECK-DAG: "_ZGVbM2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
 // CHECK-DAG: "_ZGVbN2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
 // CHECK-DAG: "_ZGVcM4va16va16vv__Z1hIiEvPT_S1_S1_S1_"
Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp
===
--- clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -11968,16 +11968,16 @@
   llvm::Function *Fn) {
   ASTContext &C = CGM.getContext();
   FD = FD->getMostRecentDecl();
-  // Map params to their positions in function decl.
-  llvm::DenseMap ParamPositions;
-  if (isa(FD))
-ParamPositions.try_emplace(FD, 0);
-  unsigned ParamPos = ParamPositions.size();
-  for (const ParmVarDecl *P : FD->parameters()) {
-ParamPositions.try_emplace(P->getCanonicalDecl(), ParamPos);
-++ParamPos;
-  }
   while (FD) {
+// Map params to their positions in function decl.
+llvm::DenseMap ParamPositions;
+if (isa(FD))
+  ParamPositions.try_emplace(FD, 0);
+unsigned ParamPos = ParamPositions.size();
+for (const ParmVarDecl *P : FD->parameters()) {
+  ParamPositions.try_emplace(P->getCanonicalDecl(), ParamPos);
+  ++ParamPos;
+}
 for (const auto *Attr : FD->specific_attrs()) {
   llvm::SmallVector ParamAttrs(ParamPositions.size());
   // Mark uniform parameters.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commit

[PATCH] D122338: [OPENMP] Eliminate extra set of simd variant function attribute.

2022-03-24 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 417944.
jyu2 added a comment.

Address Alexey's comment.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122338

Files:
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/test/OpenMP/declare_simd_codegen.cpp


Index: clang/test/OpenMP/declare_simd_codegen.cpp
===
--- clang/test/OpenMP/declare_simd_codegen.cpp
+++ clang/test/OpenMP/declare_simd_codegen.cpp
@@ -153,6 +153,23 @@
 // CHECK-DAG: "_ZGVdN4v__Z5add_1Pf"
 // CHECK-DAG: "_ZGVeN8v__Z5add_1Pf"
 
+// CHECK-NOT: _ZGVbN2vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeN8vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbN4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeN16l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVbM4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeM16l32v__Z5add_1Pf
+
 // CHECK-DAG: "_ZGVbM2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
 // CHECK-DAG: "_ZGVbN2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
 // CHECK-DAG: "_ZGVcM4va16va16vv__Z1hIiEvPT_S1_S1_S1_"
Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp
===
--- clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -11968,16 +11968,16 @@
   llvm::Function *Fn) {
   ASTContext &C = CGM.getContext();
   FD = FD->getMostRecentDecl();
-  // Map params to their positions in function decl.
-  llvm::DenseMap ParamPositions;
-  if (isa(FD))
-ParamPositions.try_emplace(FD, 0);
-  unsigned ParamPos = ParamPositions.size();
-  for (const ParmVarDecl *P : FD->parameters()) {
-ParamPositions.try_emplace(P->getCanonicalDecl(), ParamPos);
-++ParamPos;
-  }
   while (FD) {
+// Map params to their positions in function decl.
+llvm::DenseMap ParamPositions;
+if (isa(FD))
+  ParamPositions.try_emplace(FD, 0);
+unsigned ParamPos = ParamPositions.size();
+for (const ParmVarDecl *P : FD->parameters()) {
+  ParamPositions.try_emplace(P->getCanonicalDecl(), ParamPos);
+  ++ParamPos;
+}
 for (const auto *Attr : FD->specific_attrs()) {
   llvm::SmallVector ParamAttrs(ParamPositions.size());
   // Mark uniform parameters.
@@ -11989,6 +11989,7 @@
 } else {
   const auto *PVD = cast(cast(E)->getDecl())
 ->getCanonicalDecl();
+  assert(ParamPositions.find(PVD) != ParamPositions.end());
   Pos = ParamPositions[PVD];
 }
 ParamAttrs[Pos].Kind = Uniform;
@@ -12005,6 +12006,7 @@
 } else {
   const auto *PVD = cast(cast(E)->getDecl())
 ->getCanonicalDecl();
+  assert(ParamPositions.find(PVD) != ParamPositions.end());
   Pos = ParamPositions[PVD];
   ParmTy = PVD->getType();
 }
@@ -12030,6 +12032,7 @@
 } else {
   const auto *PVD = cast(cast(E)->getDecl())
 ->getCanonicalDecl();
+  assert(ParamPositions.find(PVD) != ParamPositions.end());
   Pos = ParamPositions[PVD];
   if (auto *P = dyn_cast(PVD->getType()))
 PtrRescalingFactor = CGM.getContext()
@@ -12048,6 +12051,8 @@
   if (const auto *StridePVD =
   dyn_cast(DRE->getDecl())) {
 ParamAttr.Kind = LinearWithVarStride;
+assert(ParamPositions.find(StridePVD->getCanonicalDecl()) !=
+   ParamPositions.end());
 ParamAttr.StrideOrArg = llvm::APSInt::getUnsigned(
 ParamPositions[StridePVD->getCanonicalDecl()]);
   }


Index: clang/test/OpenMP/declare_simd_codegen.cpp
===
--- clang/test/OpenMP/declare_simd_codegen.cpp
+++ clang/test/OpenMP/declare_simd_codegen.cpp
@@ -153,6 +153,23 @@
 // CHECK-DAG: "_ZGVdN4v__Z5add_1Pf"
 // CHECK-DAG: "_ZGVeN8v__Z5add_1Pf"
 
+// CHECK-NOT: _ZGVbN2vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeN8vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbN4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeN16l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVbM4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeM16l32v__Z5add_1Pf
+
 // CHECK-DAG: "_ZGVbM2va16va16vv__Z1hIiEvPT_S1_S1_S1_

[PATCH] D122338: [OPENMP] Eliminate extra set of simd variant function attribute.

2022-03-24 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 417981.
jyu2 added a comment.

Address Alexey comment.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122338

Files:
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/test/OpenMP/declare_simd_codegen.cpp

Index: clang/test/OpenMP/declare_simd_codegen.cpp
===
--- clang/test/OpenMP/declare_simd_codegen.cpp
+++ clang/test/OpenMP/declare_simd_codegen.cpp
@@ -153,6 +153,23 @@
 // CHECK-DAG: "_ZGVdN4v__Z5add_1Pf"
 // CHECK-DAG: "_ZGVeN8v__Z5add_1Pf"
 
+// CHECK-NOT: _ZGVbN2vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeN8vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbN4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeN16l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVbM4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeM16l32v__Z5add_1Pf
+
 // CHECK-DAG: "_ZGVbM2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
 // CHECK-DAG: "_ZGVbN2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
 // CHECK-DAG: "_ZGVcM4va16va16vv__Z1hIiEvPT_S1_S1_S1_"
Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp
===
--- clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -11968,16 +11968,16 @@
   llvm::Function *Fn) {
   ASTContext &C = CGM.getContext();
   FD = FD->getMostRecentDecl();
-  // Map params to their positions in function decl.
-  llvm::DenseMap ParamPositions;
-  if (isa(FD))
-ParamPositions.try_emplace(FD, 0);
-  unsigned ParamPos = ParamPositions.size();
-  for (const ParmVarDecl *P : FD->parameters()) {
-ParamPositions.try_emplace(P->getCanonicalDecl(), ParamPos);
-++ParamPos;
-  }
   while (FD) {
+// Map params to their positions in function decl.
+llvm::DenseMap ParamPositions;
+if (isa(FD))
+  ParamPositions.try_emplace(FD, 0);
+unsigned ParamPos = ParamPositions.size();
+for (const ParmVarDecl *P : FD->parameters()) {
+  ParamPositions.try_emplace(P->getCanonicalDecl(), ParamPos);
+  ++ParamPos;
+}
 for (const auto *Attr : FD->specific_attrs()) {
   llvm::SmallVector ParamAttrs(ParamPositions.size());
   // Mark uniform parameters.
@@ -11989,7 +11989,9 @@
 } else {
   const auto *PVD = cast(cast(E)->getDecl())
 ->getCanonicalDecl();
-  Pos = ParamPositions[PVD];
+  auto It = ParamPositions.find(PVD);
+  assert(It != ParamPositions.end() && "Function parameter not found");
+  Pos = It->second;
 }
 ParamAttrs[Pos].Kind = Uniform;
   }
@@ -12005,7 +12007,9 @@
 } else {
   const auto *PVD = cast(cast(E)->getDecl())
 ->getCanonicalDecl();
-  Pos = ParamPositions[PVD];
+  auto It = ParamPositions.find(PVD);
+  assert(It != ParamPositions.end() && "Function parameter not found");
+  Pos = It->second;
   ParmTy = PVD->getType();
 }
 ParamAttrs[Pos].Alignment =
@@ -12030,7 +12034,9 @@
 } else {
   const auto *PVD = cast(cast(E)->getDecl())
 ->getCanonicalDecl();
-  Pos = ParamPositions[PVD];
+  auto It = ParamPositions.find(PVD);
+  assert(It != ParamPositions.end() && "Function parameter not found");
+  Pos = It->second;
   if (auto *P = dyn_cast(PVD->getType()))
 PtrRescalingFactor = CGM.getContext()
  .getTypeSizeInChars(P->getPointeeType())
@@ -12048,8 +12054,10 @@
   if (const auto *StridePVD =
   dyn_cast(DRE->getDecl())) {
 ParamAttr.Kind = LinearWithVarStride;
-ParamAttr.StrideOrArg = llvm::APSInt::getUnsigned(
-ParamPositions[StridePVD->getCanonicalDecl()]);
+auto It = ParamPositions.find(StridePVD->getCanonicalDecl());
+assert(It != ParamPositions.end() &&
+   "Function parameter not found");
+ParamAttr.StrideOrArg = llvm::APSInt::getUnsigned(It->second);
   }
 }
   } else {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D122338: [OPENMP] Eliminate extra set of simd variant function attribute.

2022-03-24 Thread Jennifer Yu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGa6cdac48ffaf: Eliminate extra set of simd variant function 
attribute. (authored by jyu2).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122338

Files:
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/test/OpenMP/declare_simd_codegen.cpp

Index: clang/test/OpenMP/declare_simd_codegen.cpp
===
--- clang/test/OpenMP/declare_simd_codegen.cpp
+++ clang/test/OpenMP/declare_simd_codegen.cpp
@@ -153,6 +153,23 @@
 // CHECK-DAG: "_ZGVdN4v__Z5add_1Pf"
 // CHECK-DAG: "_ZGVeN8v__Z5add_1Pf"
 
+// CHECK-NOT: _ZGVbN2vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdN4vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeN8vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVcM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVdM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVeM32vv__Z5add_1Pf
+// CHECK-NOT: _ZGVbN4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdN8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeN16l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVbM4l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVcM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVdM8l32v__Z5add_1Pf
+// CHECK-NOT: _ZGVeM16l32v__Z5add_1Pf
+
 // CHECK-DAG: "_ZGVbM2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
 // CHECK-DAG: "_ZGVbN2va16va16vv__Z1hIiEvPT_S1_S1_S1_"
 // CHECK-DAG: "_ZGVcM4va16va16vv__Z1hIiEvPT_S1_S1_S1_"
Index: clang/lib/CodeGen/CGOpenMPRuntime.cpp
===
--- clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -11939,16 +11939,16 @@
   llvm::Function *Fn) {
   ASTContext &C = CGM.getContext();
   FD = FD->getMostRecentDecl();
-  // Map params to their positions in function decl.
-  llvm::DenseMap ParamPositions;
-  if (isa(FD))
-ParamPositions.try_emplace(FD, 0);
-  unsigned ParamPos = ParamPositions.size();
-  for (const ParmVarDecl *P : FD->parameters()) {
-ParamPositions.try_emplace(P->getCanonicalDecl(), ParamPos);
-++ParamPos;
-  }
   while (FD) {
+// Map params to their positions in function decl.
+llvm::DenseMap ParamPositions;
+if (isa(FD))
+  ParamPositions.try_emplace(FD, 0);
+unsigned ParamPos = ParamPositions.size();
+for (const ParmVarDecl *P : FD->parameters()) {
+  ParamPositions.try_emplace(P->getCanonicalDecl(), ParamPos);
+  ++ParamPos;
+}
 for (const auto *Attr : FD->specific_attrs()) {
   llvm::SmallVector ParamAttrs(ParamPositions.size());
   // Mark uniform parameters.
@@ -11960,7 +11960,9 @@
 } else {
   const auto *PVD = cast(cast(E)->getDecl())
 ->getCanonicalDecl();
-  Pos = ParamPositions[PVD];
+  auto It = ParamPositions.find(PVD);
+  assert(It != ParamPositions.end() && "Function parameter not found");
+  Pos = It->second;
 }
 ParamAttrs[Pos].Kind = Uniform;
   }
@@ -11976,7 +11978,9 @@
 } else {
   const auto *PVD = cast(cast(E)->getDecl())
 ->getCanonicalDecl();
-  Pos = ParamPositions[PVD];
+  auto It = ParamPositions.find(PVD);
+  assert(It != ParamPositions.end() && "Function parameter not found");
+  Pos = It->second;
   ParmTy = PVD->getType();
 }
 ParamAttrs[Pos].Alignment =
@@ -12000,7 +12004,9 @@
 } else {
   const auto *PVD = cast(cast(E)->getDecl())
 ->getCanonicalDecl();
-  Pos = ParamPositions[PVD];
+  auto It = ParamPositions.find(PVD);
+  assert(It != ParamPositions.end() && "Function parameter not found");
+  Pos = It->second;
   if (auto *P = dyn_cast(PVD->getType()))
 PtrRescalingFactor = CGM.getContext()
  .getTypeSizeInChars(P->getPointeeType())
@@ -12018,8 +12024,10 @@
   if (const auto *StridePVD =
   dyn_cast(DRE->getDecl())) {
 ParamAttr.Kind = LinearWithVarStride;
-ParamAttr.StrideOrArg = llvm::APSInt::getUnsigned(
-ParamPositions[StridePVD->getCanonicalDecl()]);
+auto It = ParamPositions.find(StridePVD->getCanonicalDecl());
+assert(It != ParamPositions.end() &&
+   "Function parameter not found");
+ParamAttr.StrideOrArg = llvm::APSInt::getUnsigned(It->second);
   }
 }
   } else {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D122338: [OPENMP] Eliminate extra set of simd variant function attribute.

2022-03-24 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

In D122338#3405948 , @ABataev wrote:

> LG

Thank you so much Alexey.




Comment at: clang/lib/CodeGen/CGOpenMPRuntime.cpp:11988
 if (isa(E)) {
   Pos = ParamPositions[FD];
 } else {

ABataev wrote:
> I would also recommend to replace all `operator []` calls to something that 
> does not modify the map, like `find`.
How about adding assert?  Thanks.



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D122338

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


[PATCH] D122852: [OPENMP] Fix assertion in clang::ASTContext::getTypeInfoImpl

2022-03-31 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 created this revision.
jyu2 added reviewers: ABataev, jdoerfert, mikerice.
jyu2 added a project: OpenMP.
Herald added subscribers: guansong, yaxunl.
Herald added a project: All.
jyu2 requested review of this revision.
Herald added a subscriber: sstefan1.

The problem is when mapping of array section, currently call
getTypeSizeInChars with BuiltinType::OMPArraySection causing assert.

One way to fix this is using array element type instead.

BTW with this fix, test will fail in libomptarget.so
with error message: double free or corruption (out)
But it passes with intel customized libomptarget.so

I am not sure it is clang problem.  I will submit issues to 
libtarget after this checked in for more investigation.


Repository:
  rC Clang

https://reviews.llvm.org/D122852

Files:
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/test/OpenMP/target_map_codegen_36.cpp

Index: clang/test/OpenMP/target_map_codegen_36.cpp
===
--- /dev/null
+++ clang/test/OpenMP/target_map_codegen_36.cpp
@@ -0,0 +1,514 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+///==///
+// RUN: %clang_cc1 -DCK36 -verify -fopenmp -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK36 --check-prefix CK36-64
+// RUN: %clang_cc1 -DCK36 -fopenmp -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s  --check-prefix CK36 --check-prefix CK36-64
+// RUN: %clang_cc1 -DCK36 -verify -fopenmp -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s  --check-prefix CK36 --check-prefix CK36-32
+// RUN: %clang_cc1 -DCK36 -fopenmp -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s  --check-prefix CK36 --check-prefix CK36-32
+
+// RUN: %clang_cc1 -DCK36 -verify -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY32 %s
+// RUN: %clang_cc1 -DCK36 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple powerpc64le-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY32 %s
+// RUN: %clang_cc1 -DCK36 -verify -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck --check-prefix SIMD-ONLY32 %s
+// RUN: %clang_cc1 -DCK36 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -std=c++11 -triple i386-unknown-unknown -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -fopenmp-targets=i386-pc-linux-gnu -x c++ -triple i386-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY32 %s
+// SIMD-ONLY32-NOT: {{__kmpc|__tgt}}
+#ifdef CK36
+typedef struct {
+  int a;
+  double *b;
+} C;
+#pragma omp declare mapper(C s) map(to : s.a) map(tofrom : s.b [0:2])
+
+typedef struct {
+  int e;
+  int h;
+  C f;
+} D;
+// CK36-DAG: [[SIZE_TO:@.+]] = private {{.*}}constant [4 x i64] [i64 0, i64 0, i64 0, i64 {{48|32}}]
+// CK36--DAG: [[MTYPE_TO:@.+]] = {{.+}}constant [4 x i64] [i64 32, i64 281474976710659, i64 281474976710659, i64 281474976711171]
+
+// CK36-64-LABEL: @_Z4testv(
+// CK36-64-NEXT:  entry:
+// CK36-64-NEXT:[[SA:%.*]] = alloca [10 x %struct.D], align 8
+// CK36-64-NEXT:[[X:%.*]] = alloca [2 x double], align 8
+// CK36-64-NEXT:[[Y:%.*]] = alloca [2 x double], align 8
+// CK36-64-NEXT:[[DOTOFFLOAD_BASEPTRS:%.*]] = alloca [4 x i8*], align 8
+// CK36-64-NEXT:[[DOTOFFLOAD_PTRS:%.*]] = alloca [4 x i8*], align 8
+// CK36-64-NEXT:[[DOTOFFLOAD_MAPPERS:%.*]] = alloca [4 x i8*], align 8
+// CK36-64-NEXT:[[DOTOFFLOAD_SIZES:%.*]] = alloca [4 x i64], align 8
+// CK36-64-NEXT:[[SAAA:%.*]] = alloca [10 x %struct.D], align 8
+// CK36-64-NEXT:[[SAA:%.*]] = alloca %struct.D*, align 8
+// CK36-64-NEXT:[[DOTOFFLOAD_BASEPTRS32:%.*]] = alloca [4 x i8*], align 8
+// CK36-64-NEXT:

[PATCH] D127803: Generate the capture for field when the field is used in openmp region with implicit default in the member function.

2022-08-02 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

In D127803#3693301 , @mgabka wrote:

> I noticed that this patch is causing now an assertion failure for cases like :
>
> class A{
>
>   void a() {
> #pragma omp parallel
> a(b);
>   }
>
> };
>
> The failed assertion is: "const clang::ValueDecl* getCanonicalDecl(const 
> clang::ValueDecl*): Assertion `FD' failed."
>
> while before it clang was correctly  reporting error:
> error: use of undeclared identifier 'b'
>
> is it the same assertion you were trying to fix here?

No, the assert I am fixing is when default(firstprivate) is used inside member 
function.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127803

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


[PATCH] D127803: Generate the capture for field when the field is used in openmp region with implicit default in the member function.

2022-08-02 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added a comment.

In D127803#3693660 , @ABataev wrote:

> In D127803#3693655 , @jyu2 wrote:
>
>> In D127803#3693301 , @mgabka wrote:
>>
>>> I noticed that this patch is causing now an assertion failure for cases 
>>> like :
>>>
>>> class A{
>>>
>>>   void a() {
>>> #pragma omp parallel
>>> a(b);
>>>   }
>>>
>>> };
>>>
>>> The failed assertion is: "const clang::ValueDecl* getCanonicalDecl(const 
>>> clang::ValueDecl*): Assertion `FD' failed."
>>>
>>> while before it clang was correctly  reporting error:
>>> error: use of undeclared identifier 'b'
>>>
>>> is it the same assertion you were trying to fix here?
>>
>> No, the assert I am fixing is when default(firstprivate) is used inside 
>> member function.
>
> Could you please investigate and fix it?

Yes, I will fix this.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D127803

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


[PATCH] D131024: Fix assert in the call to isOpenMPRebuildMemberExpr

2022-08-02 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 created this revision.
Herald added subscribers: guansong, yaxunl.
Herald added a project: All.
jyu2 requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added subscribers: cfe-commits, sstefan1.
Herald added a project: clang.

This is to fix https://github.com/llvm/llvm-project/issues/56884

The problem is in isOpenMPRebuildMemberExpr, it is only need to rebuild
for field expression.  No need for member function call.

The fix is to check field for member expression and skip rebuild for member
function call


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D131024

Files:
  clang/lib/Sema/SemaOpenMP.cpp
  clang/test/OpenMP/parallel_default_messages.cpp


Index: clang/test/OpenMP/parallel_default_messages.cpp
===
--- clang/test/OpenMP/parallel_default_messages.cpp
+++ clang/test/OpenMP/parallel_default_messages.cpp
@@ -49,3 +49,10 @@
 
   return 0;
 }
+
+class A{
+  void a() {
+#pragma omp parallel
+a(b); // expected-error {{use of undeclared identifier 'b'}}
+ }
+};
Index: clang/lib/Sema/SemaOpenMP.cpp
===
--- clang/lib/Sema/SemaOpenMP.cpp
+++ clang/lib/Sema/SemaOpenMP.cpp
@@ -2270,6 +2270,9 @@
 }
 
 bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) {
+  // Only rebuild for Field.
+  if (!dyn_cast(D))
+return false;
   DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
   D,
   [](OpenMPClauseKind C, bool AppliedToPointee,


Index: clang/test/OpenMP/parallel_default_messages.cpp
===
--- clang/test/OpenMP/parallel_default_messages.cpp
+++ clang/test/OpenMP/parallel_default_messages.cpp
@@ -49,3 +49,10 @@
 
   return 0;
 }
+
+class A{
+  void a() {
+#pragma omp parallel
+a(b); // expected-error {{use of undeclared identifier 'b'}}
+ }
+};
Index: clang/lib/Sema/SemaOpenMP.cpp
===
--- clang/lib/Sema/SemaOpenMP.cpp
+++ clang/lib/Sema/SemaOpenMP.cpp
@@ -2270,6 +2270,9 @@
 }
 
 bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) {
+  // Only rebuild for Field.
+  if (!dyn_cast(D))
+return false;
   DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
   D,
   [](OpenMPClauseKind C, bool AppliedToPointee,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D131024: Fix assert in the call to isOpenMPRebuildMemberExpr

2022-08-03 Thread Jennifer Yu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGa7bca18bc50c: Fix assert during the call to 
getCanonicalDecl. (authored by jyu2).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D131024

Files:
  clang/lib/Sema/SemaOpenMP.cpp
  clang/test/OpenMP/parallel_default_messages.cpp


Index: clang/test/OpenMP/parallel_default_messages.cpp
===
--- clang/test/OpenMP/parallel_default_messages.cpp
+++ clang/test/OpenMP/parallel_default_messages.cpp
@@ -49,3 +49,10 @@
 
   return 0;
 }
+
+class A{
+  void a() {
+#pragma omp parallel
+a(b); // expected-error {{use of undeclared identifier 'b'}}
+ }
+};
Index: clang/lib/Sema/SemaOpenMP.cpp
===
--- clang/lib/Sema/SemaOpenMP.cpp
+++ clang/lib/Sema/SemaOpenMP.cpp
@@ -2270,6 +2270,9 @@
 }
 
 bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) {
+  // Only rebuild for Field.
+  if (!dyn_cast(D))
+return false;
   DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
   D,
   [](OpenMPClauseKind C, bool AppliedToPointee,


Index: clang/test/OpenMP/parallel_default_messages.cpp
===
--- clang/test/OpenMP/parallel_default_messages.cpp
+++ clang/test/OpenMP/parallel_default_messages.cpp
@@ -49,3 +49,10 @@
 
   return 0;
 }
+
+class A{
+  void a() {
+#pragma omp parallel
+a(b); // expected-error {{use of undeclared identifier 'b'}}
+ }
+};
Index: clang/lib/Sema/SemaOpenMP.cpp
===
--- clang/lib/Sema/SemaOpenMP.cpp
+++ clang/lib/Sema/SemaOpenMP.cpp
@@ -2270,6 +2270,9 @@
 }
 
 bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) {
+  // Only rebuild for Field.
+  if (!dyn_cast(D))
+return false;
   DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
   D,
   [](OpenMPClauseKind C, bool AppliedToPointee,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D107141: [Inline-asm] Add diagnosts for unsupported inline assembly arguments

2022-03-09 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added inline comments.



Comment at: clang/lib/Sema/SemaStmtAsm.cpp:679
+  !llvm::isPowerOf2_32(OutSize))
+targetDiag(OutputExpr->getExprLoc(), diag::err_store_value_to_reg);
+

Error message is not very clear to me.  I think we should create more specified 
error message there.  Like power of two, or size <  8 or > pointer size?

Using error message selector.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D107141

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


[PATCH] D107141: [Inline-asm] Add diagnosts for unsupported inline assembly arguments

2022-03-10 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added inline comments.



Comment at: clang/lib/Sema/SemaStmtAsm.cpp:622
+if (InTy->isIntegerType() || InTy->isPointerType() ||
+InTy->isStructureType() || InTy->isConstantArrayType())
   InputDomain = AD_Int;

Are you sure you want to change the Input/output Domain?  Since you changed 
this, could you add both codegen and sema check tests for  struct type(you 
already has sema check for struct type, but I don't see any array type) and 
array type.  

Thanks.
Jennifer



Comment at: clang/lib/Sema/SemaStmtAsm.cpp:677
+  Context.getIntTypeForBitwidth(OutSize, /*Signed*/ false).isNull())
+targetDiag(OutputExpr->getExprLoc(), diag::err_store_value_to_reg);
+

Do you need return NS after diagnostic?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D107141

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


[PATCH] D107141: [Inline-asm] Add diagnosts for unsupported inline assembly arguments

2022-03-21 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 added inline comments.



Comment at: clang/lib/Sema/SemaStmtAsm.cpp:622
+if (InTy->isIntegerType() || InTy->isPointerType() ||
+InTy->isStructureType() || InTy->isConstantArrayType())
   InputDomain = AD_Int;

pengfei wrote:
> jyu2 wrote:
> > Are you sure you want to change the Input/output Domain?  Since you changed 
> > this, could you add both codegen and sema check tests for  struct type(you 
> > already has sema check for struct type, but I don't see any array type) and 
> > array type.  
> > 
> > Thanks.
> > Jennifer
> The input / output domain are just for sema check here. I don't think it 
> changes codegen behavior.
Yes, for seam check, once error emit, compiler stop at CodeGen.  However, if no 
error emit, compiler will go though the CodeGen.

Since pointer/struct and constantArray are allowed for small size of type, so 
would you please add code gen test for that?

In your test where no-error should emit part...

asm ("" : "=rm" (a): "0" (1)); // no-error

Thanks.
Jennifer


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D107141

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


[PATCH] D107141: [Inline-asm] Add diagnosts for unsupported inline assembly arguments

2022-03-22 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 accepted this revision.
jyu2 added a comment.
This revision is now accepted and ready to land.

This is okay with me.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D107141

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


[PATCH] D123402: [clang][OpenMP5.1] Initial parsing/sema for has_device_addr

2022-04-08 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 created this revision.
jyu2 added reviewers: ABataev, mikerice, jdoerfert.
jyu2 added projects: clang, OpenMP.
Herald added subscribers: arphaman, guansong, yaxunl.
Herald added a reviewer: sscalpone.
Herald added projects: Flang, All.
jyu2 requested review of this revision.
Herald added subscribers: llvm-commits, sstefan1.
Herald added a project: LLVM.

Added basic parsing/sema/ support for the 'has_device_addr' clause


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D123402

Files:
  clang/include/clang/AST/OpenMPClause.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/OpenMPClause.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/Basic/OpenMPKinds.cpp
  clang/lib/CodeGen/CGStmtOpenMP.cpp
  clang/lib/Parse/ParseOpenMP.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/OpenMP/target_has_device_addr_ast_print.cpp
  clang/test/OpenMP/target_has_device_addr_messages.cpp
  clang/tools/libclang/CIndex.cpp
  flang/lib/Semantics/check-omp-structure.cpp
  llvm/include/llvm/Frontend/OpenMP/OMP.td

Index: llvm/include/llvm/Frontend/OpenMP/OMP.td
===
--- llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -253,6 +253,11 @@
   let flangClass = "Name";
   let isValueList = true;
 }
+def OMPC_HasDeviceAddr : Clause<"has_device_addr"> {
+  let clangClass = "OMPHasDeviceAddrClause";
+  let flangClass = "Name";
+  let isValueList = true;
+}
 def OMPC_TaskReduction : Clause<"task_reduction"> {
   let clangClass = "OMPTaskReductionClause";
   let flangClass = "OmpReductionClause";
@@ -556,6 +561,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause
@@ -652,6 +658,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause
   ];
@@ -684,6 +691,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause
@@ -700,6 +708,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1133,6 +1142,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1163,6 +1173,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1176,6 +1187,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1349,6 +1361,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1372,6 +1385,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1402,6 +1416,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1427,6 +1442,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1463,6 +1479,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1492,6 +1509,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1530,6 +1548,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1741,6 +1760,7 @@
   let allowedClauses = [
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1790,6 +1810,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1836,6 +1857,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
Index: flang/lib/Semantics/check-omp-structure.cpp
===
--- flang/lib/Semantics/check-omp-structure.cpp
+++ flang/lib/Semantics/check-omp-structure.cpp
@@ -1683,6 +1683,7 @@
 CHECK_SIMPLE_CLAUSE(Th

[PATCH] D123402: [clang][OpenMP5.1] Initial parsing/sema for has_device_addr

2022-04-08 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 421637.
jyu2 added a comment.

Thanks Alexey, for the review!  This patch addresses his comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123402

Files:
  clang/include/clang/AST/OpenMPClause.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/OpenMPClause.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/Basic/OpenMPKinds.cpp
  clang/lib/CodeGen/CGStmtOpenMP.cpp
  clang/lib/Parse/ParseOpenMP.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/OpenMP/target_has_device_addr_ast_print.cpp
  clang/test/OpenMP/target_has_device_addr_messages.cpp
  clang/tools/libclang/CIndex.cpp
  flang/lib/Semantics/check-omp-structure.cpp
  llvm/include/llvm/Frontend/OpenMP/OMP.td

Index: llvm/include/llvm/Frontend/OpenMP/OMP.td
===
--- llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -253,6 +253,11 @@
   let flangClass = "Name";
   let isValueList = true;
 }
+def OMPC_HasDeviceAddr : Clause<"has_device_addr"> {
+  let clangClass = "OMPHasDeviceAddrClause";
+  let flangClass = "Name";
+  let isValueList = true;
+}
 def OMPC_TaskReduction : Clause<"task_reduction"> {
   let clangClass = "OMPTaskReductionClause";
   let flangClass = "OmpReductionClause";
@@ -556,6 +561,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause
@@ -652,6 +658,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause
   ];
@@ -684,6 +691,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause
@@ -700,6 +708,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1133,6 +1142,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1163,6 +1173,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1176,6 +1187,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1349,6 +1361,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1372,6 +1385,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1402,6 +1416,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1427,6 +1442,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1463,6 +1479,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1492,6 +1509,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1530,6 +1548,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1741,6 +1760,7 @@
   let allowedClauses = [
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1790,6 +1810,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1836,6 +1857,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
Index: flang/lib/Semantics/check-omp-structure.cpp
===
--- flang/lib/Semantics/check-omp-structure.cpp
+++ flang/lib/Semantics/check-omp-structure.cpp
@@ -1683,6 +1683,7 @@
 CHECK_SIMPLE_CLAUSE(Threads, OMPC_threads)
 CHECK_SIMPLE_CLAUSE(Inbranch, OMPC_inbranch)
 CHECK_SIMPLE_CLAUSE(IsDevicePtr, OMPC_is_device_ptr)
+CHECK_SIMPLE_CLAUSE(HasDeviceAddr, OMPC_has_device_addr)
 CHECK_SIMPLE_CLAUSE(Link, OMPC_link)
 CHECK_SIMPL

[PATCH] D123402: [clang][OpenMP5.1] Initial parsing/sema for has_device_addr

2022-04-08 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 421639.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123402

Files:
  clang/include/clang/AST/OpenMPClause.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/OpenMPClause.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/Basic/OpenMPKinds.cpp
  clang/lib/CodeGen/CGStmtOpenMP.cpp
  clang/lib/Parse/ParseOpenMP.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/OpenMP/target_has_device_addr_ast_print.cpp
  clang/test/OpenMP/target_has_device_addr_messages.cpp
  clang/tools/libclang/CIndex.cpp
  flang/lib/Semantics/check-omp-structure.cpp
  llvm/include/llvm/Frontend/OpenMP/OMP.td

Index: llvm/include/llvm/Frontend/OpenMP/OMP.td
===
--- llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -253,6 +253,11 @@
   let flangClass = "Name";
   let isValueList = true;
 }
+def OMPC_HasDeviceAddr : Clause<"has_device_addr"> {
+  let clangClass = "OMPHasDeviceAddrClause";
+  let flangClass = "Name";
+  let isValueList = true;
+}
 def OMPC_TaskReduction : Clause<"task_reduction"> {
   let clangClass = "OMPTaskReductionClause";
   let flangClass = "OmpReductionClause";
@@ -556,6 +561,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause
@@ -652,6 +658,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause
   ];
@@ -684,6 +691,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause
@@ -700,6 +708,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1133,6 +1142,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1163,6 +1173,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1176,6 +1187,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1349,6 +1361,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1372,6 +1385,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1402,6 +1416,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1427,6 +1442,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1463,6 +1479,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1492,6 +1509,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1530,6 +1548,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1741,6 +1760,7 @@
   let allowedClauses = [
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1790,6 +1810,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1836,6 +1857,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
Index: flang/lib/Semantics/check-omp-structure.cpp
===
--- flang/lib/Semantics/check-omp-structure.cpp
+++ flang/lib/Semantics/check-omp-structure.cpp
@@ -1683,6 +1683,7 @@
 CHECK_SIMPLE_CLAUSE(Threads, OMPC_threads)
 CHECK_SIMPLE_CLAUSE(Inbranch, OMPC_inbranch)
 CHECK_SIMPLE_CLAUSE(IsDevicePtr, OMPC_is_device_ptr)
+CHECK_SIMPLE_CLAUSE(HasDeviceAddr, OMPC_has_device_addr)
 CHECK_SIMPLE_CLAUSE(Link, OMPC_link)
 CHECK_SIMPLE_CLAUSE(Indirect, OMPC_indirect)
 CHECK_SIMPLE_CLAUSE(Mergeable, OMPC_mergeable)
Index: cl

[PATCH] D123402: [clang][OpenMP5.1] Initial parsing/sema for has_device_addr

2022-04-08 Thread Jennifer Yu via Phabricator via cfe-commits
jyu2 updated this revision to Diff 421657.
jyu2 added a comment.

Add test in cfg-openmp.cpp


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D123402

Files:
  clang/include/clang/AST/OpenMPClause.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/OpenMPClause.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/Basic/OpenMPKinds.cpp
  clang/lib/CodeGen/CGStmtOpenMP.cpp
  clang/lib/Parse/ParseOpenMP.cpp
  clang/lib/Sema/SemaOpenMP.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/test/Analysis/cfg-openmp.cpp
  clang/test/OpenMP/target_has_device_addr_ast_print.cpp
  clang/test/OpenMP/target_has_device_addr_messages.cpp
  clang/tools/libclang/CIndex.cpp
  flang/lib/Semantics/check-omp-structure.cpp
  llvm/include/llvm/Frontend/OpenMP/OMP.td

Index: llvm/include/llvm/Frontend/OpenMP/OMP.td
===
--- llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -253,6 +253,11 @@
   let flangClass = "Name";
   let isValueList = true;
 }
+def OMPC_HasDeviceAddr : Clause<"has_device_addr"> {
+  let clangClass = "OMPHasDeviceAddrClause";
+  let flangClass = "Name";
+  let isValueList = true;
+}
 def OMPC_TaskReduction : Clause<"task_reduction"> {
   let clangClass = "OMPTaskReductionClause";
   let flangClass = "OmpReductionClause";
@@ -556,6 +561,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause
@@ -652,6 +658,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause
   ];
@@ -684,6 +691,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause
@@ -700,6 +708,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1133,6 +1142,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1163,6 +1173,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1176,6 +1187,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1349,6 +1361,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1372,6 +1385,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1402,6 +1416,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1427,6 +1442,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1463,6 +1479,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1492,6 +1509,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1530,6 +1548,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1741,6 +1760,7 @@
   let allowedClauses = [
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1790,6 +1810,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
@@ -1836,6 +1857,7 @@
 VersionedClause,
 VersionedClause,
 VersionedClause,
+VersionedClause,
 VersionedClause,
 VersionedClause,
 VersionedClause,
Index: flang/lib/Semantics/check-omp-structure.cpp
===
--- flang/lib/Semantics/check-omp-structure.cpp
+++ flang/lib/Semantics/check-omp-structure.cpp
@@ -1683,6 +1683,7 @@
 CHECK_SIMPLE_CLAUSE(Threads, OMPC_threads)
 CHECK_SIMPLE_CLAUSE(Inbranch, OMPC_inbranch)
 CHECK_SIMPLE_CLAUSE(IsDevicePtr, OMPC_is_device_ptr)
+CHECK_SIMPLE_CLAUSE(HasDeviceAddr, OMPC_has_device_addr)
 CHECK_SIMPLE_CLAUSE(Link, OMPC_link)
 CHECK_SIMPLE_C

  1   2   3   4   >