diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc
index 9b746be231ae34ccd0664deaf5a14be091d780c8..da0a65c613d3b07787034bcc95b33e19894d6268 100644
--- a/gcc/cp/except.cc
+++ b/gcc/cp/except.cc
@@ -1253,7 +1253,7 @@ build_noexcept_spec (tree expr, tsubst_flags_t complain)
   if (check_for_bare_parameter_packs (expr))
     return error_mark_node;
   if (TREE_CODE (expr) != DEFERRED_NOEXCEPT
-      && !value_dependent_expression_p (expr))
+      && !instantiation_dependent_expression_p (expr))
     {
       expr = build_converted_constant_bool_expr (expr, complain);
       expr = instantiate_non_dependent_expr_sfinae (expr, complain);
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 9153c74f0694de2ddf3053da6966c2492a80992d..5c342ca631b371ce5762133cd1eda259f746ebc3 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -7958,7 +7958,6 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
 static cp_expr
 cp_parser_parenthesized_expression_list_elt (cp_parser *parser, bool cast_p,
 					     bool allow_expansion_p,
-					     bool fold_expr_p,
 					     bool *non_constant_p)
 {
   cp_expr expr (NULL_TREE);
@@ -7985,9 +7984,6 @@ cp_parser_parenthesized_expression_list_elt (cp_parser *parser, bool cast_p,
   else
     expr = cp_parser_assignment_expression (parser, /*pidk=*/NULL, cast_p);
 
-  if (fold_expr_p)
-    expr = instantiate_non_dependent_expr (expr);
-
   /* If we have an ellipsis, then this is an expression expansion.  */
   if (allow_expansion_p
       && cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
@@ -8053,8 +8049,6 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
 							       false,
 							       /*allow_exp_p=*/
 							       true,
-							       /*fold_expr_p=*/
-							       false,
 							       /*non_cst_p=*/
 							       NULL);
 
@@ -8424,7 +8418,6 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
 					 bool wrap_locations_p)
 {
   vec<tree, va_gc> *expression_list;
-  bool fold_expr_p = is_attribute_list != non_attr;
   tree identifier = NULL_TREE;
   bool saved_greater_than_is_operator_p;
 
@@ -8467,7 +8460,6 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
 	    expr
 	      = cp_parser_parenthesized_expression_list_elt (parser, cast_p,
 							     allow_expansion_p,
-							     fold_expr_p,
 							     non_constant_p);
 
 	    if (wrap_locations_p)
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index f8069b2ea0ebace2a6dcd9d388f103c419ebeb87..f7ee33a6dfd130e8c556abd436dc54c354de9210 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -3817,7 +3817,7 @@ expand_integer_pack (tree call, tree args, tsubst_flags_t complain,
   tree hi = tsubst_copy_and_build (ohi, args, complain, in_decl,
 				   false/*fn*/, true/*int_cst*/);
 
-  if (value_dependent_expression_p (hi))
+  if (instantiation_dependent_expression_p (hi))
     {
       if (hi != ohi)
 	{
@@ -6349,9 +6349,7 @@ redeclare_class_template (tree type, tree parms, tree cons)
 
 /* The actual substitution part of instantiate_non_dependent_expr_sfinae,
    to be used when the caller has already checked
-   (processing_template_decl
-    && !instantiation_dependent_expression_p (expr)
-    && potential_constant_expression (expr))
+    !instantiation_dependent_uneval_expression_p (expr)
    and cleared processing_template_decl.  */
 
 tree
@@ -6365,8 +6363,7 @@ instantiate_non_dependent_expr_internal (tree expr, tsubst_flags_t complain)
 				/*integral_constant_expression_p=*/true);
 }
 
-/* Simplify EXPR if it is a non-dependent expression.  Returns the
-   (possibly simplified) expression.  */
+/* Instantiate the non-dependent expression EXPR.  */
 
 tree
 instantiate_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain)
@@ -6374,16 +6371,10 @@ instantiate_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain)
   if (expr == NULL_TREE)
     return NULL_TREE;
 
-  /* If we're in a template, but EXPR isn't value dependent, simplify
-     it.  We're supposed to treat:
-
-       template <typename T> void f(T[1 + 1]);
-       template <typename T> void f(T[2]);
-
-     as two declarations of the same function, for example.  */
-  if (processing_template_decl
-      && is_nondependent_constant_expression (expr))
+  if (processing_template_decl)
     {
+      /* The caller should have checked this already.  */
+      gcc_checking_assert (!instantiation_dependent_uneval_expression_p (expr));
       processing_template_decl_sentinel s;
       expr = instantiate_non_dependent_expr_internal (expr, complain);
     }
@@ -6396,8 +6387,8 @@ instantiate_non_dependent_expr (tree expr)
   return instantiate_non_dependent_expr_sfinae (expr, tf_error);
 }
 
-/* Like instantiate_non_dependent_expr, but return NULL_TREE rather than
-   an uninstantiated expression.  */
+/* Like instantiate_non_dependent_expr, but return NULL_TREE if the
+   expression is dependent or non-constant.  */
 
 tree
 instantiate_non_dependent_or_null (tree expr)
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index a2c0eb050e649416bc75d601e502b04011ee2867..799ce943279f976d42cc4c3b6611a5d50f6aaec9 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -11217,6 +11217,8 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
   /* decltype is an unevaluated context.  */
   cp_unevaluated u;
 
+  processing_template_decl_sentinel ptds (/*reset=*/false);
+
   /* Depending on the resolution of DR 1172, we may later need to distinguish
      instantiation-dependent but not type-dependent expressions so that, say,
      A<decltype(sizeof(T))>::U doesn't require 'typename'.  */
@@ -11235,6 +11237,10 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
       expr = instantiate_non_dependent_expr_sfinae (expr, complain);
       if (expr == error_mark_node)
 	return error_mark_node;
+      /* Keep processing_template_decl cleared for the rest of the function
+	 (for sake of the call to lvalue_kind below, which handles templated
+	 and non-templated COND_EXPR differently).  */
+      processing_template_decl = 0;
     }
 
   /* The type denoted by decltype(e) is defined as follows:  */
diff --git a/gcc/testsuite/g++.dg/cpp0x/Wnarrowing19.C b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing19.C
new file mode 100644
index 0000000000000000000000000000000000000000..77357016502838b0067ba3d0d76dd15ee904aec3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing19.C
@@ -0,0 +1,6 @@
+// PR c++/104823
+// { dg-do compile { target c++11 } }
+
+struct S { S(int); };
+double id(double);
+template<class> auto f(double v) -> decltype(S{id(v)}); // { dg-error "narrowing" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-attribute4.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-attribute4.C
new file mode 100644
index 0000000000000000000000000000000000000000..c52d58f8d32930061aa961d6ef0f445d21ebfd20
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-attribute4.C
@@ -0,0 +1,14 @@
+// Verify we correctly handle the non-dependent attribute expression which
+// which we used to reject due to double folding.
+// { dg-do compile { target { c++11 } } }
+
+struct A {
+  constexpr int f() const { return __alignof__(int); };
+};
+
+template<class...>
+void f() {
+  int a __attribute__((aligned(A{}.f())));
+}
+
+template void f();