spyffe created this revision.
spyffe added reviewers: bruno, akyrtzi, a.sidorin.
spyffe added a subscriber: cfe-commits.

When the `ASTImporter`imports a source location, it avoids importing macro 
expansions by calling `getSpellingLoc()`.  That's great in most cases, but for 
macros defined in the '<built-in>' source file, the source file is invalid and 
does not import correctly, causing an assertion failure (the assertion is 
`Invalid SLocOffset or bad function choice`).

A more reliable way to avoid this is to use `getFileLoc()`, which does not 
return built-in locations.  This avoids the crash but still preserves valid 
source locations.

I've added a testcase that covers the previously crashing scenario.


https://reviews.llvm.org/D26054

Files:
  lib/AST/ASTImporter.cpp
  test/ASTMerge/Inputs/macro.modulemap
  test/ASTMerge/Inputs/macro1.h
  test/ASTMerge/Inputs/macro1.m
  test/ASTMerge/Inputs/macro2.m
  test/ASTMerge/macro.m


Index: test/ASTMerge/macro.m
===================================================================
--- test/ASTMerge/macro.m
+++ test/ASTMerge/macro.m
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/cache
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache 
-fmodule-map-file=%S/Inputs/macro.modulemap -I%S/Inputs -emit-pch -o %t.1.ast 
%S/Inputs/macro1.m
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache 
-fmodule-map-file=%S/Inputs/macro.modulemap -I%S/Inputs -emit-pch -o %t.2.ast 
%S/Inputs/macro2.m
+// RUN: %clang_cc1 -fmodules -ast-merge %t.1.ast -ast-merge %t.2.ast 
-fsyntax-only -verify %s
+// expected-no-diagnostics
Index: test/ASTMerge/Inputs/macro2.m
===================================================================
--- test/ASTMerge/Inputs/macro2.m
+++ test/ASTMerge/Inputs/macro2.m
@@ -0,0 +1,5 @@
+void foo();
+
+void bar() {
+  foo();
+}
Index: test/ASTMerge/Inputs/macro1.m
===================================================================
--- test/ASTMerge/Inputs/macro1.m
+++ test/ASTMerge/Inputs/macro1.m
@@ -0,0 +1,5 @@
+@import macro1;
+
+void foo() {
+  maybeNull(0, 0);
+}
Index: test/ASTMerge/Inputs/macro1.h
===================================================================
--- test/ASTMerge/Inputs/macro1.h
+++ test/ASTMerge/Inputs/macro1.h
@@ -0,0 +1,5 @@
+typedef void *VoidRef;
+
+void maybeNull(
+  int i,
+  __nullable VoidRef *__nullable);
Index: test/ASTMerge/Inputs/macro.modulemap
===================================================================
--- test/ASTMerge/Inputs/macro.modulemap
+++ test/ASTMerge/Inputs/macro.modulemap
@@ -0,0 +1,4 @@
+module macro1 [extern_c] {
+  header "macro1.h"
+  export *
+}
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -6946,7 +6946,7 @@
   // For now, map everything down to its spelling location, so that we
   // don't have to import macro expansions.
   // FIXME: Import macro expansions!
-  FromLoc = FromSM.getSpellingLoc(FromLoc);
+  FromLoc = FromSM.getFileLoc(FromLoc);
   std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
   SourceManager &ToSM = ToContext.getSourceManager();
   FileID ToFileID = Import(Decomposed.first);


Index: test/ASTMerge/macro.m
===================================================================
--- test/ASTMerge/macro.m
+++ test/ASTMerge/macro.m
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/cache
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -fmodule-map-file=%S/Inputs/macro.modulemap -I%S/Inputs -emit-pch -o %t.1.ast %S/Inputs/macro1.m
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -fmodule-map-file=%S/Inputs/macro.modulemap -I%S/Inputs -emit-pch -o %t.2.ast %S/Inputs/macro2.m
+// RUN: %clang_cc1 -fmodules -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -verify %s
+// expected-no-diagnostics
Index: test/ASTMerge/Inputs/macro2.m
===================================================================
--- test/ASTMerge/Inputs/macro2.m
+++ test/ASTMerge/Inputs/macro2.m
@@ -0,0 +1,5 @@
+void foo();
+
+void bar() {
+  foo();
+}
Index: test/ASTMerge/Inputs/macro1.m
===================================================================
--- test/ASTMerge/Inputs/macro1.m
+++ test/ASTMerge/Inputs/macro1.m
@@ -0,0 +1,5 @@
+@import macro1;
+
+void foo() {
+  maybeNull(0, 0);
+}
Index: test/ASTMerge/Inputs/macro1.h
===================================================================
--- test/ASTMerge/Inputs/macro1.h
+++ test/ASTMerge/Inputs/macro1.h
@@ -0,0 +1,5 @@
+typedef void *VoidRef;
+
+void maybeNull(
+  int i,
+  __nullable VoidRef *__nullable);
Index: test/ASTMerge/Inputs/macro.modulemap
===================================================================
--- test/ASTMerge/Inputs/macro.modulemap
+++ test/ASTMerge/Inputs/macro.modulemap
@@ -0,0 +1,4 @@
+module macro1 [extern_c] {
+  header "macro1.h"
+  export *
+}
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -6946,7 +6946,7 @@
   // For now, map everything down to its spelling location, so that we
   // don't have to import macro expansions.
   // FIXME: Import macro expansions!
-  FromLoc = FromSM.getSpellingLoc(FromLoc);
+  FromLoc = FromSM.getFileLoc(FromLoc);
   std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
   SourceManager &ToSM = ToContext.getSourceManager();
   FileID ToFileID = Import(Decomposed.first);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to