-
Notifications
You must be signed in to change notification settings - Fork 342
Implement a warning that detects Swift compile units that were compiled with #3361
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
Changes from all commits
17eecb2
6ce519e
8d10843
d0e1226
639b9f6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -609,52 +609,45 @@ bool DWARFUnit::DW_AT_decl_file_attributes_are_invalid() { | |
} | ||
|
||
bool DWARFUnit::Supports_unnamed_objc_bitfields() { | ||
if (GetProducer() == eProducerClang) { | ||
const uint32_t major_version = GetProducerVersionMajor(); | ||
return major_version > 425 || | ||
(major_version == 425 && GetProducerVersionUpdate() >= 13); | ||
} | ||
return true; // Assume all other compilers didn't have incorrect ObjC bitfield | ||
// info | ||
if (GetProducer() == eProducerClang) | ||
return GetProducerVersion() >= llvm::VersionTuple(425, 0, 13); | ||
// Assume all other compilers didn't have incorrect ObjC bitfield info. | ||
return true; | ||
Comment on lines
+612
to
+615
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why can't this live upstream? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a cherry-pick. |
||
} | ||
|
||
void DWARFUnit::ParseProducerInfo() { | ||
m_producer_version_major = UINT32_MAX; | ||
m_producer_version_minor = UINT32_MAX; | ||
m_producer_version_update = UINT32_MAX; | ||
|
||
m_producer = eProducerOther; | ||
const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly(); | ||
if (die) { | ||
|
||
const char *producer_cstr = | ||
die->GetAttributeValueAsString(this, DW_AT_producer, nullptr); | ||
if (producer_cstr) { | ||
RegularExpression llvm_gcc_regex( | ||
llvm::StringRef("^4\\.[012]\\.[01] \\(Based on Apple " | ||
"Inc\\. build [0-9]+\\) \\(LLVM build " | ||
"[\\.0-9]+\\)$")); | ||
if (llvm_gcc_regex.Execute(llvm::StringRef(producer_cstr))) { | ||
m_producer = eProducerLLVMGCC; | ||
} else if (strstr(producer_cstr, "clang")) { | ||
static RegularExpression g_clang_version_regex( | ||
llvm::StringRef("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)")); | ||
llvm::SmallVector<llvm::StringRef, 4> matches; | ||
if (g_clang_version_regex.Execute(llvm::StringRef(producer_cstr), | ||
&matches)) { | ||
m_producer_version_major = | ||
StringConvert::ToUInt32(matches[1].str().c_str(), UINT32_MAX, 10); | ||
m_producer_version_minor = | ||
StringConvert::ToUInt32(matches[2].str().c_str(), UINT32_MAX, 10); | ||
m_producer_version_update = | ||
StringConvert::ToUInt32(matches[3].str().c_str(), UINT32_MAX, 10); | ||
} | ||
m_producer = eProducerClang; | ||
} else if (strstr(producer_cstr, "GNU")) | ||
m_producer = eProducerGCC; | ||
} | ||
if (!die) | ||
return; | ||
|
||
llvm::StringRef producer( | ||
die->GetAttributeValueAsString(this, DW_AT_producer, nullptr)); | ||
if (producer.empty()) | ||
return; | ||
|
||
static RegularExpression g_swiftlang_version_regex( | ||
llvm::StringRef(R"(swiftlang-([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?))")); | ||
static RegularExpression g_clang_version_regex( | ||
llvm::StringRef(R"(clang-([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?))")); | ||
static RegularExpression g_llvm_gcc_regex( | ||
llvm::StringRef(R"(4\.[012]\.[01] )" | ||
R"(\(Based on Apple Inc\. build [0-9]+\) )" | ||
R"(\(LLVM build [\.0-9]+\)$)")); | ||
|
||
llvm::SmallVector<llvm::StringRef, 3> matches; | ||
if (g_swiftlang_version_regex.Execute(producer, &matches)) { | ||
m_producer_version.tryParse(matches[1]); | ||
m_producer = eProducerSwift; | ||
} else if (producer.contains("clang")) { | ||
if (g_clang_version_regex.Execute(producer, &matches)) | ||
m_producer_version.tryParse(matches[1]); | ||
m_producer = eProducerClang; | ||
} else if (producer.contains("GNU")) { | ||
m_producer = eProducerGCC; | ||
} else if (g_llvm_gcc_regex.Execute(producer)) { | ||
m_producer = eProducerLLVMGCC; | ||
} | ||
if (m_producer == eProducerInvalid) | ||
m_producer = eProcucerOther; | ||
} | ||
|
||
DWARFProducer DWARFUnit::GetProducer() { | ||
|
@@ -663,22 +656,10 @@ DWARFProducer DWARFUnit::GetProducer() { | |
return m_producer; | ||
} | ||
|
||
uint32_t DWARFUnit::GetProducerVersionMajor() { | ||
if (m_producer_version_major == 0) | ||
ParseProducerInfo(); | ||
return m_producer_version_major; | ||
} | ||
|
||
uint32_t DWARFUnit::GetProducerVersionMinor() { | ||
if (m_producer_version_minor == 0) | ||
ParseProducerInfo(); | ||
return m_producer_version_minor; | ||
} | ||
|
||
uint32_t DWARFUnit::GetProducerVersionUpdate() { | ||
if (m_producer_version_update == 0) | ||
llvm::VersionTuple DWARFUnit::GetProducerVersion() { | ||
if (m_producer_version.empty()) | ||
ParseProducerInfo(); | ||
return m_producer_version_update; | ||
return m_producer_version; | ||
} | ||
|
||
uint64_t DWARFUnit::GetDWARFLanguageType() { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -241,6 +241,9 @@ let Definition = "process" in { | |
def WarningUnsupportedLanguage: Property<"unsupported-language-warnings", "Boolean">, | ||
DefaultTrue, | ||
Desc<"If true, warn when stopped in code that is written in a source language that LLDB does not support.">; | ||
def WarningToolchainMismatch: Property<"toolchain-mismatch-warnings", "Boolean">, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Which scenarios would people want this off? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any warning that potentially prints on every frame should be switchable. More specifically, I can see how this warning gets annoying when you use LLDB to debug or symbolicate crashes of previously built production software where you just don't have access to a historical matching LLDB. |
||
DefaultTrue, | ||
Desc<"If true, warn when stopped in code that was compiled by a Swift compiler different from the one embedded in LLDB.">; | ||
def StopOnExec: Property<"stop-on-exec", "Boolean">, | ||
Global, | ||
DefaultTrue, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# REQUIRES: swift | ||
|
||
# Tests that a warning is printed when stopped in a Swift frame | ||
# compiled by a different Swift compiler than the one embedded in LLDB. | ||
|
||
# RUN: rm -rf %t && mkdir %t && cd %t | ||
# RUN: %target-swiftc -g \ | ||
# RUN: -module-cache-path %t/cache %S/Inputs/main.swift \ | ||
# RUN: -module-name main -o %t/a.ll -emit-ir | ||
# RUN: sed -i -e 's/producer: "[^"]*Swift [^"]*"/producer: "Future Swift (swiftlang-9999.8.7.6)"/g' %t/a.ll | ||
# RUN: %clang_host -c %t/a.ll -o %t/a.o | ||
# RUN: llvm-dwarfdump -r 0 %t/a.o | grep -q swiftlang-9999 | ||
# RUN: %target-swiftc \ | ||
# RUN: -module-cache-path %t/cache \ | ||
# RUN: %t/a.o -o %t/a.out | ||
# RUN: %lldb %t/a.out -s %s 2>&1 | FileCheck %s | ||
|
||
# Sanity check: Swift | ||
# RUN: %target-swiftc -g \ | ||
# RUN: -module-cache-path %t/cache %S/Inputs/main.swift \ | ||
# RUN: -module-name main -o %t/good.out | ||
# RUN: %lldb %t/good.out -s %s 2>&1 | FileCheck %s --check-prefix=SANITY | ||
|
||
# Sanity check: Clang | ||
# RUN: %clang_host -g \ | ||
# RUN: %S/../Driver/Inputs/hello.cpp \ | ||
# RUN: -o %t/clang.out | ||
# RUN: %lldb %t/clang.out -s %s 2>&1 | FileCheck %s --check-prefix=SANITY | ||
|
||
b main | ||
run | ||
quit | ||
|
||
# The {{ }} avoids accidentally matching the input script! | ||
# CHECK: {{a\.out}} was compiled with a Swift compiler from a different toolchain. | ||
# CHECK: stop reason{{ = }}breakpoint | ||
# SANITY-NOT: {{a\.out}} was compiled with a Swift compiler from a different toolchain. | ||
# SANITY: stop reason{{ = }}breakpoint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a follow up patch, can we get rid of this function and the
PrintWarning.*
ones below by moving them into the language plugin?