Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -212,22 +212,11 @@ const Expr *LHS = BO->getLHS(); const Expr *RHS = BO->getRHS(); - // Deal with operations which have composite or void types. - switch (BO->getOpcode()) { - case BO_Comma: - if (!discard(LHS)) - return false; - if (!this->visit(RHS)) - return false; - return true; - default: - break; - } - // Typecheck the args. std::optional LT = classify(LHS->getType()); std::optional RT = classify(RHS->getType()); std::optional T = classify(BO->getType()); + if (!LT || !RT || !T) { return this->bail(BO); } @@ -238,6 +227,13 @@ return DiscardResult ? this->emitPop(*T, BO) : true; }; + // Deal with operations which have composite or void types. + if (BO->isCommaOp()) { + if (!discard(LHS)) + return false; + return Discard(this->visit(RHS)); + } + // Pointer arithmetic special case. if (BO->getOpcode() == BO_Add || BO->getOpcode() == BO_Sub) { if (*T == PT_Ptr || (*LT == PT_Ptr && *RT == PT_Ptr)) Index: clang/test/SemaCXX/constexpr-duffs-device.cpp =================================================================== --- clang/test/SemaCXX/constexpr-duffs-device.cpp +++ clang/test/SemaCXX/constexpr-duffs-device.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -std=c++1y -verify %s +// RUN: %clang_cc1 -std=c++1y -verify -fexperimental-new-constant-interpreter %s // expected-no-diagnostics constexpr void copy(const char *from, unsigned long count, char *to) {