diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-09-17 06:31:27 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-09-17 06:31:27 +0000 |
commit | 687fa86a3083a8895f156265d1750c6d8c29ddfb (patch) | |
tree | 87e18ed13d88847267b433a0aa458cda864f8ea8 | |
parent | 4782a6ead5408cf55e086fd4f4e37558437f742d (diff) | |
download | bcm5719-llvm-687fa86a3083a8895f156265d1750c6d8c29ddfb.tar.gz bcm5719-llvm-687fa86a3083a8895f156265d1750c6d8c29ddfb.zip |
Fix two crashes on value dependent expressions (shift and null-pointer check).
- Doug, please check.
- PR4940.
llvm-svn: 82129
-rw-r--r-- | clang/lib/AST/Expr.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 3 | ||||
-rw-r--r-- | clang/test/SemaCXX/value-dependent-exprs.cpp | 44 |
3 files changed, 49 insertions, 1 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 5682eb6dd55..d7565c7bbef 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1626,6 +1626,9 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, /// integer constant expression with the value zero, or if this is one that is /// cast to void*. bool Expr::isNullPointerConstant(ASTContext &Ctx) const { + // Ignore value dependent expressions. + if (isValueDependent()) + return true; // Strip off a cast to void*, if it exists. Except in C++. if (const ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(this)) { if (!Ctx.getLangOptions().CPlusPlus) { diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 7b23486d5fd..70e137462f4 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4339,7 +4339,8 @@ QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, // Sanity-check shift operands llvm::APSInt Right; // Check right/shifter operand - if (rex->isIntegerConstantExpr(Right, Context)) { + if (!rex->isValueDependent() && + rex->isIntegerConstantExpr(Right, Context)) { if (Right.isNegative()) Diag(Loc, diag::warn_shift_negative) << rex->getSourceRange(); else { diff --git a/clang/test/SemaCXX/value-dependent-exprs.cpp b/clang/test/SemaCXX/value-dependent-exprs.cpp new file mode 100644 index 00000000000..603da9b38e9 --- /dev/null +++ b/clang/test/SemaCXX/value-dependent-exprs.cpp @@ -0,0 +1,44 @@ +// RUN: clang-cc -verify %s + +template <unsigned I> +class C0 { + static const int iv0 = 1 << I; + + enum { + A = I, + B = I + 1 + }; + + struct s0 { + int a : I; + int b[I]; + }; + + void f0(int *p) { + if (p == I) { + } + } + +#if 0 + // FIXME: Not sure whether we care about these. + void f1(int *a) + __attribute__((nonnull(1 + I))) + __attribute__((constructor(1 + I))) + __attribute__((destructor(1 + I))) + __attribute__((sentinel(1 + I, 2 + I))), + __attribute__((reqd_work_group_size(1 + I, 2 + I, 3 + I))), + __attribute__((format_arg(1 + I))), + __attribute__((aligned(1 + I))), + __attribute__((regparm(1 + I))); + + typedef int int_a0 __attribute__((address_space(1 + B))); +#endif + +#if 0 + // FIXME: This doesn't work. PR4996. + int f2() { + return __builtin_choose_expr(I, 1, 2); + } +#endif + +}; |