Skip to content

[Clang] Report an error and crash on source location exhaustion in macros #69908

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 23, 2023

Conversation

ilya-biryukov
Copy link
Contributor

createExpansionLocImpl has an assert that checks if we ran out of source locations. We have observed this happening on real code and in release builds the assertion does not fire and the compiler just keeps running indefinitely without giving any indication that something went wrong.

Diagnose this problem and reliably crash to make sure the problem is easy to detect.

I have also tried:

  • returning invalid source locations,
  • reporting sloc address space usage on error.

Both caused the compiler to run indefinitely. It would be nice to dig further why that happens, but until then crashing seems like a better alternative.

@ilya-biryukov ilya-biryukov added the clang Clang issues not falling into any other category label Oct 23, 2023
@ilya-biryukov ilya-biryukov self-assigned this Oct 23, 2023
@llvmbot llvmbot added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Oct 23, 2023
@llvmbot
Copy link
Member

llvmbot commented Oct 23, 2023

@llvm/pr-subscribers-clang

Author: Ilya Biryukov (ilya-biryukov)

Changes

createExpansionLocImpl has an assert that checks if we ran out of source locations. We have observed this happening on real code and in release builds the assertion does not fire and the compiler just keeps running indefinitely without giving any indication that something went wrong.

Diagnose this problem and reliably crash to make sure the problem is easy to detect.

I have also tried:

  • returning invalid source locations,
  • reporting sloc address space usage on error.

Both caused the compiler to run indefinitely. It would be nice to dig further why that happens, but until then crashing seems like a better alternative.


Full diff: https://github.com/llvm/llvm-project/pull/69908.diff

2 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticCommonKinds.td (+2)
  • (modified) clang/lib/Basic/SourceManager.cpp (+7-4)
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index f2df283c74829f6..080748a73571690 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -356,6 +356,8 @@ def err_file_modified : Error<
   "file '%0' modified since it was first processed">, DefaultFatal;
 def err_file_too_large : Error<
   "sorry, unsupported: file '%0' is too large for Clang to process">;
+def err_expansions_too_large : Error<
+  "sorry, the translation unit is too large: ran out of source locations while processing a macro expansion">, DefaultFatal;
 def err_include_too_large : Error<
   "sorry, this include generates a translation unit too large for"
   " Clang to process.">, DefaultFatal;
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
index c44ecacb3de3a10..dcf18c47cbaf9ae 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -663,10 +663,13 @@ SourceManager::createExpansionLocImpl(const ExpansionInfo &Info,
     return SourceLocation::getMacroLoc(LoadedOffset);
   }
   LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
-  // FIXME: Produce a proper diagnostic for this case.
-  assert(NextLocalOffset + Length + 1 > NextLocalOffset &&
-         NextLocalOffset + Length + 1 <= CurrentLoadedOffset &&
-         "Ran out of source locations!");
+  if (NextLocalOffset + Length + 1 <= NextLocalOffset ||
+      NextLocalOffset + Length + 1 > CurrentLoadedOffset) {
+    Diag.Report(Info.getExpansionLocStart(), diag::err_expansions_too_large);
+    Diag.Report(Info.getExpansionLocStart(), diag::remark_sloc_usage);
+    noteSLocAddressSpaceUsage(Diag);
+    return SourceLocation();
+  }
   // See createFileID for that +1.
   NextLocalOffset += Length + 1;
   return SourceLocation::getMacroLoc(NextLocalOffset - (Length + 1));

Copy link
Collaborator

@sam-mccall sam-mccall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upgrading this from assert to diag+crash makes sense to me.
Am I missing where the crash happens though?

Copy link
Collaborator

@sam-mccall sam-mccall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG but would be great if we could fix the note!

…on in macros

`createExpansionLocImpl` has an assert that checks if we ran out of source
locations. We have observed this happening on real code and in release builds
the assertion does not fire and the compiler just keeps running
indefinitely without giving any indication that something went wrong.

Diagnose this problem and reliably crash to make sure the problem is easy to
detect.

I have also tried:
- returning invalid source locations,
- reporting sloc address space usage on error.

Both caused the compiler to run indefinitely. It would be nice to dig
further why that happens, but until then crashing seems like a better
alternative.
…xhaustion in macros

- Unify the error when running out of slocs in includes and macro
- Use `SourceLocation()` instead of `Info.getSpellingLoc()` to avoid printing
  the location, which also causes Clang to run indefinitely.
…xhaustion in macros

- Add a comment about using SourceLocation()
…xhaustion in macros

- Update test for sloc overflow
@ilya-biryukov
Copy link
Contributor Author

I will land this, but happy to follow up if Aaron or anyone else will have comments.

@ilya-biryukov ilya-biryukov merged commit 324d1bb into llvm:main Oct 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants