[flang-commits] [flang] 85d9745 - [flang] Fix a crash when creating generics from a copy

Pete Steinfeld via flang-commits flang-commits at lists.llvm.org
Thu Jul 9 15:50:47 PDT 2020


Author: Pete Steinfeld
Date: 2020-07-09T15:49:45-07:00
New Revision: 85d9745c83a105692a8784b8c8a83482696b4900

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

LOG: [flang] Fix a crash when creating generics from a copy

Summary:
When a program unit creates a generic based on one defined in a module, the
function `CopyFrom()` is called to create the `GenericDetails`.  This function
copied the `specificProcs_` but failed to copy the `bindingNames_`.  If the
function `CheckGeneric()` then gets called, it tries to index into the empty
binding names and causes the crash.

I fixed this by adding code to `CopyFrom()` to copy the binding names.

I also added a test that causes the crash.

Reviewers: klausler, tskeith, DavidTruby

Subscribers: llvm-commits

Tags: #llvm, #flang

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

Added: 
    

Modified: 
    flang/include/flang/Semantics/symbol.h
    flang/lib/Semantics/symbol.cpp
    flang/test/Semantics/resolve53.f90

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Semantics/symbol.h b/flang/include/flang/Semantics/symbol.h
index 0de6e462133d..227f951aef5f 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -423,7 +423,6 @@ struct GenericKind {
 class GenericDetails {
 public:
   GenericDetails() {}
-  GenericDetails(const SymbolVector &specificProcs);
 
   GenericKind kind() const { return kind_; }
   void set_kind(GenericKind kind) { kind_ = kind; }

diff  --git a/flang/lib/Semantics/symbol.cpp b/flang/lib/Semantics/symbol.cpp
index 998342667003..a7e2696518ff 100644
--- a/flang/lib/Semantics/symbol.cpp
+++ b/flang/lib/Semantics/symbol.cpp
@@ -150,9 +150,6 @@ UseErrorDetails &UseErrorDetails::add_occurrence(
   return *this;
 }
 
-GenericDetails::GenericDetails(const SymbolVector &specificProcs)
-    : specificProcs_{specificProcs} {}
-
 void GenericDetails::AddSpecificProc(
     const Symbol &proc, SourceName bindingName) {
   specificProcs_.push_back(proc);
@@ -186,6 +183,8 @@ Symbol *GenericDetails::CheckSpecific() {
 }
 
 void GenericDetails::CopyFrom(const GenericDetails &from) {
+  CHECK(specificProcs_.size() == bindingNames_.size());
+  CHECK(from.specificProcs_.size() == from.bindingNames_.size());
   if (from.specific_) {
     CHECK(!specific_ || specific_ == from.specific_);
     specific_ = from.specific_;
@@ -194,11 +193,13 @@ void GenericDetails::CopyFrom(const GenericDetails &from) {
     CHECK(!derivedType_ || derivedType_ == from.derivedType_);
     derivedType_ = from.derivedType_;
   }
-  for (const Symbol &symbol : from.specificProcs_) {
+  for (std::size_t i{0}; i < from.specificProcs_.size(); ++i) {
     if (std::find_if(specificProcs_.begin(), specificProcs_.end(),
-            [&](const Symbol &mySymbol) { return &mySymbol == &symbol; }) ==
-        specificProcs_.end()) {
-      specificProcs_.push_back(symbol);
+            [&](const Symbol &mySymbol) {
+              return &mySymbol == &*from.specificProcs_[i];
+            }) == specificProcs_.end()) {
+      specificProcs_.push_back(from.specificProcs_[i]);
+      bindingNames_.push_back(from.bindingNames_[i]);
     }
   }
 }

diff  --git a/flang/test/Semantics/resolve53.f90 b/flang/test/Semantics/resolve53.f90
index 69c13dbe52eb..acb27c8575b7 100644
--- a/flang/test/Semantics/resolve53.f90
+++ b/flang/test/Semantics/resolve53.f90
@@ -457,3 +457,26 @@ integer function f3(i, j)
     integer :: i, j
   end
 end
+
+module m20
+  interface operator(.not.)
+    real function f(x)
+      character(*),intent(in) :: x
+    end function
+  end interface
+  interface operator(+)
+    procedure f
+  end interface
+end module
+
+subroutine s1()
+  use m20
+  interface operator(.not.)
+    !ERROR: Procedure 'f' is already specified in generic 'operator(.not.)'
+    procedure f
+  end interface
+  interface operator(+)
+    !ERROR: Procedure 'f' is already specified in generic 'operator(+)'
+    procedure f
+  end interface
+end subroutine s1


        


More information about the flang-commits mailing list