llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.95k stars 11.53k forks source link

bad fixit for Wstrncat-size in macro #17574

Open llvmbot opened 11 years ago

llvmbot commented 11 years ago
Bugzilla Link 17200
Version trunk
OS Linux
Reporter LLVM Bugzilla Contributor
CC @efriedma-quic

Extended Description

Example:

nlewycky@ducttape:~$ llvm/Debug+Asserts/bin/clang -fsyntax-only strncat-macro.c
In file included from strncat-macro.c:1:
./strncat-hdr.h:6:24: warning: the value of the size argument in 'strncat' is
      too large, might lead to a buffer overflow [-Wstrncat-size]
    (strncat((A), (B), sizeof(A)-strlen(A)), *((A)+sizeof(A)-1) = '\0')
                       ^~~~~~~~~~~~~~~~~~~
./strncat-hdr.h:5:24: note: change the argument to be the free space in the
      destination buffer minus the terminating null byte
    (strncat((A), (B), sizeof(A)-strlen(A)), *((A)+sizeof(A)-1) = '\0')
                       ^~~~~~~~~~~~~~~~~~~
                       sizeof(dtString) - strlen(dtString) - 1
1 warning generated.

Of course writing in "dtString" for macro argument "A" isn't right. Here's the two-file testcase: nlewycky@ducttape:~$ cat strncat-macro.c

#include "strncat-hdr.h"

void test() {
  char dtString[64];
  char usecString[64];
  STRSCAT(dtString, usecString);
}

nlewycky@ducttape:~$ cat strncat-hdr.h

#define strncat(dest, src, n) __builtin_strncat (dest, src, n)
unsigned long strlen(const char *s);

#define STRSCAT(A,B) \
    (strncat((A), (B), sizeof(A)-strlen(A)), *((A)+sizeof(A)-1) = '\0'
efriedma-quic commented 11 years ago

The problem is this bit of code in SemaChecking.cpp:

// If the function is defined as a builtin macro, do not show macro expansion. if (SM.isMacroArgExpansion(SL)) { SL = SM.getSpellingLoc(SL); SR = SourceRange(SM.getSpellingLoc(SR.getBegin()), SM.getSpellingLoc(SR.getEnd())); }

Not sure what the correct logic is off the top of my head.