Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit e4f7210

Browse files
AutomergerAutomerger
authored andcommitted
Propagating prior merge from 'llvm.org/master'.
2 parents 5165413 + f956753 commit e4f7210

File tree

136 files changed

+2934
-540
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

136 files changed

+2934
-540
lines changed

docs/ReleaseNotes.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,29 @@ Static Analyzer
198198
Undefined Behavior Sanitizer (UBSan)
199199
------------------------------------
200200

201+
* The Implicit Conversion Sanitizer (``-fsanitize=implicit-conversion``) group
202+
was extended. One more type of issues is caught - implicit integer sign change.
203+
(``-fsanitize=implicit-integer-sign-change``).
204+
This makes the Implicit Conversion Sanitizer feature-complete,
205+
with only missing piece being bitfield handling.
206+
While there is a ``-Wsign-conversion`` diagnostic group that catches this kind
207+
of issues, it is both noisy, and does not catch **all** the cases.
208+
209+
.. code-block:: c++
210+
211+
bool consume(unsigned int val);
212+
213+
void test(int val) {
214+
(void)consume(val); // If the value was negative, it is now large positive.
215+
(void)consume((unsigned int)val); // OK, the conversion is explicit.
216+
}
217+
218+
Like some other ``-fsanitize=integer`` checks, these issues are **not**
219+
undefined behaviour. But they are not *always* intentional, and are somewhat
220+
hard to track down. This group is **not** enabled by ``-fsanitize=undefined``,
221+
but the ``-fsanitize=implicit-integer-sign-change`` check
222+
is enabled by ``-fsanitize=integer``.
223+
(as is ``-fsanitize=implicit-integer-truncation`` check)
201224

202225
Core Analysis Improvements
203226
==========================

docs/UndefinedBehaviorSanitizer.rst

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ Available checks are:
100100
conversions - when either one, or both of the types are signed.
101101
Issues caught by these sanitizers are not undefined behavior,
102102
but are often unintentional.
103+
- ``-fsanitize=implicit-integer-sign-change``: Implicit conversion between
104+
integer types, if that changes the sign of the value. That is, if the the
105+
original value was negative and the new value is positive (or zero),
106+
or the original value was positive, and the new value is negative.
107+
Issues caught by this sanitizer are not undefined behavior,
108+
but are often unintentional.
103109
- ``-fsanitize=integer-divide-by-zero``: Integer division by zero.
104110
- ``-fsanitize=nonnull-attribute``: Passing null pointer as a function
105111
parameter which is declared to never be null.
@@ -161,17 +167,24 @@ You can also use the following check groups:
161167
``nullability-*`` group of checks.
162168
- ``-fsanitize=undefined-trap``: Deprecated alias of
163169
``-fsanitize=undefined``.
170+
- ``-fsanitize=implicit-integer-truncation``: Catches lossy integral
171+
conversions. Enables ``implicit-signed-integer-truncation`` and
172+
``implicit-unsigned-integer-truncation``.
173+
- ``-fsanitize=implicit-integer-arithmetic-value-change``: Catches implicit
174+
conversions that change the arithmetic value of the integer. Enables
175+
``implicit-signed-integer-truncation`` and ``implicit-integer-sign-change``.
176+
- ``-fsanitize=implicit-conversion``: Checks for suspicious
177+
behaviour of implicit conversions. Enables
178+
``implicit-unsigned-integer-truncation``,
179+
``implicit-signed-integer-truncation`` and
180+
``implicit-integer-sign-change``.
164181
- ``-fsanitize=integer``: Checks for undefined or suspicious integer
165182
behavior (e.g. unsigned integer overflow).
166183
Enables ``signed-integer-overflow``, ``unsigned-integer-overflow``,
167-
``shift``, ``integer-divide-by-zero``, and ``implicit-integer-truncation``.
168-
- ``fsanitize=implicit-integer-truncation``: Checks for implicit integral
169-
conversions that result in data loss.
170-
Enables ``implicit-unsigned-integer-truncation`` and
171-
``implicit-signed-integer-truncation``.
172-
- ``-fsanitize=implicit-conversion``: Checks for suspicious behaviours of
173-
implicit conversions.
174-
Currently, only ``-fsanitize=implicit-integer-truncation`` is implemented.
184+
``shift``, ``integer-divide-by-zero``,
185+
``implicit-unsigned-integer-truncation``,
186+
``implicit-signed-integer-truncation`` and
187+
``implicit-integer-sign-change``.
175188
- ``-fsanitize=nullability``: Enables ``nullability-arg``,
176189
``nullability-assign``, and ``nullability-return``. While violating
177190
nullability does not have undefined behavior, it is often unintentional,

include/clang/AST/Expr.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,65 @@ class Expr : public Stmt {
868868
}
869869
};
870870

871+
//===----------------------------------------------------------------------===//
872+
// Wrapper Expressions.
873+
//===----------------------------------------------------------------------===//
874+
875+
/// FullExpr - Represents a "full-expression" node.
876+
class FullExpr : public Expr {
877+
protected:
878+
Stmt *SubExpr;
879+
880+
FullExpr(StmtClass SC, Expr *subexpr)
881+
: Expr(SC, subexpr->getType(),
882+
subexpr->getValueKind(), subexpr->getObjectKind(),
883+
subexpr->isTypeDependent(), subexpr->isValueDependent(),
884+
subexpr->isInstantiationDependent(),
885+
subexpr->containsUnexpandedParameterPack()), SubExpr(subexpr) {}
886+
FullExpr(StmtClass SC, EmptyShell Empty)
887+
: Expr(SC, Empty) {}
888+
public:
889+
const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
890+
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
891+
892+
/// As with any mutator of the AST, be very careful when modifying an
893+
/// existing AST to preserve its invariants.
894+
void setSubExpr(Expr *E) { SubExpr = E; }
895+
896+
static bool classof(const Stmt *T) {
897+
return T->getStmtClass() >= firstFullExprConstant &&
898+
T->getStmtClass() <= lastFullExprConstant;
899+
}
900+
};
901+
902+
/// ConstantExpr - An expression that occurs in a constant context.
903+
class ConstantExpr : public FullExpr {
904+
public:
905+
ConstantExpr(Expr *subexpr)
906+
: FullExpr(ConstantExprClass, subexpr) {}
907+
908+
/// Build an empty constant expression wrapper.
909+
explicit ConstantExpr(EmptyShell Empty)
910+
: FullExpr(ConstantExprClass, Empty) {}
911+
912+
SourceLocation getBeginLoc() const LLVM_READONLY {
913+
return SubExpr->getBeginLoc();
914+
}
915+
SourceLocation getEndLoc() const LLVM_READONLY {
916+
return SubExpr->getEndLoc();
917+
}
918+
919+
static bool classof(const Stmt *T) {
920+
return T->getStmtClass() == ConstantExprClass;
921+
}
922+
923+
// Iterators
924+
child_range children() { return child_range(&SubExpr, &SubExpr+1); }
925+
const_child_range children() const {
926+
return const_child_range(&SubExpr, &SubExpr + 1);
927+
}
928+
};
929+
871930
//===----------------------------------------------------------------------===//
872931
// Primary Expressions.
873932
//===----------------------------------------------------------------------===//

include/clang/AST/ExprCXX.h

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3031,7 +3031,7 @@ class DependentScopeDeclRefExpr final
30313031
/// potentially-evaluated block literal. The lifetime of a block
30323032
/// literal is the extent of the enclosing scope.
30333033
class ExprWithCleanups final
3034-
: public Expr,
3034+
: public FullExpr,
30353035
private llvm::TrailingObjects<ExprWithCleanups, BlockDecl *> {
30363036
public:
30373037
/// The type of objects that are kept in the cleanup.
@@ -3044,8 +3044,6 @@ class ExprWithCleanups final
30443044
friend class ASTStmtReader;
30453045
friend TrailingObjects;
30463046

3047-
Stmt *SubExpr;
3048-
30493047
ExprWithCleanups(EmptyShell, unsigned NumObjects);
30503048
ExprWithCleanups(Expr *SubExpr, bool CleanupsHaveSideEffects,
30513049
ArrayRef<CleanupObject> Objects);
@@ -3070,17 +3068,10 @@ class ExprWithCleanups final
30703068
return getObjects()[i];
30713069
}
30723070

3073-
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
3074-
const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
3075-
30763071
bool cleanupsHaveSideEffects() const {
30773072
return ExprWithCleanupsBits.CleanupsHaveSideEffects;
30783073
}
30793074

3080-
/// As with any mutator of the AST, be very careful
3081-
/// when modifying an existing AST to preserve its invariants.
3082-
void setSubExpr(Expr *E) { SubExpr = E; }
3083-
30843075
SourceLocation getBeginLoc() const LLVM_READONLY {
30853076
return SubExpr->getBeginLoc();
30863077
}

include/clang/AST/RecursiveASTVisitor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,6 +2199,8 @@ DEF_TRAVERSE_STMT(ReturnStmt, {})
21992199
DEF_TRAVERSE_STMT(SwitchStmt, {})
22002200
DEF_TRAVERSE_STMT(WhileStmt, {})
22012201

2202+
DEF_TRAVERSE_STMT(ConstantExpr, {})
2203+
22022204
DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
22032205
TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
22042206
TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));

0 commit comments

Comments
 (0)