https://github.com/Aadhu23 updated 
https://github.com/llvm/llvm-project/pull/226207

>From ff729b39e00948fb77e51a47f3a35bd3cb4a4477 Mon Sep 17 00:00:00 2001
From: Aadhu23 <[email protected]>
Date: Thu, 24 Sep 2026 04:37:55 +0530
Subject: [PATCH] [InferAttrs] Avoid conflicting argument memory attributes

---
 clang/test/CodeGen/inferattrs-const-variadic.c     |  6 ++++++
 llvm/lib/Transforms/Utils/BuildLibCalls.cpp        | 14 ++++++++++++--
 .../argument-memory-attributes.ll                  | 10 ++++++++++
 3 files changed, 28 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/CodeGen/inferattrs-const-variadic.c
 create mode 100644 
llvm/test/Transforms/InferFunctionAttrs/argument-memory-attributes.ll

diff --git a/clang/test/CodeGen/inferattrs-const-variadic.c 
b/clang/test/CodeGen/inferattrs-const-variadic.c
new file mode 100644
index 00000000000000..fffeb0c9b1ec80
--- /dev/null
+++ b/clang/test/CodeGen/inferattrs-const-variadic.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -O1 -triple x86_64-unknown-linux-gnu -emit-llvm -o 
/dev/null -verify %s
+// expected-no-diagnostics
+
+int __attribute__((const)) snprintf(char *, __SIZE_TYPE__, const char *, ...);
+
+long foo(char c, long d) { return snprintf(&c, d, ""); }
diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp 
b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
index fa61a18de15de3..2b70a0dbf0d231 100644
--- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -205,7 +205,13 @@ static bool setDoesNotSync(Function &F) {
 }
 
 static bool setOnlyReadsMemory(Function &F, unsigned ArgNo) {
-  if (F.hasParamAttribute(ArgNo, Attribute::ReadOnly))
+  // readnone, readonly, and writeonly are mutually exclusive.  In particular,
+  // a frontend can add readnone to a const variadic function's fixed pointer
+  // arguments before libcall inference runs.  Do not add a conflicting
+  // inferred attribute.
+  if (F.hasParamAttribute(ArgNo, Attribute::ReadNone) ||
+      F.hasParamAttribute(ArgNo, Attribute::ReadOnly) ||
+      F.hasParamAttribute(ArgNo, Attribute::WriteOnly))
     return false;
   F.addParamAttr(ArgNo, Attribute::ReadOnly);
   ++NumReadOnlyArg;
@@ -213,7 +219,11 @@ static bool setOnlyReadsMemory(Function &F, unsigned 
ArgNo) {
 }
 
 static bool setOnlyWritesMemory(Function &F, unsigned ArgNo) {
-  if (F.hasParamAttribute(ArgNo, Attribute::WriteOnly))
+  // See setOnlyReadsMemory above.  Preserve an existing access attribute
+  // rather than creating an invalid combination with an inferred one.
+  if (F.hasParamAttribute(ArgNo, Attribute::ReadNone) ||
+      F.hasParamAttribute(ArgNo, Attribute::ReadOnly) ||
+      F.hasParamAttribute(ArgNo, Attribute::WriteOnly))
     return false;
   F.addParamAttr(ArgNo, Attribute::WriteOnly);
   ++NumWriteOnlyArg;
diff --git 
a/llvm/test/Transforms/InferFunctionAttrs/argument-memory-attributes.ll 
b/llvm/test/Transforms/InferFunctionAttrs/argument-memory-attributes.ll
new file mode 100644
index 00000000000000..94b1414cf9153a
--- /dev/null
+++ b/llvm/test/Transforms/InferFunctionAttrs/argument-memory-attributes.ll
@@ -0,0 +1,10 @@
+; RUN: opt -mtriple=x86_64-unknown-linux-gnu -passes=inferattrs,verify -S %s | 
FileCheck %s
+
+; A const variadic declaration can already have readnone on its fixed pointer
+; arguments.  Libcall inference must not add conflicting access attributes.
+; CHECK: declare noundef i32 @snprintf(ptr {{.*}}readnone{{.*}}, i64 noundef, 
ptr {{.*}}readnone{{.*}}, ...)
+declare i32 @snprintf(ptr readnone, i64, ptr readnone, ...)
+
+; The same applies to sprintf, which exercises both inferred access directions.
+; CHECK: declare noundef i32 @sprintf(ptr {{.*}}readnone{{.*}}, ptr 
{{.*}}readnone{{.*}}, ...)
+declare i32 @sprintf(ptr readnone, ptr readnone, ...)

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

Reply via email to