Index: wp-includes/shortcodes.php
===================================================================
--- wp-includes/shortcodes.php	(revision 7594)
+++ wp-includes/shortcodes.php	(working copy)
@@ -67,17 +67,24 @@
 }
 
 function do_shortcode($content) {
+	$pattern = get_shortcode_regex();
+	if ( !$pattern )
+		return $content;
+	else
+		return preg_replace_callback('/' . $pattern . '/s', 'do_shortcode_tag', $content);
+}
+
+// Note: this returns a partial regex for integration into a larger regex. Your final regex should use "/" as delimiters and use the "s" switch
+function get_shortcode_regex() {
 	global $shortcode_tags;
 
 	if (empty($shortcode_tags) || !is_array($shortcode_tags))
-		return $content;
+		return false;
 
 	$tagnames = array_keys($shortcode_tags);
+
 	$tagregexp = join( '|', array_map('preg_quote', $tagnames) );
-
-	$pattern = '/\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\1\])?/s';
-
-	return preg_replace_callback($pattern, 'do_shortcode_tag', $content);
+	return '\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\1\])?';
 }
 
 function do_shortcode_tag($m) {
Index: wp-includes/formatting.php
===================================================================
--- wp-includes/formatting.php	(revision 7594)
+++ wp-includes/formatting.php	(working copy)
@@ -74,6 +74,7 @@
 	$pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
 	$pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n", $pee); // make paragraphs, including one at the end
 	$pee = preg_replace('|<p>\s*?</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
+	$pee = preg_replace('/<p>(\s*?' . get_shortcode_regex() . '\s*)<\/p>/s', '$1', $pee); // don't auto-p wrap block-level shortcodes
 	$pee = preg_replace('!<p>([^<]+)\s*?(</(?:div|address|form)[^>]*>)!', "<p>$1</p>$2", $pee);
 	$pee = preg_replace( '|<p>|', "$1<p>", $pee );
 	$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag
