llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-static-analyzer-1

Author: Balázs Kéri (balazske)

<details>
<summary>Changes</summary>

Names with "weak" link attribute can have a definition in multiple source 
files. The externalDefMap file used at CTU analysis did not contain information 
about this and using more (weak) definitions with same name was indicated as 
error.

Format of the externalDefMap file is changed in a way that the USR string 
contains a '-' character at the begin if the symbol is weak (this is counted in 
the USR-length value). At non-weak symbols the format remains unchanged. At 
reading the definitions, one of the weak symbols is chosen if there is no 
"strong" definition, otherwise the "strong" is used, and multiple "strong" 
definitions are error (like before).

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


3 Files Affected:

- (modified) clang/lib/CrossTU/CrossTranslationUnit.cpp (+35-6) 
- (added) clang/test/Analysis/ctu/test-weak-sym-1.c (+42) 
- (added) clang/test/Analysis/ctu/test-weak-sym-2.c (+42) 


``````````diff
diff --git a/clang/lib/CrossTU/CrossTranslationUnit.cpp 
b/clang/lib/CrossTU/CrossTranslationUnit.cpp
index 248c6320bc61b..5773e4d2a7813 100644
--- a/clang/lib/CrossTU/CrossTranslationUnit.cpp
+++ b/clang/lib/CrossTU/CrossTranslationUnit.cpp
@@ -179,9 +179,13 @@ std::error_code IndexError::convertToErrorCode() const {
 ///
 /// @param[in]  LineRef     The input CTU index item in format
 ///                         "<USR-Length>:<USR> <File-Path>".
-/// @param[out] LookupName  The lookup name in format "<USR-Length>:<USR>".
+///                         <USR> may contain a '-' at the start which 
indicates
+///                         that the symbol is weak.
+/// @param[out] IsWeak      The weakness status of the symbol.
+/// @param[out] LookupName  The lookup name in format "<USR-Length>:<USR>". The
+///                         optional '-' is removed from it.
 /// @param[out] FilePath    The file path "<File-Path>".
-static bool parseCrossTUIndexItem(StringRef LineRef, StringRef &LookupName,
+static bool parseCrossTUIndexItem(StringRef LineRef, bool &IsWeak, StringRef 
&LookupName,
                                   StringRef &FilePath) {
   // `LineRef` is "<USR-Length>:<USR> <File-Path>" now.
 
@@ -199,6 +203,16 @@ static bool parseCrossTUIndexItem(StringRef LineRef, 
StringRef &LookupName,
   if (USRLength >= LineRef.size() || ' ' != LineRef[USRLength])
     return false;
 
+  // The first character of this USR can be a '-' to indicate weakness of the
+  // symbol. The input USR-length includes this character, it is removed from
+  // the result.
+  char MaybeWeak = LineRef.front();
+  IsWeak = MaybeWeak == '-';
+  if (IsWeak) {
+    LineRef.consume_front(MaybeWeak);
+    --USRLength;
+  }
+
   LookupName = LineRef.substr(0, USRLength);
   FilePath = LineRef.substr(USRLength + 1);
   return true;
@@ -212,12 +226,14 @@ parseCrossTUIndex(StringRef IndexPath) {
                                         IndexPath.str());
 
   llvm::StringMap<std::string> Result;
+  llvm::StringSet<> WeakSyms;
   std::string Line;
   unsigned LineNo = 1;
   while (std::getline(ExternalMapFile, Line)) {
     // Split lookup name and file path
     StringRef LookupName, FilePathInIndex;
-    if (!parseCrossTUIndexItem(Line, LookupName, FilePathInIndex))
+    bool IsWeak;
+    if (!parseCrossTUIndexItem(Line, IsWeak, LookupName, FilePathInIndex))
       return llvm::make_error<IndexError>(
           index_error_code::invalid_index_format, IndexPath.str(), LineNo);
 
@@ -228,9 +244,20 @@ parseCrossTUIndex(StringRef IndexPath) {
     bool InsertionOccurred;
     std::tie(std::ignore, InsertionOccurred) =
         Result.try_emplace(LookupName, FilePath.begin(), FilePath.end());
-    if (!InsertionOccurred)
-      return llvm::make_error<IndexError>(
-          index_error_code::multiple_definitions, IndexPath.str(), LineNo);
+    if (!InsertionOccurred) {
+      if (!IsWeak) {
+        if (!WeakSyms.contains(LookupName)) {
+          return llvm::make_error<IndexError>(
+              index_error_code::multiple_definitions, IndexPath.str(), LineNo);
+        } else {
+          Result[LookupName].assign(FilePath.begin(), FilePath.end());
+          WeakSyms.erase(LookupName);
+        }
+      }
+    } else {
+      if (IsWeak)
+        WeakSyms.insert(LookupName);
+    }
 
     ++LineNo;
   }
@@ -279,6 +306,8 @@ CrossTranslationUnitContext::~CrossTranslationUnitContext() 
{}
 std::optional<std::string>
 CrossTranslationUnitContext::getLookupName(const Decl *D) {
   SmallString<128> DeclUSR;
+  if (D->hasAttr<WeakAttr>())
+    DeclUSR.push_back('-');
   bool Ret = index::generateUSRForDecl(D, DeclUSR);
   if (Ret)
     return {};
diff --git a/clang/test/Analysis/ctu/test-weak-sym-1.c 
b/clang/test/Analysis/ctu/test-weak-sym-1.c
new file mode 100644
index 0000000000000..602f9aa2f752f
--- /dev/null
+++ b/clang/test/Analysis/ctu/test-weak-sym-1.c
@@ -0,0 +1,42 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -x c -emit-pch -o %t/a.c.ast %t/a.c
+// RUN: %clang_cc1 -x c -emit-pch -o %t/b.c.ast %t/b.c
+
+// RUN: %clang_extdef_map %t/a.c %t/b.c -- -c -x c > %t/externalDefMap.tmp1.txt
+// RUN: sed -e 's|\.c$|.c.ast|g' %t/externalDefMap.tmp1.txt > 
%t/externalDefMap.tmp2.txt
+// RUN: sed -e 's|%t\/||g' %t/externalDefMap.tmp2.txt > %t/externalDefMap.txt
+
+// RUN: %clang_cc1 -analyze \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config display-ctu-progress=true \
+// RUN:   -analyzer-config ctu-dir=%t \
+// RUN:   -verify %t/main.c 2>&1 | FileCheck %s
+
+//--- main.c
+
+// expected-no-diagnostics
+// CHECK: CTU loaded AST file: b.c.ast
+
+int fn(void);
+
+int main(int argc, char* argv[]) {
+  return fn();
+}
+
+//--- a.c
+
+int fn(void) __attribute__((weak));
+
+int fn(void) {
+   return 1;
+}
+
+//--- b.c
+
+int fn(void) {
+   return 0;
+}
diff --git a/clang/test/Analysis/ctu/test-weak-sym-2.c 
b/clang/test/Analysis/ctu/test-weak-sym-2.c
new file mode 100644
index 0000000000000..6335f38867e00
--- /dev/null
+++ b/clang/test/Analysis/ctu/test-weak-sym-2.c
@@ -0,0 +1,42 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -x c -emit-pch -o %t/a.c.ast %t/a.c
+// RUN: %clang_cc1 -x c -emit-pch -o %t/b.c.ast %t/b.c
+
+// RUN: %clang_extdef_map %t/a.c %t/b.c -- -c -x c > %t/externalDefMap.tmp1.txt
+// RUN: sed -e 's|\.c$|.c.ast|g' %t/externalDefMap.tmp1.txt > 
%t/externalDefMap.tmp2.txt
+// RUN: sed -e 's|%t\/||g' %t/externalDefMap.tmp2.txt > %t/externalDefMap.txt
+
+// RUN: %clang_cc1 -analyze \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config display-ctu-progress=true \
+// RUN:   -analyzer-config ctu-dir=%t \
+// RUN:   -verify %t/main.c 2>&1 | FileCheck %s
+
+//--- main.c
+
+// expected-no-diagnostics
+// CHECK: CTU loaded AST file: a.c.ast
+
+int fn(void);
+
+int main(int argc, char* argv[]) {
+  return fn();
+}
+
+//--- a.c
+
+int fn(void) {
+   return 1;
+}
+
+//--- b.c
+
+int fn(void) __attribute__((weak));
+
+int fn(void) {
+   return 0;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/204188
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to