Index: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td =================================================================== --- clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -298,6 +298,12 @@ Dependencies<[PthreadLockBase]>, Documentation; +def StrictAliasingChecker : Checker<"StrictAliasing">, + HelpText<"Check conformity with Strict Alising Rule. Check an access to the " + "stored value through a glvalue whose type is not allowed by " + "the Standard. ([basic.lval])">, + Documentation; + } // end "alpha.core" //===----------------------------------------------------------------------===// Index: clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt =================================================================== --- clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -105,6 +105,7 @@ StdLibraryFunctionsChecker.cpp STLAlgorithmModeling.cpp StreamChecker.cpp + StrictAliasingChecker.cpp StringChecker.cpp Taint.cpp TaintTesterChecker.cpp Index: clang/lib/StaticAnalyzer/Checkers/StrictAliasingChecker.cpp =================================================================== --- /dev/null +++ clang/lib/StaticAnalyzer/Checkers/StrictAliasingChecker.cpp @@ -0,0 +1,207 @@ +//===- StrictAliasingChecker - ... ------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// StrictAliasingChecker implements checks on violation of the next paragraph of +// the Standard which is known as `Strict Aliasing Rule`. +// C++20 7.2.1 p11 [basic.lval]: +// If a program attempts to access the stored value of an object through a +// glvalue whose type is not similar to one of the following types the behavior +// is undefined: +// - the dynamic type of the object, +// - a type that is the signed or unsigned type corresponding to the dynamic +// type of the object, or +// - a char, unsigned char, or std::byte type. +// +// NOTE: The checker operates only when strict-aliasing is enabled with +// corresponding compiler flag. +// +// NOTE: There are differences in strict aliasing rules between C, C++ +// Standards. Now we only impelement checks since C++20 Standard (there were +// changes applied in C++20 http://wg21.link/cwg2051). +// +// TODO: Support C++98/11/14/17. Shall we? +// TODO: Support C. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/Attr.h" +#include "clang/AST/ExprCXX.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" + +using namespace clang; +using namespace ento; + +namespace { + +class AccessInferrer { + QualType From; + QualType To; + ASTContext &Ctx; + +public: + // Check whether the given types submit to the Strict Aliasing Rule. + // + // NOTE: User must provide canonical and unqualified QualType's for the + // correct result. + static bool canAccess(QualType From, QualType To, ASTContext &Ctx) { + // NOTE: Despite the function name `isCanonical()`, it also check whether + // the type is unqualified. (See implementation) + assert(From.isCanonical() && "The type shall be an unqualified canonical."); + assert(To.isCanonical() && "The type shall be an unqualified canonical."); + AccessInferrer AI(From, To, Ctx); + return AI.canAccessImpl(); + } + +private: + AccessInferrer(QualType From, QualType To, ASTContext &Ctx) + : From(From), To(To), Ctx(Ctx) {} + bool canAccessImpl() { + return isSameDynamic() || isCharOrByte() || isOppositeSign(); + } + // - the dynamic type of the object + bool isSameDynamic() { return From == To; } + // - a char, unsigned char, or std::byte type. + bool isCharOrByte() { + return To == Ctx.CharTy || To == Ctx.UnsignedCharTy || To->isStdByteType(); + } + // - a type that is the signed or unsigned type corresponding to the dynamic + // type of the object + bool isOppositeSign() { + // `char` type is a distinct type which has `signed char` or `unsigned char` + // as its underlying type. But there is nowhere in the Standard mentioned + // that `char` has corresponding signed/unsigned types and not mentioned + // that the stored value of an object can be accessed through a type which + // is similar to underlying type of the object. + // The same is true for other fundamental types (`bool`, `char8_t`, + // 'wchar_t', etc.) specified to have a signed or unsigned integer types as + // theirs underlying types. + + if (const auto *BT = dyn_cast(To)) { + BuiltinType::Kind Kind = BT->getKind(); + // `To` is unsigned. + if (((Kind >= BuiltinType::UShort) && (Kind <= BuiltinType::UInt128)) || + (Kind == BuiltinType::UChar)) + return From == Ctx.getCorrespondingSignedType(To); + // `To` is signed. + if (((Kind >= BuiltinType::Short) && (Kind <= BuiltinType::Int128)) || + (Kind == BuiltinType::SChar)) + return From == Ctx.getCorrespondingUnsignedType(To); + } + + return false; + } +}; + +class StrictAliasingChecker : public Checker, + check::PreStmt, + check::PreStmt> { + BugType BT{this, "Strict Aliasing Rule", + "Access Violation through unallowed type."}; + +public: + void checkPreStmt(const UnaryOperator *UO, CheckerContext &C) const { + // Handle indirection operator '*' only. + if (UO->getOpcode() == UO_Deref) + checkAccess(UO->getSubExpr(), UO->getType(), C); + } + void checkPreStmt(const ArraySubscriptExpr *ASE, CheckerContext &C) const { + checkAccess(ASE->getBase(), ASE->getType(), C); + } + void checkPreStmt(const MemberExpr *ME, CheckerContext &C) const { + const Expr *B = ME->getBase()->IgnoreParenBaseCasts(); + checkAccess(B, B->getType()->getPointeeType(), C); + } + +private: + void checkAccess(const Expr *OrigEx, QualType AliasedTy, + CheckerContext &C) const { + AliasedTy = getCanonicalUnqualifiedType(AliasedTy); + // TODO: Handle this case in a proper way, if any. + if (AliasedTy.isNull()) + return; + + const QualType OrigTy = getOriginalType(OrigEx, C); + // TODO: Handle this case in a proper way, if any. + if (OrigTy.isNull()) + return; + + if (!AccessInferrer::canAccess(OrigTy, AliasedTy, C.getASTContext())) + reportBug(C, OrigTy, AliasedTy); + } + + // FIXME: Probably, we should have such function in QualType class. + // Existing `T->getCanonicalTypeUnqualified()` does not return unqualified + // type which, apparently, is expected. + QualType getCanonicalUnqualifiedType(QualType T) const { + if (!T.isNull()) { + T = T->getCanonicalTypeUnqualified(); + T.removeLocalFastQualifiers(); + } + return T; + } + + QualType getOriginalType(const Expr *OrigEx, CheckerContext &C) const { + QualType T; + + SVal V = C.getSVal(OrigEx->IgnoreParens()); + if (V.isUnknownOrUndef()) + return T; + + if (auto MRV = V.getAs()) { + // Unwrap ElementRegion and CXXBaseObjectRegion nesting to get the base + // region. + const MemRegion *Base = MRV->getRegion()->StripCasts(true); + // Get type of the original declaration. + if (const auto *VR = dyn_cast(Base)) + T = VR->getValueType(); + else if (const auto *SR = dyn_cast(Base)) + T = SR->getSymbol()->getType()->getPointeeType(); + // TODO: Support other regions in a proper way if would need. + } + + // Get type from other types. + // NOTE: This is very inaccurate but it's better than NULL though. + if (T.isNull()) + T = V.getType(C.getASTContext()); + + return getCanonicalUnqualifiedType(T); + } + + void reportBug(CheckerContext &C, QualType From, QualType To) const { + SmallString<256> Buf; + llvm::raw_svector_ostream OS(Buf); + OS << "Undefined behavior. Attempting to access the stored value of type "; + OS << "'" << From.getAsString() << "'"; + OS << " through unallowed type "; + OS << "'" << To.getAsString() << "'."; + + ExplodedNode *Node = C.generateNonFatalErrorNode(); + auto Report = std::make_unique(BT, OS.str(), Node); + C.emitReport(std::move(Report)); + } +}; +} // end anonymous namespace + +//===----------------------------------------------------------------------===// +// Registration. +//===----------------------------------------------------------------------===// + +void ento::registerStrictAliasingChecker(CheckerManager &CM) { + CM.registerChecker(); +} + +bool ento::shouldRegisterStrictAliasingChecker(const CheckerManager &CM) { + const LangOptions &LO = CM.getLangOpts(); + const bool IsStrictAliasing = !CM.getCodeGenOpts().RelaxedAliasing; + // Support from C++20 for now. + // TODO: Support C++98/11/14/17. Shall we? + // TODO: Support C. + return IsStrictAliasing && (LO.CPlusPlus20 || LO.CPlusPlus2b); +} Index: clang/test/Analysis/Checkers/StrictAliasingChecker/cv.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/Checkers/StrictAliasingChecker/cv.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -std=c++20 -analyze -analyzer-config eagerly-assume=false -analyzer-checker=debug.ExprInspection,alpha.core.StrictAliasing -verify %s +// NOTE: -relaxed-aliasing flag disables StrictAliasing checker. + +#define CHECK_CV(var, type) \ + { auto y = *(type *)&var; } \ + { auto y = *(const type *)&var; } \ + { auto y = *(const volatile type *)&var; } + +void cv_test() { + int x = 42; + CHECK_CV(x, char) // no-warning + CHECK_CV(x, short) // expected-warning 3{{Undefined behavior}} + + const int cx = 42; + CHECK_CV(cx, char) // no-warning + CHECK_CV(cx, short) // expected-warning 3{{Undefined behavior}} + + const volatile int cvx = 42; + CHECK_CV(cvx, char) // no-warning + CHECK_CV(cvx, short) // expected-warning 3{{Undefined behavior}} +} Index: clang/test/Analysis/Checkers/StrictAliasingChecker/scalar-ptr-to-scalar.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/Checkers/StrictAliasingChecker/scalar-ptr-to-scalar.cpp @@ -0,0 +1,561 @@ +// RUN: %clang_cc1 -std=c++20 -analyze -analyzer-config eagerly-assume=false -analyzer-checker=debug.ExprInspection,alpha.core.StrictAliasing -verify %s +// NOTE: -relaxed-aliasing flag disables StrictAliasing checker. + +template +T *create(); + +#define CHECK(var, type) \ + { auto y = *(type *)var; } + +void bool_test() { + auto *x = create(); + CHECK(x, bool) // no-warning + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void char_test() { + auto *x = create(); + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void short_test() { + auto *x = create(); + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // no-warning + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // no-warning + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void int_test() { + auto *x = create(); + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // no-warning + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // no-warning + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void long_test() { + auto *x = create(); + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // no-warning + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // no-warning + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void long_long_test() { + auto *x = create(); + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // no-warning + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // no-warning + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void schar_test() { + auto *x = create(); + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // no-warning + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void uchar_test() { + auto *x = create(); + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // no-warning + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void ushort_test() { + auto *x = create(); + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // no-warning + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // no-warning + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void uint_test() { + auto *x = create(); + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // no-warning + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // no-warning + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void ulong_test() { + auto *x = create(); + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // no-warning + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // no-warning + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void ulong_long_test() { + auto *x = create(); + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // no-warning + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // no-warning + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void char_test(char *x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void short_test(short *x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // no-warning + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // no-warning + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} +} + +void int_test(int *x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // no-warning + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // no-warning + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void long_test(long *x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // no-warning + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // no-warning + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void long_long_test(long long *x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // no-warning + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // no-warning + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void schar_test(signed char *x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // no-warning + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void uchar_test(unsigned char *x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // no-warning + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} +} + +void ushort_test(unsigned short *x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // no-warning + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // no-warning + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void uint_test(unsigned int *x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // no-warning + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // no-warning + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void ulong_test(unsigned long *x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // no-warning + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // no-warning + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void ulong_long_test(unsigned long long *x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // no-warning + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // no-warning + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void float_test() { + auto *x = create(); + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // no-warning + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void double_test() { + auto *x = create(); + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // no-warning + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void long_double_test() { + auto *x = create(); + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // no-warning +} Index: clang/test/Analysis/Checkers/StrictAliasingChecker/scalar-var-to-scalar.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/Checkers/StrictAliasingChecker/scalar-var-to-scalar.cpp @@ -0,0 +1,650 @@ +// RUN: %clang_cc1 -std=c++20 -analyze -analyzer-config eagerly-assume=false -analyzer-checker=debug.ExprInspection,alpha.core.StrictAliasing -verify %s +// NOTE: -relaxed-aliasing flag disables StrictAliasing checker. + +#define CHECK(var, type) \ + { auto y = *(type *)&var; } + +void bool_test() { + bool x = true; + CHECK(x, bool) // no-warning + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void char_test() { + char x = 42; + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void short_test() { + short x = 42; + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // no-warning + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // no-warning + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void int_test() { + int x = 42; + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // no-warning + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // no-warning + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void long_test() { + long x = 42; + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // no-warning + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // no-warning + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void long_long_test() { + long long x = 42; + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // no-warning + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // no-warning + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void schar_test() { + signed char x = 42; + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // no-warning + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void uchar_test() { + unsigned char x = 42; + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // no-warning + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void ushort_test() { + unsigned short x = 42; + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // no-warning + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // no-warning + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void uint_test() { + unsigned int x = 42; + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // no-warning + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // no-warning + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void ulong_test() { + unsigned long x = 42; + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // no-warning + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // no-warning + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void ulong_long_test() { + unsigned long long x = 42; + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // no-warning + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // no-warning + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void float_test() { + float x = 42; + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // no-warning + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void double_test() { + double x = 42; + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // no-warning + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void long_double_test() { + long double x = 42; + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // no-warning +} + +void bool_test(bool x) { + CHECK(x, bool) // no-warning + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void char_test(char x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void short_test(short x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // no-warning + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // no-warning + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void int_test(int x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // no-warning + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // no-warning + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void long_test(long x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // no-warning + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // no-warning + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void long_long_test(long long x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // no-warning + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // no-warning + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void schar_test(signed char x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // no-warning + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void uchar_test(unsigned char x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // no-warning + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void ushort_test(unsigned short x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // no-warning + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // no-warning + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void uint_test(unsigned int x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // no-warning + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // no-warning + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void ulong_test(unsigned long x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // no-warning + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // no-warning + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void ulong_long_test(unsigned long long x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // no-warning + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // no-warning + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void float_test(float x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // no-warning + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void double_test(double x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // no-warning + CHECK(x, long double) // expected-warning {{Undefined behavior}} +} + +void long_double_test(long double x) { + CHECK(x, bool) // expected-warning {{Undefined behavior}} + + CHECK(x, char) // no-warning + CHECK(x, short) // expected-warning {{Undefined behavior}} + CHECK(x, int) // expected-warning {{Undefined behavior}} + CHECK(x, long) // expected-warning {{Undefined behavior}} + CHECK(x, long long) // expected-warning {{Undefined behavior}} + + CHECK(x, signed char) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned char) // no-warning + CHECK(x, unsigned short) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned int) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long) // expected-warning {{Undefined behavior}} + CHECK(x, unsigned long long) // expected-warning {{Undefined behavior}} + + CHECK(x, float) // expected-warning {{Undefined behavior}} + CHECK(x, double) // expected-warning {{Undefined behavior}} + CHECK(x, long double) // no-warning +} Index: clang/test/Analysis/Checkers/StrictAliasingChecker/typedef.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/Checkers/StrictAliasingChecker/typedef.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -std=c++20 -analyze -analyzer-config eagerly-assume=false -analyzer-checker=debug.ExprInspection,alpha.core.StrictAliasing -verify %s +// NOTE: -relaxed-aliasing flag disables StrictAliasing checker. + +typedef int MyInt; +typedef MyInt MyAnotherInt; +typedef char MyChar; +typedef short MyShort; +typedef MyChar *MyCharPtr; +typedef MyShort *MyShortPtr; +typedef MyInt *MyIntPtr; + +MyAnotherInt x = 42; + +void typedef_test() { + MyChar y1 = *(MyCharPtr)&x; // no-warning + MyShort y2 = *(MyShortPtr)&x; // expected-warning{{Undefined behavior}} + MyInt y3 = *(MyIntPtr)&x; // no-warning +}