[PATCH] D61424: [ASTImporter] Fix inequivalence of unresolved exception spec

2019-05-08 Thread Gabor Marton via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL360261: [ASTImporter] Fix inequivalence of unresolved 
exception spec (authored by martong, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D61424?vs=198626=198665#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D61424

Files:
  cfe/trunk/lib/AST/ASTImporter.cpp
  cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp


Index: cfe/trunk/lib/AST/ASTImporter.cpp
===
--- cfe/trunk/lib/AST/ASTImporter.cpp
+++ cfe/trunk/lib/AST/ASTImporter.cpp
@@ -3130,6 +3130,11 @@
 auto *Recent = const_cast(
   FoundByLookup->getMostRecentDecl());
 ToFunction->setPreviousDecl(Recent);
+// FIXME Probably we should merge exception specifications.  E.g. In the
+// "To" context the existing function may have exception specification with
+// noexcept-unevaluated, while the newly imported function may have an
+// evaluated noexcept.  A call to adjustExceptionSpec() on the imported
+// decl and its redeclarations may be required.
   }
 
   // Import Ctor initializers.
Index: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
===
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
@@ -322,6 +322,36 @@
   return true;
 }
 
+/// Check the equivalence of exception specifications.
+static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext ,
+  const FunctionProtoType *Proto1,
+  const FunctionProtoType *Proto2) {
+
+  auto Spec1 = Proto1->getExceptionSpecType();
+  auto Spec2 = Proto2->getExceptionSpecType();
+
+  if (isUnresolvedExceptionSpec(Spec1) || isUnresolvedExceptionSpec(Spec2))
+return true;
+
+  if (Spec1 != Spec2)
+return false;
+  if (Spec1 == EST_Dynamic) {
+if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
+  return false;
+for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
+  if (!IsStructurallyEquivalent(Context, Proto1->getExceptionType(I),
+Proto2->getExceptionType(I)))
+return false;
+}
+  } else if (isComputedNoexcept(Spec1)) {
+if (!IsStructurallyEquivalent(Context, Proto1->getNoexceptExpr(),
+  Proto2->getNoexceptExpr()))
+  return false;
+  }
+
+  return true;
+}
+
 /// Determine structural equivalence of two types.
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
  QualType T1, QualType T2) {
@@ -536,24 +566,8 @@
 cast(OrigT1.getDesugaredType(Context.FromCtx));
 const auto *OrigProto2 =
 cast(OrigT2.getDesugaredType(Context.ToCtx));
-auto Spec1 = OrigProto1->getExceptionSpecType();
-auto Spec2 = OrigProto2->getExceptionSpecType();
-
-if (Spec1 != Spec2)
+if (!IsEquivalentExceptionSpec(Context, OrigProto1, OrigProto2))
   return false;
-if (Spec1 == EST_Dynamic) {
-  if (OrigProto1->getNumExceptions() != OrigProto2->getNumExceptions())
-return false;
-  for (unsigned I = 0, N = OrigProto1->getNumExceptions(); I != N; ++I) {
-if (!IsStructurallyEquivalent(Context, OrigProto1->getExceptionType(I),
-  OrigProto2->getExceptionType(I)))
-  return false;
-  }
-} else if (isComputedNoexcept(Spec1)) {
-  if (!IsStructurallyEquivalent(Context, OrigProto1->getNoexceptExpr(),
-OrigProto2->getNoexceptExpr()))
-return false;
-}
 
 // Fall through to check the bits common with FunctionNoProtoType.
 LLVM_FALLTHROUGH;


Index: cfe/trunk/lib/AST/ASTImporter.cpp
===
--- cfe/trunk/lib/AST/ASTImporter.cpp
+++ cfe/trunk/lib/AST/ASTImporter.cpp
@@ -3130,6 +3130,11 @@
 auto *Recent = const_cast(
   FoundByLookup->getMostRecentDecl());
 ToFunction->setPreviousDecl(Recent);
+// FIXME Probably we should merge exception specifications.  E.g. In the
+// "To" context the existing function may have exception specification with
+// noexcept-unevaluated, while the newly imported function may have an
+// evaluated noexcept.  A call to adjustExceptionSpec() on the imported
+// decl and its redeclarations may be required.
   }
 
   // Import Ctor initializers.
Index: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
===
--- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
+++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
@@ -322,6 +322,36 @@
   return true;
 }
 
+/// Check the equivalence of 

[PATCH] D61424: [ASTImporter] Fix inequivalence of unresolved exception spec

2019-05-08 Thread Gabor Marton via Phabricator via cfe-commits
martong updated this revision to Diff 198626.
martong marked 2 inline comments as done.
martong added a comment.

- Improve and fix typo in comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D61424

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ASTStructuralEquivalence.cpp


Index: clang/lib/AST/ASTStructuralEquivalence.cpp
===
--- clang/lib/AST/ASTStructuralEquivalence.cpp
+++ clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -322,6 +322,36 @@
   return true;
 }
 
+/// Check the equivalence of exception specifications.
+static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext ,
+  const FunctionProtoType *Proto1,
+  const FunctionProtoType *Proto2) {
+
+  auto Spec1 = Proto1->getExceptionSpecType();
+  auto Spec2 = Proto2->getExceptionSpecType();
+
+  if (isUnresolvedExceptionSpec(Spec1) || isUnresolvedExceptionSpec(Spec2))
+return true;
+
+  if (Spec1 != Spec2)
+return false;
+  if (Spec1 == EST_Dynamic) {
+if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
+  return false;
+for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
+  if (!IsStructurallyEquivalent(Context, Proto1->getExceptionType(I),
+Proto2->getExceptionType(I)))
+return false;
+}
+  } else if (isComputedNoexcept(Spec1)) {
+if (!IsStructurallyEquivalent(Context, Proto1->getNoexceptExpr(),
+  Proto2->getNoexceptExpr()))
+  return false;
+  }
+
+  return true;
+}
+
 /// Determine structural equivalence of two types.
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
  QualType T1, QualType T2) {
@@ -536,24 +566,8 @@
 cast(OrigT1.getDesugaredType(Context.FromCtx));
 const auto *OrigProto2 =
 cast(OrigT2.getDesugaredType(Context.ToCtx));
-auto Spec1 = OrigProto1->getExceptionSpecType();
-auto Spec2 = OrigProto2->getExceptionSpecType();
-
-if (Spec1 != Spec2)
+if (!IsEquivalentExceptionSpec(Context, OrigProto1, OrigProto2))
   return false;
-if (Spec1 == EST_Dynamic) {
-  if (OrigProto1->getNumExceptions() != OrigProto2->getNumExceptions())
-return false;
-  for (unsigned I = 0, N = OrigProto1->getNumExceptions(); I != N; ++I) {
-if (!IsStructurallyEquivalent(Context, OrigProto1->getExceptionType(I),
-  OrigProto2->getExceptionType(I)))
-  return false;
-  }
-} else if (isComputedNoexcept(Spec1)) {
-  if (!IsStructurallyEquivalent(Context, OrigProto1->getNoexceptExpr(),
-OrigProto2->getNoexceptExpr()))
-return false;
-}
 
 // Fall through to check the bits common with FunctionNoProtoType.
 LLVM_FALLTHROUGH;
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -3101,6 +3101,11 @@
 auto *Recent = const_cast(
   FoundByLookup->getMostRecentDecl());
 ToFunction->setPreviousDecl(Recent);
+// FIXME Probably we should merge exception specifications.  E.g. In the
+// "To" context the existing function may have exception specification with
+// noexcept-unevaluated, while the newly imported function may have an
+// evaluated noexcept.  A call to adjustExceptionSpec() on the imported
+// decl and its redeclarations may be required.
   }
 
   // Import Ctor initializers.


Index: clang/lib/AST/ASTStructuralEquivalence.cpp
===
--- clang/lib/AST/ASTStructuralEquivalence.cpp
+++ clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -322,6 +322,36 @@
   return true;
 }
 
+/// Check the equivalence of exception specifications.
+static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext ,
+  const FunctionProtoType *Proto1,
+  const FunctionProtoType *Proto2) {
+
+  auto Spec1 = Proto1->getExceptionSpecType();
+  auto Spec2 = Proto2->getExceptionSpecType();
+
+  if (isUnresolvedExceptionSpec(Spec1) || isUnresolvedExceptionSpec(Spec2))
+return true;
+
+  if (Spec1 != Spec2)
+return false;
+  if (Spec1 == EST_Dynamic) {
+if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
+  return false;
+for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
+  if (!IsStructurallyEquivalent(Context, Proto1->getExceptionType(I),
+Proto2->getExceptionType(I)))
+return false;
+}
+  } else if (isComputedNoexcept(Spec1)) {
+if (!IsStructurallyEquivalent(Context, Proto1->getNoexceptExpr(),
+   

[PATCH] D61424: [ASTImporter] Fix inequivalence of unresolved exception spec

2019-05-04 Thread Aleksei Sidorin via Phabricator via cfe-commits
a_sidorin accepted this revision.
a_sidorin added a comment.
This revision is now accepted and ready to land.

Looks good!




Comment at: clang/lib/AST/ASTImporter.cpp:3107
+// noexcept-unevaluated, while the newly imported function may have an
+// evaluated noexcept.
   }

This looks to be true -  a call `adjustExceptionSpec()` on the imported decl 
and its redeclarations can be required. Thank you for noticing this!



Comment at: clang/lib/AST/ASTStructuralEquivalence.cpp:325
 
+/// Check the eqeuivalence of exception specifications.
+static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext ,

equivalence


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D61424



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


[PATCH] D61424: [ASTImporter] Fix inequivalence of unresolved exception spec

2019-05-02 Thread Gabor Marton via Phabricator via cfe-commits
martong created this revision.
martong added reviewers: a_sidorin, shafik.
Herald added subscribers: cfe-commits, gamesh411, Szelethus, dkrupp, rnkovacs.
Herald added a reviewer: a.sidorin.
Herald added a project: clang.

Structural equivalence of methods can falsely report false when the
exception specifier is unresolved (i.e unevaluated or not instantiated).

(This caused one assertion during bitcoin ctu-analysis.)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D61424

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/ASTStructuralEquivalence.cpp


Index: clang/lib/AST/ASTStructuralEquivalence.cpp
===
--- clang/lib/AST/ASTStructuralEquivalence.cpp
+++ clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -322,6 +322,36 @@
   return true;
 }
 
+/// Check the eqeuivalence of exception specifications.
+static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext ,
+  const FunctionProtoType *Proto1,
+  const FunctionProtoType *Proto2) {
+
+  auto Spec1 = Proto1->getExceptionSpecType();
+  auto Spec2 = Proto2->getExceptionSpecType();
+
+  if (isUnresolvedExceptionSpec(Spec1) || isUnresolvedExceptionSpec(Spec2))
+return true;
+
+  if (Spec1 != Spec2)
+return false;
+  if (Spec1 == EST_Dynamic) {
+if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
+  return false;
+for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
+  if (!IsStructurallyEquivalent(Context, Proto1->getExceptionType(I),
+Proto2->getExceptionType(I)))
+return false;
+}
+  } else if (isComputedNoexcept(Spec1)) {
+if (!IsStructurallyEquivalent(Context, Proto1->getNoexceptExpr(),
+  Proto2->getNoexceptExpr()))
+  return false;
+  }
+
+  return true;
+}
+
 /// Determine structural equivalence of two types.
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext ,
  QualType T1, QualType T2) {
@@ -536,24 +566,8 @@
 cast(OrigT1.getDesugaredType(Context.FromCtx));
 const auto *OrigProto2 =
 cast(OrigT2.getDesugaredType(Context.ToCtx));
-auto Spec1 = OrigProto1->getExceptionSpecType();
-auto Spec2 = OrigProto2->getExceptionSpecType();
-
-if (Spec1 != Spec2)
+if (!IsEquivalentExceptionSpec(Context, OrigProto1, OrigProto2))
   return false;
-if (Spec1 == EST_Dynamic) {
-  if (OrigProto1->getNumExceptions() != OrigProto2->getNumExceptions())
-return false;
-  for (unsigned I = 0, N = OrigProto1->getNumExceptions(); I != N; ++I) {
-if (!IsStructurallyEquivalent(Context, OrigProto1->getExceptionType(I),
-  OrigProto2->getExceptionType(I)))
-  return false;
-  }
-} else if (isComputedNoexcept(Spec1)) {
-  if (!IsStructurallyEquivalent(Context, OrigProto1->getNoexceptExpr(),
-OrigProto2->getNoexceptExpr()))
-return false;
-}
 
 // Fall through to check the bits common with FunctionNoProtoType.
 LLVM_FALLTHROUGH;
Index: clang/lib/AST/ASTImporter.cpp
===
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -3101,6 +3101,10 @@
 auto *Recent = const_cast(
   FoundByLookup->getMostRecentDecl());
 ToFunction->setPreviousDecl(Recent);
+// FIXME Should we merge exception specifications?  E.g. In the "To"
+// context the existing function may have exception specification with
+// noexcept-unevaluated, while the newly imported function may have an
+// evaluated noexcept.
   }
 
   // Import Ctor initializers.


Index: clang/lib/AST/ASTStructuralEquivalence.cpp
===
--- clang/lib/AST/ASTStructuralEquivalence.cpp
+++ clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -322,6 +322,36 @@
   return true;
 }
 
+/// Check the eqeuivalence of exception specifications.
+static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext ,
+  const FunctionProtoType *Proto1,
+  const FunctionProtoType *Proto2) {
+
+  auto Spec1 = Proto1->getExceptionSpecType();
+  auto Spec2 = Proto2->getExceptionSpecType();
+
+  if (isUnresolvedExceptionSpec(Spec1) || isUnresolvedExceptionSpec(Spec2))
+return true;
+
+  if (Spec1 != Spec2)
+return false;
+  if (Spec1 == EST_Dynamic) {
+if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
+  return false;
+for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
+  if (!IsStructurallyEquivalent(Context, Proto1->getExceptionType(I),
+Proto2->getExceptionType(I)))
+return false;
+}
+  } else if