diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -449,6 +449,11 @@ ProgramStateRef stateTrue, stateFalse; + // Assume different address spaces cannot overlap. + if (First.Expression->getType()->getPointeeType().getAddressSpace() != + Second.Expression->getType()->getPointeeType().getAddressSpace()) + return state; + // Get the buffer values and make sure they're known locations. const LocationContext *LCtx = C.getLocationContext(); SVal firstVal = state->getSVal(First.Expression, LCtx); diff --git a/clang/test/Analysis/cstring-checker-addressspace.c b/clang/test/Analysis/cstring-checker-addressspace.c new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/cstring-checker-addressspace.c @@ -0,0 +1,21 @@ +// RUN: %clang_analyze_cc1 -triple amdgcn-unknown-unknown \ +// RUN: -analyze -analyzer-checker=core,alpha.unix.cstring \ +// RUN: -analyze -analyzer-checker=debug.ExprInspection \ +// RUN: -analyzer-config crosscheck-with-z3=true -verify %s +// REQUIRES: z3 + +void clang_analyzer_warnIfReached(); + +#define DEVICE __attribute__((address_space(256))) +_Static_assert(sizeof(int *) == 4, ""); +_Static_assert(sizeof(DEVICE int *) == 8, ""); + +// Copy from host to device memory. +DEVICE void *memcpy(DEVICE void *dst, const void *src, unsigned long len); + +void top(DEVICE int *dst, int *src, int len) { + memcpy(dst, src, len); + + // Create a bugreport for triggering Z3 refutation. + clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}} +}