================
@@ -1165,7 +1165,112 @@ void 
Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD,
 
   unsigned BuiltinID = UseDecl->getBuiltinID(/*ConsiderWrappers=*/true);
 
-  if (!BuiltinID)
+  // Some libc I/O functions are intentionally not Clang builtins:
+  //   * "read", "write", "readlink", "readlinkat", and "getcwd" are common
+  //     identifiers (or names that appear in asm-label wrappers); declaring
+  //     them as builtins triggers -Wincompatible-library-redeclaration on
+  //     harmless local declarations (an error under -Werror).
+  //   * pread/pwrite prototypes use off_t, whose width is platform- and
+  //     macro-dependent (notably _FILE_OFFSET_BITS); a fixed builtin signature
+  //     would clash with the system header on some targets.
+  // Recognize them by name, but only after checking the full POSIX prototype
+  // so that an unrelated function happening to share the name is not
+  // diagnosed as if it were the libc function.
+  enum class LibCDispatch {
+    None,
+    Read,
+    Write,
+    PRead,
+    PWrite,
+    ReadLink,
+    ReadLinkAt,
+    GetCWD,
+  };
+  LibCDispatch LibC = LibCDispatch::None;
+  StringRef LibCName;
+  if (!BuiltinID && FD->isExternC() && FD->getIdentifier() &&
----------------
nuclearcat wrote:

Thanks, I agree, table + one equivalence loop would read much better. Sorry for 
the back and forth on this, I just want to make sure we get the libc-divergence 
edge cases right.
The issue is that three of the types we're matching aren't fixed QualTypes:

ssize_t is long on glibc but int on musl/Bionic/ILP32, so 
hasSameUnqualifiedType against any single expected type rejects one libc or the 
other. The current code matches structurally (signed int, width == size_t 
width).
off_t width depends on _FILE_OFFSET_BITS;
pread vs pread64 can't be told apart by type equivalence at all, both are just 
typedefs to a signed int in the AST, so the disambiguator has to be name + 
width.

We could look those up as typedefs from the AST, but that's the same 
triple-hardcoding pattern you (rightly) pushed back on in the poll PR.

What I think works: i can keep a table of expected signatures, but let each 
parameter slot be either a QualType or a small predicate (SSizeTLike, OffTLike, 
Off64TLike). Generic equivalence loop dispatches on the variant. Most slots 
collapse to QualType; only the irregular ones use a predicate. That readability 
win without breaking the ibc-divergence edge cases.

If you like that, I'll proceed with the implementation. If you have a better 
idea, I'm all ears!

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

Reply via email to