Error on capturing return value in before advice.
authorJustin Seyster <jseyster@cs.sunysb.edu>
Mon, 5 Jul 2010 20:55:05 +0000 (16:55 -0400)
committerJustin Seyster <jseyster@cs.sunysb.edu>
Mon, 5 Jul 2010 20:55:05 +0000 (16:55 -0400)
src/aop-pc-fun-call.c
src/aop-weave.c

index a900f45a9307f3b06a6477dde334b925d15bcc2e..fa7a82d247899e5a7dde085b35e0cf01ab8a708f 100644 (file)
@@ -323,6 +323,10 @@ aop_capture_called_function_name(struct aop_joinpoint *jp)
  * Get a dynval representing a function call's return value.  Note
  * that you must filter with aop_filter_call_pc_by_return_type() in
  * order to capture the return value using aop_capture_return_value().
+ *
+ * Note that it is illegal to pass the resulting aop_dynval to
+ * aop_insert_advice() with #AOP_INSERT_BEFORE, as that would require
+ * the function's return value to be known before it exectues.
  * \param jp A function call join point.  Function call join points
  * are obtained by joining on an aop_match_function_call() pointcut.
  * \return A dynval with its type determined by
index ce2d86c9b7571f0b307335776061ba99adc66376..6ee9d6dad60ae33adc0c697e7a59590dc979029d 100644 (file)
 #include <tm.h>
 #include <tree.h>
 #include <gimple.h>
+#include <toplev.h>
 
 #include "aop.h"
 #include "aop-dynval.h"
 #include "aop-pointcut.h"
 
+/* Throw a fatal error if a dynval is not allowed in a before-advice
+   call. */
+static void
+verify_legal_in_before_advice (struct aop_dynval *dv)
+{
+  switch (dv->kind)
+    {
+    case ADV_FUN_RETVAL:
+      fatal_error("(InterAspect) Attempt to capture return value in"
+                 " before advice (see aop_capture_return_value()"
+                 " documentation).");
+    default:
+      break;  /* Permitted. */
+    }
+}
+
 static tree
 build_string_ptr (const char *string)
 {
@@ -78,7 +95,8 @@ build_dynval (struct aop_dynval *dv)
 
    The new nodes get stored in arglist. */
 static gimple
-build_gcc_call (const char *func_name, tree return_type, va_list argp)
+build_gcc_call (const char *func_name, tree return_type,
+               enum aop_insert_location location, va_list argp)
 {
   enum aop_argkind kind;
   VEC(tree, heap) *arg_list;
@@ -106,6 +124,11 @@ build_gcc_call (const char *func_name, tree return_type, va_list argp)
          break;
        case ATA_DYNVAL:
          dv = va_arg (argp, struct aop_dynval *);
+
+         /* Some dynvals aren't permitted in before advice. */
+         if (location == AOP_INSERT_BEFORE)
+           verify_legal_in_before_advice (dv);
+
          new_arg = build_dynval (dv);
          VEC_safe_push (tree, heap, arg_list, new_arg);
          break;
@@ -201,7 +224,7 @@ aop_insert_advice (struct aop_joinpoint *jp, const char *func_name,
     }
 
   va_start (argp, location);
-  func_call = build_gcc_call (func_name, void_type_node, argp);
+  func_call = build_gcc_call (func_name, void_type_node, location, argp);
   va_end (argp);
   
   if(location == AOP_INSERT_BEFORE)