]> granicus.if.org Git - clang/commitdiff
Fix two crashes on value dependent expressions (shift and null-pointer check).
authorDaniel Dunbar <daniel@zuster.org>
Thu, 17 Sep 2009 06:31:27 +0000 (06:31 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 17 Sep 2009 06:31:27 +0000 (06:31 +0000)
 - Doug, please check.

 - PR4940.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82129 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/Expr.cpp
lib/Sema/SemaExpr.cpp
test/SemaCXX/value-dependent-exprs.cpp [new file with mode: 0644]

index 5682eb6dd55b1171bb2212070e86c7f8fdc6810a..d7565c7bbef0d2ce1d74cd20e2e550a07f9ceabe 100644 (file)
@@ -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) {
index 7b23486d5fd732aaa71b9114b15e88860511a126..70e137462f46f1ba852d8babd27706b00160c075 100644 (file)
@@ -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/test/SemaCXX/value-dependent-exprs.cpp b/test/SemaCXX/value-dependent-exprs.cpp
new file mode 100644 (file)
index 0000000..603da9b
--- /dev/null
@@ -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
+
+};