Skip to content

Commit 0c43e50

Browse files
committed
Fix stack-use-after-scope issue by making LangOptions parameter non temporary (carbon-language#5586)
The parameter is kept by reference. Added a test that accesses `LangOptions` and crashes without this fix. Part of carbon-language#5176.
1 parent ab607c0 commit 0c43e50

File tree

2 files changed

+78
-4
lines changed

2 files changed

+78
-4
lines changed

toolchain/check/import_cpp.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,11 @@ class CarbonClangDiagnosticConsumer : public clang::DiagnosticConsumer {
8787
info.FormatDiagnostic(message);
8888

8989
RawStringOstream diagnostics_stream;
90+
// TODO: Consider allowing setting `LangOptions` or use
91+
// `ASTContext::getLangOptions()`.
92+
clang::LangOptions lang_options;
9093
clang::TextDiagnostic text_diagnostic(
91-
diagnostics_stream,
92-
// TODO: Consider allowing setting `LangOptions` or use
93-
// `ASTContext::getLangOptions()`.
94-
clang::LangOptions(),
94+
diagnostics_stream, lang_options,
9595
// TODO: Consider allowing setting `DiagnosticOptions` or use
9696
// `ASTUnit::getDiagnostics().::getLangOptions().getDiagnosticOptions()`.
9797
new clang::DiagnosticOptions());

toolchain/check/testdata/interop/cpp/no_prelude/cpp_diagnostics.carbon

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,47 @@ library "[[@TEST_NAME]]"; // Trailing comment
450450
// CHECK:STDERR:
451451
import Cpp library "one_warning.h";
452452

453+
// ============================================================================
454+
// Diagnostic accesses LangOptions
455+
// ============================================================================
456+
457+
// --- lang_options.h
458+
459+
template <>
460+
// CHECK:STDERR: ./lang_options.h:[[@LINE+6]]: error: C++:
461+
// CHECK:STDERR: In file included from fail_import_lang_options.carbon.generated.cpp_imports.h:1:
462+
// CHECK:STDERR: ./lang_options.h:[[@LINE+4]]:6: error: no variable template matches specialization
463+
// CHECK:STDERR: 9 | auto foo<int> -> void;
464+
// CHECK:STDERR: | ^
465+
// CHECK:STDERR: [CppInteropParseError]
466+
auto foo<int> -> void;
467+
468+
// --- fail_import_lang_options.carbon
469+
470+
library "[[@TEST_NAME]]";
471+
472+
// CHECK:STDERR: fail_import_lang_options.carbon:[[@LINE+15]]:1: note: in `Cpp` import [InCppImport]
473+
// CHECK:STDERR: import Cpp library "lang_options.h";
474+
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
475+
// CHECK:STDERR:
476+
// CHECK:STDERR: ./lang_options.h:9: error: C++:
477+
// CHECK:STDERR: In file included from fail_import_lang_options.carbon.generated.cpp_imports.h:1:
478+
// CHECK:STDERR: ./lang_options.h:9:14: error: expected ';' after top level declarator
479+
// CHECK:STDERR: 9 | auto foo<int> -> void;
480+
// CHECK:STDERR: | ^
481+
// CHECK:STDERR: | ;
482+
// CHECK:STDERR: [CppInteropParseError]
483+
// CHECK:STDERR: fail_import_lang_options.carbon:[[@LINE+4]]:1: note: in `Cpp` import [InCppImport]
484+
// CHECK:STDERR: import Cpp library "lang_options.h";
485+
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
486+
// CHECK:STDERR:
487+
import Cpp library "lang_options.h";
488+
489+
fn F() {
490+
Cpp.foo();
491+
}
492+
493+
453494
// CHECK:STDOUT: --- fail_import_cpp_file_with_one_error.carbon
454495
// CHECK:STDOUT:
455496
// CHECK:STDOUT: imports {
@@ -645,3 +686,36 @@ import Cpp library "one_warning.h";
645686
// CHECK:STDOUT: }
646687
// CHECK:STDOUT: }
647688
// CHECK:STDOUT:
689+
// CHECK:STDOUT: --- fail_import_lang_options.carbon
690+
// CHECK:STDOUT:
691+
// CHECK:STDOUT: constants {
692+
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
693+
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
694+
// CHECK:STDOUT: }
695+
// CHECK:STDOUT:
696+
// CHECK:STDOUT: imports {
697+
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
698+
// CHECK:STDOUT: .foo = <poisoned>
699+
// CHECK:STDOUT: import Cpp//...
700+
// CHECK:STDOUT: has_error
701+
// CHECK:STDOUT: }
702+
// CHECK:STDOUT: }
703+
// CHECK:STDOUT:
704+
// CHECK:STDOUT: file {
705+
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
706+
// CHECK:STDOUT: .Cpp = imports.%Cpp
707+
// CHECK:STDOUT: .F = %F.decl
708+
// CHECK:STDOUT: }
709+
// CHECK:STDOUT: %Cpp.import_cpp = import_cpp {
710+
// CHECK:STDOUT: import Cpp "lang_options.h"
711+
// CHECK:STDOUT: }
712+
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {}
713+
// CHECK:STDOUT: }
714+
// CHECK:STDOUT:
715+
// CHECK:STDOUT: fn @F() {
716+
// CHECK:STDOUT: !entry:
717+
// CHECK:STDOUT: %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
718+
// CHECK:STDOUT: %foo.ref: <error> = name_ref foo, <error> [concrete = <error>]
719+
// CHECK:STDOUT: return
720+
// CHECK:STDOUT: }
721+
// CHECK:STDOUT:

0 commit comments

Comments
 (0)